Repository navigation
Conversation
The JS editor filter adds hmUrlTabVisibility to all blocks client-side, but without a matching server-side registration the REST API block renderer rejects any request that includes the attribute. WordPress uses additionalProperties:false when validating the attributes parameter, so unrecognised attributes cause a 400 error. Hooks into registered_block_type (fired after every register_block_type call) to add the attribute to the server-side WP_Block_Type object, mirroring the JS filter exactly — all blocks except core/navigation-link. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Playwright test resultsDetails
Skipped testschromium › multiple-endpoints.spec.js › Multiple endpoints - EP_CATEGORIES overview endpoint › Editor endpoint selector › endpoint selector appears in Tab Visibility panel with multiple registered endpoints |
The previous implementation accepted WP_Block_Type as the second action argument, but that parameter was only added in WordPress 6.7. On older installs the callback received null and silently did nothing. Fix by accepting only the block name (1 arg, available since WP 5.0) and looking the live object up from the registry directly. Also add a rest_api_init priority-1 sweep over all registered block types. This guarantees the attribute is present when WordPress builds the per-block attributes schema for the block renderer REST endpoint, regardless of when individual block types were registered. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Block types are registered during init, so the safety-net sweep belongs there rather than at rest_api_init. Using PHP_INT_MAX priority ensures it runs after all plugins have had a chance to register their blocks. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Nesting the hook registration inside init (priority 1) ensures it only starts listening once WordPress's bootstrap is underway, at a consistent and predictable point rather than at arbitrary plugin-load time. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Single init priority-1 callback: first sweeps blocks already registered, then attaches registered_block_type to catch any registered after. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
WordPress core does not fire a registered_block_type action, so the listener was dead code. The init PHP_INT_MAX sweep is sufficient — it runs after all plugins have registered their blocks during init. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…hook
block_type_metadata_settings fires inside register_block_type_from_metadata(),
which all register_block_type('name', [...]) calls go through. This adds
hmUrlTabVisibility to the settings before the WP_Block_Type object is created,
so it is present in the REST API schema from the start.
Keeps the init PHP_INT_MAX sweep as a safety net for blocks registered
directly as WP_Block_Type objects, which bypass the filter.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The helper function was only called from the init sweep, so there was no DRY benefit to keeping it separate. Inline it and drop the function. Also skip blocks already carrying hmUrlTabVisibility in the sweep. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Updated comments to clarify the purpose of filters and actions related to hmUrlTabVisibility for block types.
Summary
Fix
Hooks into
registered_block_type(fired after everyregister_block_type()call) to addhmUrlTabVisibilityto the server-sideWP_Block_Typeobject, mirroring the existing JS filter exactly — all blocks exceptcore/navigation-link.Test plan
ServerSideRenderfor a custom block (e.g. hm-query-loop with the SSR preview PR)rest_additional_properties_forbiddenforhmUrlTabVisibility