wp-plugin-development: hook timing, CPT queryability, gotchas/traps, secrets, i18n - #3
Open
sboisvert wants to merge 2 commits into
Open
wp-plugin-development: hook timing, CPT queryability, gotchas/traps, secrets, i18n#3sboisvert wants to merge 2 commits into
sboisvert wants to merge 2 commits into
Conversation
…tchas/traps, secrets, i18n Adds three new reference files: - security-deep-cuts.md: nonce internals (lifetime, generation, verify return values), password hashing, capability edge cases (super-admin, primitive vs meta caps), KSES defaults and how `wp_kses_post()` differs from `wp_kses_data()`. - gotchas-and-traps.md: return-value traps that break "did it succeed?" checks (`get_post_meta` returning `''` not `null`, `$wpdb->insert()` returning rows-affected not insert ID, `update_post_meta()` returning `false` on identical values, `is_admin()` checking the URL not the user, `wp_redirect()` not exiting), numeric limits, hook-ordering, and `WP_Query` vs `get_posts()` differences. - i18n-gotchas.md: text-domain-must-be-literal-string rule, why locale functions only return reliable values after `init`, sprintf vs number-format, escaping and translating in the same call. SKILL.md changes: - Hook-registration timing: register `add_action`/`add_filter` at plugin load, not from inside a method that itself runs on `init`. Calling `add_action()` from an `init` callback re-registers the callback every request and causes hooks to fire multiple times. - CPT publicly_queryable matching: when requirements describe a "landing page" or "URL per resource", `publicly_queryable => true` is required (or an explicit alternative documented as a design decision). - Server-side validation: enforce min/max/required/format constraints in save handlers, not only in JS. Direct POST and API requests bypass client-side validation entirely. - Secrets storage: API keys and credentials belong in environment variables or a host-provided secrets store, never in `wp_options`, post meta, or transients. - New step "Avoid common WordPress gotchas" routes to the two new reference files for return-value traps and i18n traps. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
sboisvert
force-pushed
the
principal-wp/wp-plugin-development-improvements
branch
from
May 6, 2026 23:38
cb37a03 to
054e107
Compare
New references/recent-release-deltas.md covering plugin-author-relevant changes that drive code edits across WP 6.7, 6.8, and 6.9: - Requires Plugins header (6.5 baseline) - register_block_template() (6.7) -- ship templates without a child theme - Speculation Rules ship by default; opt out stateful URLs (6.8) - bcrypt default password hash + wp_check_password() rehash semantics (6.8) - Auto translation loading; drop load_plugin_textdomain() at 6.7+ - HTML API maturation (full parser, set_modifiable_text, normalize, serialize_token) - WP_Block_Processor streaming parser (6.9) -- 3MB post 14GB scenario fixed - WP_Query cache key changes (6.9) -- breaking for warm-cache plugins - register_post_type embeddable, wp_next_scheduled as filter (6.8) - Abilities API registration pattern for plugin features (6.9) - HTTPS URL escaping default (6.9) - wp_mail() cid: inline images + state isolation (6.9) - Admin menu search source change (6.9) - fetchpriority + in_footer args on scripts and script modules (6.9) - Template enhancement output buffer -- ob_start replacement (6.9) - apiVersion 3 deprecation runway (6.9, enforced 7.0) - IE conditional support removed (6.9) - UTF-8 modernization with pure-PHP fallback (6.9) Sources: Make/Core dev notes, 6.7/6.8/6.9 Field Guides, 6.9 Frontend Perf Field Guide. Each entry has source URL and version anchor. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds three new reference files and several procedure improvements to the
wp-plugin-developmentskill.New reference files
references/security-deep-cuts.mdreferences/gotchas-and-traps.mdget_post_metareturning'',\$wpdb->insert()returning rows-affected not insert ID,update_post_meta()returningfalseon identical values,is_admin()checking URL not role,wp_redirect()not exiting; plus numeric limits, hook ordering,WP_Queryvsget_posts()references/i18n-gotchas.mdinit, escaping and translating in the same callSKILL.md updates
add_action/add_filterat plugin load time — not from inside a method that itself runs oninit. Callingadd_action()from aninitcallback re-registers on every request and causes hooks to fire multiple times.publicly_queryablematching: When requirements describe a "landing page" or "URL per resource", the CPT needspublicly_queryable => true(or an explicit alternative documented as a design decision). Mismatched queryability is a common source of "where's my page?" bugs.wp_options/ post meta / transients.Why this is useful
These cover failures that look correct in code review and break under realistic conditions:
add_action-from-an-init-callback bug is invisible until production traffic — at which point the same callback runs 5–50 times per request.update_post_meta()returningfalsefor identical values is the most common "my code seems broken" misread when calls are wrapped inif ( ! update_post_meta(...) ).Test plan
🤖 Generated with Claude Code