Receber por email
← Voltar para o catálogo

wordpress-plugin-core

This skill provides comprehensive knowledge for WordPress plugin development, covering core patterns, security best practices, database interactions, hooks/filters, Settings API, custom post types, REST API, and AJAX. This skill should be used when creating WordPress plugins, troubleshooting security issues, implementing custom post types/taxonomies, building admin interfaces, or working with the

15estrelas
Atualizado há 11 meses

Ver no GitHub ↗ Licença: MIT

Como adicionar

/plugin marketplace add jackspace/ClaudeSkillz

O comando exato pode variar conforme o repositório. Confira o README no GitHub.

Para o autor da skill

Cole no README do seu repo

Mostra que sua skill está catalogada na Skillteca, gera backlink e tráfego rastreável.

[![Skillteca](https://www.skillteca.com.br/api/badge/wordpress-plugin-core/svg)](https://www.skillteca.com.br/skills/wordpress-plugin-core)

Skills relacionadas

Ver todas de Documentos →

Alerta por categoria

Receba novas skills de Documentos toda segunda

1 email curto, só com as skills novas de Documentos. 4 minutos de leitura, sem spam, cancela com 1 clique.

Você confirma o email no primeiro envio. Sem spam. Cancela com 1 clique.

Ler descrição completa

WordPress Plugin Development (Core)

Status: Production Ready Last Updated: 2025-11-06 Dependencies: None (WordPress 5.9+, PHP 7.4+) Latest Versions: WordPress 6.7+, PHP 8.0+ recommended

Quick Start (10 Minutes)

1. Choose Your Plugin Structure

WordPress plugins can use three architecture patterns:

  • Simple (functions only) - For small plugins with <5 functions
  • OOP (Object-Oriented) - For medium plugins with related functionality
  • PSR-4 (Namespaced + Composer autoload) - For large/modern plugins

Why this matters:

  • Simple plugins are easiest to start but don't scale well
  • OOP provides organization without modern PHP features
  • PSR-4 is the modern standard (2025) and most maintainable

2. Create Plugin Header

Every plugin MUST have a header comment in the main file:

<?php
/**
 * Plugin Name:       My Awesome Plugin
 * Plugin URI:        https://example.com/my-plugin/
 * Description:       Brief description of what this plugin does.
 * Version:           1.0.0
 * Requires at least: 5.9
 * Requires PHP:      7.4
 * Author:            Your Name
 * Author URI:        https://yoursite.com/
 * License:           GPL v2 or later
 * License URI:       https://www.gnu.org/licenses/gpl-2.0.html
 * Text Domain:       my-plugin
 * Domain Path:       /languages
 */

// Exit if accessed directly
if ( ! defined( 'ABSPATH' ) ) {
    exit;
}

CRITICAL:

  • Plugin Name is the ONLY required field
  • Text Domain must match plugin slug exactly (for translations)
  • Always add ABSPATH check to prevent direct file access

3. Implement The Security Foundation

Before writing ANY functionality, implement these 5 security essentials:

// 1. Unique Prefix (4-5 chars minimum)
define( 'MYPL_VERSION', '1.0.0' );

function mypl_init() {
    // Your code
}
add_action( 'init', 'mypl_init' );

// 2. ABSPATH Check (every PHP file)
if ( ! defined( 'ABSPATH' ) ) {
    exit;
}

// 3. Nonces for Forms
<input type="hidden" name="mypl_nonce" value="<?php echo wp_create_nonce( 'mypl_action' ); ?>" />

// 4. Sanitize Input, Escape Output
$clean = sanitize_text_field( $_POST['input'] );
echo esc_html( $output );

// 5. Prepared Statements for Database
global $wpdb;
$results = $wpdb->get_results(
    $wpdb->prepare(
        "SELECT * FROM {$wpdb->prefix}table WHERE id = %d",
        $id
    )
);

The 5-Step Security Foundation

WordPress plugin security has THREE components that must ALL be present:

Step 1: Use Unique Prefix for Everything

Why: Prevents naming conflicts with other plugins and WordPress core.

Rules:

  • 4-5 characters minimum
  • Apply to: functions, classes, constants, options, transients, meta keys, global variables
  • Avoid: wp_, __, _, "WordPress"
// GOOD
function mypl_function_name() {}
class MyPL_Class_Name {}
define( 'MYPL_CONSTANT', 'value' );
add_option( 'mypl_option', 'value' );
set_transient( 'mypl_cache', $data, HOUR_IN_SECONDS );

// BAD
function function_name() {}  // No prefix, will conflict
class Settings {}  // Too generic

Step 2: Check Capabilities, Not Just Admin Status

ERROR: Using is_admin() for permission checks

// WRONG - Anyone can access admin area URLs
if ( is_admin() ) {
    // Delete user data - SECURITY HOLE
}

// CORRECT - Check user capability
if ( current_user_can( 'manage_options' ) ) {
    // Delete user data - Now secure
}

Common Capabilities:

  • manage_options - Administrator
  • edit_posts - Editor/Author
  • publish_posts - Author
  • edit_pages - Editor
  • read - Subscriber

Step 3: The Security Trinity

Input → Processing → Output each require different functions:

// SANITIZATION (Input) - Clean user data
$name = sanitize_text_field( $_POST['name'] );
$email = sanitize_email( $_POST['email'] );
$url = esc_url_raw( $_POST['url'] );
$html = wp_kses_post( $_POST['content'] );  // Allow safe HTML
$key = sanitize_key( $_POST['option'] );
$ids = array_map( 'absint', $_POST['ids'] );  // Array of integers

// VALIDATION (Logic) - Verify it meets requirements
if ( ! is_email( $email ) ) {
    wp_die( 'Invalid email' );
}

// ESCAPING (Output) - Make safe for display
echo esc_html( $name );
echo '<a href="' . esc_url( $url ) . '">';
echo '<div class="' . esc_attr( $class ) . '">';
echo '<textarea>' . esc_textarea( $content ) . '</textarea>';

Critical Rule: Sanitize on INPUT, escape on OUTPUT. Never trust user data.

Step 4: Nonces (CSRF Protection)

What: One-time tokens that prove requests came from your site.

Form Pattern:

// Generate nonce in form
<form method="post">
    <?php wp_nonce_field( 'mypl_action', 'mypl_nonce' ); ?>
    <input type="text" name="data" />
    <button type="submit">Submit</button>
</form>

// Verify nonce in handler
if ( ! isset( $_POST['mypl_nonce'] ) || ! wp_verify_nonce( $_POST['mypl_nonce'], 'mypl_action' ) ) {
    wp_die( 'Security check failed' );
}

// Now safe to proceed
$data = sanitize_text_field( $_POST['data'] );

AJAX Pattern:

// JavaScript
jQuery.ajax({
    url: ajaxurl,
    data: {
        action: 'mypl_ajax_action',
        nonce: mypl_ajax_object.nonce,
        data: formData
    }
});
// PHP Handler
function mypl_ajax_handler() {
    check_ajax_referer( 'mypl-ajax-nonce', 'nonce' );

    // Safe to proceed
    wp_send_json_success( array( 'message' => 'Success' ) );
}
add_action( 'wp_ajax_mypl_ajax_action', 'mypl_ajax_handler' );

// Localize script with nonce
wp_localize_script( 'mypl-script', 'mypl_ajax_object', array(
    'ajaxurl' => admin_url( 'admin-ajax.php' ),
    'nonce'   => wp_create_nonce( 'mypl-ajax-nonce' ),
) );

Step 5: Prepared Statements for Database

CRITICAL: Always use $wpdb->prepare() for queries with user input.

global $wpdb;

// WRONG - SQL Injection vulnerability
$results = $wpdb->get_results( "SELECT * FROM {$wpdb->prefix}table WHERE id = {$_GET['id']}" );

// CORRECT - Prepared statement
$results = $wpdb->get_results(
    $wpdb->prepare(
        "SELECT * FROM {$wpdb->prefix}table WHERE id = %d",
        $_GET['id']
    )
);

Placeholders:

  • %s - String
  • %d - Integer
  • %f - Float

LIKE Queries (Special Case):

$search = '%' . $wpdb->esc_like( $term ) . '%';
$results = $wpdb->get_results(
    $wpdb->prepare(
        "SELECT * FROM {$wpdb->prefix}posts WHERE post_title LIKE %s",
        $search
    )
);

Critical Rules

Always Do

✅ 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 Do

❌ 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

Known Issues Prevention

This skill prevents 20 documented issues:

Issue #1: SQL Injection

Compartilhar X LinkedIn