Develops WordPress plugins with structure patterns, hooks, security (nonces, sanitization, prepared $wpdb queries), REST API, custom post types, and Settings API.
How this skill is triggered — by the user, by Claude, or both
Slash command
/wordpress-plugin-core:wordpress-plugin-coreThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
**Status**: Production Ready
assets/example-template.txtexamples/github-updater.phpreferences/advanced-topics.mdreferences/common-hooks.mdreferences/common-patterns.mdreferences/error-catalog.mdreferences/example-reference.mdreferences/github-auto-updates.mdreferences/plugin-architectures.mdreferences/security-checklist.mdscripts/example-script.shscripts/scaffold-plugin.shtemplates/examples/ajax-handler.phptemplates/examples/custom-post-type.phptemplates/examples/meta-box.phptemplates/examples/rest-endpoint.phptemplates/examples/settings-page.phptemplates/plugin-oop/README.mdtemplates/plugin-oop/my-oop-plugin.phptemplates/plugin-oop/uninstall.phpStatus: Production Ready Last Updated: 2025-11-27 Dependencies: None (WordPress 5.9+, PHP 7.4+) Latest Versions: WordPress 6.7+, PHP 8.0+ recommended
Three architecture patterns available (see references/plugin-architectures.md for detailed examples):
Every plugin MUST have a header comment in the main file:
<?php
/**
* Plugin Name: My Awesome Plugin
* Description: Brief description.
* Version: 1.0.0
* Requires at least: 5.9
* Requires PHP: 7.4
* Text Domain: my-plugin
*/
if ( ! defined( 'ABSPATH' ) ) exit;
CRITICAL: Plugin Name is required, Text Domain must match plugin slug exactly.
// 1. Unique Prefix (4-5 chars)
function mypl_init() { /* code */ }
add_action( 'init', 'mypl_init' );
// 2. ABSPATH Check (every file)
if ( ! defined( 'ABSPATH' ) ) exit;
// 3. Nonces for Forms
wp_nonce_field( 'mypl_action', 'mypl_nonce' );
// 4. Sanitize Input, Escape Output
$clean = sanitize_text_field( $_POST['input'] );
echo esc_html( $output );
// 5. Prepared Statements
$wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}table WHERE id = %d", $id ) );
Rules: 4-5 chars minimum, apply to functions, classes, constants, options, transients, meta keys. Avoid wp_, __, _.
// GOOD
function mypl_init() {}
class MyPL_Settings {}
add_option( 'mypl_option', 'value' );
// BAD - Will conflict
function init() {}
class Settings {}
// WRONG
if ( is_admin() ) { /* SECURITY HOLE */ }
// CORRECT
if ( current_user_can( 'manage_options' ) ) { /* Secure */ }
Common Capabilities: manage_options (Admin), edit_posts (Editor), publish_posts (Author)
Input → Processing → Output (Sanitize → Validate → Escape):
// SANITIZATION (Input)
$name = sanitize_text_field( $_POST['name'] );
$email = sanitize_email( $_POST['email'] );
$url = esc_url_raw( $_POST['url'] );
$html = wp_kses_post( $_POST['content'] );
// VALIDATION (Logic)
if ( ! is_email( $email ) ) wp_die( 'Invalid email' );
// ESCAPING (Output)
echo esc_html( $name );
echo '<a href="' . esc_url( $url ) . '">' . esc_html( $text ) . '</a>';
Rule: Sanitize INPUT, escape OUTPUT. Never trust user data.
One-time tokens proving requests came from your site.
// Form
<form method="post">
<?php wp_nonce_field( 'mypl_action', 'mypl_nonce' ); ?>
<input type="text" name="data" />
</form>
// Verify
if ( ! wp_verify_nonce( $_POST['mypl_nonce'], 'mypl_action' ) ) wp_die( 'Security check failed' );
// AJAX
check_ajax_referer( 'mypl-ajax-nonce', 'nonce' );
CRITICAL: Always use $wpdb->prepare() for user input.
// WRONG - SQL Injection
$wpdb->get_results( "SELECT * FROM {$wpdb->prefix}table WHERE id = {$_GET['id']}" );
// CORRECT
$wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}table WHERE id = %d", $_GET['id'] ) );
Placeholders: %s (String), %d (Integer), %f (Float)
LIKE Queries: Use $wpdb->esc_like() before adding wildcards:
$search = '%' . $wpdb->esc_like( $term ) . '%';
$wpdb->get_results( $wpdb->prepare( "... WHERE title LIKE %s", $search ) );
✅ Use unique prefix (4-5 chars) for all global code (functions, classes, options, transients)
✅ Add ABSPATH check to every PHP file: if ( ! defined( 'ABSPATH' ) ) exit;
✅ Check capabilities (current_user_can()) not just is_admin()
✅ Verify nonces for all forms and AJAX requests
✅ Use $wpdb->prepare() for all database queries with user input
✅ Sanitize input with sanitize_*() functions before saving
✅ Escape output with esc_*() functions before displaying
✅ Flush rewrite rules on activation when registering custom post types
✅ Use uninstall.php for permanent cleanup (not deactivation hook)
✅ Follow WordPress Coding Standards (tabs for indentation, Yoda conditions)
❌ Never use extract() - Creates security vulnerabilities
❌ Never trust $_POST/$_GET without sanitization
❌ Never concatenate user input into SQL - Always use prepare()
❌ Never use is_admin() alone for permission checks
❌ Never output unsanitized data - Always escape
❌ Never use generic function/class names - Always prefix
❌ Never use short PHP tags <? or <?= - Use <?php only
❌ Never delete user data on deactivation - Only on uninstall
❌ Never register uninstall hook repeatedly - Only once on activation
❌ Never use register_uninstall_hook() in main flow - Use uninstall.php instead
This skill prevents 20 documented issues:
Error: Database compromised via unescaped user input
Source: https://patchstack.com/articles/sql-injection/ (15% of all vulnerabilities)
Why It Happens: Direct concatenation of user input into SQL queries
Prevention: Always use $wpdb->prepare() with placeholders
// VULNERABLE
$wpdb->query( "DELETE FROM {$wpdb->prefix}table WHERE id = {$_GET['id']}" );
// SECURE
$wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->prefix}table WHERE id = %d", $_GET['id'] ) );
Error: Malicious JavaScript executed in user browsers Source: https://patchstack.com (35% of all vulnerabilities) Why It Happens: Outputting unsanitized user data to HTML Prevention: Always escape output with context-appropriate function
// VULNERABLE
echo $_POST['name'];
echo '<div class="' . $_POST['class'] . '">';
// SECURE
echo esc_html( $_POST['name'] );
echo '<div class="' . esc_attr( $_POST['class'] ) . '">';
Error: Unauthorized actions performed on behalf of users
Source: https://blog.nintechnet.com/25-wordpress-plugins-vulnerable-to-csrf-attacks/
Why It Happens: No verification that requests originated from your site
Prevention: Use nonces with wp_nonce_field() and wp_verify_nonce()
// VULNERABLE
if ( $_POST['action'] == 'delete' ) {
delete_user( $_POST['user_id'] );
}
// SECURE
if ( ! wp_verify_nonce( $_POST['nonce'], 'mypl_delete_user' ) ) {
wp_die( 'Security check failed' );
}
delete_user( absint( $_POST['user_id'] ) );
Error: Regular users can access admin functions
Source: WordPress Security Review Guidelines
Why It Happens: Using is_admin() instead of current_user_can()
Prevention: Always check capabilities, not just admin context
// VULNERABLE
if ( is_admin() ) {
// Any logged-in user can trigger this
}
// SECURE
if ( current_user_can( 'manage_options' ) ) {
// Only administrators can trigger this
}
Error: PHP files executed outside WordPress context Source: WordPress Plugin Handbook Why It Happens: No ABSPATH check at top of file Prevention: Add ABSPATH check to every PHP file
// Add to top of EVERY PHP file
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
For comprehensive error coverage beyond the Top 5, load references/error-catalog.md which includes:
Each issue includes: error description, source, why it happens, prevention code, impact severity, and frequency.
Choose the right architecture for your plugin size and complexity:
Simple (Functions Only)
OOP (Singleton Pattern)
PSR-4 (Namespaced + Composer)
For full implementation examples with directory structure, activation hooks, and code patterns, load references/plugin-architectures.md.
This skill provides production-ready patterns for 8 common WordPress plugin features:
For complete implementation code, load references/common-patterns.md when implementing any of these features. Each pattern includes:
Plugins hosted outside WordPress.org can provide automatic updates using Plugin Update Checker by YahnisElsts (recommended).
Quick Solutions:
For complete implementation, load references/github-auto-updates.md which includes:
Required:
Optional:
Fatal Errors: Enable WP_DEBUG, check wp-content/debug.log, verify prefixed names
404 on CPTs: Flush rewrite rules (add flush_rewrite_rules(); temporarily in wp-admin)
Nonce Failures: Check matching names, correct action, 24-hour expiration
AJAX Returns 0/-1: Verify action name matches wp_ajax_{action}, nonce sent/verified, handler hooked
HTML Stripped: Use wp_kses_post() instead of sanitize_text_field()
DB Queries Fail: Always use $wpdb->prepare(), include $wpdb->prefix, verify syntax
This skill uses progressive disclosure - main file contains essentials, reference files have detailed implementation. Load references based on your current task:
references/common-patterns.md (465 lines)Load when: Implementing specific WordPress features Contains:
references/plugin-architectures.md (220 lines)Load when: Choosing plugin structure or migrating between patterns Contains:
references/error-catalog.md (Issues #6-20, 573 lines)Load when: Debugging issues beyond Top 5 security vulnerabilities Contains:
references/advanced-topics.md (150 lines)Load when: Implementing i18n, WP-CLI, cron jobs, or dependency checking Contains:
references/security-checklist.md (527 lines)Load when: Performing security audit or reviewing code for vulnerabilities Contains:
references/github-auto-updates.md (1,224 lines)Load when: Setting up auto-updates for plugins hosted outside WordPress.org Contains:
references/common-hooks.md (234 lines)Load when: Working with WordPress hooks and need hook reference Contains:
Use this checklist to verify your plugin:
Questions? Issues?
references/error-catalog.md for additional issues #6-20npx claudepluginhub secondsky/claude-skills --plugin wordpress-plugin-coreGuides modern WordPress plugin development: scaffolding, debugging, testing, and refactoring. Covers WooCommerce, Gutenberg blocks, custom post types, WordPress REST API, hooks, admin pages, WPCS, PHPUnit, Playwright, and wp-scripts.
Guides WordPress plugin development: architecture, hooks, admin interfaces, REST API, security practices, and WP 7.0 features like Real-Time Collaboration, AI Connectors, Abilities API. Use for custom plugins and extensions.
Builds custom WordPress themes, plugins, Gutenberg blocks, and WooCommerce stores with security hardening and performance optimization.