wp-plugin-development
Use when developing WordPress plugins: architecture and hooks, activation/deactivation/uninstall, admin UI and Settings API, data storage, cron/tasks, security (nonces/capabilities/sanitization/escaping), and release packaging.
Packaged view
This page reorganizes the original catalog entry around fit, installability, and workflow context first. The original raw source lives below.
Install command
npx @skill-hub/cli install wordpress-agent-skills-wp-plugin-development
Repository
Skill path: skills/wp-plugin-development
Use when developing WordPress plugins: architecture and hooks, activation/deactivation/uninstall, admin UI and Settings API, data storage, cron/tasks, security (nonces/capabilities/sanitization/escaping), and release packaging.
Open repositoryBest for
Primary workflow: Analyze Data & AI.
Technical facets: Full Stack, Frontend, Backend, Data / AI, Security, Integration.
Target audience: everyone.
License: Unknown.
Original source
Catalog source: SkillHub Club.
Repository owner: WordPress.
This is still a mirrored public skill entry. Review the repository before installing into production workflows.
What it helps with
- Install wp-plugin-development into Claude Code, Codex CLI, Gemini CLI, or OpenCode workflows
- Review https://github.com/WordPress/agent-skills before adding wp-plugin-development to shared team environments
- Use wp-plugin-development for development workflows
Works across
Favorites: 0.
Sub-skills: 0.
Aggregator: No.
Original source / Raw SKILL.md
--- name: wp-plugin-development description: "Use when developing WordPress plugins: architecture and hooks, activation/deactivation/uninstall, admin UI and Settings API, data storage, cron/tasks, security (nonces/capabilities/sanitization/escaping), and release packaging." compatibility: "Targets WordPress 6.9+ (PHP 7.2.24+). Filesystem-based agent with bash + node. Some workflows require WP-CLI." --- # WP Plugin Development ## When to use Use this skill for plugin work such as: - creating or refactoring plugin structure (bootstrap, includes, namespaces/classes) - adding hooks/actions/filters - activation/deactivation/uninstall behavior and migrations - adding settings pages / options / admin UI (Settings API) - security fixes (nonces, capabilities, sanitization/escaping, SQL safety) - packaging a release (build artifacts, readme, assets) ## Inputs required - Repo root + target plugin(s) (path to plugin main file if known). - Where this plugin runs: single site vs multisite; WP.com conventions if applicable. - Target WordPress + PHP versions (affects available APIs and placeholder support in `$wpdb->prepare()`). ## Procedure ### 0) Triage and locate plugin entrypoints 1. Run triage: - `node skills/wp-project-triage/scripts/detect_wp_project.mjs` 2. Detect plugin headers (deterministic scan): - `node skills/wp-plugin-development/scripts/detect_plugins.mjs` If this is a full site repo, pick the specific plugin under `wp-content/plugins/` or `mu-plugins/` before changing code. ### 1) Follow a predictable architecture Guidelines: - Keep a single bootstrap (main plugin file with header). - Avoid heavy side effects at file load time; load on hooks. - Prefer a dedicated loader/class to register hooks. - Keep admin-only code behind `is_admin()` (or admin hooks) to reduce frontend overhead. See: - `references/structure.md` ### 2) Hooks and lifecycle (activation/deactivation/uninstall) Activation hooks are fragile; follow guardrails: - register activation/deactivation hooks at top-level, not inside other hooks - flush rewrite rules only when needed and only after registering CPTs/rules - uninstall should be explicit and safe (`uninstall.php` or `register_uninstall_hook`) See: - `references/lifecycle.md` ### 3) Settings and admin UI (Settings API) Prefer Settings API for options: - `register_setting()`, `add_settings_section()`, `add_settings_field()` - sanitize via `sanitize_callback` See: - `references/settings-api.md` ### 4) Security baseline (always) Before shipping: - Validate/sanitize input early; escape output late. - Use nonces to prevent CSRF *and* capability checks for authorization. - Avoid directly trusting `$_POST` / `$_GET`; use `wp_unslash()` and specific keys. - Use `$wpdb->prepare()` for SQL; avoid building SQL with string concatenation. See: - `references/security.md` ### 5) Data storage, cron, migrations (if needed) - Prefer options for small config; custom tables only if necessary. - For cron tasks, ensure idempotency and provide manual run paths (WP-CLI or admin). - For schema changes, write upgrade routines and store schema version. See: - `references/data-and-cron.md` ## Verification - Plugin activates with no fatals/notices. - Settings save and read correctly (capability + nonce enforced). - Uninstall removes intended data (and nothing else). - Run repo lint/tests (PHPUnit/PHPCS if present) and any JS build steps if the plugin ships assets. ## Failure modes / debugging - Activation hook not firing: - hook registered incorrectly (not in main file scope), wrong main file path, or plugin is network-activated - Settings not saving: - settings not registered, wrong option group, missing capability, nonce failure - Security regressions: - nonce present but missing capability checks; or sanitized input not escaped on output See: - `references/debugging.md` ## Escalation For canonical detail, consult the Plugin Handbook and security guidelines before inventing patterns. --- ## Referenced Files > The following files are referenced in this skill and included for context. ### references/structure.md ```markdown # Plugin structure and loading Use this file when introducing or refactoring a plugin architecture. ## Core concepts - Main plugin file contains the plugin header and bootstraps the plugin. - Prefer predictable init: - minimal boot file - a loader/class that registers hooks - admin-only code behind admin hooks Upstream reference: - https://developer.wordpress.org/plugins/plugin-basics/ ``` ### references/lifecycle.md ```markdown # Activation, deactivation, uninstall Use this file for lifecycle changes and data cleanup. ## Activation / deactivation hooks - `register_activation_hook( __FILE__, 'callback' )` - `register_deactivation_hook( __FILE__, 'callback' )` Guardrails: - These hooks must be registered at top-level (not inside other hooks). - If you flush rewrite rules, ensure rules are registered first (often via a shared function called both on `init` and activation). Upstream reference: - https://developer.wordpress.org/plugins/plugin-basics/activation-deactivation-hooks/ ## Uninstall Preferred approaches: - `uninstall.php` (runs only on uninstall) - `register_uninstall_hook()` Guardrails: - Check `WP_UNINSTALL_PLUGIN` before running destructive cleanup. Upstream reference: - https://developer.wordpress.org/plugins/plugin-basics/uninstall-methods/ ``` ### references/settings-api.md ```markdown # Settings API (admin options) Use this file when adding settings pages or storing user-configurable options. Core APIs: - `register_setting()` - `add_settings_section()` - `add_settings_field()` Upstream references: - Settings API overview: https://developer.wordpress.org/plugins/settings/settings-api/ - Register settings: https://developer.wordpress.org/plugins/settings/registration/ - Add settings fields: https://developer.wordpress.org/plugins/settings/settings-fields/ Practical guardrails: - Use `sanitize_callback` to validate/sanitize data. - Use capability checks (commonly `manage_options`) for settings screens and saves. - Escape values on output (`esc_attr`, `esc_html`, etc.). ``` ### references/security.md ```markdown # Security guardrails (plugin work) Use this file when making security fixes or when handling any input/output. ## Nonces + permissions - Nonces help prevent CSRF, not authorization. - Always pair nonces with capability checks (`current_user_can()` or a more specific capability). Upstream reference: - https://developer.wordpress.org/apis/security/nonces/ ## Sanitization and escaping Golden rule: - sanitize/validate on input, escape on output. Practical rules: - never process the entire `$_POST` / `$_GET` array; read explicit keys - use `wp_unslash()` before sanitizing when needed - use prepared statements for SQL; avoid interpolating user input into queries Common review guidance: - https://developer.wordpress.org/plugins/wordpress-org/detailed-plugin-guidelines/ ``` ### references/data-and-cron.md ```markdown # Data storage, cron, and upgrades Use this file when adding persistent storage, background jobs, or upgrade routines. ## Data storage - Prefer Options API for small config/state. - Use custom tables only when needed; store schema version and provide upgrade paths. ## Cron - Ensure tasks are idempotent (may run late or multiple times). - Provide a manual trigger path for debugging (WP-CLI or admin-only action). ## Database safety note If using `$wpdb->prepare()`, avoid building queries with concatenated user input. Recent WordPress versions support identifier placeholders (`%i`) but you must not assume it exists without checking capabilities or target versions. ``` ### references/debugging.md ```markdown # Debugging quick routes ## Plugin doesn’t load / fatal errors - Confirm correct plugin main file and header. - Check PHP error logs and `WP_DEBUG_LOG`. - If the repo is a site repo, confirm you edited the correct plugin under `wp-content/plugins/`. ## Activation hook surprises - Hooks must be registered at top-level. - Activation runs in a special context; avoid assuming other hooks already ran. ## Settings not saving - Confirm `register_setting()` is called. - Confirm the option group matches the form. - Confirm capability checks and nonces. ```