wp_get_global_stylesheet

The timeline below displays how wordpress function wp_get_global_stylesheet has changed across different WordPress versions. If a version is not listed, refer to the next available version below.

WordPress Version: 6.5

/**
 * Returns the stylesheet resulting of merging core, theme, and user data.
 *
 * @since 5.9.0
 * @since 6.1.0 Added 'base-layout-styles' support.
 *
 * @param array $types Optional. Types of styles to load.
 *                     It accepts as values 'variables', 'presets', 'styles', 'base-layout-styles'.
 *                     If empty, it'll load the following:
 *                     - for themes without theme.json: 'variables', 'presets', 'base-layout-styles'.
 *                     - for themes with theme.json: 'variables', 'presets', 'styles'.
 * @return string Stylesheet.
 */
function wp_get_global_stylesheet($types = array())
{
    /*
     * Ignore cache when the development mode is set to 'theme', so it doesn't interfere with the theme
     * developer's workflow.
     */
    $can_use_cached = empty($types) && !wp_is_development_mode('theme');
    /*
     * By using the 'theme_json' group, this data is marked to be non-persistent across requests.
     * @see `wp_cache_add_non_persistent_groups()`.
     *
     * The rationale for this is to make sure 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.).
     * See some of the existing hooks to modify theme.json behavior:
     * @see https://make.wordpress.org/core/2022/10/10/filters-for-theme-json-data/
     *
     * A different alternative considered was to invalidate the cache upon certain
     * events such as options add/update/delete, user meta, etc.
     * It was judged not enough, hence this approach.
     * @see https://github.com/WordPress/gutenberg/pull/45372
     */
    $cache_group = 'theme_json';
    $cache_key = 'wp_get_global_stylesheet';
    if ($can_use_cached) {
        $cached = wp_cache_get($cache_key, $cache_group);
        if ($cached) {
            return $cached;
        }
    }
    $tree = WP_Theme_JSON_Resolver::get_merged_data();
    $supports_theme_json = wp_theme_has_theme_json();
    if (empty($types) && !$supports_theme_json) {
        $types = array('variables', 'presets', 'base-layout-styles');
    } elseif (empty($types)) {
        $types = array('variables', 'styles', 'presets');
    }
    /*
     * If variables are part of the stylesheet, then add them.
     * This is so themes without a theme.json still work as before 5.9:
     * they can override the default presets.
     * See https://core.trac.wordpress.org/ticket/54782
     */
    $styles_variables = '';
    if (in_array('variables', $types, true)) {
        /*
         * Only use the default, theme, and custom origins. Why?
         * Because styles for `blocks` origin are added at a later phase
         * (i.e. in the render cycle). Here, only the ones in use are rendered.
         * @see wp_add_global_styles_for_blocks
         */
        $origins = array('default', 'theme', 'custom');
        $styles_variables = $tree->get_stylesheet(array('variables'), $origins);
        $types = array_diff($types, array('variables'));
    }
    /*
     * For the remaining types (presets, styles), we do consider origins:
     *
     * - themes without theme.json: only the classes for the presets defined by core
     * - themes with theme.json: the presets and styles classes, both from core and the theme
     */
    $styles_rest = '';
    if (!empty($types)) {
        /*
         * Only use the default, theme, and custom origins. Why?
         * Because styles for `blocks` origin are added at a later phase
         * (i.e. in the render cycle). Here, only the ones in use are rendered.
         * @see wp_add_global_styles_for_blocks
         */
        $origins = array('default', 'theme', 'custom');
        /*
         * If the theme doesn't have theme.json but supports both appearance tools and color palette,
         * the 'theme' origin should be included so color palette presets are also output.
         */
        if (!$supports_theme_json && (current_theme_supports('appearance-tools') || current_theme_supports('border')) && current_theme_supports('editor-color-palette')) {
            $origins = array('default', 'theme');
        } elseif (!$supports_theme_json) {
            $origins = array('default');
        }
        $styles_rest = $tree->get_stylesheet($types, $origins);
    }
    $stylesheet = $styles_variables . $styles_rest;
    if ($can_use_cached) {
        wp_cache_set($cache_key, $stylesheet, $cache_group);
    }
    return $stylesheet;
}

