From bea14dfb3e8147e1fb4561d4f00f6a36d81248bf Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Thu, 2 Jun 2022 10:47:24 +1200 Subject: [PATCH 1/7] Add utility classnames back to blocks that have layout attributes specified --- lib/block-supports/layout.php | 39 ++++++++++++++++++-- packages/block-editor/src/hooks/layout.js | 44 +++++++++++++++++++++-- 2 files changed, 77 insertions(+), 6 deletions(-) diff --git a/lib/block-supports/layout.php b/lib/block-supports/layout.php index 01e6b9324e5a5d..60753fe02197f6 100644 --- a/lib/block-supports/layout.php +++ b/lib/block-supports/layout.php @@ -145,6 +145,35 @@ function gutenberg_get_layout_style( $selector, $layout, $has_block_gap_support return $style; } +/** + * Generates the utility classnames for the given blocks layout attributes. + * + * @param array $block_attributes Array of block attributes. + * + * @return array Array of CSS classname strings. + */ +function gutenberg_get_layout_classes( $block_attributes ) { + $class_names = array(); + + if ( empty( $block_attributes['layout'] ) ) { + return $class_names; + } + + if ( ! empty( $block_attributes['layout']['orientation'] ) ) { + $class_names[] = 'is-' . $block_attributes['layout']['orientation']; + } + + if ( ! empty( $block_attributes['layout']['justifyContent'] ) ) { + $class_names[] = 'is-content-justification-' . $block_attributes['layout']['justifyContent']; + } + + if ( ! empty( $block_attributes['layout']['flexWrap'] ) && 'nowrap' === $block_attributes['layout']['flexWrap'] ) { + $class_names[] = 'is-nowrap'; + } + + return $class_names; +} + /** * Renders the layout config to the block wrapper. * @@ -172,7 +201,11 @@ function gutenberg_render_layout_support_flag( $block_content, $block ) { $used_layout = $default_layout; } - $class_name = wp_unique_id( 'wp-container-' ); + // TODO: Should we handle the case where a block has opted out of using a classname? (e.g. how paragraph disables classnames) + $block_classname = wp_get_block_default_classname( $block['blockName'] ); + $container_class = wp_unique_id( 'wp-container-' ); + $class_names = array_merge( array( $block_classname, $container_class ), gutenberg_get_layout_classes( $block['attrs'] ) ); + $gap_value = _wp_array_get( $block, array( 'attrs', 'style', 'spacing', 'blockGap' ) ); // Skip if gap value contains unsupported characters. // Regex for CSS value borrowed from `safecss_filter_attr`, and used here @@ -190,12 +223,12 @@ function gutenberg_render_layout_support_flag( $block_content, $block ) { // If a block's block.json skips serialization for spacing or spacing.blockGap, // don't apply the user-defined value to the styles. $should_skip_gap_serialization = gutenberg_should_skip_block_supports_serialization( $block_type, 'spacing', 'blockGap' ); - $style = gutenberg_get_layout_style( ".$class_name", $used_layout, $has_block_gap_support, $gap_value, $should_skip_gap_serialization, $fallback_gap_value ); + $style = gutenberg_get_layout_style( ".$block_classname.$container_class", $used_layout, $has_block_gap_support, $gap_value, $should_skip_gap_serialization, $fallback_gap_value ); // This assumes the hook only applies to blocks with a single wrapper. // I think this is a reasonable limitation for that particular hook. $content = preg_replace( '/' . preg_quote( 'class="', '/' ) . '/', - 'class="' . esc_attr( $class_name ) . ' ', + 'class="' . esc_attr( implode( ' ', $class_names ) ) . ' ', $block_content, 1 ); diff --git a/packages/block-editor/src/hooks/layout.js b/packages/block-editor/src/hooks/layout.js index 586b38bf4c8a0e..64fff90518ae01 100644 --- a/packages/block-editor/src/hooks/layout.js +++ b/packages/block-editor/src/hooks/layout.js @@ -32,6 +32,40 @@ import { getLayoutType, getLayoutTypes } from '../layouts'; const layoutBlockSupportKey = '__experimentalLayout'; +/** + * Generates the utility classnames for the given blocks layout attributes. + * + * @param { Array } attributes Array of block attributes. + * + * @return { Array } Array of CSS classname strings. + */ +function getLayoutClasses( attributes ) { + const layoutClassnames = []; + + if ( ! attributes.layout ) { + return layoutClassnames; + } + + if ( attributes?.layout?.orientation ) { + layoutClassnames.push( `is-${ attributes.layout.orientation }` ); + } + + if ( attributes?.layout?.justifyContent ) { + layoutClassnames.push( + `is-content-justification-${ attributes.layout.justifyContent }` + ); + } + + if ( + attributes?.layout?.flexWrap && + attributes.layout.flexWrap === 'nowrap' + ) { + layoutClassnames.push( 'is-nowrap' ); + } + + return layoutClassnames; +} + function LayoutPanel( { setAttributes, attributes, name: blockName } ) { const { layout } = attributes; const defaultThemeLayout = useSetting( 'layout' ); @@ -212,9 +246,13 @@ export const withLayoutStyles = createHigherOrderComponent( const usedLayout = layout?.inherit ? defaultThemeLayout : layout || defaultBlockLayout || {}; - const className = classnames( props?.className, { - [ `wp-container-${ id }` ]: shouldRenderLayoutStyles, - } ); + const className = classnames( + props?.className, + { + [ `wp-container-${ id }` ]: shouldRenderLayoutStyles, + }, + getLayoutClasses( attributes ) + ); return ( <> From ab3f530dd30a1d12eeba8d8051116b7664866bca Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Thu, 2 Jun 2022 12:30:00 +1200 Subject: [PATCH 2/7] Changes from review --- lib/block-supports/layout.php | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/lib/block-supports/layout.php b/lib/block-supports/layout.php index 60753fe02197f6..e15aa708ad5b6b 100644 --- a/lib/block-supports/layout.php +++ b/lib/block-supports/layout.php @@ -160,11 +160,11 @@ function gutenberg_get_layout_classes( $block_attributes ) { } if ( ! empty( $block_attributes['layout']['orientation'] ) ) { - $class_names[] = 'is-' . $block_attributes['layout']['orientation']; + $class_names[] = 'is-' . sanitize_title( $block_attributes['layout']['orientation'] ); } if ( ! empty( $block_attributes['layout']['justifyContent'] ) ) { - $class_names[] = 'is-content-justification-' . $block_attributes['layout']['justifyContent']; + $class_names[] = 'is-content-justification-' . sanitize_title( $block_attributes['layout']['justifyContent'] ); } if ( ! empty( $block_attributes['layout']['flexWrap'] ) && 'nowrap' === $block_attributes['layout']['flexWrap'] ) { @@ -201,10 +201,9 @@ function gutenberg_render_layout_support_flag( $block_content, $block ) { $used_layout = $default_layout; } - // TODO: Should we handle the case where a block has opted out of using a classname? (e.g. how paragraph disables classnames) - $block_classname = wp_get_block_default_classname( $block['blockName'] ); $container_class = wp_unique_id( 'wp-container-' ); - $class_names = array_merge( array( $block_classname, $container_class ), gutenberg_get_layout_classes( $block['attrs'] ) ); + $class_names = gutenberg_get_layout_classes( $block['attrs'] ); + $class_names[] = $container_class; $gap_value = _wp_array_get( $block, array( 'attrs', 'style', 'spacing', 'blockGap' ) ); // Skip if gap value contains unsupported characters. @@ -223,7 +222,7 @@ function gutenberg_render_layout_support_flag( $block_content, $block ) { // If a block's block.json skips serialization for spacing or spacing.blockGap, // don't apply the user-defined value to the styles. $should_skip_gap_serialization = gutenberg_should_skip_block_supports_serialization( $block_type, 'spacing', 'blockGap' ); - $style = gutenberg_get_layout_style( ".$block_classname.$container_class", $used_layout, $has_block_gap_support, $gap_value, $should_skip_gap_serialization, $fallback_gap_value ); + $style = gutenberg_get_layout_style( ".$container_class", $used_layout, $has_block_gap_support, $gap_value, $should_skip_gap_serialization, $fallback_gap_value ); // This assumes the hook only applies to blocks with a single wrapper. // I think this is a reasonable limitation for that particular hook. $content = preg_replace( From 2735e72de30e6a40f1e4a160a78bcd7653ed41ef Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Thu, 2 Jun 2022 12:38:48 +1200 Subject: [PATCH 3/7] Improve method doc comment --- lib/block-supports/layout.php | 5 +++++ packages/block-editor/src/hooks/layout.js | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/lib/block-supports/layout.php b/lib/block-supports/layout.php index e15aa708ad5b6b..86d14c9ff01670 100644 --- a/lib/block-supports/layout.php +++ b/lib/block-supports/layout.php @@ -147,6 +147,11 @@ function gutenberg_get_layout_style( $selector, $layout, $has_block_gap_support /** * Generates the utility classnames for the given blocks layout attributes. + * This method was primarily added to reintroduce classnames that were removed + * in the 5.9 release (https://github.com/WordPress/gutenberg/issues/38719), rather + * than providing an extensive list of all possible layout classes. The plan is to + * have the style engine generate a more extensive list of utility classnames which + * will then replace this method. * * @param array $block_attributes Array of block attributes. * diff --git a/packages/block-editor/src/hooks/layout.js b/packages/block-editor/src/hooks/layout.js index 64fff90518ae01..74be7e97645fcb 100644 --- a/packages/block-editor/src/hooks/layout.js +++ b/packages/block-editor/src/hooks/layout.js @@ -34,6 +34,11 @@ const layoutBlockSupportKey = '__experimentalLayout'; /** * Generates the utility classnames for the given blocks layout attributes. + * This method was primarily added to reintroduce classnames that were removed + * in the 5.9 release (https://github.com/WordPress/gutenberg/issues/38719), rather + * than providing an extensive list of all possible layout classes. The plan is to + * have the style engine generate a more extensive list of utility classnames which + * will then replace this method. * * @param { Array } attributes Array of block attributes. * From 9d461d9a5e8b475cf03cb4c98c7a22fdbc45e48c Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Thu, 2 Jun 2022 12:43:34 +1200 Subject: [PATCH 4/7] Add kebabCase to ensure slugs for class names --- packages/block-editor/src/hooks/layout.js | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/packages/block-editor/src/hooks/layout.js b/packages/block-editor/src/hooks/layout.js index 74be7e97645fcb..2a9f280f97a07a 100644 --- a/packages/block-editor/src/hooks/layout.js +++ b/packages/block-editor/src/hooks/layout.js @@ -2,7 +2,7 @@ * External dependencies */ import classnames from 'classnames'; -import { has } from 'lodash'; +import { has, kebabCase } from 'lodash'; /** * WordPress dependencies @@ -52,12 +52,16 @@ function getLayoutClasses( attributes ) { } if ( attributes?.layout?.orientation ) { - layoutClassnames.push( `is-${ attributes.layout.orientation }` ); + layoutClassnames.push( + `is-${ kebabCase( attributes.layout.orientation ) }` + ); } if ( attributes?.layout?.justifyContent ) { layoutClassnames.push( - `is-content-justification-${ attributes.layout.justifyContent }` + `is-content-justification-${ kebabCase( + attributes.layout.justifyContent + ) }` ); } From ec2d0be3a3902617181b8ed448a60d79ba6ccf92 Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Thu, 2 Jun 2022 14:27:21 +1200 Subject: [PATCH 5/7] Linting fix Co-authored-by: Andrew Serong <14988353+andrewserong@users.noreply.github.com> --- lib/block-supports/layout.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/block-supports/layout.php b/lib/block-supports/layout.php index 86d14c9ff01670..db845b9ccc320e 100644 --- a/lib/block-supports/layout.php +++ b/lib/block-supports/layout.php @@ -169,7 +169,7 @@ function gutenberg_get_layout_classes( $block_attributes ) { } if ( ! empty( $block_attributes['layout']['justifyContent'] ) ) { - $class_names[] = 'is-content-justification-' . sanitize_title( $block_attributes['layout']['justifyContent'] ); + $class_names[] = 'is-content-justification-' . sanitize_title( $block_attributes['layout']['justifyContent'] ); } if ( ! empty( $block_attributes['layout']['flexWrap'] ) && 'nowrap' === $block_attributes['layout']['flexWrap'] ) { From d313102c61578a7aa8d95d7657264f31eb10c543 Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Thu, 2 Jun 2022 14:27:34 +1200 Subject: [PATCH 6/7] Another linting fix Co-authored-by: Andrew Serong <14988353+andrewserong@users.noreply.github.com> --- lib/block-supports/layout.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/block-supports/layout.php b/lib/block-supports/layout.php index db845b9ccc320e..081a9b90e4f2a5 100644 --- a/lib/block-supports/layout.php +++ b/lib/block-supports/layout.php @@ -210,7 +210,7 @@ function gutenberg_render_layout_support_flag( $block_content, $block ) { $class_names = gutenberg_get_layout_classes( $block['attrs'] ); $class_names[] = $container_class; - $gap_value = _wp_array_get( $block, array( 'attrs', 'style', 'spacing', 'blockGap' ) ); + $gap_value = _wp_array_get( $block, array( 'attrs', 'style', 'spacing', 'blockGap' ) ); // Skip if gap value contains unsupported characters. // Regex for CSS value borrowed from `safecss_filter_attr`, and used here // because we only want to match against the value, not the CSS attribute. From c1f97511491c886fd5e551c946f857cdfa8c2aba Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Fri, 3 Jun 2022 09:10:52 +1200 Subject: [PATCH 7/7] Check for renderLayoutStyles before outputting layout classes --- packages/block-editor/src/hooks/layout.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/block-editor/src/hooks/layout.js b/packages/block-editor/src/hooks/layout.js index 2a9f280f97a07a..7fbb4a0a662c22 100644 --- a/packages/block-editor/src/hooks/layout.js +++ b/packages/block-editor/src/hooks/layout.js @@ -255,12 +255,15 @@ export const withLayoutStyles = createHigherOrderComponent( const usedLayout = layout?.inherit ? defaultThemeLayout : layout || defaultBlockLayout || {}; + const layoutClasses = shouldRenderLayoutStyles + ? getLayoutClasses( attributes ) + : null; const className = classnames( props?.className, { [ `wp-container-${ id }` ]: shouldRenderLayoutStyles, }, - getLayoutClasses( attributes ) + layoutClasses ); return (