Themes: Deprecate usage of `TEMPLATEPATH` and `STYLESHEETPATH` constants.

While generally the functions `get_template_directory()` and `get_stylesheet_directory()` were long recommended to use to get the parent or child theme directory, the `TEMPLATEPATH` and `STYLESHEETPATH` constants were still used in a few places in core, most importantly in template related logic.

The remaining usage was problematic as it prevented testability of certain key components of WordPress core.

This changeset replaces all remaining usage with the corresponding functions and effectively marks these constants as deprecated. It also adds test coverage accordingly and even unlocks some existing, previously commented out test coverage to work as expected.

Performance of the new approach has been benchmarked and shows no notable differences. Yet, given that the current theme directories are not expected to change within a regular WordPress page load, the `get_template_directory()` and `get_stylesheet_directory()` functions were amended with in-memory caching of the result, unless one of the defining values is being filtered.

Props thekt12, spacedmonkey, mukesh27, aaroncampbell, scribu, lloydbudd, cais, chipbennett, toscho, omarabid, CrazyJaco, DrewAPicture, obenland, wonderboymusic, nacin, helen, dd32, chriscct7, SergeyBiryukov, swissspidy, joemcgill, flixos90.
Fixes #18298.

Built from https://develop.svn.wordpress.org/trunk@56635


git-svn-id: http://core.svn.wordpress.org/trunk@56147 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This commit is contained in:
Felix Arntz 2023-09-20 17:27:23 +00:00
parent 68be796e1d
commit 59e8596941
7 changed files with 105 additions and 46 deletions

View File

