Skip to content

Guidelines: Drop default_term from wp_guideline_type taxonomy#77592

Merged
gziolo merged 5 commits intotrunkfrom
fix/guidelines-taxonomy-default-term
Apr 24, 2026
Merged

Guidelines: Drop default_term from wp_guideline_type taxonomy#77592
gziolo merged 5 commits intotrunkfrom
fix/guidelines-taxonomy-default-term

Conversation

@gziolo
Copy link
Copy Markdown
Member

@gziolo gziolo commented Apr 23, 2026

What

Stop passing default_term when registering the wp_guideline_type taxonomy. Assign the artifact fallback from a save_post_wp_guideline hook instead, and only when the saved post has no type term yet.

Why

Registering the taxonomy with default_term routes through core paths that trigger cross-site clean_term_cache work. On multisite installations with a large number of sites (reported on WordPress.com after v23.0.0), this caused significant load even for sites with zero guidelines posts. The default_term registration argument also has limited precedent in core and is not well-tested under caching/invalidation scenarios.

How

  • Remove the default_term argument from register_taxonomy().
  • Add Gutenberg_Guidelines_Post_Type::ensure_default_type_term() that runs on save_post_wp_guideline. Because that action fires after wp_insert_post() processes tax_input, any explicit term is already attached when the callback runs. The callback queries attached terms and only assigns artifact when none are present.
  • The REST controller's singleton creation already sets content via tax_input, so that path is a no-op for this new hook.

Behavior

  • REST singleton create → content attached → hook is a no-op.
  • Manual /wp-admin create with a type chosen → user term attached → hook is a no-op.
  • Manual create with no type chosen → artifact assigned.
  • Subsequent updates → post already has a term → hook is a no-op.

Test plan

  • Existing Gutenberg_Guidelines_REST_Controller_Test suite passes (31 tests).
  • Verify on a fresh install that no guidelines posts exist and no taxonomy-related DB writes occur on init.
  • Create a wp_guideline post via wp-admin without picking a type → confirm it gets the artifact term.
  • Create a wp_guideline post via wp-admin with a type picked → confirm the picked term is preserved.
  • Exercise the REST create endpoint → confirm the content term is assigned.

🤖 Generated with Claude Code

Registering the taxonomy with default_term triggers cross-site
clean_term_cache work, which caused major load on multisite installs
with many sites even when no guidelines existed.

Replace it with a save_post_wp_guideline callback that assigns the
artifact fallback only when the post has no type term yet. The REST
controller's singleton path already sets content explicitly via
tax_input, so that flow is unaffected.

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

github-actions Bot commented Apr 23, 2026

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>
Co-authored-by: tyxla <tyxla@git.wordpress.org>

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

gziolo and others added 2 commits April 23, 2026 09:47
Covers:
- Regression guard that the taxonomy is registered without default_term.
- The save_post fallback assigns artifact only when the post has no type.
- An explicit type passed via tax_input is preserved, not overwritten.
- Updates to an existing post do not reset the term.
- The hook is scoped to wp_guideline and leaves other post types alone.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Move the save_post_wp_guideline registration inside the register()
method so it lives behind the same post_type_exists() guard as the
CPT itself. If WordPress core ever ships the guidelines CPT and its
own fallback hook, Gutenberg will skip both and avoid registering a
duplicate callback.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@gziolo gziolo requested a review from tyxla April 23, 2026 07:52
@gziolo gziolo self-assigned this Apr 23, 2026
@gziolo gziolo added [Type] Bug An existing feature does not function as intended [Feature] Guidelines An experimental feature for adding site-wide editorial rules. Backport to Gutenberg Minor Release Pull request that needs to be backported to a Gutenberg minor release labels Apr 23, 2026
Copy link
Copy Markdown
Member

@tyxla tyxla left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks mostly good, but I have another potential concern about performance.

Comment thread lib/experimental/guidelines/class-gutenberg-guidelines-post-type.php Outdated
@github-actions
Copy link
Copy Markdown

github-actions Bot commented Apr 23, 2026

Flaky tests detected in de55e44.
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/24876505973
📝 Reported issues:

wp_get_object_terms() queries the database directly on every call.
get_the_terms() uses the object term cache populated by
update_object_term_cache(), which keeps repeated reads cheap within
the same request.

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

@tyxla tyxla left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is looking good and works well. 👍

I've added a few suggestions to address before landing it.

