[wp-trac] [WordPress Trac] #60025: Changeset 57156 breaks themes that relied on update_option( 'stylesheet', '...' )
WordPress Trac
noreply at wordpress.org
Tue Dec 19 02:35:34 UTC 2023
#60025: Changeset 57156 breaks themes that relied on update_option( 'stylesheet',
'...' )
--------------------------+------------------------
Reporter: blindmikey | Owner: joemcgill
Type: defect (bug) | Status: accepted
Priority: normal | Milestone: 6.4.3
Component: Themes | Version: 6.4.2
Severity: critical | Resolution:
Keywords: needs-patch | Focuses:
--------------------------+------------------------
Changes (by joemcgill):
* status: reviewing => accepted
* milestone: Awaiting Review => 6.4.3
Comment:
After spending some time trying to diagnose what's happening here, I think
this bug was introduced by [56635], which deprecated the `TEMPLATEPATH`
and `STYLESHEET` path constants in favor of `get_template_directory()` and
`get_stylesheet_directory()`, respectively.
The Sage theme, and probably others, were relying a specific race
condition of `get_template_directory()`, where it initially gets called by
`wp_templating_constants()` in `wp-settings.php` before the active theme's
`functions.php` file is loaded, and thus, before filters the theme has
added are applied. This resulted in the `TEMPLATEPATH` environment
variable always being set to the value of `get_option( 'template' )` which
was then used by `locate_template()` and a few other functions. After this
environment value is set, the theme then filters the value of
`get_template_directory()` back to the original location so that templates
are loaded from a different path than what `get_template_directory()` will
return.
A reduced test case to reproduce this behavior is to do something like
this in your functions.php file:
{{{#!php
<?php
// Set the template path option to a different location.
update_option( 'template', __DIR__ . '/templates' );
// Filter `get_template()` back to the theme root.
add_filter('template', function () {
return __DIR__;
});
}}}
The reason this issue was only visible starting in WP 6.4.2, is that the
original change shipped in 6.4.0 cached the value of
`get_template_directory()` to a static global variable the first time the
function was called, similar to how the value was first set as the
environment variable by `wp_templating_constants()`. However, this led to
bugs like #59847. Once that cached value was reverted in [57156], the
change in behavior to `locate_template()` became observable.
We could consider fully reverting the change from [56635], but it I think
doing so would be choosing to support unintended behavior here, since
`get_stylesheet()` and `get_template()` (and their respective DB options)
are meant to store the directory name of the current theme and parent
theme (if applicable), not the path to where the theme stores it's
template files (despite the fact that the naming convention used is easy
to misunderstand).
I think the proposed workaround here—filtering the `template_directory`
and `stylesheet_directory` values is a better solution if you need the
store templates in a different directory than the theme root, but we also
may need to consider revising `locate_template()` to prefer the unfiltered
template and stylesheet option values, rather than the filtered value to
maintain backwards compatibility, or introduce a new filter to
`locate_template()` that would more easily allow themes to load their
templates from a different location without resorting to these types of
workarounds.
--
Ticket URL: <https://core.trac.wordpress.org/ticket/60025#comment:6>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform
More information about the wp-trac
mailing list