Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add API to access global settings, styles, and stylesheet #34843

Merged
merged 12 commits into from
Oct 21, 2021
Merged
7 changes: 3 additions & 4 deletions lib/block-supports/layout.php
Original file line number Diff line number Diff line change
Expand Up @@ -116,10 +116,9 @@ function gutenberg_render_layout_support_flag( $block_content, $block ) {
return $block_content;
}

$tree = WP_Theme_JSON_Resolver_Gutenberg::get_merged_data( array(), 'theme' );
$theme_settings = $tree->get_settings();
$default_layout = _wp_array_get( $theme_settings, array( 'layout' ) );
$has_block_gap_support = isset( $theme_settings['spacing']['blockGap'] ) ? null !== $theme_settings['spacing']['blockGap'] : false;
$block_gap = gutenberg_get_global_settings( array( 'spacing', 'blockGap' ) );
$default_layout = gutenberg_get_global_settings( array( 'layout' ) );
$has_block_gap_support = isset( $block_gap ) ? null !== $block_gap : false;
$default_block_layout = _wp_array_get( $block_type->supports, array( '__experimentalLayout', 'default' ), array() );
$used_layout = isset( $block['attrs']['layout'] ) ? $block['attrs']['layout'] : $default_block_layout;
if ( isset( $used_layout['inherit'] ) && $used_layout['inherit'] ) {
Expand Down
125 changes: 125 additions & 0 deletions lib/compat/wordpress-5.9/get-global-styles-and-settings.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
<?php
/**
* API to interact with global settings & styles.
*
* @package gutenberg
*/

/**
* Function to get the settings resulting of merging core, theme, and user data.
*
* @param array $path Path to the specific setting to retrieve. Optional.
* If empty, will return all settings.
* @param string $block_name Which block to retrieve the settings from. Optional
* If empty, it'll return the settings for the global context.
* @param string $origin Which origin to take data from. Optional.
* It can be 'all' (core, theme, and user) or 'base' (core and theme).
* If empty or unknown, 'all' is used.
*
* @return array The settings to retrieve.
*/
function gutenberg_get_global_settings( $path = array(), $block_name = '', $origin = 'all' ) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While right now, the $block_name is the only possible "context", I wonder if we'd have new kind of context in the future so wondering if this should be a decision factor for the API shape or if it's fine for now. (One possibility could be to use an object for the last two arguments in order to support more options in the future, but I'm hesitant).

In the frontend, I think the API is still internal so that's why it's not a problem there yet.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I brought the object approach here and in the client API as well. My understanding was that we wanted to go in this direction instead. Whatever we do, I think it'd be best if the server and the client follow the same pattern.

if ( '' !== $block_name ) {
$path = array_merge( array( 'blocks', $block_name ), $path );
}

if ( 'base' === $origin ) {
$origin = 'theme';
} else {
$origin = 'user';
}

$theme_supports = gutenberg_get_default_block_editor_settings();
$settings = WP_Theme_JSON_Resolver_Gutenberg::get_merged_data( $theme_supports, $origin )->get_settings();

return _wp_array_get( $settings, $path, $settings );
}

/**
* Function to get the styles resulting of merging core, theme, and user data.
*
* @param array $path Path to the specific style to retrieve. Optional.
* If empty, will return all styles.
* @param string $block_name Which block to retrieve the styles from. Optional.
* If empty, it'll return the styles for the global context.
* @param string $origin Which origin to take data from. Optional.
* It can be 'all' (core, theme, and user) or 'base' (core and theme).
* If empty or unknown, 'all' is used.
*
* @return array The styles to retrieve.
*/
function gutenberg_get_global_styles( $path = array(), $block_name = '', $origin = 'all' ) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The other question is whether we should support string dotted paths.

if ( '' !== $block_name ) {
$path = array_merge( array( 'blocks', $block_name ), $path );
}

if ( 'base' === $origin ) {
$origin = 'theme';
} else {
$origin = 'user';
}

$theme_supports = gutenberg_get_default_block_editor_settings();
$styles = WP_Theme_JSON_Resolver_Gutenberg::get_merged_data( $theme_supports, $origin )->get_raw_data()['styles'];

return _wp_array_get( $styles, $path, $styles );
}

/**
* Returns the stylesheet resulting of merging core, theme, and user data.
*
* @param string $type Type of the stylesheet. Optional.
* It accepts 'all', 'block_styles', 'css_variables', 'presets'.
* If empty, it'll resolve to all (theme with theme.json support)
* or 'presets' (theme without theme.json support).
*
* @return string Stylesheet.
*/
function gutenberg_get_global_stylesheet( $type = '' ) {
// 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 = (
( 'all' === $type ) &&
( ! defined( 'WP_DEBUG' ) || ! WP_DEBUG ) &&
( ! defined( 'SCRIPT_DEBUG' ) || ! SCRIPT_DEBUG ) &&
( ! defined( 'REST_REQUEST' ) || ! REST_REQUEST ) &&
! is_admin()
);
$transient_name = 'gutenberg_global_styles_' . get_stylesheet();
if ( $can_use_cached ) {
$cached = get_transient( $transient_name );
if ( $cached ) {
return $cached;
}
}

$supports_theme_json = WP_Theme_JSON_Resolver_Gutenberg::theme_has_support();
$supports_link_color = get_theme_support( 'experimental-link-color' );
if ( empty( $type ) && ! $supports_theme_json ) {
$type = 'presets';
} elseif ( empty( $type ) ) {
$type = 'all';
}

$origins = array( 'core', 'theme', 'user' );
if ( ! $supports_theme_json && ! $supports_link_color ) {
// In this case we only enqueue the core presets (CSS Custom Properties + the classes).
$origins = array( 'core' );
} elseif ( ! $supports_theme_json && $supports_link_color ) {
// For the legacy link color feauter to work, the CSS Custom Properties
// should be in scope (either the core or the theme ones).
$origins = array( 'core', 'theme' );
}

$theme_supports = gutenberg_get_default_block_editor_settings();
$tree = WP_Theme_JSON_Resolver_Gutenberg::get_merged_data( $theme_supports );
$stylesheet = $tree->get_stylesheet( $type, $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;
}
5 changes: 1 addition & 4 deletions lib/global-styles.php
Original file line number Diff line number Diff line change
Expand Up @@ -71,10 +71,7 @@ function gutenberg_experimental_global_styles_get_stylesheet( $tree, $type = nul
* and enqueues the resulting stylesheet.
*/
function gutenberg_experimental_global_styles_enqueue_assets() {
$settings = gutenberg_get_default_block_editor_settings();
$all = WP_Theme_JSON_Resolver_Gutenberg::get_merged_data( $settings );

$stylesheet = gutenberg_experimental_global_styles_get_stylesheet( $all );
$stylesheet = gutenberg_get_global_stylesheet();
if ( empty( $stylesheet ) ) {
return;
}
Expand Down
1 change: 1 addition & 0 deletions lib/load.php
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ function gutenberg_is_experiment_enabled( $name ) {
require __DIR__ . '/compat/wordpress-5.8/index.php';
require __DIR__ . '/compat/wordpress-5.8.1/index.php';
require __DIR__ . '/compat/wordpress-5.9/default-editor-styles.php';
require __DIR__ . '/compat/wordpress-5.9/get-global-styles-and-settings.php';
require __DIR__ . '/utils.php';
require __DIR__ . '/editor-settings.php';

Expand Down