Comment thread lib/experimental/guidelines/class-gutenberg-guidelines-post-type.php Outdated
Comment thread phpunit/experimental/guidelines/class-gutenberg-guidelines-post-type-test.php Outdated
Comment thread lib/experimental/guidelines/class-gutenberg-guidelines-post-type.php Outdated
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@gziolo gziolo enabled auto-merge (squash) April 24, 2026 06:54
@gziolo gziolo merged commit 1789697 into trunk Apr 24, 2026
40 of 42 checks passed
@gziolo gziolo deleted the fix/guidelines-taxonomy-default-term branch April 24, 2026 07:37
@github-actions github-actions Bot added this to the Gutenberg 23.1 milestone Apr 24, 2026
@luisherranz
Copy link
Copy Markdown
Member

I just cherry-picked this PR to the release/23.0 branch to get it included in the next release: 89ce73e

luisherranz pushed a commit that referenced this pull request Apr 24, 2026
* Guidelines: Drop default_term from wp_guideline_type registration

Registering the taxonomy with default_term triggers cross-site
clean_term_cache work, which caused major load on multisite installs
with many sites even when no guidelines existed.

Replace it with a save_post_wp_guideline callback that assigns the
artifact fallback only when the post has no type term yet. The REST
controller's singleton path already sets content explicitly via
tax_input, so that flow is unaffected.

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

* Guidelines: Add unit tests for taxonomy default-term behavior

Covers:
- Regression guard that the taxonomy is registered without default_term.
- The save_post fallback assigns artifact only when the post has no type.
- An explicit type passed via tax_input is preserved, not overwritten.
- Updates to an existing post do not reset the term.
- The hook is scoped to wp_guideline and leaves other post types alone.

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

* Guidelines: Scope the save_post hook to Gutenberg's own registration

Move the save_post_wp_guideline registration inside the register()
method so it lives behind the same post_type_exists() guard as the
CPT itself. If WordPress core ever ships the guidelines CPT and its
own fallback hook, Gutenberg will skip both and avoid registering a
duplicate callback.

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

* Guidelines: Use get_the_terms so the check hits the object term cache

wp_get_object_terms() queries the database directly on every call.
get_the_terms() uses the object term cache populated by
update_object_term_cache(), which keeps repeated reads cheap within
the same request.

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

* Guidelines: Drop redundant autosave check and cover revisions in tests

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

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

Co-authored-by: gziolo <gziolo@git.wordpress.org>
Co-authored-by: tyxla <tyxla@git.wordpress.org>
@luisherranz luisherranz removed the Backport to Gutenberg Minor Release Pull request that needs to be backported to a Gutenberg minor release label Apr 24, 2026
Copilot AI pushed a commit that referenced this pull request Apr 24, 2026
* Guidelines: Drop default_term from wp_guideline_type registration

Registering the taxonomy with default_term triggers cross-site
clean_term_cache work, which caused major load on multisite installs
with many sites even when no guidelines existed.

Replace it with a save_post_wp_guideline callback that assigns the
artifact fallback only when the post has no type term yet. The REST
controller's singleton path already sets content explicitly via
tax_input, so that flow is unaffected.

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

* Guidelines: Add unit tests for taxonomy default-term behavior

Covers:
- Regression guard that the taxonomy is registered without default_term.
- The save_post fallback assigns artifact only when the post has no type.
- An explicit type passed via tax_input is preserved, not overwritten.
- Updates to an existing post do not reset the term.
- The hook is scoped to wp_guideline and leaves other post types alone.

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

* Guidelines: Scope the save_post hook to Gutenberg's own registration

Move the save_post_wp_guideline registration inside the register()
method so it lives behind the same post_type_exists() guard as the
CPT itself. If WordPress core ever ships the guidelines CPT and its
own fallback hook, Gutenberg will skip both and avoid registering a
duplicate callback.

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

* Guidelines: Use get_the_terms so the check hits the object term cache

wp_get_object_terms() queries the database directly on every call.
get_the_terms() uses the object term cache populated by
update_object_term_cache(), which keeps repeated reads cheap within
the same request.

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

* Guidelines: Drop redundant autosave check and cover revisions in tests

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

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

Co-authored-by: gziolo <gziolo@git.wordpress.org>
Co-authored-by: tyxla <tyxla@git.wordpress.org>
Co-authored-by: simison <87168+simison@users.noreply.github.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] Bug An existing feature does not function as intended

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants