YantrikDB/packs
Sign in
officialyantrikdbsigned

wordpress-expert

yantrik/wordpress-expert@0.2.0·46 facts·1108 KB·2 downloads·by spranab

WordPress plugin and theme engineering: the hook system and load order, WP_Query and the options API, REST routes and blocks, WooCommerce data stores, multisite — and the security discipline (sanitize in, escape out, prepare every query, nonce plus capability) that separates code that runs from code that survives a plugin review.

covers

WordPress plugin and theme development · WordPress hooks, actions, filters and load order · WordPress security: sanitizing, escaping, nonces, capabilities, prepared queries · WP_Query, options, transients and post meta performance · WordPress REST API routes and permission callbacks · Gutenberg block registration, static versus dynamic blocks · WooCommerce extension through hooks and CRUD data stores · WordPress multisite and WP-Cron

rules this pack installs (15)

Injected on every turn while mounted. Shown verbatim — a pack's rules are public by design.

Escape at the point of output, matched to position: Every value entering HTML is escaped where it is printed, never where it is stored: `esc_html()` in text, `esc_attr()` inside a quoted attribute, `esc_url()` for URLs, `esc_js()` in inline script, `wp_kses_post()` for content that may carry markup. Escaping on input corrupts the stored value and double-escapes on display.
Sanitize every superglobal, unslashed first: Nothing from `$_POST`, `$_GET`, `$_REQUEST` or `$_COOKIE` is used raw. `wp_unslash()` first, then the field-appropriate sanitizer — `sanitize_text_field()`, `sanitize_email()`, `sanitize_key()`, `absint()`, `wp_kses_post()`. Not a generic cast.
Every query is prepared; every LIKE is esc_like'd first: SQL through `$wpdb` uses `$wpdb->prepare()` with `%d` / `%s` / `%f` — never interpolation, even of a value believed safe. Table names come from `$wpdb->prefix`, never a literal `wp_`. Search terms pass through `$wpdb->esc_like()` before being wrapped in `%`.
A nonce is proof of intent, never of permission: State-changing handlers verify the nonce **and** call `current_user_can()`. Both, always, in that order. A handler with a nonce and no capability check is the single most common plugin-review rejection, and it is a real privilege-escalation bug.
Check capabilities, never role names: `current_user_can('edit_posts')`, never `current_user_can('editor')`. Roles are site-customisable bundles; checking one silently grants or denies the wrong people. Object-level checks pass the id: `current_user_can('edit_post', $post_id)`.
Every REST route declares a real permission_callback: `register_rest_route` without `permission_callback` is a bug, and `'__return_true'` is a deliberate decision to publish the endpoint to the internet — it appears only with a comment saying so. Route `args` carry `validate_callback` and `sanitize_callback` rather than the callback re-checking by hand.
Hook in; never run at file scope: Behaviour attaches via `add_action()` / `add_filter()` at the right moment: post types and taxonomies on `init`, theme supports on `after_setup_theme`, cross-plugin work on `plugins_loaded`, assets on `wp_enqueue_scripts` / `admin_enqueue_scripts`. Core is never modified. A callback taking more than one argument declares `$accepted_args`.
Filters return; actions do not: A filter callback returns a value on **every** path, including early exits and error branches. Returning null or falling off the end of a `the_title` or `the_content` filter blanks that value across the entire site, feeds and REST included.
Assets are enqueued and conditional: `wp_enqueue_script()` / `wp_enqueue_style()` with real dependencies and a real `$ver` — never an echoed `<script>` tag. Loading is gated to the screens that need it (`is_singular()`, the `$hook_suffix`), and data reaches JS via `wp_localize_script()` or `wp_add_inline_script()`, never PHP interpolated into a script block.
Prefix every global name: Functions, classes, constants, options, transients, meta keys, script and style handles, hooks, shortcodes and post types all share one namespace with every other plugin on the site. All of them carry the plugin prefix, and post type keys stay within 20 characters.
Options that are large or rarely read are not autoloaded: `update_option($k, $v, false)` unless the value is small and needed on most requests. Expensive results go in transients with an explicit expiry, never in options. `posts_per_page => -1` does not appear; queries that do not paginate pass `no_found_rows => true`.
Deactivation clears schedules; only uninstall deletes data: `register_activation_hook` creates schema and flushes rewrite rules once. `register_deactivation_hook` unschedules events and touches no user data. Deletion lives in `uninstall.php`. `flush_rewrite_rules()` never runs on a normal request.
User-facing strings are translated with a literal text domain: `__()`, `esc_html__()`, `_n()`, `_x()` wrap every user-visible string, and the text domain is a literal — never a variable or constant, which the extraction tooling cannot read and silently skips.
Outbound HTTP uses the WordPress HTTP API with a timeout: `wp_remote_get()` / `wp_remote_post()` with an explicit `timeout`, then `is_wp_error()` checked before the body is touched. Raw cURL or `file_get_contents()` on a URL bypasses site proxy and host-blocking configuration and hangs page loads.
Failures return WP_Error, not false: Anything a caller must diagnose returns `new WP_Error($code, $message, ['status' => $http_status])`. In REST callbacks that status becomes the response code, which is how a proper 404 or 409 is produced.

evaluation notes

skills.constitution — pack installs 15 always-on rule(s); they are shown verbatim on the listing for review

install

Native client — verifies against the registry, then installs:

curl -O https://packs.yantrikdb.com/client/yantrik_pack_client.py
python yantrik_pack_client.py install yantrik-wordpress-expert

Manual — download first, then:

yantrikdb pack info wordpress-expert-0.2.0.ydbpack
yantrikdb pack install wordpress-expert-0.2.0.ydbpack

Verify any copy of this file, wherever it came from:

curl "https://packs.yantrikdb.com/api/v1/verify?sha256=f04598b804861997e1dbe6e20f6dd0976a4f80ae6b0b59a26e8595a799d90ac0"

get it

Download 0.2.0
sha256
f04598b804861997e1dbe6e20f6dd0976a4f80ae6b0b59a26e8595a799d90ac0
digest
blake3:f8cb71c617836382016018413ad356096da55aa0e511ec8379c86831d269c5b1
signer
13a9232bc7829ea6a03e4bd6a0706c08f80ff4a2ecc83fd10062314acfb59683

versions

0.2.0 2026-07-29 download
0.1.0 2026-07-29 download