Skip to content

Guidelines: Extract initial public API methods#77643

Open
gziolo wants to merge 5 commits intotrunkfrom
feat/guidelines-api-and-permissions
Open

Guidelines: Extract initial public API methods#77643
gziolo wants to merge 5 commits intotrunkfrom
feat/guidelines-api-and-permissions

Conversation

@gziolo
Copy link
Copy Markdown
Member

@gziolo gziolo commented Apr 24, 2026

Part of:

Summary

Builds on #77592. Three independent changes that move the Guidelines experiment a step closer to a shape that could plausibly land in WP core.

1. Treat guideline types as a first-class, extensible concept

Today the list of guideline types lives inline inside the post-type registration class, alongside taxonomy registration, hook wiring, and meta logic. That makes it impossible for plugins to add or relabel a type, and impossible for any other code in the project to ask "what types are available?" without reaching into a class internal.

This commit extracts three small functions into a new lib/experimental/guidelines/guidelines.php module and splits them into a public surface plugins can use, and internal hook callbacks they shouldn't:

  • wp_guideline_types()public. The registry of guideline types, filterable via the wp_guideline_types filter so plugins can add or relabel entries. Defaults to artifact and content; everything else can come from the filter.
  • _wp_guidelines_ensure_default_type_term()internal (@access private). Hook callback for save_post_wp_guideline that backfills the 'artifact' term when a guideline is saved without a type. Replaces the static method that previously lived on the post-type class.
  • _wp_guidelines_maybe_map_term_label()internal (@access private). Hook callback for wp_insert_term_data that, when a type term is created lazily from a raw slug, replaces the auto-derived term name with the human-readable title from wp_guideline_types() — so a term created via wp_set_object_terms( …, 'artifact' ) ends up named Artifact instead of artifact.

The leading-underscore + @access private convention follows what WP core uses for hook handlers (e.g. _wp_filter_post_kses) so it's immediately obvious from the source which functions plugins can call. Each function is wrapped in function_exists so the file is a no-op if/when these helpers ever ship in WP core. The post-type class shrinks accordingly and is now responsible only for registration and hook wiring. New unit tests cover each function and the lazy-creation behavior end-to-end.

2. Make the admin look like a real post type, and create headroom for finer permissions

The CPT was registered with two labels (name, singular_name) and capability_type = 'post'. That gave a sparse admin UI (every screen says just "Guidelines") and meant guideline permissions were tied to standard post permissions, with no way to grant access to guidelines without also granting it to all posts.

This commit fills out the full label set (with _x() context for translators) for both the post type and its taxonomy, and switches to capability_type = 'guideline' with map_meta_cap = true. To avoid an unintended access change in this commit, the explicit capabilities array continues to map every meta cap back to the equivalent post cap — so today's behavior is unchanged. The new custom type just gives us room to introduce dedicated edit_guideline / publish_guidelines / etc. primitives (and a "Guideline Editor" role) in a later pass.

3. Lock down write access at the REST layer

After commit 2, users with edit_posts (e.g. editors) could create, update, or delete guidelines through the REST API — the standard permission checks inherited from WP_REST_Posts_Controller say so. Until we have a deliberate role/capability model, the safer default is admin-only writes.

This commit overrides the create / update / delete permission checks on the guidelines REST controller and the revision-restore check on the revisions controller to require manage_options. Reads are intentionally left open to anyone who can edit posts, since editors need to be able to see the guidelines they're expected to follow. Error codes match what core uses (rest_cannot_create / _edit / _delete / _restore) so existing client error handling continues to work.

Test plan

  • PHPCS clean across lib/experimental/guidelines/ and phpunit/experimental/guidelines/.
  • 44/44 unit tests passing (117 assertions), including 7 new tests covering the extracted public API, the slug-to-label mapping (direct unit cases for each guard + an end-to-end case via wp_set_object_terms), and the previously-failing editor-permission tests for the REST controller.
  • Smoke-test the Guidelines admin screens to confirm the new label set renders correctly.
  • Confirm via REST (curl or the browser console) that an editor user gets 403 on create/update/delete and that an admin succeeds.

🤖 Generated with Claude Code

gziolo and others added 3 commits April 24, 2026 11:41
Moves the guideline-type registry, the default-term backfill, and the
slug-to-label mapping out of the post-type class into a new
guidelines.php module. The class now only registers the CPT/taxonomy
and wires the hooks. Adds focused unit tests for each public function.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ity_type

Adds the full label set (with _x() context strings) for both the
guideline post type and the wp_guideline_type taxonomy, and switches
the CPT to capability_type='guideline' with map_meta_cap so the meta
caps can be tightened independently of standard post caps. The
explicit capabilities map preserves today's behavior; REST controllers
add their own admin-only gate in a follow-up.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Overrides create/update/delete permission checks on the guidelines
controller and the revision-restore check on the revisions controller
to require manage_options. Reads stay open to anyone with edit_posts
so editors can view the guidelines they need to follow. Returns the
standard rest_cannot_create / _edit / _delete / _restore error codes.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@gziolo gziolo requested a review from spacedmonkey as a code owner April 24, 2026 09:46
@github-actions
Copy link
Copy Markdown

The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the props-bot label.

If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message.

Co-authored-by: gziolo <gziolo@git.wordpress.org>

To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook.

@gziolo gziolo added [Type] Enhancement A suggestion for improvement. [Type] New API New API to be used by plugin developers or package users. and removed [Type] Enhancement A suggestion for improvement. labels Apr 24, 2026
@gziolo gziolo self-assigned this Apr 24, 2026
@gziolo gziolo added the [Feature] Guidelines An experimental feature for adding site-wide editorial rules. label Apr 24, 2026
Renames the two hook callbacks to use the underscore prefix and the
@access private marker that WordPress core uses for functions plugins
should not call directly: _wp_guidelines_ensure_default_type_term and
_wp_guidelines_maybe_map_term_label. Their summaries now lead with
"Hook callback for ..." so the role is obvious from the docblock.

Also trims the default type list to just artifact and content. The
other names (instruction, memory, skill, plan) were placeholders;
the experiment only needs the two for now and plugins can add more
through the wp_guideline_types filter.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown

github-actions Bot commented Apr 24, 2026

Flaky tests detected in d90b4ae.
Some tests passed with failed attempts. The failures may not be related to this commit but are still reported for visibility. See the documentation for more information.

🔍 Workflow run URL: https://github.com/WordPress/gutenberg/actions/runs/24903695420
📝 Reported issues:

@gziolo gziolo changed the title Guidelines: Extract public API Guidelines: Extract initial public API methods Apr 24, 2026
wp_set_object_terms() treats strings as term names on hierarchical
taxonomies, so pass a term ID instead. Tighten the tests to verify the
lazy-created term's localized label and rename them for clarity.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

[Feature] Guidelines An experimental feature for adding site-wide editorial rules. [Type] New API New API to be used by plugin developers or package users.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant