Skip to content

RTC: Auto-register custom taxonomy rest_base values for CRDT sync#75983

Merged
chriszarate merged 5 commits intoWordPress:trunkfrom
smithjw1:smithjw1/crdt-auto-tax-sync
Mar 16, 2026
Merged

RTC: Auto-register custom taxonomy rest_base values for CRDT sync#75983
chriszarate merged 5 commits intoWordPress:trunkfrom
smithjw1:smithjw1/crdt-auto-tax-sync

Conversation

@smithjw1
Copy link
Copy Markdown
Contributor

@smithjw1 smithjw1 commented Feb 26, 2026

Summary

Alternative approach to #75876. Closes #75875.

Instead of requiring plugins to manually register properties via a filter, this PR automatically registers all taxonomy rest_base values for CRDT sync when taxonomy entities are loaded from /wp/v2/taxonomies. Custom taxonomies with show_in_rest enabled work with real-time collaboration out of the box — no plugin-side registration needed.

  • Exports registerTaxonomyRestBases() from crdt.ts
  • Calls it from loadTaxonomyEntities() in entities.js after fetching taxonomy data

Security

  • Only taxonomies returned by /wp/v2/taxonomies are registered (these already have show_in_rest: true)
  • The REST API enforces assign_terms capabilities server-side on save
  • The editor UI checks wp:action-assign-{rest_base} link relations before rendering term controls
  • Custom taxonomy terms are simple number[] arrays, handled by the existing default code path (same as categories / tags)

Trade-offs vs #75876 (filter approach)

This PR (auto-register) #75876 (filter)
Custom taxonomies Zero config — works automatically Plugin must call addFilter
Non-taxonomy properties Not supported Supported via filter
Plugin control Less — all REST taxonomies included More — explicit opt-in

Closes #75875

Test plan

  • Verify CRDT unit tests pass: npm run test:unit -- --testPathPattern="packages/core-data/src/utils/test/crdt"
  • Verify new tests for registerTaxonomyRestBases pass (dynamically registered taxonomy properties sync in both directions)
  • Verify a custom taxonomy with show_in_rest: true auto-syncs between collaborators without any plugin-side registration

🤖 Generated with Claude Code

@smithjw1 smithjw1 requested a review from nerrad as a code owner February 26, 2026 22:47
@github-actions github-actions bot added the [Package] Core data /packages/core-data label Feb 26, 2026
@github-actions
Copy link
Copy Markdown

github-actions bot commented Feb 26, 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: smithjw1 <smithjw1@git.wordpress.org>
Co-authored-by: chriszarate <czarate@git.wordpress.org>
Co-authored-by: maxschmeling <maxschmeling@git.wordpress.org>

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

@github-actions github-actions bot added the First-time Contributor Pull request opened by a first-time contributor to Gutenberg repository label Feb 26, 2026
@github-actions
Copy link
Copy Markdown

👋 Thanks for your first Pull Request and for helping build the future of Gutenberg and WordPress, @smithjw1! In case you missed it, we'd love to have you join us in our Slack community.

If you want to learn more about WordPress development in general, check out the Core Handbook full of helpful information.

@smithjw1 smithjw1 added [Feature] Real-time Collaboration Phase 3 of the Gutenberg roadmap around real-time collaboration [Type] Enhancement A suggestion for improvement. labels Feb 26, 2026
smithjw1 and others added 2 commits March 3, 2026 12:26
Auto-register all taxonomy rest_base values for CRDT sync when taxonomy
entities are loaded from the REST API. This means custom taxonomies with
show_in_rest enabled automatically work with real-time collaboration
without any plugin-side registration.

Taxonomies returned by /wp/v2/taxonomies already have show_in_rest
enabled, and the REST API enforces assign_terms capabilities on save.

Closes WordPress#75875

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@chriszarate chriszarate force-pushed the smithjw1/crdt-auto-tax-sync branch from 3aad8ee to f27a769 Compare March 3, 2026 20:24
@chriszarate
Copy link
Copy Markdown
Contributor

Nice! Since we can get access to the taxonomies object, it would be better to dynamically construct a list of syncedProperties that includes only the taxonomies that are registered against each post type. For example, the default post post type supports categories and tags, but site code could change that with a filter. Similarly, the page post type does not support any taxonomies by default.

I pushed up these changes in f27a769

@chriszarate chriszarate requested a review from maxschmeling March 3, 2026 21:13
Copy link
Copy Markdown
Contributor

@maxschmeling maxschmeling left a comment

Choose a reason for hiding this comment

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

I like it.

One performance improvement suggestion and one test suggestion.

I'll push up a pass at those two changes shortly.

Comment on lines +331 to +336
const postTypes = await apiFetch( {
path: '/wp/v2/types?context=view',
} );
const taxonomies = await apiFetch( {
path: '/wp/v2/taxonomies?context=view',
} );
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Prevent the waterfall

Suggested change
const postTypes = await apiFetch( {
path: '/wp/v2/types?context=view',
} );
const taxonomies = await apiFetch( {
path: '/wp/v2/taxonomies?context=view',
} );
const [ postTypes, taxonomies ] = await Promise.all( [
apiFetch( { path: '/wp/v2/types?context=view' } ),
apiFetch( { path: '/wp/v2/taxonomies?context=view' } ),
] );

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Comment on lines +359 to +361
...( postType.taxonomies?.map(
( taxonomy ) => taxonomies[ taxonomy ].rest_base
) ?? [] ),
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

We probably want to add a test that verifies this is actually happening properly

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Added a test here: fee20ee

@chriszarate chriszarate added the Backport to WP 7.0 Beta/RC Pull request that needs to be backported to the WordPress major release that's currently in beta label Mar 16, 2026
@chriszarate chriszarate enabled auto-merge (squash) March 16, 2026 16:08
@chriszarate chriszarate merged commit 338747b into WordPress:trunk Mar 16, 2026
42 checks passed
@github-actions github-actions bot added this to the Gutenberg 22.8 milestone Mar 16, 2026
@github-actions github-actions bot removed the Backport to WP 7.0 Beta/RC Pull request that needs to be backported to the WordPress major release that's currently in beta label Mar 16, 2026
gutenbergplugin pushed a commit that referenced this pull request Mar 16, 2026
…5983)

* RTC: Auto-register custom taxonomy rest_base values for CRDT sync

Auto-register all taxonomy rest_base values for CRDT sync when taxonomy
entities are loaded from the REST API. This means custom taxonomies with
show_in_rest enabled automatically work with real-time collaboration
without any plugin-side registration.

Taxonomies returned by /wp/v2/taxonomies already have show_in_rest
enabled, and the REST API enforces assign_terms capabilities on save.

Closes #75875

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Inspect taxonomies for each post type

* Apply suggested changes from PR

* Conditionally fetch taxonomies

---------

Co-authored-by: smithjw1 <smithjw1@git.wordpress.org>
Co-authored-by: chriszarate <czarate@git.wordpress.org>
Co-authored-by: maxschmeling <maxschmeling@git.wordpress.org>
@github-actions github-actions bot added the Backported to WP Core Pull request that has been successfully merged into WP Core label Mar 16, 2026
@github-actions
Copy link
Copy Markdown

I just cherry-picked this PR to the wp/7.0 branch to get it included in the next release: 9c088b3

pento pushed a commit to WordPress/wordpress-develop that referenced this pull request Mar 19, 2026
This updates the pinned hash from the `gutenberg` from `8c78d87453509661a9f28f978ba2c242d515563b` to `487a096a9782ba6110a7686d7b4b2d0c55ed1b06`.

The following changes are included:

