Search 3.0: gate the Jetpack Search template on the Embedded experience (RSM-2381)#48562
Search 3.0: gate the Jetpack Search template on the Embedded experience (RSM-2381)#48562adamwoodnz wants to merge 3 commits intotrunkfrom
Conversation
|
Are you an Automattician? Please test your changes on all WordPress.com environments to help mitigate accidental explosions.
Interested in more tips and information?
|
|
Thank you for your PR! When contributing to Jetpack, we have a few suggestions that can help us test and review your patch:
This comment will be updated as you work on your PR and make changes. If you think that some of those checks are not needed for your PR, please explain why you think so. Thanks for cooperation 🤖 Follow this PR Review Process:
If you have questions about anything, reach out in #jetpack-developers for guidance! |
Code Coverage SummaryCoverage changed in 1 file.
|
| return; | ||
| } | ||
|
|
||
| add_action( 'init', array( static::class, 'register_search_template' ) ); |
There was a problem hiding this comment.
I would put those two statements in a if block rather than doing early returns. It's likely that we'll need more init actions here, which might be binary based on experience.
…ce (RSM-2381) `Search_Blocks::init()` was registering the Jetpack Search block template and prepending it to `search_template_hierarchy` whenever the `jetpack_search_blocks_enabled` filter was on. With four experiences now on the dashboard (`embedded` / `overlay` / `inline` / `off`), only Embedded should override the theme's `search.html` — a site that saves Overlay or Inline still expects `/?s=…` to resolve through their theme. Splits `init()` into two layers: - **Always when the feature flag is on:** `register_blocks`, `register_block_category`, `enqueue_editor_assets`. Blocks remain insertable in the editor regardless of experience. - **Embedded-only:** `register_search_template`, `prepend_search_template`, and the two `seed_interactivity_state` hooks. `Module_Control::get_experience()` reads `get_option(...)` (object-cached) with a legacy-boolean fallback, so this is cheap on every request. `update_experience()` writes synchronously, so the next request after a save sees the new gate — no cache-bust needed. Site Editor customizations survive a switch because they're keyed by template slug; switching back to Embedded re-registers the template and the DB-stored override resolves automatically. Tests cover all four gate states: always-registered block hooks regardless of experience, template hooks absent off-Embedded (option absent / inline / overlay), template hooks present on Embedded, and template hooks absent when module is inactive even with a stale `'embedded'` value in the option. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…Embedded-only (RSM-2381)
The original implementation followed the issue spec literally and gated
`seed_interactivity_state` behind the Embedded experience too. That was
wrong: admins can insert Search blocks anywhere blocks are configurable
(post content, sidebar widgets, custom templates), and those blocks need
the seeded base state — `apiRoot`, `nonce`, URL-derived `searchQuery` /
`activeFilters` / `sortOrder`, the `filterConfigs: {}` slot — to hydrate.
Per-block `render.php` files only contribute their own config (e.g. a
filter-checkbox block's filterConfig entry) and rely on the global seed
for the base.
So the gating splits cleanly between "blocks may be anywhere" (always on
when the feature flag is on) and "the Jetpack template replaces the
theme's search.html" (Embedded-only):
- Always when the feature flag is on: `register_blocks`,
`register_block_category`, `enqueue_editor_assets`, and the two
`seed_interactivity_state` hooks (`template_redirect` +
`wp_enqueue_scripts`).
- Embedded-only: `register_search_template`, `prepend_search_template`.
Updates the docblock to reflect the corrected reasoning, the test names
and assertions, and the changelog wording.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
a0f46b3 to
31b1204
Compare
Per review feedback (kangzj): the gate is likely to grow more init actions, possibly per-experience. An if-block keeps both per-experience branches and unconditional follow-up code possible without restructuring; the early return forecloses both. Behavior-equivalent.
Fixes RSM-2381
Why
Sites that use the new feature-selector to choose Overlay or Inline (Theme search) still expect
/?s=…to resolve through their theme'ssearch.html. Today, behind thejetpack_search_blocks_enabledfilter, the Jetpack Search block template is registered and prepended tosearch_template_hierarchyunconditionally, so its slug always wins resolution and the theme's template is never consulted — regardless of which experience the admin actually saved. After this PR, the template-takeover only happens when the saved experience is'embedded'; everywhere else, the theme template renders again. Search blocks placed elsewhere (post content, sidebar widgets, custom templates) keep working on every experience, since block registration and Interactivity API state seeding stay on regardless.Proposed changes
Search_Blocks::init()now splits its hooks into two groups:register_blocksoninitregister_block_categoryonblock_categories_allenqueue_editor_assetsonenqueue_block_editor_assetsseed_interactivity_stateontemplate_redirectandwp_enqueue_scriptsregister_search_templateoninitprepend_search_templateonsearch_template_hierarchyapiRoot,nonce, URL-derivedsearchQuery/activeFilters/sortOrder, thefilterConfigs: {}slot, locale — to hydrate. Per-blockrender.phpfiles only contribute their own config (e.g. a filter-checkbox block's filterConfig entry) and rely on the global seed for the base.Module_Control::get_experience(), which consultsget_option( 'jetpack_search_experience' )with a legacy-boolean fallback. The option is object-cached andupdate_experience()writes synchronously, so the next request after a save sees the new gate — no cache-bust needed.test_init_always_registers_block_and_seed_hooks— block-level + IA-seeding hooks present regardless of experience.test_init_does_not_register_template_hooks_when_not_embedded— template-takeover hooks absent off Embedded (option absent → falls back to inline).test_init_registers_template_hooks_when_embedded— template-takeover hooks present whenEXPERIENCE_EMBEDDEDis saved.test_init_does_not_register_template_hooks_when_module_inactive— even a stale'embedded'value is overridden byis_active() === false; block-level and seed hooks still register so any post-content block keeps working.Related product discussion/links
experiencefield in settings API (RSM-2291) #48540 (RSM-2291) — backend support for theexperiencefield (merged to trunk)Does this pull request change what data or activity we track or use?
No.
Testing instructions
Set up a test site with the feature flag on:
Automated
Expected: 23 tests pass (4 new gate-behaviour tests).
Manual: template-takeover gate
/?s=anythingand confirm the page is rendered by the theme'ssearch.html(orindex.htmlfallback) — not the Jetpack Search template. The<body>class should be the theme's normal search-results class, no Jetpack Search blocks visible./?s=anythingagain. The page should now render the Jetpack Search template (results panel, filter blocks)./?s=…(theme template renders, customizations dormant). Switch back to Embedded → the customized template re-resolves with the changes intact./?s=…falls back to the theme — same as Inline/Overlay.Manual: blocks-anywhere parity (regardless of experience)
These steps verify that Search blocks placed off the Jetpack template still hydrate on every experience. The IA state seed is what makes this work — without it, blocks dropped into a post / sidebar / custom template would be missing
apiRoot,nonce, URL-derived state, and thefilterConfigsslot.jetpack/search-inputblock plus ajetpack/filter-checkbox(or any filter block) into a post's content. Save and view the post on the front end.?q=test(or?s=testifis_search()) and confirm the input is pre-populated and the filter UI reflects any active filters in the URL.apiRootwith the seedednonce).Network / cache sanity
jetpack_search_blocks_enabledoff. ConfirmSearch_Blocks::init()is not called and none of its hooks register (themesearch.htmlresolves at/?s=…, no Jetpack blocks in the inserter).