WordPress Version: 6.3

/**
 * Returns the stylesheet resulting of merging core, theme, and user data.
 *
 * @since 5.9.0
 * @since 6.1.0 Added 'base-layout-styles' support.
 *
 * @param array $types Optional. Types of styles to load.
 *                     It accepts as values 'variables', 'presets', 'styles', 'base-layout-styles'.
 *                     If empty, it'll load the following:
 *                     - for themes without theme.json: 'variables', 'presets', 'base-layout-styles'.
 *                     - for themes with theme.json: 'variables', 'presets', 'styles'.
 * @return string Stylesheet.
 */
function wp_get_global_stylesheet($types = array())
{
    /*
     * Ignore cache when the development mode is set to 'theme', so it doesn't interfere with the theme
     * developer's workflow.
     */
    $can_use_cached = empty($types) && !wp_is_development_mode('theme');
    /*
     * By using the 'theme_json' group, this data is marked to be non-persistent across requests.
     * @see `wp_cache_add_non_persistent_groups()`.
     *
     * The rationale for this is to make sure 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.).
     * See some of the existing hooks to modify theme.json behavior:
     * @see https://make.wordpress.org/core/2022/10/10/filters-for-theme-json-data/
     *
     * A different alternative considered was to invalidate the cache upon certain
     * events such as options add/update/delete, user meta, etc.
     * It was judged not enough, hence this approach.
     * @see https://github.com/WordPress/gutenberg/pull/45372
     */
    $cache_group = 'theme_json';
    $cache_key = 'wp_get_global_stylesheet';
    if ($can_use_cached) {
        $cached = wp_cache_get($cache_key, $cache_group);
        if ($cached) {
            return $cached;
        }
    }
    $tree = WP_Theme_JSON_Resolver::get_merged_data();
    $supports_theme_json = wp_theme_has_theme_json();
    if (empty($types) && !$supports_theme_json) {
        $types = array('variables', 'presets', 'base-layout-styles');
    } elseif (empty($types)) {
        $types = array('variables', 'styles', 'presets');
    }
    /*
     * If variables are part of the stylesheet, then add them.
     * This is so themes without a theme.json still work as before 5.9:
     * they can override the default presets.
     * See https://core.trac.wordpress.org/ticket/54782
     */
    $styles_variables = '';
    if (in_array('variables', $types, true)) {
        /*
         * Only use the default, theme, and custom origins. Why?
         * Because styles for `blocks` origin are added at a later phase
         * (i.e. in the render cycle). Here, only the ones in use are rendered.
         * @see wp_add_global_styles_for_blocks
         */
        $origins = array('default', 'theme', 'custom');
        $styles_variables = $tree->get_stylesheet(array('variables'), $origins);
        $types = array_diff($types, array('variables'));
    }
    /*
     * For the remaining types (presets, styles), we do consider origins:
     *
     * - themes without theme.json: only the classes for the presets defined by core
     * - themes with theme.json: the presets and styles classes, both from core and the theme
     */
    $styles_rest = '';
    if (!empty($types)) {
        /*
         * Only use the default, theme, and custom origins. Why?
         * Because styles for `blocks` origin are added at a later phase
         * (i.e. in the render cycle). Here, only the ones in use are rendered.
         * @see wp_add_global_styles_for_blocks
         */
        $origins = array('default', 'theme', 'custom');
        if (!$supports_theme_json) {
            $origins = array('default');
        }
        $styles_rest = $tree->get_stylesheet($types, $origins);
    }
    $stylesheet = $styles_variables . $styles_rest;
    if ($can_use_cached) {
        wp_cache_set($cache_key, $stylesheet, $cache_group);
    }
    return $stylesheet;
}

WordPress Version: 6.2