- Disables anchor support for the Page Break block. (WordPress/gutenberg#76434)
- WP Admin: Update Connectors screen footer text for consistency. (WordPress/gutenberg#76382)
- E2E Tests: Add coverage for AI plugin callout banner on Connectors page (WordPress/gutenberg#76432)
- Update sync docs (WordPress/gutenberg#75972)
- RTC: Add preference for collaborator notifications (WordPress/gutenberg#76460)
- Fix "should undo bold" flaky test (WordPress/gutenberg#76464)
- TimePicker: Clamp month day to valid day for month (WordPress/gutenberg#76400)
- RTC: Fix error when entity record doesn't have 'meta' property (WordPress/gutenberg#76311)
- Navigation: Update close button size. (WordPress/gutenberg#76482)
- TemplateContentPanel: fix useSelect warning (WordPress/gutenberg#76421)
- DataViews: Add spinner in `DataViewsLayout` in initial load of data (WordPress/gutenberg#76486) (WordPress/gutenberg#76490)
- RTC: Fix TypeError in areEditorStatesEqual when selection is undefined (WordPress/gutenberg#76163)
- Page/Post Content Focus Mode: Fix insertion into Post Content block (WordPress/gutenberg#76477)
- Revisions: use useSubRegistry={false} to fix global store selectors (WordPress/gutenberg#76152) (WordPress/gutenberg#76522)
- Fix RTL styling on Connectors, Font Library, and boot-based admin pages (WordPress/gutenberg#76496)
- RTC: Auto-register custom taxonomy rest_base values for CRDT sync (WordPress/gutenberg#75983)
- RTC: Add a limit for the default provider (WordPress/gutenberg#76437)
- Fix RTL styling on AI plugin callout banner (WordPress/gutenberg#76497)
- Add command palette trigger button to admin bar (WordPress/gutenberg#75757)
- Block Bindings: Remove source items constrained by enums (WordPress/gutenberg#76200)
- HTML Block: Remove "unsaved changes" check (WordPress/gutenberg#76086)
- CI: Don't build release notes during plugin build workflow for WP Core sync (WordPress/gutenberg#76398) (WordPress/gutenberg#76578)
- CI: Simplify strategy matrix in Build Gutenberg Plugin Zip workflow (WordPress/gutenberg#76435) (WordPress/gutenberg#76538)
- Media: Add hooks and extension points for client-side media processing (WordPress/gutenberg#74913)
- RTC: Fix list sidebar reset during real-time collaboration (WordPress/gutenberg#76025)
- RTC: Fix CRDT serialization of nested RichText attributes (WordPress/gutenberg#76597)
- RTC: Remove post list lock icon and replace user-specific lock text (WordPress/gutenberg#76322)
- Fix HEIC upload error handling and sub-size format (WordPress/gutenberg#76514)
- RTC: Fix cursor index sync with rich text formatting (WordPress/gutenberg#76418)
- RTC: Allow filtering of `SyncConnectionModal` (WordPress/gutenberg#76554)
- RTC: Implement front-end peer limits (WordPress/gutenberg#76565)
- Navigation overlay close button may be displayed twice (WordPress/gutenberg#76585)
- Site Editor > Templates: fix author filter (WordPress/gutenberg#76625)
- Revisions: Show changed block attributes in inspector sidebar (WordPress/gutenberg#76550)
- Fix IS_GUTENBERG_PLUGIN env var override in build config  (WordPress/gutenberg#76605)
- Real Time Collaboration: Introduce filters for the polling intervals. (WordPress/gutenberg#76518)
- RTC: Fix RichTextData deserialization (WordPress/gutenberg#76607)
- Cross Origin Isolation: Remove `img` from the list of elements that get mutated (WordPress/gutenberg#76618)
- RTC: Scroll to collaborator on click (WordPress/gutenberg#76561)
- Update changelog link for pull request 11276 (WordPress/gutenberg#76638)
- Fix backport changelog filename (WordPress/gutenberg#76651)
- Build: Skip non-minified build for WASM-inlined workers (WordPress/gutenberg#76615)
- RTC: Change RTC option name (WordPress/gutenberg#76643)
- BlockListBlock: fix crash when selectedProps are null (WordPress/gutenberg#75826)
- Build: Fix vips worker 404 when SCRIPT_DEBUG is true (WordPress/gutenberg#76657)
- useMediaQuery: support in-iframe queries via new `WindowContext` (WordPress/gutenberg#76446) (WordPress/gutenberg#76660)
- Refactor admin-ui Page component to use @wordpress/theme tokens and @wordpress/ui layout primitive (WordPress/gutenberg#75963)
- Connectors: Improve accessibility (WordPress/gutenberg#76456)
- Build: Remove unused JXL WASM module from vips worker (WordPress/gutenberg#76639)
- Connectors: fix button size (WordPress/gutenberg#76582)
- Compose: Implement useCopyToClipboard and useCopyOnClick with native clipboard API (WordPress/gutenberg#75723) (WordPress/gutenberg#76663)
- Connectors: Fetch specific plugin instead of all plugins (WordPress/gutenberg#76594)
- Revisions: Add Meta fields diff panel to document sidebar (WordPress/gutenberg#76341)
- Loosen client-side media processing requirements (WordPress/gutenberg#76616)
- Reduce the added halo for selected block. (WordPress/gutenberg#76619)
- Connectors: Add unregisterConnector and upsert support (WordPress/gutenberg#76541)

A full list of changes can be found on GitHub: https://github.com/WordPress/gutenberg/compare/8c78d87453509661a9f28f978ba2c242d515563b…487a096a9782ba6110a7686d7b4b2d0c55ed1b06.

Log created with:

git log --reverse --format="- %s" 8c78d87453509661a9f28f978ba2c242d515563b..487a096a9782ba6110a7686d7b4b2d0c55ed1b06 | sed 's|#\([0-9][0-9]*\)|https://github.com/WordPress/gutenberg/pull/\1|g; /github\.com\/WordPress\/gutenberg\/pull/!d' | pbcopy

See #64595.

git-svn-id: https://develop.svn.wordpress.org/trunk@62063 602fd350-edb4-49c9-b593-d223f7449a82
markjaquith pushed a commit to markjaquith/WordPress that referenced this pull request Mar 19, 2026
This updates the pinned hash from the `gutenberg` from `8c78d87453509661a9f28f978ba2c242d515563b` to `487a096a9782ba6110a7686d7b4b2d0c55ed1b06`.

The following changes are included:

- Disables anchor support for the Page Break block. (WordPress/gutenberg#76434)
- WP Admin: Update Connectors screen footer text for consistency. (WordPress/gutenberg#76382)
- E2E Tests: Add coverage for AI plugin callout banner on Connectors page (WordPress/gutenberg#76432)
- Update sync docs (WordPress/gutenberg#75972)
- RTC: Add preference for collaborator notifications (WordPress/gutenberg#76460)
- Fix "should undo bold" flaky test (WordPress/gutenberg#76464)
- TimePicker: Clamp month day to valid day for month (WordPress/gutenberg#76400)
- RTC: Fix error when entity record doesn't have 'meta' property (WordPress/gutenberg#76311)
- Navigation: Update close button size. (WordPress/gutenberg#76482)
- TemplateContentPanel: fix useSelect warning (WordPress/gutenberg#76421)
- DataViews: Add spinner in `DataViewsLayout` in initial load of data (WordPress/gutenberg#76486) (WordPress/gutenberg#76490)
- RTC: Fix TypeError in areEditorStatesEqual when selection is undefined (WordPress/gutenberg#76163)
- Page/Post Content Focus Mode: Fix insertion into Post Content block (WordPress/gutenberg#76477)
- Revisions: use useSubRegistry={false} to fix global store selectors (WordPress/gutenberg#76152) (WordPress/gutenberg#76522)
- Fix RTL styling on Connectors, Font Library, and boot-based admin pages (WordPress/gutenberg#76496)
- RTC: Auto-register custom taxonomy rest_base values for CRDT sync (WordPress/gutenberg#75983)
- RTC: Add a limit for the default provider (WordPress/gutenberg#76437)
- Fix RTL styling on AI plugin callout banner (WordPress/gutenberg#76497)
- Add command palette trigger button to admin bar (WordPress/gutenberg#75757)
- Block Bindings: Remove source items constrained by enums (WordPress/gutenberg#76200)
- HTML Block: Remove "unsaved changes" check (WordPress/gutenberg#76086)
- CI: Don't build release notes during plugin build workflow for WP Core sync (WordPress/gutenberg#76398) (WordPress/gutenberg#76578)
- CI: Simplify strategy matrix in Build Gutenberg Plugin Zip workflow (WordPress/gutenberg#76435) (WordPress/gutenberg#76538)
- Media: Add hooks and extension points for client-side media processing (WordPress/gutenberg#74913)
- RTC: Fix list sidebar reset during real-time collaboration (WordPress/gutenberg#76025)
- RTC: Fix CRDT serialization of nested RichText attributes (WordPress/gutenberg#76597)
- RTC: Remove post list lock icon and replace user-specific lock text (WordPress/gutenberg#76322)
- Fix HEIC upload error handling and sub-size format (WordPress/gutenberg#76514)
- RTC: Fix cursor index sync with rich text formatting (WordPress/gutenberg#76418)
- RTC: Allow filtering of `SyncConnectionModal` (WordPress/gutenberg#76554)
- RTC: Implement front-end peer limits (WordPress/gutenberg#76565)
- Navigation overlay close button may be displayed twice (WordPress/gutenberg#76585)
- Site Editor > Templates: fix author filter (WordPress/gutenberg#76625)
- Revisions: Show changed block attributes in inspector sidebar (WordPress/gutenberg#76550)
- Fix IS_GUTENBERG_PLUGIN env var override in build config  (WordPress/gutenberg#76605)
- Real Time Collaboration: Introduce filters for the polling intervals. (WordPress/gutenberg#76518)
- RTC: Fix RichTextData deserialization (WordPress/gutenberg#76607)
- Cross Origin Isolation: Remove `img` from the list of elements that get mutated (WordPress/gutenberg#76618)
- RTC: Scroll to collaborator on click (WordPress/gutenberg#76561)
- Update changelog link for pull request 11276 (WordPress/gutenberg#76638)
- Fix backport changelog filename (WordPress/gutenberg#76651)
- Build: Skip non-minified build for WASM-inlined workers (WordPress/gutenberg#76615)
- RTC: Change RTC option name (WordPress/gutenberg#76643)
- BlockListBlock: fix crash when selectedProps are null (WordPress/gutenberg#75826)
- Build: Fix vips worker 404 when SCRIPT_DEBUG is true (WordPress/gutenberg#76657)
- useMediaQuery: support in-iframe queries via new `WindowContext` (WordPress/gutenberg#76446) (WordPress/gutenberg#76660)
- Refactor admin-ui Page component to use @wordpress/theme tokens and @wordpress/ui layout primitive (WordPress/gutenberg#75963)
- Connectors: Improve accessibility (WordPress/gutenberg#76456)
- Build: Remove unused JXL WASM module from vips worker (WordPress/gutenberg#76639)
- Connectors: fix button size (WordPress/gutenberg#76582)
- Compose: Implement useCopyToClipboard and useCopyOnClick with native clipboard API (WordPress/gutenberg#75723) (WordPress/gutenberg#76663)
- Connectors: Fetch specific plugin instead of all plugins (WordPress/gutenberg#76594)
- Revisions: Add Meta fields diff panel to document sidebar (WordPress/gutenberg#76341)
- Loosen client-side media processing requirements (WordPress/gutenberg#76616)
- Reduce the added halo for selected block. (WordPress/gutenberg#76619)
- Connectors: Add unregisterConnector and upsert support (WordPress/gutenberg#76541)

A full list of changes can be found on GitHub: https://github.com/WordPress/gutenberg/compare/8c78d87453509661a9f28f978ba2c242d515563b…487a096a9782ba6110a7686d7b4b2d0c55ed1b06.

Log created with:

git log --reverse --format="- %s" 8c78d87453509661a9f28f978ba2c242d515563b..487a096a9782ba6110a7686d7b4b2d0c55ed1b06 | sed 's|#\([0-9][0-9]*\)|https://github.com/WordPress/gutenberg/pull/\1|g; /github\.com\/WordPress\/gutenberg\/pull/!d' | pbcopy

See #64595.
Built from https://develop.svn.wordpress.org/trunk@62063


git-svn-id: http://core.svn.wordpress.org/trunk@61345 1a063a9b-81f0-0310-95a4-ce76da25c4cd
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Backported to WP Core Pull request that has been successfully merged into WP Core [Feature] Real-time Collaboration Phase 3 of the Gutenberg roadmap around real-time collaboration First-time Contributor Pull request opened by a first-time contributor to Gutenberg repository [Package] Core data /packages/core-data [Type] Enhancement A suggestion for improvement.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

RTC: [Engine] - Allow plugins to filter synced properties

3 participants