Exercises
Six WordPress exercises that exercise hooks, REST, security, and performance.
Six WordPress drills
EXAMPLE
# ============================================================
# Drill 1 — Add a custom field to a Customs Post Type
# ============================================================
# TASK: store + display a 'reading_time' int on posts of type 'article'.
#
# ANSWER:
add_action('add_meta_boxes', function () {
add_meta_box('reading_time', 'Reading Time', function ($post) {
wp_nonce_field('rt_save', 'rt_nonce');
$v = get_post_meta($post->ID, '_reading_time', true);
echo '<input type="number" name="reading_time" value="' . esc_attr($v) . '" min="1">';
}, 'article', 'side');
});
add_action('save_post_article', function ($post_id) {
if (!isset($_POST['rt_nonce']) || !wp_verify_nonce($_POST['rt_nonce'], 'rt_save')) return;
if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) return;
if (!current_user_can('edit_post', $post_id)) return;
update_post_meta($post_id, '_reading_time', absint($_POST['reading_time'] ?? 0));
});
# ============================================================
# Drill 2 — Expose the field in the REST API
# ============================================================
# ANSWER:
add_action('rest_api_init', function () {
register_rest_field('article', 'reading_time', [
'get_callback' => fn($o) => (int) get_post_meta($o['id'], '_reading_time', true),
'schema' => ['type' => 'integer'],
]);
});
# ============================================================
# Drill 3 — Custom REST endpoint with capability check
# ============================================================
# ANSWER:
add_action('rest_api_init', function () {
register_rest_route('shop/v1', '/refund', [
'methods' => 'POST',
'callback' => 'shop_refund_handler',
'permission_callback' => fn() => current_user_can('manage_woocommerce'),
'args' => [
'order_id' => ['required' => true, 'type' => 'integer', 'sanitize_callback' => 'absint'],
'amount' => ['required' => true, 'type' => 'integer', 'validate_callback' => fn($v) => is_int($v) && $v > 0],
],
]);
});
# ============================================================
# Drill 4 — Cache an expensive query with transients
# ============================================================
# ANSWER:
function get_popular_products() {
$cached = get_transient('popular_products');
if ($cached !== false) return $cached;
$products = wc_get_products(['orderby' => 'popularity', 'limit' => 12]);
set_transient('popular_products', $products, 60 * 60);
return $products;
}
# Bust on product save:
add_action('save_post_product', fn() => delete_transient('popular_products'));
# ============================================================
# Drill 5 — Disable XML-RPC if unused
# ============================================================
# ANSWER:
add_filter('xmlrpc_enabled', '__return_false');
# Also block at the .htaccess level
# <Files xmlrpc.php>
# Require all denied
# </Files>
# ============================================================
# Drill 6 — Defer non-critical scripts for performance
# ============================================================
# ANSWER:
add_filter('script_loader_tag', function ($tag, $handle) {
$defer = ['analytics', 'chat-widget'];
if (in_array($handle, $defer)) {
return str_replace(' src=', ' defer src=', $tag);
}
return $tag;
}, 10, 2);
# ============================================================
# Bonus — what makes a plugin update SAFE?
# ============================================================
# ANSWER:
# 1) Staging site that mirrors prod (same theme, plugins, version)
# 2) Test on staging first
# 3) Database backup BEFORE the update
# 4) Roll back plan (WP-Rollback plugin OR restore the backup)
# 5) Monitor error logs + Crashlytics-style tools after the update
# ============================================================
# Scoring
# 6 / 6 -> production-ready WP dev
# 4 / 6 -> revisit wordpress/cheatsheet
# < 4 -> read the Plugin Handbook + Security cheat sheet
Why it matters
Always sanitise on input, escape on output, verify nonces on writes, and capability-check on REST endpoints. Those four habits cover most WordPress security wins. Get them into the teams reflexes and the next CVE in your dependencies stops being a stomach-drop moment.
Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.
Discussion
Loading…