$npx -y skills add wpacademy/wordpress-dev-skills --skill wp-plugin-devDevelop WordPress plugins following official WordPress coding standards, security best practices, and WordPress.org directory guidelines. Use this skill whenever the user wants to create, scaffold, or develop a WordPress plugin — including standard plugins (settings pages, CPTs,
| 1 | # WordPress Plugin Development |
| 2 | |
| 3 | ## Overview |
| 4 | |
| 5 | Create production-ready WordPress plugins that follow official WordPress coding standards, the WordPress.org |
| 6 | plugin directory guidelines, and security best practices. Every plugin produced by this skill is modular, |
| 7 | secure, translatable, and ready for WordPress.org submission. |
| 8 | |
| 9 | ## Quick Start Workflow |
| 10 | |
| 11 | 1. **Read references** — Before writing any code, read the relevant reference files: |
| 12 | - `references/architecture.md` — Plugin structure, boilerplate patterns for all plugin types |
| 13 | - `references/security.md` — Sanitization, escaping, prepared statements, nonces, caching |
| 14 | - `references/wp-org-guidelines.md` — WordPress.org directory rules (18 guidelines) |
| 15 | 2. **Gather requirements** — Ask the user what the plugin should do, then determine which modules are needed |
| 16 | 3. **Scaffold** — Generate the directory structure and bootstrap file |
| 17 | 4. **Build features** — Create each feature as a separate modular class |
| 18 | 5. **Generate readme.txt** — Always include a WordPress.org-compliant readme.txt |
| 19 | 6. **Deliver** — Ask user if they want files in `/mnt/user-data/outputs/` for download or a custom path |
| 20 | |
| 21 | ## Core Principles — ALWAYS Follow These |
| 22 | |
| 23 | ### 1. Clean Bootstrap File |
| 24 | The main plugin file (`plugin-name.php`) is ONLY a bootstrap loader. It contains: |
| 25 | - Plugin header comment (with all required headers) |
| 26 | - Constants (`VERSION`, `PLUGIN_DIR`, `PLUGIN_URL`, `PLUGIN_BASENAME`) |
| 27 | - `register_activation_hook()` / `register_deactivation_hook()` |
| 28 | - Autoloader or `require_once` statements |
| 29 | - A single init function that instantiates the main class |
| 30 | |
| 31 | **NEVER** put settings registration, shortcode handlers, AJAX callbacks, CPT registration, hook callbacks, |
| 32 | template rendering, or ANY feature logic in the main plugin file. |
| 33 | |
| 34 | ### 2. Modular Architecture |
| 35 | Every distinct feature gets its own class file in the appropriate directory: |
| 36 | - `includes/` — Core classes, shared utilities, data models |
| 37 | - `admin/` — Admin-only functionality (settings pages, meta boxes, admin notices) |
| 38 | - `public/` — Public-facing functionality (shortcodes, frontend rendering) |
| 39 | - `blocks/` — Gutenberg blocks (each block gets its own subdirectory) |
| 40 | - `api/` — REST API endpoints |
| 41 | |
| 42 | Each class follows the single-responsibility principle. When a feature grows beyond ~200 lines, |
| 43 | split it into sub-components. |
| 44 | |
| 45 | ### 3. Security — Non-Negotiable |
| 46 | Apply ALL of the following on EVERY piece of code: |
| 47 | |
| 48 | **Input:** Sanitize ALL user input immediately upon receipt. |
| 49 | ```php |
| 50 | $title = sanitize_text_field( wp_unslash( $_POST['title'] ) ); |
| 51 | ``` |
| 52 | |
| 53 | **Output:** Escape ALL output at the point of rendering (late escaping). |
| 54 | ```php |
| 55 | echo esc_html( $title ); |
| 56 | ``` |
| 57 | |
| 58 | **Database:** Use `$wpdb->prepare()` for ALL custom SQL queries. No exceptions. |
| 59 | ```php |
| 60 | $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$table} WHERE id = %d", $id ) ); |
| 61 | ``` |
| 62 | |
| 63 | **Auth:** Check nonces for ALL form submissions and AJAX requests. Check capabilities before ALL privileged operations. |
| 64 | |
| 65 | **Caching:** Use Transients API or `wp_cache_*` for expensive queries and external API calls. |
| 66 | |
| 67 | Read `references/security.md` for the complete function reference. |
| 68 | |
| 69 | ### 4. WordPress Coding Standards |
| 70 | - Use WordPress naming conventions: `snake_case` for functions/variables, `Upper_Snake_Case` for classes |
| 71 | - Prefix ALL functions, classes, hooks, options, transients, and database tables with the plugin prefix |
| 72 | - Use proper PHPDoc blocks on all classes, methods, and functions |
| 73 | - All user-facing strings must be translatable using `__()`, `_e()`, `esc_html__()`, etc. |
| 74 | - Set the text domain to match the plugin slug |
| 75 | - Use `wp_enqueue_script()` / `wp_enqueue_style()` — never hardcode `<script>` or `<link>` tags |
| 76 | - Use WordPress bundled libraries (jQuery, etc.) — never bundle your own copies |
| 77 | - Enqueue admin assets only on plugin pages (check `$hook` parameter) |
| 78 | - Enqueue public assets conditionally (only when the plugin's output is on the page) |
| 79 | |
| 80 | ### 5. WordPress.org Compliance |
| 81 | Every plugin MUST: |
| 82 | - Use GPLv2 or later license |
| 83 | - Include a complete `readme.txt` following the WordPress.org format |
| 84 | - Include `uninstall.php` for clean removal |
| 85 | - Not include obfuscated code |
| 86 | - Not include tracking without opt-in consent |
| 87 | - Not bundle WordPress default libraries |
| 88 | - Have human-readable code with meaningful names |
| 89 | - |