Make WordPress Core


Ignore:
Timestamp:
01/18/2023 11:38:16 AM (3 years ago)
Author:
hellofromTonya
Message:

Themes: Introduce wp_theme_has_theme_json() for public consumption.

Adds wp_theme_has_theme_json() for public consumption, to replace the private internal Core-only WP_Theme_JSON_Resolver::theme_has_support() method. This new global function checks if a theme or its parent has a theme.json file.

For performance, results are cached as an integer 1 or 0 in the 'theme_json' group with 'wp_theme_has_theme_json' key. This is a non-persistent cache. Why? To make the derived data from theme.json is always fresh from the potential modifications done via hooks that can use dynamic data (modify the stylesheet depending on some option, settings depending on user permissions, etc.).

Also adds a new public function wp_clean_theme_json_cache() to clear the cache on 'switch_theme' and start_previewing_theme'.

References:

Follow-up to [54493], [53282], [52744], [52049], [50959].

Props oandregal, afragen, alexstine, aristath, azaozz, costdev, flixos90, hellofromTonya, mamaduka, mcsf, ocean90, spacedmonkey.
Fixes #56975.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/global-styles-and-settings.php

    r54703 r55086  
    103103    $tree = WP_Theme_JSON_Resolver::get_merged_data();
    104104
    105     $supports_theme_json = WP_Theme_JSON_Resolver::theme_has_support();
     105    $supports_theme_json = wp_theme_has_theme_json();
    106106    if ( empty( $types ) && ! $supports_theme_json ) {
    107107        $types = array( 'variables', 'presets', 'base-layout-styles' );
     
    185185    }
    186186
    187     $supports_theme_json = WP_Theme_JSON_Resolver::theme_has_support();
     187    $supports_theme_json = wp_theme_has_theme_json();
    188188
    189189    $origins = array( 'default', 'theme', 'custom' );
     
    256256    }
    257257}
     258
     259/**
     260 * Checks whether a theme or its parent has a theme.json file.
     261 *
     262 * @since 6.2.0
     263 *
     264 * @return bool Returns true if theme or its parent has a theme.json file, false otherwise.
     265 */
     266function wp_theme_has_theme_json() {
     267    /*
     268     * By using the 'theme_json' group, this data is marked to be non-persistent across requests.
     269     * @see `wp_cache_add_non_persistent_groups()`.
     270     *
     271     * The rationale for this is to make sure derived data from theme.json
     272     * is always fresh from the potential modifications done via hooks
     273     * that can use dynamic data (modify the stylesheet depending on some option,
     274     * settings depending on user permissions, etc.).
     275     * For some of the existing hooks to modify theme.json behavior:
     276     * @see https://make.wordpress.org/core/2022/10/10/filters-for-theme-json-data/
     277     *
     278     * A different alternative considered was to invalidate the cache upon certain
     279     * events such as options add/update/delete, user meta, etc.
     280     * It was judged not enough, hence this approach.
     281     * @see https://github.com/WordPress/gutenberg/pull/45372
     282     */
     283    $cache_group       = 'theme_json';
     284    $cache_key         = 'wp_theme_has_theme_json';
     285    $theme_has_support = wp_cache_get( $cache_key, $cache_group );
     286
     287    /*
     288     * $theme_has_support is stored as an int in the cache.
     289     *
     290     * The reason not to store it as a boolean is to avoid working
     291     * with the $found parameter which apparently had some issues in some implementations
     292     * @see https://developer.wordpress.org/reference/functions/wp_cache_get/
     293     *
     294     * Ignore cache when `WP_DEBUG` is enabled, so it doesn't interfere with the theme
     295     * developer's workflow.
     296     *
     297     * @todo Replace `WP_DEBUG` once an "in development mode" check is available in Core.
     298     */
     299    if ( ! WP_DEBUG && is_int( $theme_has_support ) ) {
     300        return (bool) $theme_has_support;
     301    }
     302
     303    // Does the theme have its own theme.json?
     304    $theme_has_support = is_readable( get_stylesheet_directory() . '/theme.json' );
     305
     306    // Look up the parent if the child does not have a theme.json.
     307    if ( ! $theme_has_support ) {
     308        $theme_has_support = is_readable( get_template_directory() . '/theme.json' );
     309    }
     310
     311    $theme_has_support = $theme_has_support ? 1 : 0;
     312
     313    wp_cache_set( $cache_key, $theme_has_support, $cache_group );
     314
     315    return (bool) $theme_has_support;
     316}
     317
     318/**
     319 * Cleans the caches under the theme_json group.
     320 *
     321 * @since 6.2.0
     322 */
     323function wp_clean_theme_json_cache() {
     324    wp_cache_delete( 'wp_theme_has_theme_json', 'theme_json' );
     325    WP_Theme_JSON_Resolver::clean_cached_data();
     326}
Note: See TracChangeset for help on using the changeset viewer.