#63086 closed defect (bug) (fixed)
Customizer: notice errror regarding WP_Theme::is_block_theme
Reported by: |
|
Owned by: |
|
---|---|---|---|
Milestone: | 6.8 | Priority: | normal |
Severity: | normal | Version: | trunk |
Component: | Customize | Keywords: | has-testing-info dev-feedback needs-testing has-patch |
Focuses: | Cc: |
Description
[59968] added _doing_it_wrong()
error when WP_Theme::is_block_theme
is called too early.
This warning tells me that the customizer might be using WP_Theme::is_block_theme
too early.
Here's what's causing this error:
Attachments (1)
Change History (48)
#1
@
6 weeks ago
- Summary changed from Customizer: warning errror regarding WP_Theme::is_block_theme to Customizer: notice errror regarding WP_Theme::is_block_theme
#2
@
6 weeks ago
Reproduction Report
Description
This report validates whether the issue can be reproduced.
Environment
- WordPress: 6.8-beta2-59971-src
- PHP: 8.2.27
- Server: nginx/1.27.4
- Database: mysqli (Server: 8.0.41 / Client: mysqlnd 8.2.27)
- Browser: Chrome 133.0.0.0
- OS: macOS
- Theme: Twenty Twenty-Five 1.1
- MU Plugins: None activated
- Plugins:
- Test Reports 1.2.0
Actual Results
- ✅ Error condition occurs (reproduced).
The following error message appears
Notice: WP_Theme::is_block_theme was called incorrectly. This method should not be called before themes are set up.
Supplemental Artifacts
#3
@
6 weeks ago
- Keywords has-testing-info added
Reproduction Report
Description
This report validates whether the issue can be reproduced.
Environment
- WordPress: 6.8-beta2-59971-src
- PHP: 8.2.27
- Server: nginx/1.27.4
- Database: mysqli (Server: 8.0.41 / Client: mysqlnd 8.2.27)
- Browser: Chrome 133.0.0.0
- OS: macOS
- Theme: Twenty Twenty-Five 1.1
- MU Plugins: None activated
- Plugins:
- Test Reports 1.2.0
Actual Results
- ✅ Error condition occurs (reproduced).
The following error message appearing.
Notice: WP_Theme::is_block_theme was called incorrectly. This method should not be called before themes are set up.
Supplemental Artifacts :
#4
@
6 weeks ago
Thanks for opening this ticket. [59968] is also causing a regression on WooCommerce: https://github.com/woocommerce/woocommerce/issues/56322.
Considering the significant impact [59968] could have on other plugins, should it be reverted?
This ticket was mentioned in Slack in #core by gigitux. View the logs.
6 weeks ago
This ticket was mentioned in PR #8497 on WordPress/wordpress-develop by @yogeshbhutkar.
6 weeks ago
#6
- Keywords has-patch added
### Description
Trac ticket: https://core.trac.wordpress.org/ticket/63086
This changeset introduced displaying a _doing_it_wrong()
error if WP_Theme::is_block_theme is called too early. This caused the warnings to be displayed within Customizer
where wp_get_theme
and wp_is_block_theme
were getting called before themes were set up.
This PR resolves the issue by calling them within the setup_theme
hook.
#7
follow-up:
↓ 8
@
6 weeks ago
- Owner set to joemcgill
- Status changed from new to assigned
@wildworks Thanks for the report! Calling that method too early is what caused parent themes to not be found in #63062. If other code is calling that method too early without causing the same bug, then I’d like to investigate further to see if there is a better place for that warning. If not, then we could choose to keep the fix for that ticket in place while removing the _doing_it_wrong()
.
#8
in reply to:
↑ 7
@
6 weeks ago
If not, then we could choose to keep the fix for that ticket in place while removing the _doing_it_wrong().
If the intention is to keep the following logic:
if ( ! did_action( 'setup_theme' ) ) {
return false;
}
it is a breaking change and could break several plugins.
As noted in 63062, it may be worth investigating why wp_is_block_theme
returns an incorrect value before the after_setup_theme
action and addressing that issue directly.
#9
@
6 weeks ago
- Keywords needs-unit-tests added
Test Report
Description
This report validates the patch is solving the issue in my environment but its not passing some unit tests
Patch tested: https://patch-diff.githubusercontent.com/raw/WordPress/wordpress-develop/pull/8497.diff
Environment
- WordPress: 6.8-beta2-59971-src
- PHP: 8.2.27
- Server: nginx/1.27.4
- Database: mysqli (Server: 8.4.4 / Client: mysqlnd 8.2.27)
- Browser: Chrome 134.0.0.0
- OS: Windows 10/11
- Theme: Twenty Nineteen 3.0
- MU Plugins: None activated
- Plugins:
- Global Post Population Tester 1.0
- Test Reports 1.2.0
Actual Results
- ✅ Issue resolved with patch.
- ❌ Checked unit test
test_setup_theme_in_customize_admin
and failed.
Supplemental Artifacts
Using 2019 theme
With Patch: Solved
Without Patch: Failing with Notices
@SirLouen commented on PR #8497:
6 weeks ago
#10
@yogeshbhutkar
Despite the notice is removed, some unit tests like test_setup_theme_in_customize_admin
are not passing.
Can you review the patch to see what's going on?
@SirLouen commented on PR #8497:
6 weeks ago
#11
@yogeshbhutkar
Despite the notice is removed, some unit tests like test_setup_theme_in_customize_admin
are not passing.
Can you review the patch to see what's going on?
#12
@
6 weeks ago
I had to create a plugin to suppress the messages as this is not workable while testing the wordpress beta. Not only woocommerce triggers this.
Plugins calling the function wp_get_theme to check the theme information also trigger the error message for each time it is called.
<?php /* Plugin Name: WP Hide Doing It Wrong Message Description: WordPress Hide the WordPress doing it wrong message for loading textdomain and is_block_theme Version: 1.0 Author: BackuPs License: GPL2 */ if ( !function_exists( 'theme_hide_doing_it_wrong_notice' ) ) { function theme_hide_doing_it_wrong_notice( $trigger, $function, $message, $version ) { // Update the $trigger variable according to your website requirements and return this variable. You can modify the $trigger variable conditionally too if you want. if( $function == 'WP_Theme::is_block_theme' || $function == 'load_plugin_textdomain' ) return false; return $trigger; } add_filter( "doing_it_wrong_trigger_error", "theme_hide_doing_it_wrong_notice", 10, 4 ); }
This ticket was mentioned in PR #8508 on WordPress/wordpress-develop by @dinhtungdu.
6 weeks ago
#13
This PR partially reverts https://core.trac.wordpress.org/changeset/59968 by removing the warning and early return in WP_Theme::is_block_theme()
, which causes issues if active plugins call wp_is_block_theme()
early. It's safe for plugins to call wp_is_block_theme()
anytime so the early return and warning should be removed.
Trac ticket: https://core.trac.wordpress.org/ticket/63086
#14
follow-ups:
↓ 15
↓ 23
@
6 weeks ago
If other code is calling that method too early without causing the same bug, then I’d like to investigate further to see if there is a better place for that warning. If not, then we could choose to keep the fix for that ticket in place while removing
the _doing_it_wrong()
.
From my investigation, I believe that it's safe for plugin to call wp_is_block_theme()
. I'm copying my comment from https://core.trac.wordpress.org/ticket/63062#comment:30 for visibility:
Digging deeper into the Core to understand the issue, I found that:
wp_is_block_theme
doesn't need to be called afterafter_theme_setup
, it just needs to be called after theme directories registration.- The initial issue with the child theme is caused by calling that function after creating post types, which is before the theme directories registration.
- Moving that logic to
after_theme_setup
, as we did in this ticket, is enough to solve the issue.- Plugins can never break the theme resolution because they are loaded after theme directories registration.
So the warning and early return don't protect us from anything and should be removed.
#15
in reply to:
↑ 14
@
6 weeks ago
- Keywords needs-refresh added; has-patch removed
Replying to dinhtungdu:
From my investigation, I believe that it's safe for plugin to call
wp_is_block_theme()
. I'm copying my comment from https://core.trac.wordpress.org/ticket/63062#comment:30 for visibility:
Try for example in a plugin adding this:
<?php add_action('plugins_loaded', 'test_is_block_theme'); function test_is_block_theme () { $is_block_theme = wp_get_theme()->is_block_theme(); if ($is_block_theme) { //Whatever } });
And then switch add_action('plugins_loaded', 'test_is_block_theme');
for
add_action('after_setup_theme', 'test_is_block_theme', 20);
Can you see the difference?
From what I can understand, it's just a notice for developers that could be willing to use this method, not just for the core code itself.
Maybe @joemcgill can provide more insight about this topic
Anyway the last patches from @yogeshbhutkar are still not passing tests.
This ticket was mentioned in PR #8509 on WordPress/wordpress-develop by @SirLouen.
6 weeks ago
#16
- Keywords has-patch has-unit-tests added; needs-unit-tests needs-refresh removed
After some debugging, I've found that this issue is three-folded: There are 3 points in the current code that are generating the notice because there is a check that avoids using is_block_theme()
calls too early.
In this first commit, I'm sorting the first one, but I have to do some "extra" edits (like a filter in wp_is_block_theme
) and added some tests taking advantage of these edits
I would like some dev feedback (maybe @joemcgill that was involved in the introduction of this check in the ticket 63062), to see if it's ok to continue with this line and sort the other two notices in a similar fashion.
Trac ticket: https://core.trac.wordpress.org/ticket/63086
#17
follow-ups:
↓ 18
↓ 21
@
6 weeks ago
- Keywords needs-unit-tests needs-refresh added; has-patch has-unit-tests removed
@SirLouen I tested your snippet and I can see the difference after switching: the warning and value of $is_block_theme
is false
when using the plugins_loaded
callback. Is that the difference you're talking about?
What I'm trying to prove is that it's fine to call WP_Theme::is_block_theme()
early, as long as we call it after theme directories registration. So the early return and warning added in [59968] should be removed.
I removed the early return and warning from WP_Theme::is_block_theme()
and tested your snippet against four types of themes, the value of $is_block_theme
was correct in all cases, either with plugins_loaded
or after_setup_theme
:
- Block parent theme.
- Block child theme.
- Classic parent theme.
- Classic child theme.
#18
in reply to:
↑ 17
@
6 weeks ago
Replying to dinhtungdu:
@SirLouen I tested your snippet and I can see the difference after switching: the warning and value of
$is_block_theme
isfalse
when using theplugins_loaded
callback. Is that the difference you're talking about?
It's not a warning.
I'm not 1000% of the background intentions because I have not read all the context with detail, but from what I see at first sight, this is just a notice with _doing_it_wrong
. It's not "protecting" anything but the developer to code wrongly.
It's merely a developer notice that is informing of what you are saying here:
Themes are not yet loaded at this point, therefore the
$is_block_theme
is always going to befalse
, so please, gently move youris_block_theme
call forward to a point where the call tois_block_theme
, makes real sense.
#19
@
6 weeks ago
- Keywords has-unit-tests needs-patch needs-testing added; needs-unit-tests needs-refresh removed
Patch closed in https://github.com/WordPress/wordpress-develop/pull/8509
5 weeks ago
#20
Absolutely agree. This is filling up my logs and not sure it's even effecting function.
#21
in reply to:
↑ 17
@
5 weeks ago
Replying to dinhtungdu:
What I'm trying to prove is that it's fine to call
WP_Theme::is_block_theme()
early, as long as we call it after theme directories registration. So the early return and warning added in [59968] should be removed.
I've done some quick testing and you are correct. The notice is protecting against calls to the method much later than it needs to be.
The issue in #63062 arose not because the method was called before themes were set up, but because the method was called before theme directories were set up. The directories are configured prior to plugins being loaded.
Perhaps the test should be:
<?php if ( empty( $GLOBALS['wp_theme_directories'] ) ) { _doing_it_wrong( __METHOD__, __( 'This method should not be called before theme directories are set up.' ), '6.8.0' ); return false; }
Possibly with some consideration for the possibility of define( 'WP_USE_THEMES', false );
#22
@
5 weeks ago
Since we’re in the beta stage, it would be best to apply @dinhtungdu’s patch (allowing a revert to the original state) and revisit improvements to this function in the next release. I’m concerned that these kinds of changes might break some extensions, so I’d prefer not to rush it.
#23
in reply to:
↑ 14
;
follow-up:
↓ 25
@
5 weeks ago
Replying to dinhtungdu:
From my investigation, I believe that it's safe for plugin to call
wp_is_block_theme()
. I'm copying my comment from https://core.trac.wordpress.org/ticket/63062#comment:30 for visibility:
Digging deeper into the Core to understand the issue, I found that:
wp_is_block_theme
doesn't need to be called afterafter_theme_setup
, it just needs to be called after theme directories registration.- The initial issue with the child theme is caused by calling that function after creating post types, which is before the theme directories registration.
- Moving that logic to
after_theme_setup
, as we did in this ticket, is enough to solve the issue.- Plugins can never break the theme resolution because they are loaded after theme directories registration.
So the warning and early return don't protect us from anything and should be removed.
@dinhtungdu thank you for investigating further!
Even though regularly loaded plugins can call wp_is_block_theme()
before the themes are set up without causing the same bug that was reported in #63062, plugins loaded as mu-plugins would cause the bug to reappear. I was able to confirm this by creating a simple mu-plugin that called wp_is_block_theme()
directly. Seems like we should still throw a warning of some sort so developers will know that they should not call this method too early.
On further investigation, it's not the WP_Theme::is_block_theme()
that causes the global $wp_theme_directories
value to become corrupted, but it's actually the call to wp_get_theme()
in wp_is_block_theme()
, so the warning is indeed being added in the wrong place.
We chose to add this warning on setup_theme
so that the theme's themselves safely use the functions that rely on wp_is_block_theme()
, during setup, but that any code trying to rely on checking on whether the current theme was a block theme was waiting for themes to be set up first. The intent of that placement still seems correct to me since I'm unsure why a plugin would want to call wp_is_block_theme()
prior to the themes actually being set up.
My suggestion is to move the warning from the WP_Theme::is_block_theme()
to wp_is_block_theme()
directly, and still keep the warning on the setup_theme
hook. This may still result in warnings from plugins that are calling this code directly, but seems like the expectation should be that this function is not called until after themes are properly set up, otherwise, the plugin may return an incorrect value.
#24
@
5 weeks ago
@joemcgill I agree that throwing an error when someone is calling and using the function inappropriately is warranted, however, it is clear that any properly loaded plugin may call wp_get_themes()
resulting in a call to WP_Theme::is_block_theme()
which calls wp_get_themes()->is_block_theme()
. Bearing in mind that wp_get_themes()
can call new WP_Theme
whose constructor may call $this->is_block_theme()
too.
There's a huge vicious circle here that simply doesn't seem to apply to plugins calling wp_get_themes()
.
Somehow limiting this error only to when themes are calling these functions seems more appropriate. Not sure how that would be accomplished.
I'm actually not certain if your suggestion to move the warning to wp_is_block_theme()
is the solution. I use this call in plugins as well and I don't know if it will trigger this warning.
I'm happy to help test this.
#25
in reply to:
↑ 23
@
5 weeks ago
- Keywords has-unit-tests needs-testing removed
Replying to afragen:
I'm actually not certain if your suggestion to move the warning to wp_is_block_theme() is the solution. I use this call in plugins as well and I don't know if it will trigger this warning.
@afragen are any of these plugins public to test this out?
Replying to joemcgill:
The intent of that placement still seems correct to me since I'm unsure why a plugin would want to call
wp_is_block_theme()
prior to the themes actually being set up.
Maybe we should follow some words that one wise guy once told me in the past:
I'm not in support of throwing a
_doing_it_wrong
warning in this case, as the software cannot know the intent the developer had in doing things this way and throwing a warning would be presumptive, at best.
This ticket was mentioned in PR #8526 on WordPress/wordpress-develop by @joemcgill.
5 weeks ago
#27
- Keywords has-patch added; needs-patch removed
This moves the location of the _doing_it_wrong()
call added to WP_Theme::is_block_theme()
in [59968] to wp_is_block_theme()
in order to inform developers that calling this function too early can result in broken parent/child theme relationships.
Trac ticket: https://core.trac.wordpress.org/ticket/63086
#28
@
5 weeks ago
- Keywords needs-patch added; has-patch removed
@afragen I agree that this is tricky. Technically, we should throw the error if wp_get_theme()
is called too early (not the plural, wp_get_themes()
), since calling this function before the theme directories are set up will break the resolution of parent/child themes. However, given that this function has been in core basically unchanged for 13 years, I'm hesitant to add a new _doing_it_wrong()
there.
It's much more likely for wp_is_block_theme()
to be called too early, given the amount of features that checking to see if the current theme is a block theme. That's why I think moving the warning there, instead of the WP_Theme
method would be more appropriate. Hopefully that's more clear.
I've opened a new PR to demonstrate what I'm proposing.
5 weeks ago
#29
Doesn’t is_block_theme()
return false if directories aren’t set up? If so, is there a need to exit early in the warning?
@joemcgill commented on PR #8526:
5 weeks ago
#30
Good question, @afragen! Returning early ensures that wp_get_theme()
is avoided to avoid the bug from Trac-63062.
5 weeks ago
#31
@joemcgill I didn't think there was an issue in Core Rollback, but it is an example of use in a plugin.
I've added your changes in 2 of my test sites running 6.8-beta2. I think there might still be an issue somewhere in The Events Calendar plugin.
@joemcgill commented on PR #8526:
5 weeks ago
#32
I've added your changes in 2 of my test sites running 6.8-beta2. I think there might still be an issue somewhere in The Events Calendar plugin.
Thanks for testing, @afragen! You're right, this will get triggered on TEC, because they are calling wp_is_block_theme()
on the plugins_loaded
hook in order to determine whether the current theme supports full site editing. While calling wp_is_block_theme()
this early won't cause the bug from https://core.trac.wordpress.org/ticket/63062 to occur, it will result in incorrect behavior, because it will return false
even if the active theme is a block theme, since the theme has not yet been set up.
5 weeks ago
#33
The changes have been running on 2 of my test servers and only reported errors are from The Events Calendar and Events Calendar Pro.
It’s looking much better.
#34
@
5 weeks ago
- Keywords has-patch dev-feedback added; needs-patch removed
- Version set to trunk
Test Report
Description
This report validates that the indicated patch works as expected.
Massive error on my side: I prejudged, mistakenly overestimating the correctness of current implementation without doing thorough testing.
Patch tested: https://patch-diff.githubusercontent.com/raw/WordPress/wordpress-develop/pull/8508.diff
Environment
- WordPress: 6.8-beta2-59971-src
- PHP: 8.2.28
- Server: nginx/1.27.4
- Database: mysqli (Server: 8.4.4 / Client: mysqlnd 8.2.28)
- Browser: Chrome 134.0.0.0
- OS: Windows 10/11
- Theme: Twenty Twenty-Four 1.3/Twenty Eleven 4.8
- MU Plugins:
- SimpleBlock Theme Detection 1.0.0
- Plugins:
- Test Reports 1.2.0
Testing Steps
- I have created an adhoc plugin that checks the result of
wp_is_block_theme()
function in each step - Install this plugin as a mu-plugin
- Add the shortcode
[block_theme_detection]
- Most hook checks are useless, just for visual purposes.
Actual Results
- ✅ Issue resolved with patch 8508
Additional Notes
❌ The PR 8526 alternative implementation is always going to fail for the same reason stated
As many have suggested, the check and notice should be removed because it's completely pointless
Supplemental Artifacts
My test plugin repo: https://github.com/SirLouen/simple-block-theme-detection/
Results with a block theme:
Results with a non-block theme:
@peterwilsoncc commented on PR #8526:
5 weeks ago
#35
I've merged in Joe's suggestion of switching to test for the definition of theme directories. No error is thrown in the customizer during my testing.
Using a modified version of @SirLouen's testing plugin while running @fabiankaegy's MVP block child theme attached to Core-63062, I've been able to confirm child theme are working as expected. Without the early return prior to the the directories being set up, the child theme continues to result in a fatal error when the function is called on muplugins_loaded
.
#36
@
5 weeks ago
Replying to joemcgill:
Thanks for your explanation. You're right about must use plugins, they're loaded before theme directory registration, so it's possible for plugins to call wp_is_block_theme()
before theme directory registration and break the theme resolution.
That's why I think moving the warning there, instead of the
WP_Theme
method would be more appropriate.
This is the safer and less disruptive approach than having the early return in the WP_Theme::is_block_theme()
which breaks the Site Editor for block themes if wp_is_block_theme()
is called before theme directory registration. Moving it out of the method prevents that critical issue. I’m sharing my investigation on that topic below in case anyone is interested.
Why does having an early return in WP_Theme::is_block_theme()
and calling wp_is_block_theme()
before theme directory registration breaks the Site Editor?
- When the method is called, the first thing that happens is
WP_Theme
initialization. We care about these lines particularly, as there is a call to WP_Theme::is_block_theme()
. - If this logic runs too early (before theme directory registration),
WP_Theme::is_block_theme()
returnsfalse
, and an error is set for the block theme (which doesn’t haveindex.php
). The instance is cached for later use. - During Site Editor initialization, we need to preload some REST API routes, specifically, the theme route.
- The response for this route will be empty (instead of the active theme data) because of the error mentioned in point 2 above:
wp_get_themes()
only returns themes without error, which means that the current block theme with error isn’t included in the returned data.- Because of that,
WP_REST_Themes_Controller::get_items()
will return an empty array. - The Site Editor will be broken because of the missing active theme data.
@dinhtungdu commented on PR #8508:
5 weeks ago
#37
Closing in favor of #8526
@SirLouen commented on PR #8526:
5 weeks ago
#39
Replying to @peterwilsoncc
No error is thrown in the customizer during my testing.
I got this error yesterday in the morning and this is why I started researching further in the idea proposed by dinhtungdu.
Then I built the plugin in the evening, tested everything according to his suggested ideas, and thereafter, tested again this patch, and got the error once more.
But I was testing against the if ( ! did_action( 'setup_theme' ) ) {
version
Not the current if ( empty( $GLOBALS['wp_theme_directories'] ) ) {
version, which is entirely different.
In fact, my plugin cannot catch this. But anyway, I could have not detected even if I modified my testing plugin, it fully because now I realize that I was not using the child theme, which was the originator of all this issue in the previous report.
PS: I've noted that the convention to check for the global $wp_theme_directories is using this format:
global $wp_theme_directories;
if ( empty( $wp_theme_directories ) ) {
_doing_it_wrong( __FUNCTION__, __( 'This function should not be called before themes are set up.' ), '6.8.0' );
return false;
}
Instead of $GLOBALS['wp_theme_directories']
that I observe it's only used in the testing files, despite both forms are right
#40
@
5 weeks ago
- Keywords needs-testing added; has-patch removed
- Resolution fixed deleted
- Status changed from closed to reopened
I've been exploring this thing a little bit more because, don't ask me why, I still feel there is a pebble in my shoe. After breaking my head in this completely failed PR I found some inconsistencies in the code that I could not clearly describe until now.
The thing is that there is something strange in the code: After the last post of @dinhtungdu that references to one of the blocks of code I was finding massive troubles, something weird in the code caught my eye, a little to the bottom of the lines that he tracked down:
This lines
In these lines, the comment says:
// If we got our data from cache, we can assume that 'template' is pointing to the right place.
This is the first block of code that wp_is_block_theme()
accesses (more specifically via wp_get_theme()
, that is in fact, the real conflicting function, because it creates a new WP_Theme instance, without initializing the theme_directories). So not being able to initialize everything ends with a wrongly allocated parent with missing and cached parameters for the whole loading, which results in a blank screen.
The thing is that more to the bottom there is another very similar block
https://github.com/WordPress/wordpress-develop/blob/001a86a7ca833535533e59dc59babddc50fe2afa/src/wp-includes/class-wp-theme.php#L469
That says:
// Set the parent if we're a child theme.
Ngl, I'm getting a little bit lost in all these blocks of code that repeat code over and over again and are a little convoluted to my eye (maybe @spacedmonkey could lend a hand here because he is the creator of all these blocks of code only 1 year and a half ago).
But the reality is that if I make this conditional not pass in this first interaction, for example, by adding an empty and innocuous index.php
to our example parent theme (note that this is not the failing conditional, but its the fastest way to test this, I think that the real failing conditional is ! is_array( $cache )
)
https://github.com/wordpress/wordpress-develop/blob/001a86a7ca833535533e59dc59babddc50fe2afa/src/wp-includes/class-wp-theme.php#L421-L424
So it jumps into the next conditional block:
https://github.com/WordPress/wordpress-develop/blob/001a86a7ca833535533e59dc59babddc50fe2afa/src/wp-includes/class-wp-theme.php#L469-L470
The whole issue is solved and the child plugin loads correctly without the errors we found in #63062
Conclusion: I feel that the issue goes beyond this simple notice and still believe that the notice is not necessary and wp_is_block_theme
should be able to be called without trouble.
PS: Remember to follow first my testing steps to set it up
https://core.trac.wordpress.org/ticket/63086#comment:34
UPDATE 1
I've been able to narrow down to the point that I've found that the problem is exactly here:
<?php $parent_dir = dirname( $this->stylesheet ); $directories = search_theme_directories(); if ( '.' !== $parent_dir && file_exists( $this->theme_root . '/' . $parent_dir . '/' . $this->template . '/index.php' ) ) { $this->template = $parent_dir . '/' . $this->template; } elseif ( $directories && isset( $directories[ $this->template ] ) ) { /* * Look for the template in the search_theme_directories() results, in case it is in another theme root. * We don't look into directories of themes, just the theme root. */ $theme_root_template = $directories[ $this->template ]['theme_root']; } else { // Parent theme is missing. $this->errors = new WP_Error( 'theme_no_parent', sprintf( /* translators: %s: Theme directory name. */ __( 'The parent theme is missing. Please install the "%s" parent theme.' ), esc_html( $this->template ) ) ); $this->cache_add( 'theme', array( 'block_template_folders' => $this->get_block_template_folders(), 'block_theme' => $this->is_block_theme(), 'headers' => $this->headers, 'errors' => $this->errors, 'stylesheet' => $this->stylesheet, 'template' => $this->template, ) ); $this->parent = new WP_Theme( $this->template, $this->theme_root, $this ); return; }
The cache_add
is done too early.
By removing this fragment
<?php $this->cache_add( 'theme', array( 'block_template_folders' => $this->get_block_template_folders(), 'block_theme' => $this->is_block_theme(), 'headers' => $this->headers, 'errors' => $this->errors, 'stylesheet' => $this->stylesheet, 'template' => $this->template, ) );
It works well.
This code is historical, before the introduction of block themes, where having a index.php
in parent was a staple, useful for checks, but with block themes, this isn't the case anymore
For example, adding this check here:
<?php if ( ! $this->is_block_theme() ) { $this->cache_add( 'theme', array( 'block_template_folders' => $this->get_block_template_folders(), 'block_theme' => $this->is_block_theme(), 'headers' => $this->headers, 'errors' => $this->errors, 'stylesheet' => $this->stylesheet, 'template' => $this->template, ) ); }
Solves this report also, but cache should be populated after the parent call.
Maybe the solution is simply considering another check specific for block themes instead of asking devs for not using this function between 'muplugins_loaded' and 'plugins_loaded' (in a mu-plugin basically)
This ticket was mentioned in PR #8539 on WordPress/wordpress-develop by @SirLouen.
5 weeks ago
#41
- Keywords has-patch added
I was going crazy with so many repetitions of the same code in the WP_Theme
class. Extremely difficult to understand the constructor and to track down the problems. But still, I think that comments are not very self-explanatory.
This patch partially refactors the constructor and sorts this issue (that is mostly caused because of the current convoluted state of such constructor). And still, I'm not 100% sure that this is the best solution.
Apart from this, here are the testing instructions for this patch:
- I have created an adhoc plugin that checks the result of wp_is_block_theme() function in each step
- Install this plugin as a mu-plugin
- Install this Child theme and activate it
- Make sure you have TwentyTwentyFive also installed
- Theme should be loading without issues.
- Go to customizer, check no notices there
- Add the shortcode [block_theme_detection] to a post and check if its passing in all the actions hooks
Trac ticket: https://core.trac.wordpress.org/ticket/63086
#42
@
5 weeks ago
Test Environment:
WordPress Version: 6.8
Theme: Custom Child Theme (with Twenty Twenty-Five installed)
Plugin: Adhoc MU-Plugin for wp_is_block_theme() Detection
Test Scenario
Create and Install Adhoc Plugin
The plugin checks the result of wp_is_block_theme() at different execution stages.
Install it as a must-use (mu-plugin) in wp-content/mu-plugins/.
Install and Activate Custom Child Theme
Ensure Twenty Twenty-Five is installed alongside the child theme.
Activate the child theme.
The theme should load without any issues.
Verify Customizer Behavior
Navigate to Appearance → Customize.
Ensure no notices appear.
Test Shortcode Execution
Add [block_theme_detection] shortcode to a post.
View the post and verify if the function passes through all action hooks.
Expected Result
The function wp_is_block_theme() should return correct values at each step.
No notices should appear in the Customizer.
The shortcode should execute correctly in all action hooks.
Actual Result (Before Patch)
Error Notice: WP_Theme::is_block_theme() called incorrectly.
The function did not return the expected values in all cases.
The error appeared in both Customizer and shortcode execution.
Result (After Patch Applied)
The function WP_Theme::is_block_theme() works correctly.
No PHP notices in Customizer or on the frontend.
The shortcode successfully detects the theme status at each action hook.
Attachments
https://prnt.sc/BUlXbmss3yIC
https://prnt.sc/LcTKsQCs5Be5
https://prnt.sc/zXGw4LQ2NuoX
Test Conclusion
Status: ✅ Issue Resolved After Patch
Impact: Medium (Affects theme detection logic and compatibility)
Recommendation:
Ensure the patch is included in future releases.
Verify compatibility with upcoming WordPress versions.
Perform additional testing with other child themes and FSE themes.
#43
@
5 weeks ago
@joemcgill Thanks for the patch! I’ve tested it on Woo with WordPress 6.8-beta3, and the issue no longer occurs.
#44
follow-up:
↓ 45
@
5 weeks ago
- Resolution set to fixed
- Status changed from reopened to closed
@gigitux thanks for testing and confirming!
@SirLouen thanks for continuing to investigate the root cause for why calling wp_get_theme()
before the theme directory is registered is leading to broken parent themes. Like you, I've been wondering if there is more we can do to improve that code path.
Given that we're close to RC1, let's create a new follow-up ticket for further investigation and possible refactor effort.
#45
in reply to:
↑ 44
@
5 weeks ago
Replying to joemcgill:
@gigitux thanks for testing and confirming!
@SirLouen thanks for continuing to investigate the root cause for why calling
wp_get_theme()
before the theme directory is registered is leading to broken parent themes. Like you, I've been wondering if there is more we can do to improve that code path.
Given that we're close to RC1, let's create a new follow-up ticket for further investigation and possible refactor effort.
Ok I've created the follow-up in #63128 and I will be moving my patch there.
@addweb-solution-pvt-ltd
Thanks for your test report.
If you can re-add in this new post #63128 your testing results will be appreciated.
Also, remember to put a link to the patch you are testing always.
My recommendation, is to use this plugin: https://wordpress.org/plugins/test-reports/
To generate the standard testing reports.
@SirLouen commented on PR #8539:
5 weeks ago
#46
Closing this PR in favor of the new follow-up ticket and PR: https://github.com/WordPress/wordpress-develop/pull/8545
PHP Errors in Customizer Screen