iwantcoding.com
🔥 Daily 👥 Rooms 🏆 Top Log in Sign up

Examples

Five concrete WordPress recipes that come up in real projects: a custom post type, a REST API endpoint, a shortcode, a metabox with sanitised meta, and a cron-driven job. Each is paste-ready into a small plugin or functions.php.

Five working WordPress snippets

EXAMPLE
<?php
// ============================================================
// 1) Custom post type — case studies / portfolio
// ============================================================
add_action('init', function () {
    register_post_type('case_study', [
        'labels' => [
            'name'          => 'Case Studies',
            'singular_name' => 'Case Study',
            'add_new_item'  => 'Add New Case Study',
        ],
        'public'        => true,
        'show_in_rest'  => true,                           // exposes via REST + block editor
        'has_archive'   => 'case-studies',
        'rewrite'       => ['slug' => 'case-studies'],
        'supports'      => ['title','editor','thumbnail','excerpt','custom-fields'],
        'taxonomies'    => ['category', 'post_tag'],
        'menu_icon'     => 'dashicons-portfolio',
    ]);
});

// ============================================================
// 2) Custom REST API endpoint — typed, capability-gated
// ============================================================
add_action('rest_api_init', function () {
    register_rest_route('shop/v1', '/refunds', [
        'methods'             => 'POST',
        'callback'            => 'shop_request_refund',
        'permission_callback' => fn() => current_user_can('edit_orders'),
        'args' => [
            'order_id' => [
                'required'          => true,
                'type'              => 'integer',
                'sanitize_callback' => 'absint',
            ],
            'amount_cents' => [
                'required'          => true,
                'type'              => 'integer',
                'validate_callback' => fn($v) => is_int($v) && $v > 0,
            ],
        ],
    ]);
});

function shop_request_refund(WP_REST_Request $req) {
    $id     = (int) $req->get_param('order_id');
    $amount = (int) $req->get_param('amount_cents');
    // ... do the work, return WP_REST_Response
    return new WP_REST_Response(['queued' => true, 'order_id' => $id, 'amount_cents' => $amount], 202);
}

// ============================================================
// 3) Shortcode — render dynamic data inside a post or page
// ============================================================
add_shortcode('shop_ticker', function ($atts) {
    $atts = shortcode_atts(['symbol' => 'BTC'], $atts);
    $symbol = sanitize_text_field($atts['symbol']);
    // imagine a transient cached fetch
    $price = get_transient("ticker_$symbol");
    if ($price === false) {
        // fetch + sanitize
        $price = 12345.67;
        set_transient("ticker_$symbol", $price, 60);
    }
    return sprintf(
        '<span class="ticker">%s: <strong>$%s</strong></span>',
        esc_html($symbol),
        esc_html(number_format($price, 2))
    );
});
// Usage in a post:   [shop_ticker symbol='ETH']

// ============================================================
// 4) Metabox — admin UI for custom fields, sanitised on save
// ============================================================
add_action('add_meta_boxes', function () {
    add_meta_box('case_study_meta', 'Case Study Settings', 'case_study_meta_box', 'case_study', 'side');
});

function case_study_meta_box(WP_Post $post) {
    wp_nonce_field('save_case_study_meta', 'case_study_nonce');
    $client = get_post_meta($post->ID, '_client', true);
    $url    = get_post_meta($post->ID, '_url', true);
    echo '<p><label>Client<br><input type="text" name="client" value="' . esc_attr($client) . '" class="widefat"></label></p>';
    echo '<p><label>Live URL<br><input type="url" name="url" value="' . esc_attr($url) . '" class="widefat"></label></p>';
}

add_action('save_post_case_study', function (int $post_id) {
    if (!isset($_POST['case_study_nonce']) ||
        !wp_verify_nonce($_POST['case_study_nonce'], 'save_case_study_meta')) return;
    if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) return;
    if (!current_user_can('edit_post', $post_id)) return;

    update_post_meta($post_id, '_client', sanitize_text_field($_POST['client'] ?? ''));
    update_post_meta($post_id, '_url',    esc_url_raw($_POST['url'] ?? ''));
});

// ============================================================
// 5) Cron job — daily housekeeping
// ============================================================
add_filter('cron_schedules', function ($schedules) {
    $schedules['daily_at_2am'] = [
        'interval' => DAY_IN_SECONDS,
        'display'  => 'Daily at 2am',
    ];
    return $schedules;
});

register_activation_hook(__FILE__, function () {
    if (!wp_next_scheduled('shop_daily_cleanup')) {
        wp_schedule_event(strtotime('tomorrow 02:00'), 'daily', 'shop_daily_cleanup');
    }
});

register_deactivation_hook(__FILE__, function () {
    wp_clear_scheduled_hook('shop_daily_cleanup');
});

add_action('shop_daily_cleanup', function () {
    // Reach into custom tables, purge stale transients, send a summary, etc.
    global $wpdb;
    $wpdb->query("DELETE FROM $wpdb->options WHERE option_name LIKE '_transient_timeout_%' AND option_value < UNIX_TIMESTAMP()");
});

// ============================================================
// Patterns to internalise
// ============================================================
// - Always escape output (esc_html, esc_attr, esc_url, wp_kses_post)
// - Always sanitise input (sanitize_text_field, absint, esc_url_raw)
// - Always verify nonces on form submits + capability-check on REST endpoints
// - Treat WP-Cron as 'best effort' — for important jobs use real cron + wp-cli
// - Keep this in a small plugin file, not in functions.php, so theme switches do not break it

Why it matters

Always escape on output and sanitise on input — different functions for different contexts, applied at the point of use. WordPress security is mostly that one habit; the rest is patches and least-privileged DB credentials. Get the escape-and-sanitise reflex into the team and most of the OWASP list goes away.

Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.

Example

Example
// See the lesson body for ready-to-paste snippets.
echo 'Hello, WordPress';
Try it Yourself »

Discussion

Loading…