/**
 * Returns the stylesheet resulting of merging core, theme, and user data.
 *
 * @since 5.9.0
 * @since 6.1.0 Added 'base-layout-styles' support.
 *
 * @param array $types Optional. Types of styles to load.
 *                     It accepts as values 'variables', 'presets', 'styles', 'base-layout-styles'.
 *                     If empty, it'll load the following:
 *                     - for themes without theme.json: 'variables', 'presets', 'base-layout-styles'.
 *                     - for themes with theme.json: 'variables', 'presets', 'styles'.
 * @return string Stylesheet.
 */
function wp_get_global_stylesheet($types = array())
{
    /*
     * Ignore cache when `WP_DEBUG` is enabled, so it doesn't interfere with the theme
     * developer's workflow.
     *
     * @todo Replace `WP_DEBUG` once an "in development mode" check is available in Core.
     */
    $can_use_cached = empty($types) && !WP_DEBUG;
    /*
     * By using the 'theme_json' group, this data is marked to be non-persistent across requests.
     * @see `wp_cache_add_non_persistent_groups()`.
     *
     * The rationale for this is to make sure 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.).
     * See some of the existing hooks to modify theme.json behavior:
     * @see https://make.wordpress.org/core/2022/10/10/filters-for-theme-json-data/
     *
     * A different alternative considered was to invalidate the cache upon certain
     * events such as options add/update/delete, user meta, etc.
     * It was judged not enough, hence this approach.
     * @see https://github.com/WordPress/gutenberg/pull/45372
     */
    $cache_group = 'theme_json';
    $cache_key = 'wp_get_global_stylesheet';
    if ($can_use_cached) {
        $cached = wp_cache_get($cache_key, $cache_group);
        if ($cached) {
            return $cached;
        }
    }
    $tree = WP_Theme_JSON_Resolver::get_merged_data();
    $supports_theme_json = wp_theme_has_theme_json();
    if (empty($types) && !$supports_theme_json) {
        $types = array('variables', 'presets', 'base-layout-styles');
    } elseif (empty($types)) {
        $types = array('variables', 'styles', 'presets');
    }
    /*
     * If variables are part of the stylesheet, then add them.
     * This is so themes without a theme.json still work as before 5.9:
     * they can override the default presets.
     * See https://core.trac.wordpress.org/ticket/54782
     */
    $styles_variables = '';
    if (in_array('variables', $types, true)) {
        /*
         * Only use the default, theme, and custom origins. Why?
         * Because styles for `blocks` origin are added at a later phase
         * (i.e. in the render cycle). Here, only the ones in use are rendered.
         * @see wp_add_global_styles_for_blocks
         */
        $origins = array('default', 'theme', 'custom');
        $styles_variables = $tree->get_stylesheet(array('variables'), $origins);
        $types = array_diff($types, array('variables'));
    }
    /*
     * For the remaining types (presets, styles), we do consider origins:
     *
     * - themes without theme.json: only the classes for the presets defined by core
     * - themes with theme.json: the presets and styles classes, both from core and the theme
     */
    $styles_rest = '';
    if (!empty($types)) {
        /*
         * Only use the default, theme, and custom origins. Why?
         * Because styles for `blocks` origin are added at a later phase
         * (i.e. in the render cycle). Here, only the ones in use are rendered.
         * @see wp_add_global_styles_for_blocks
         */
        $origins = array('default', 'theme', 'custom');
        if (!$supports_theme_json) {
            $origins = array('default');
        }
        $styles_rest = $tree->get_stylesheet($types, $origins);
    }
    $stylesheet = $styles_variables . $styles_rest;
    if ($can_use_cached) {
        wp_cache_set($cache_key, $stylesheet, $cache_group);
    }
    return $stylesheet;
}

WordPress Version: 6.1