@ -1166,11 +1166,14 @@ function resume_theme( $theme, $redirect = '' ) {
* creating a fatal error. * creating a fatal error.
*/ */
if ( ! empty( $redirect ) ) { if ( ! empty( $redirect ) ) {
$stylesheet_path = get_stylesheet_directory();
$template_path = get_template_directory();
$functions_path = ''; $functions_path = '';
if ( str_contains( STYLESHEETPATH, $extension ) ) { if ( str_contains( $stylesheet_path, $extension ) ) {
$functions_path = STYLESHEETPATH . '/functions.php'; $functions_path = $stylesheet_path . '/functions.php';
} elseif ( str_contains( TEMPLATEPATH, $extension ) ) { } elseif ( str_contains( $template_path, $extension ) ) {
$functions_path = TEMPLATEPATH . '/functions.php'; $functions_path = $template_path . '/functions.php';
} }
if ( ! empty( $functions_path ) ) { if ( ! empty( $functions_path ) ) {

View File

@ -1381,7 +1381,7 @@ function wp_comment_form_unfiltered_html_nonce() {
* and the post ID respectively. * and the post ID respectively.
* *
* The `$file` path is passed through a filter hook called {@see 'comments_template'}, * The `$file` path is passed through a filter hook called {@see 'comments_template'},
* which includes the TEMPLATEPATH and $file combined. Tries the $filtered path * which includes the template directory and $file combined. Tries the $filtered path
* first and if it fails it will require the default comment template from the * first and if it fails it will require the default comment template from the
* default theme. If either does not exist, then the WordPress process will be * default theme. If either does not exist, then the WordPress process will be
* halted. It is advised for that reason, that the default theme is not deleted. * halted. It is advised for that reason, that the default theme is not deleted.
@ -1600,7 +1600,10 @@ function comments_template( $file = '/comments.php', $separate_comments = false
define( 'COMMENTS_TEMPLATE', true ); define( 'COMMENTS_TEMPLATE', true );
} }
$theme_template = STYLESHEETPATH . $file; $stylesheet_path = get_stylesheet_directory();
$template_path = get_template_directory();
$theme_template = $stylesheet_path . $file;
/** /**
* Filters the path to the theme template file used for the comments template. * Filters the path to the theme template file used for the comments template.
@ -1613,8 +1616,8 @@ function comments_template( $file = '/comments.php', $separate_comments = false
if ( file_exists( $include ) ) { if ( file_exists( $include ) ) {
require $include; require $include;
} elseif ( file_exists( TEMPLATEPATH . $file ) ) { } elseif ( file_exists( $template_path . $file ) ) {
require TEMPLATEPATH . $file; require $template_path . $file;
} else { // Backward compat code will be removed in a future release. } else { // Backward compat code will be removed in a future release.
require ABSPATH . WPINC . '/theme-compat/comments.php'; require ABSPATH . WPINC . '/theme-compat/comments.php';
} }

View File

@ -407,6 +407,8 @@ function wp_templating_constants() {
* Filesystem path to the current active template directory. * Filesystem path to the current active template directory.
* *
* @since 1.5.0 * @since 1.5.0
* @deprecated 6.4.0 Use get_template_directory() instead.
* @see get_template_directory()
*/ */
define( 'TEMPLATEPATH', get_template_directory() ); define( 'TEMPLATEPATH', get_template_directory() );
@ -414,6 +416,8 @@ function wp_templating_constants() {
* Filesystem path to the current active template stylesheet directory. * Filesystem path to the current active template stylesheet directory.
* *
* @since 2.1.0 * @since 2.1.0
* @deprecated 6.4.0 Use get_stylesheet_directory() instead.
* @see get_stylesheet_directory()
*/ */
define( 'STYLESHEETPATH', get_stylesheet_directory() ); define( 'STYLESHEETPATH', get_stylesheet_directory() );

View File

@ -1049,11 +1049,14 @@ function wp_get_active_and_valid_themes() {
return $themes; return $themes;
} }
if ( TEMPLATEPATH !== STYLESHEETPATH ) { $stylesheet_path = get_stylesheet_directory();
$themes[] = STYLESHEETPATH; $template_path = get_template_directory();
if ( $template_path !== $stylesheet_path ) {
$themes[] = $stylesheet_path;
} }
$themes[] = TEMPLATEPATH; $themes[] = $template_path;
/* /*
* Remove themes from the list of active themes when we're on an endpoint * Remove themes from the list of active themes when we're on an endpoint

View File

@ -684,8 +684,9 @@ function get_attachment_template() {
/** /**
* Retrieves the name of the highest priority template file that exists. * Retrieves the name of the highest priority template file that exists.
* *
* Searches in the STYLESHEETPATH before TEMPLATEPATH and wp-includes/theme-compat * Searches in the stylesheet directory before the template directory and
* so that themes which inherit from a parent theme can just overload one file. * wp-includes/theme-compat so that themes which inherit from a parent theme
* can just overload one file.
* *
* @since 2.7.0 * @since 2.7.0
* @since 5.5.0 The `$args` parameter was added. * @since 5.5.0 The `$args` parameter was added.
@ -699,16 +700,20 @@ function get_attachment_template() {
* @return string The template filename if one is located. * @return string The template filename if one is located.
*/ */
function locate_template( $template_names, $load = false, $load_once = true, $args = array() ) { function locate_template( $template_names, $load = false, $load_once = true, $args = array() ) {
$stylesheet_path = get_stylesheet_directory();
$template_path = get_template_directory();
$is_child_theme = $stylesheet_path !== $template_path;
$located = ''; $located = '';
foreach ( (array) $template_names as $template_name ) { foreach ( (array) $template_names as $template_name ) {
if ( ! $template_name ) { if ( ! $template_name ) {
continue; continue;
} }
if ( file_exists( STYLESHEETPATH . '/' . $template_name ) ) { if ( file_exists( $stylesheet_path . '/' . $template_name ) ) {
$located = STYLESHEETPATH . '/' . $template_name; $located = $stylesheet_path . '/' . $template_name;
break; break;
} elseif ( is_child_theme() && file_exists( TEMPLATEPATH . '/' . $template_name ) ) { } elseif ( $is_child_theme && file_exists( $template_path . '/' . $template_name ) ) {
$located = TEMPLATEPATH . '/' . $template_name; $located = $template_path . '/' . $template_name;
break; break;
} elseif ( file_exists( ABSPATH . WPINC . '/theme-compat/' . $template_name ) ) { } elseif ( file_exists( ABSPATH . WPINC . '/theme-compat/' . $template_name ) ) {
$located = ABSPATH . WPINC . '/theme-compat/' . $template_name; $located = ABSPATH . WPINC . '/theme-compat/' . $template_name;

View File

@ -157,7 +157,7 @@ function wp_clean_themes_cache( $clear_update_cache = true ) {
* @return bool True if a child theme is in use, false otherwise. * @return bool True if a child theme is in use, false otherwise.
*/ */
function is_child_theme() { function is_child_theme() {
return ( TEMPLATEPATH !== STYLESHEETPATH ); return get_template_directory() !== get_stylesheet_directory();
} }
/** /**
@ -187,24 +187,40 @@ function get_stylesheet() {
* Retrieves stylesheet directory path for the active theme. * Retrieves stylesheet directory path for the active theme.
* *
* @since 1.5.0 * @since 1.5.0
* @since 6.4.0 Memoizes filter execution so that it only runs once for the current theme.
*
* @global string $wp_stylesheet_path Current theme stylesheet directory path.
* *
* @return string Path to active theme's stylesheet directory. * @return string Path to active theme's stylesheet directory.
*/ */
function get_stylesheet_directory() { function get_stylesheet_directory() {
$stylesheet = get_stylesheet(); global $wp_stylesheet_path;
$theme_root = get_theme_root( $stylesheet );
$stylesheet_dir = "$theme_root/$stylesheet";
/** if ( null === $wp_stylesheet_path ) {
* Filters the stylesheet directory path for the active theme. $stylesheet = get_stylesheet();
* $theme_root = get_theme_root( $stylesheet );
* @since 1.5.0 $stylesheet_dir = "$theme_root/$stylesheet";
*
* @param string $stylesheet_dir Absolute path to the active theme. /**
* @param string $stylesheet Directory name of the active theme. * Filters the stylesheet directory path for the active theme.
* @param string $theme_root Absolute path to themes directory. *
*/ * @since 1.5.0
return apply_filters( 'stylesheet_directory', $stylesheet_dir, $stylesheet, $theme_root ); *
* @param string $stylesheet_dir Absolute path to the active theme.
* @param string $stylesheet Directory name of the active theme.
* @param string $theme_root Absolute path to themes directory.
*/
$stylesheet_dir = apply_filters( 'stylesheet_directory', $stylesheet_dir, $stylesheet, $theme_root );
// If there are filter callbacks, force the logic to execute on every call.
if ( has_filter( 'stylesheet' ) || has_filter( 'theme_root' ) || has_filter( 'stylesheet_directory' ) ) {
return $stylesheet_dir;
}
$wp_stylesheet_path = $stylesheet_dir;
}
return $wp_stylesheet_path;
} }
/** /**
@ -321,24 +337,40 @@ function get_template() {
* Retrieves template directory path for the active theme. * Retrieves template directory path for the active theme.
* *
* @since 1.5.0 * @since 1.5.0
* @since 6.4.0 Memoizes filter execution so that it only runs once for the current theme.
*
* @global string $wp_template_path Current theme template directory path.
* *
* @return string Path to active theme's template directory. * @return string Path to active theme's template directory.
*/ */
function get_template_directory() { function get_template_directory() {
$template = get_template(); global $wp_template_path;
$theme_root = get_theme_root( $template );
$template_dir = "$theme_root/$template";
/** if ( null === $wp_template_path ) {
* Filters the active theme directory path. $template = get_template();
* $theme_root = get_theme_root( $template );
* @since 1.5.0 $template_dir = "$theme_root/$template";
*
* @param string $template_dir The path of the active theme directory. /**
* @param string $template Directory name of the active theme. * Filters the active theme directory path.
* @param string $theme_root Absolute path to the themes directory. *
*/ * @since 1.5.0
return apply_filters( 'template_directory', $template_dir, $template, $theme_root ); *
* @param string $template_dir The path of the active theme directory.
* @param string $template Directory name of the active theme.
* @param string $theme_root Absolute path to the themes directory.
*/
$template_dir = apply_filters( 'template_directory', $template_dir, $template, $theme_root );
// If there are filter callbacks, force the logic to execute on every call.
if ( has_filter( 'template' ) || has_filter( 'theme_root' ) || has_filter( 'template_directory' ) ) {
return $template_dir;
}
$wp_template_path = $template_dir;
}
return $wp_template_path;
} }
/** /**
@ -744,11 +776,13 @@ function locale_stylesheet() {
* @global WP_Customize_Manager $wp_customize * @global WP_Customize_Manager $wp_customize
* @global array $sidebars_widgets * @global array $sidebars_widgets
* @global array $wp_registered_sidebars * @global array $wp_registered_sidebars
* @global string $wp_stylesheet_path
* @global string $wp_template_path
* *
* @param string $stylesheet Stylesheet name. * @param string $stylesheet Stylesheet name.
*/ */
function switch_theme( $stylesheet ) { function switch_theme( $stylesheet ) {
global $wp_theme_directories, $wp_customize, $sidebars_widgets, $wp_registered_sidebars; global $wp_theme_directories, $wp_customize, $sidebars_widgets, $wp_registered_sidebars, $wp_stylesheet_path, $wp_template_path;
$requirements = validate_theme_requirements( $stylesheet ); $requirements = validate_theme_requirements( $stylesheet );
if ( is_wp_error( $requirements ) ) { if ( is_wp_error( $requirements ) ) {
@ -832,6 +866,13 @@ function switch_theme( $stylesheet ) {
update_option( 'theme_switched', $old_theme->get_stylesheet() ); update_option( 'theme_switched', $old_theme->get_stylesheet() );
/*
* Reset globals to force refresh the next time these directories are
* accessed via `get_stylesheet_directory()` / `get_template_directory()`.
*/
$wp_stylesheet_path = null;
$wp_template_path = null;
/** /**
* Fires after the theme is switched. * Fires after the theme is switched.
* *

View File

@ -16,7 +16,7 @@
* *
* @global string $wp_version * @global string $wp_version
*/ */
$wp_version = '6.4-alpha-56634'; $wp_version = '6.4-alpha-56635';
/** /**
* Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema. * Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.