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

Layout: Move layout definitions out of theme.json #50621

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
194 changes: 186 additions & 8 deletions lib/block-supports/layout.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,189 @@
* @package gutenberg
*/

/**
* Returns layout definitions, keyed by layout type.
*
* Provides a common definition of slugs, classnames, base styles, and spacing styles for each layout type.
* When making changes or additions to layout definitions, the corresponding JavaScript definitions should
* also be updated.
Copy link
Contributor

Choose a reason for hiding this comment

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

Might be nice to add the file path for the JS definitions here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I was thinking of adding that in originally, but once we backport the changes, any JS path won't quite make sense from the perspective of wordpress-develop, so I thought I'd leave it off for now. Happy to add it in once we've done the backports, though!

*
* @return array[] Layout definitions.
*/
function gutenberg_get_layout_definitions() {
$layout_definitions = array(
'default' => array(
'name' => 'default',
'slug' => 'flow',
'className' => 'is-layout-flow',
'baseStyles' => array(
array(
'selector' => ' > .alignleft',
'rules' => array(
'float' => 'left',
'margin-inline-start' => '0',
'margin-inline-end' => '2em',
),
),
array(
'selector' => ' > .alignright',
'rules' => array(
'float' => 'right',
'margin-inline-start' => '2em',
'margin-inline-end' => '0',
),
),
array(
'selector' => ' > .aligncenter',
'rules' => array(
'margin-left' => 'auto !important',
'margin-right' => 'auto !important',
),
),
),
'spacingStyles' => array(
array(
'selector' => ' > :first-child:first-child',
'rules' => array(
'margin-block-start' => '0',
),
),
array(
'selector' => ' > :last-child:last-child',
'rules' => array(
'margin-block-end' => '0',
),
),
array(
'selector' => ' > *',
'rules' => array(
'margin-block-start' => null,
'margin-block-end' => '0',
),
),
),
),
'constrained' => array(
'name' => 'constrained',
'slug' => 'constrained',
'className' => 'is-layout-constrained',
'baseStyles' => array(
array(
'selector' => ' > .alignleft',
'rules' => array(
'float' => 'left',
'margin-inline-start' => '0',
'margin-inline-end' => '2em',
),
),
array(
'selector' => ' > .alignright',
'rules' => array(
'float' => 'right',
'margin-inline-start' => '2em',
'margin-inline-end' => '0',
),
),
array(
'selector' => ' > .aligncenter',
'rules' => array(
'margin-left' => 'auto !important',
'margin-right' => 'auto !important',
),
),
array(
'selector' => ' > :where(:not(.alignleft):not(.alignright):not(.alignfull))',
'rules' => array(
'max-width' => 'var(--wp--style--global--content-size)',
'margin-left' => 'auto !important',
'margin-right' => 'auto !important',
),
),
array(
'selector' => ' > .alignwide',
'rules' => array(
'max-width' => 'var(--wp--style--global--wide-size)',
),
),
),
'spacingStyles' => array(
array(
'selector' => ' > :first-child:first-child',
'rules' => array(
'margin-block-start' => '0',
),
),
array(
'selector' => ' > :last-child:last-child',
'rules' => array(
'margin-block-end' => '0',
),
),
array(
'selector' => ' > *',
'rules' => array(
'margin-block-start' => null,
'margin-block-end' => '0',
),
),
),
),
'flex' => array(
'name' => 'flex',
'slug' => 'flex',
'className' => 'is-layout-flex',
'displayMode' => 'flex',
'baseStyles' => array(
array(
'selector' => '',
'rules' => array(
'flex-wrap' => 'wrap',
'align-items' => 'center',
),
),
array(
'selector' => ' > *',
'rules' => array(
'margin' => '0',
),
),
),
'spacingStyles' => array(
array(
'selector' => '',
'rules' => array(
'gap' => null,
),
),
),
),
'grid' => array(
'name' => 'grid',
'slug' => 'grid',
'className' => 'is-layout-grid',
'displayMode' => 'grid',
'baseStyles' => array(
array(
'selector' => ' > *',
'rules' => array(
'margin' => '0',
),
),
),
'spacingStyles' => array(
array(
'selector' => '',
'rules' => array(
'gap' => null,
),
),
),
),
);

return $layout_definitions;
}