/**
 * Returns the stylesheet resulting of merging core, theme, and user data.
 *
 * @since 5.9.0
 *
 * @param array $types Types of styles to load. Optional.
 *                     It accepts 'variables', 'styles', 'presets' as values.
 *                     If empty, it'll load all for themes with theme.json support
 *                     and only [ 'variables', 'presets' ] for themes without theme.json support.
 * @return string Stylesheet.
 */
function wp_get_global_stylesheet($types = array())
{
    // Return cached value if it can be used and exists.
    // It's cached by theme to make sure that theme switching clears the cache.
    $can_use_cached = empty($types) && (!defined('WP_DEBUG') || !WP_DEBUG) && (!defined('SCRIPT_DEBUG') || !SCRIPT_DEBUG) && (!defined('REST_REQUEST') || !REST_REQUEST) && !is_admin();
    $transient_name = 'global_styles_' . get_stylesheet();
    if ($can_use_cached) {
        $cached = get_transient($transient_name);
        if ($cached) {
            return $cached;
        }
    }
    $tree = WP_Theme_JSON_Resolver::get_merged_data();
    $supports_theme_json = WP_Theme_JSON_Resolver::theme_has_support();
    if (empty($types) && !$supports_theme_json) {
        $types = array('variables', 'presets', 'base-layout-styles');
    } elseif (empty($types)) {
        $types = array('variables', 'styles', 'presets');
    }
    /*
     * If variables are part of the stylesheet, then add them.
     * This is so themes without a theme.json still work as before 5.9:
     * they can override the default presets.
     * See https://core.trac.wordpress.org/ticket/54782
     */
    $styles_variables = '';
    if (in_array('variables', $types, true)) {
        /*
         * Only use the default, theme, and custom origins. Why?
         * Because styles for `blocks` origin are added at a later phase
         * (i.e. in the render cycle). Here, only the ones in use are rendered.
         * @see wp_add_global_styles_for_blocks
         */
        $origins = array('default', 'theme', 'custom');
        $styles_variables = $tree->get_stylesheet(array('variables'), $origins);
        $types = array_diff($types, array('variables'));
    }
    /*
     * For the remaining types (presets, styles), we do consider origins:
     *
     * - themes without theme.json: only the classes for the presets defined by core
     * - themes with theme.json: the presets and styles classes, both from core and the theme
     */
    $styles_rest = '';
    if (!empty($types)) {
        /*
         * Only use the default, theme, and custom origins. Why?
         * Because styles for `blocks` origin are added at a later phase
         * (i.e. in the render cycle). Here, only the ones in use are rendered.
         * @see wp_add_global_styles_for_blocks
         */
        $origins = array('default', 'theme', 'custom');
        if (!$supports_theme_json) {
            $origins = array('default');
        }
        $styles_rest = $tree->get_stylesheet($types, $origins);
    }
    $stylesheet = $styles_variables . $styles_rest;
    if ($can_use_cached) {
        // Cache for a minute.
        // This cache doesn't need to be any longer, we only want to avoid spikes on high-traffic sites.
        set_transient($transient_name, $stylesheet, MINUTE_IN_SECONDS);
    }
    return $stylesheet;
}

WordPress Version: 9.1

/**
 * Returns the stylesheet resulting of merging core, theme, and user data.
 *
 * @since 5.9.0
 *
 * @param array $types Types of styles to load. Optional.
 *                     It accepts 'variables', 'styles', 'presets' as values.
 *                     If empty, it'll load all for themes with theme.json support
 *                     and only [ 'variables', 'presets' ] for themes without theme.json support.
 *
 * @return string Stylesheet.
 */
