Opened 12 months ago
Closed 12 months ago
#59732 closed defect (bug) (fixed)
Theme live preview is broken
Reported by: | karl94 | Owned by: | flixos90 |
---|---|---|---|
Milestone: | 6.4 | Priority: | normal |
Severity: | normal | Version: | 5.8 |
Component: | Themes | Keywords: | has-patch has-testing-info dev-reviewed commit |
Focuses: | Cc: |
Description
The newly added memoization in 6.4 for get_stylesheet_directory()
and get_template_directory()
breaks themes live preview.
How to reproduce:
- Load a WP 6.4 beta or RC (playground link: https://playground.wordpress.net/?theme=twentynineteen&lazy&wp=beta)
- Install some classic themes e.g. twentytwenty and twentynineteen
- Activate twentynineteen
- Live preview twentytwenty
- The preview is broken: the HTML comes from twentynineteen but the stylesheet is from twentytwenty
Attachments (4)
Change History (22)
#2
@
12 months ago
- Keywords needs-patch added
- Milestone changed from Awaiting Review to 6.4
- Owner set to flixos90
- Status changed from new to assigned
- Version changed from trunk to 5.8
Thank you for the report @karl94! I have investigated the problem and identified the root cause: There are two default filters (_add_default_theme_supports()
, and wp_enable_block_templates()
as you've mentioned), which are hooked into the setup_theme
action to add_theme_support()
for certain features.
This is incorrect, as theme support should only be added on the after_setup_theme
hook. Using the setup_theme
hook does not only introduce the above bug, but leads to other problems as well as the theme can only be expected to be completely set up after the setup_theme
action. For example, at the moment these callbacks will add theme support based on the current theme which then would still be maintained even when previewing another theme in the Customizer.
It looks like these problems were introduced in [51199] and [52369] respectively, therefore pinging @jorgefilipecosta and @audrasjb for visibility.
This should be relatively straightforward to fix by relying on the appropriate action after_setup_theme
instead. There is no relevant usage of these functions in the plugin repository which would be affected by this change, see https://wpdirectory.net/search/01HDKY6F7BJ58ZD7H6JQ8K4P3S and https://wpdirectory.net/search/01HDKY998M6WV6TRE2WR3ZCYG6.
This ticket was mentioned in PR #5574 on WordPress/wordpress-develop by @flixos90.
12 months ago
#3
- Keywords has-patch added; needs-patch removed
This fixes the bug of using the setup_theme
action for adding theme support, which is incorrect for such purposes, as at that point the current theme is not set up yet. For example, Customizer previewing, which may exchange the current theme at runtime only fires on setup_theme
.
Therefore any code depending on the current theme must only run after that, i.e. on after_setup_theme
. This is also the hook which theme authors have been encouraged for more than a decade to use to add theme supports.
See https://core.trac.wordpress.org/ticket/59732#comment:2 for additional context.
Trac ticket: https://core.trac.wordpress.org/ticket/59732
This ticket was mentioned in PR #5574 on WordPress/wordpress-develop by @flixos90.
12 months ago
#4
This fixes the bug of using the setup_theme
action for adding theme support, which is incorrect for such purposes, as at that point the current theme is not set up yet. For example, Customizer previewing, which may exchange the current theme at runtime only fires on setup_theme
.
Therefore any code depending on the current theme must only run after that, i.e. on after_setup_theme
. This is also the hook which theme authors have been encouraged for more than a decade to use to add theme supports.
See https://core.trac.wordpress.org/ticket/59732#comment:2 for additional context.
Trac ticket: https://core.trac.wordpress.org/ticket/59732
This ticket was mentioned in Slack in #core by flixos90. View the logs.
12 months ago
#6
@
12 months ago
I have implemented https://github.com/WordPress/wordpress-develop/pull/5574 as a fix for this bug. It addresses the root problem and through that the concrete broken user experience reported: With the PR applied, the Customizer-previewed theme's data is correctly loaded, without any data from the original theme bleeding over.
@hellofromTonya commented on PR #5574:
12 months ago
#7
I share the concerns @joemcgill expressed:
could there be some unintentional side effects where some block data or settings get instantiated between
setup_theme
andafter_setup_theme
and assume that theme support has already been established?
While it fixes Customizer theme live preview, what might it do to block powered sites? Is something dependent upon on it? Not sure, but should be validated with careful testing within the editors and front-end.
@flixos90 commented on PR #5574:
12 months ago
#8
@hellofromtonya
While it fixes Customizer theme live preview, what might it do to block powered sites? Is something dependent upon on it? Not sure, but should be validated with careful testing within the editors and front-end.
I have checked the WordPress core codebase for further usage of the setup_theme
action, and I couldn't find any relevant instances where delaying the execution of _add_default_theme_supports()
and wp_enable_block_templates()
could lead to a problem. In fact the hook is only used to register the available theme features and for the Customizer preview.
This ticket was mentioned in Slack in #core by hellofromtonya. View the logs.
12 months ago
@flixos90 commented on PR #5574:
12 months ago
#10
@hellofromtonya I've tested this PR using the Site Editor for a bit, with both Twenty Twenty-Three and Twenty Twenty-Four, and couldn't find any problems. It also fixes the original Customizer bug. I personally think this change is safe to make, though of course any additional testing would be appreciated.
#11
@
12 months ago
- Keywords needs-testing has-testing-info added
Patch: https://github.com/WordPress/wordpress-develop/pull/5574
The patch changes the "when" (to after the theme is set up) for:
- adding block theme's theme supports (including
'block-templates'
), - turning on
'should_load_separate_core_block_assets'
, - and removing Customizer's Menu panel.
Testing instructions need to test for:
- the bug reported (i.e. Customizer themes live preview)
- and the above changes for block themes, i.e. to ensure the patch does not change the behavior.
Test Instructions: Customizer themes live preview bug
Steps to Reproduce
Though listed in the ticket's description, repeating here to keep all testing instructions in one place:
- Load WordPress 6.4 RC2
- Install some classic themes e.g. twentytwenty and twentynineteen
- Activate twentynineteen
- Live preview twentytwenty 🐞 Bug occurs.
Expected Results
When reproducing a bug:
- ❌ Before applying the patch, the live preview should not work.
When testing a patch to validate it works as expected:
- ✅ After applying the patch, the live preview should work.
Test Instructions: Block themes not affected by the patch
Though listed in the ticket's description, repeating here to keep all testing instructions in one place:
- Load WordPress 6.4 RC2.
- With a classic theme, such as Twenty Twenty-One (TT1) activated, open Customizer in a different browser tab or ease of access in the next steps.
- Notice: The "Menus" item in the navigation sidebar.
- Activate Twenty Twenty-Four (TT4).
- Refresh Customizer. Expected: The "Menus" item should not be in the navigation sidebar. ✅
- Apply the patch.
- Repeat step 4. Expected: No "Menus" item ✅
- Navigate to Posts > and open a post.
- Expected: "Featured image" subpanel should render in the right sidebar and be functional. ✅
Expected Results
After applying the patch, the following should still work for block themes:
- ✅ In Customizer, the "Menus" item should not in the navigation sidebar.
- ✅ When adding or editing a post, the "Featured image" subpanel should render and be functional.
Test Report Icons:
🐞 <= Indicates where issue ("bug") occurs.
✅ <= Behavior is expected.
❌ <= Behavior is NOT expected.
@
12 months ago
Test Report: After applying PR 5574, with block theme TT4 activated, Menus does not show and live preview (for classic theme) still works ✅
#12
@
12 months ago
- Keywords needs-testing removed
Environment
- OS: macOS
- Localhost: wp-env Docker
- PHP: 7.4
- WordPress:
trunk
- Browser: Firefox
- Theme: TT1 and TT0 (classic themes) and TT4 (block theme)
- Active Plugins: none
Actual Results: For Live Theme Preview bug
✅ After applying the patch, the live preview works.
See test-report-theme-live-preview.png
Actual Results: For Block Theme
✅ In Customizer, the "Menus" item does not show in the navigation sidebar.
✅ In Customizer, selecting TT0, live preview works.
See test-report-block-theme-in-customizer.png
✅ When adding or editing a post, the "Featured image" subpanel still renders and is functional.
#13
@
12 months ago
- Keywords dev-reviewed commit added
Patch: https://github.com/WordPress/wordpress-develop/pull/5574
With multiple testing reports and the patch being approved by 2 committers, the patch is ready for commit
.
To expedite, the patch is also okay to backport to the 6.4 branch.
@
12 months ago
Test Report: Bug before the patch: Live Preview in WP 6.3.2 (left) ✅ vs 6.4 RC (right) ❌
#14
@
12 months ago
Additional information why this regression should be included in 6.4 RC4:
Without the patch applied (i.e. before the patch), test-report-6.3.2v6.4-rc2.png shows theme live preview:
- Works with WordPress 6.3.2 ✅
- Broken with WordPress 6.4. RC2 ❌
With the live theme preview experience broken, a fix is indeed needed. As previously noted, the patch resolves the issue without impacting block themes.
@flixos90 commented on PR #5574:
12 months ago
#16
Committed in https://core.trac.wordpress.org/changeset/57009
@flixos90 can you give a look at this?
It appears that WP is invoking
get_stylesheet_directory()
before thatWP_Customize_Manager
attaches its filters for previewing the theme.WP_Customize_Manager
adds its preview filters inWP_Customize_Manager::start_previewing_theme()
, which is called fromWP_Customize_Manager::setup_theme()
, which is run on actionsetup_theme
at default priority (10).The first invocation of
get_stylesheet_directory()
appears to be fromwp_theme_has_theme_json()
(https://github.com/WordPress/wordpress-develop/blob/9352b2a/src/wp-includes/global-styles-and-settings.php#L399) which is called bywp_enable_block_templates()
(https://github.com/WordPress/wordpress-develop/blob/9352b2a/src/wp-includes/theme-templates.php#L227) yet again during the hooksetup_theme
at priority 10 (https://github.com/WordPress/wordpress-develop/blob/9352b2a/src/wp-includes/default-filters.php#L721).So, both
wp_enable_block_templates()
andWP_Customize_Manager::setup_theme()
are attached to the same hook at the same priority, therefore they get invoked in the same order they were attached to the hook.default-filters.php
is executed before, then the callback order is: firstwp_enable_block_templates()
, thenWP_Customize_Manager::setup_theme()
.Because
get_stylesheet_directory()
is used insidewp_enable_block_templates()
, the global variable$wp_stylesheet_path
is set, caching$stylesheet_dir
. Any followingget_stylesheet_directory()
call will always return the same value.The cache-bypass logic doesn't help in this case since when
get_stylesheet_directory()
is first invoked (viawp_enable_block_templates()
) the customizer hasn't added its filter yet.get_template_directory()
has the same issue.Maybe a
doing_it_wrong()
should be added to bothget_stylesheet_directory()
andget_template_directory()
to warn of every usage before or during the hooksetup_theme
? And bypass their cache until that hook completes?