/**
* Registers the layout block attribute for block types that support it.
*
Expand Down Expand Up @@ -400,16 +583,11 @@ function gutenberg_render_layout_support_flag( $block_content, $block ) {
return (string) $content;
}

$global_settings = gutenberg_get_global_settings();
$global_layout_settings = _wp_array_get( $global_settings, array( 'layout' ), null );
$used_layout = isset( $block['attrs']['layout'] ) ? $block['attrs']['layout'] : _wp_array_get( $block_type->supports, array( '__experimentalLayout', 'default' ), array() );

if ( isset( $used_layout['inherit'] ) && $used_layout['inherit'] && ! $global_layout_settings ) {
return $block_content;
}
$global_settings = gutenberg_get_global_settings();
$used_layout = isset( $block['attrs']['layout'] ) ? $block['attrs']['layout'] : _wp_array_get( $block_type->supports, array( '__experimentalLayout', 'default' ), array() );

$class_names = array();
$layout_definitions = _wp_array_get( $global_layout_settings, array( 'definitions' ), array() );
$layout_definitions = gutenberg_get_layout_definitions();
Copy link
Member

Choose a reason for hiding this comment

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

A few lines above, there's some code to query for the data stored in theme.json via gutenberg_get_global_settings. Now that the definitions would be stored elsewhere, does that code need to be updated as well?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oh, good catch! Yes, there's no longer a need to check for $global_layout_settings so I've removed a few lines.

We still need the overall $global_settings query for root padding aware alignments, and to grab the root block spacing value (blockGap) if available, so the main query is preserved.

$container_class = wp_unique_id( 'wp-container-' );
$layout_classname = '';

Expand Down
4 changes: 2 additions & 2 deletions lib/class-wp-theme-json-gutenberg.php
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,7 @@ class WP_Theme_JSON_Gutenberg {
* @since 6.1.0 Added `layout.definitions` and `useRootPaddingAwareAlignments`.
* @since 6.2.0 Added `dimensions.minHeight`, 'shadow.presets', 'shadow.defaultPresets',
* `position.fixed` and `position.sticky`.
* @since 6.3.0 Removed `layout.definitions`.
* @var array
*/
const VALID_SETTINGS = array(
Expand Down Expand Up @@ -371,7 +372,6 @@ class WP_Theme_JSON_Gutenberg {
),
'layout' => array(
'contentSize' => null,
'definitions' => null,
'wideSize' => null,
),
'position' => array(
Expand Down Expand Up @@ -1272,7 +1272,7 @@ protected function get_layout_styles( $block_metadata ) {
$has_block_gap_support = _wp_array_get( $this->theme_json, array( 'settings', 'spacing', 'blockGap' ) ) !== null;
$has_fallback_gap_support = ! $has_block_gap_support; // This setting isn't useful yet: it exists as a placeholder for a future explicit fallback gap styles support.
$node = _wp_array_get( $this->theme_json, $block_metadata['path'], array() );
$layout_definitions = _wp_array_get( $this->theme_json, array( 'settings', 'layout', 'definitions' ), array() );
$layout_definitions = gutenberg_get_layout_definitions();
Copy link
Member

Choose a reason for hiding this comment

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

We also need to remove layout.definitions from the VALID_SETTINGS in this class.

Copy link
Member

Choose a reason for hiding this comment

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

What happened if 3rd parties provided layout.definitions via theme.json? The potential scenarios are: the theme via its theme.json and plugins via the existing filters.

Copy link
Member

Choose a reason for hiding this comment

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

I found that layout.definitions were merged in core as of 6.1. PR WordPress/wordpress-develop@72380e3 and trac ticket https://core.trac.wordpress.org/ticket/56467 If there wasn't any code to prevent them from being overridden by themes/plugins, we probably need to communicate this via a devnote stating it is a bug that others were able to override the definitions.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks! I've removed it from layout.definitions. If and when this PR lands, I'm happy to draft a dev note for 6.3 to flag the change 🙂

$layout_selector_pattern = '/^[a-zA-Z0-9\-\.\ *+>:\(\)]*$/'; // Allow alphanumeric classnames, spaces, wildcard, sibling, child combinator and pseudo class selectors.

// Gap styles will only be output if the theme has block gap support, or supports a fallback gap.
Expand Down
Loading