function wp_get_global_stylesheet($types = array())
{
    // Return cached value if it can be used and exists.
    // It's cached by theme to make sure that theme switching clears the cache.
    $can_use_cached = empty($types) && (!defined('WP_DEBUG') || !WP_DEBUG) && (!defined('SCRIPT_DEBUG') || !SCRIPT_DEBUG) && (!defined('REST_REQUEST') || !REST_REQUEST) && !is_admin();
    $transient_name = 'global_styles_' . get_stylesheet();
    if ($can_use_cached) {
        $cached = get_transient($transient_name);
        if ($cached) {
            return $cached;
        }
    }
    $tree = WP_Theme_JSON_Resolver::get_merged_data();
    $supports_theme_json = WP_Theme_JSON_Resolver::theme_has_support();
    if (empty($types) && !$supports_theme_json) {
        $types = array('variables', 'presets');
    } elseif (empty($types)) {
        $types = array('variables', 'styles', 'presets');
    }
    /*
     * If variables are part of the stylesheet,
     * we add them for all origins (default, theme, user).
     * This is so themes without a theme.json still work as before 5.9:
     * they can override the default presets.
     * See https://core.trac.wordpress.org/ticket/54782
     */
    $styles_variables = '';
    if (in_array('variables', $types, true)) {
        $styles_variables = $tree->get_stylesheet(array('variables'));
        $types = array_diff($types, array('variables'));
    }
    /*
     * For the remaining types (presets, styles), we do consider origins:
     *
     * - themes without theme.json: only the classes for the presets defined by core
     * - themes with theme.json: the presets and styles classes, both from core and the theme
     */
    $styles_rest = '';
    if (!empty($types)) {
        $origins = array('default', 'theme', 'custom');
        if (!$supports_theme_json) {
            $origins = array('default');
        }
        $styles_rest = $tree->get_stylesheet($types, $origins);
    }
    $stylesheet = $styles_variables . $styles_rest;
    if ($can_use_cached) {
        // Cache for a minute.
        // This cache doesn't need to be any longer, we only want to avoid spikes on high-traffic sites.
        set_transient($transient_name, $stylesheet, MINUTE_IN_SECONDS);
    }
    return $stylesheet;
}

WordPress Version: 5.9

/**
 * Returns the stylesheet resulting of merging core, theme, and user data.
 *
 * @since 5.9.0
 *
 * @param array $types Types of styles to load. Optional.
 *                     It accepts 'variables', 'styles', 'presets' as values.
 *                     If empty, it'll load all for themes with theme.json support
 *                     and only [ 'variables', 'presets' ] for themes without theme.json support.
 *
 * @return string Stylesheet.
 */
function wp_get_global_stylesheet($types = array())
{
    // Return cached value if it can be used and exists.
    // It's cached by theme to make sure that theme switching clears the cache.
    $can_use_cached = empty($types) && (!defined('WP_DEBUG') || !WP_DEBUG) && (!defined('SCRIPT_DEBUG') || !SCRIPT_DEBUG) && (!defined('REST_REQUEST') || !REST_REQUEST) && !is_admin();
    $transient_name = 'global_styles_' . get_stylesheet();
    if ($can_use_cached) {
        $cached = get_transient($transient_name);
        if ($cached) {
            return $cached;
        }
    }
    $supports_theme_json = WP_Theme_JSON_Resolver::theme_has_support();
    $supports_link_color = get_theme_support('experimental-link-color');
    if (empty($types) && !$supports_theme_json) {
        $types = array('variables', 'presets');
    } elseif (empty($types)) {
        $types = array('variables', 'styles', 'presets');
    }
    $origins = array('default', 'theme', 'custom');
    if (!$supports_theme_json && !$supports_link_color) {
        // In this case we only enqueue the core presets (CSS Custom Properties + the classes).
        $origins = array('default');
    } elseif (!$supports_theme_json && $supports_link_color) {
        // For the legacy link color feature to work, the CSS Custom Properties
        // should be in scope (either the core or the theme ones).
        $origins = array('default', 'theme');
    }
    $tree = WP_Theme_JSON_Resolver::get_merged_data();
    $stylesheet = $tree->get_stylesheet($types, $origins);
    if ($can_use_cached) {
        // Cache for a minute.
        // This cache doesn't need to be any longer, we only want to avoid spikes on high-traffic sites.
        set_transient($transient_name, $stylesheet, MINUTE_IN_SECONDS);
    }
    return $stylesheet;
}