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
- Run triage:
node skills/wp-project-triage/scripts/detect_wp_project.mjs
- 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:
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:
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:
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:
Escalation
For canonical detail, consult the Plugin Handbook and security guidelines before inventing patterns.
Source: soderlind/ralph — distributed by TomeVault.
1---2name: soderlind-ralph-ralph3description: WP Plugin Development4---56# WP Plugin Development78## When to use910Use this skill for plugin work such as:1112- creating or refactoring plugin structure (bootstrap, includes, namespaces/classes)13- adding hooks/actions/filters14- activation/deactivation/uninstall behavior and migrations15- adding settings pages / options / admin UI (Settings API)16- security fixes (nonces, capabilities, sanitization/escaping, SQL safety)17- packaging a release (build artifacts, readme, assets)1819## Inputs required2021- Repo root + target plugin(s) (path to plugin main file if known).22- Where this plugin runs: single site vs multisite; WP.com conventions if applicable.23- Target WordPress + PHP versions (affects available APIs and placeholder support in `$wpdb->prepare()`).2425## Procedure2627### 0) Triage and locate plugin entrypoints28291. Run triage:30 - `node skills/wp-project-triage/scripts/detect_wp_project.mjs`312. Detect plugin headers (deterministic scan):32 - `node skills/wp-plugin-development/scripts/detect_plugins.mjs`3334If this is a full site repo, pick the specific plugin under `wp-content/plugins/` or `mu-plugins/` before changing code.3536### 1) Follow a predictable architecture3738Guidelines:3940- Keep a single bootstrap (main plugin file with header).41- Avoid heavy side effects at file load time; load on hooks.42- Prefer a dedicated loader/class to register hooks.43- Keep admin-only code behind `is_admin()` (or admin hooks) to reduce frontend overhead.4445See:46- `references/structure.md`4748### 2) Hooks and lifecycle (activation/deactivation/uninstall)4950Activation hooks are fragile; follow guardrails:5152- register activation/deactivation hooks at top-level, not inside other hooks53- flush rewrite rules only when needed and only after registering CPTs/rules54- uninstall should be explicit and safe (`uninstall.php` or `register_uninstall_hook`)5556See:57- `references/lifecycle.md`5859### 3) Settings and admin UI (Settings API)6061Prefer Settings API for options:6263- `register_setting()`, `add_settings_section()`, `add_settings_field()`64- sanitize via `sanitize_callback`6566See:67- `references/settings-api.md`6869### 4) Security baseline (always)7071Before shipping:7273- Validate/sanitize input early; escape output late.74- Use nonces to prevent CSRF *and* capability checks for authorization.75- Avoid directly trusting `$_POST` / `$_GET`; use `wp_unslash()` and specific keys.76- Use `$wpdb->prepare()` for SQL; avoid building SQL with string concatenation.7778See:79- `references/security.md`8081### 5) Data storage, cron, migrations (if needed)8283- Prefer options for small config; custom tables only if necessary.84- For cron tasks, ensure idempotency and provide manual run paths (WP-CLI or admin).85- For schema changes, write upgrade routines and store schema version.8687See:88- `references/data-and-cron.md`8990## Verification9192- Plugin activates with no fatals/notices.93- Settings save and read correctly (capability + nonce enforced).94- Uninstall removes intended data (and nothing else).95- Run repo lint/tests (PHPUnit/PHPCS if present) and any JS build steps if the plugin ships assets.9697## Failure modes / debugging9899- Activation hook not firing:100 - hook registered incorrectly (not in main file scope), wrong main file path, or plugin is network-activated101- Settings not saving:102 - settings not registered, wrong option group, missing capability, nonce failure103- Security regressions:104 - nonce present but missing capability checks; or sanitized input not escaped on output105106See:107- `references/debugging.md`108109## Escalation110111For canonical detail, consult the Plugin Handbook and security guidelines before inventing patterns.112113---114> Source: [soderlind/ralph](https://github.com/soderlind/ralph) — distributed by [TomeVault](https://tomevault.io).115<!-- tomevault:4.0:skill_md:2026-06-20 -->