From 2b32e56c9730889dcfd31eb0923d12ad3b2838bf Mon Sep 17 00:00:00 2001 From: Andrew Serong <14988353+andrewserong@users.noreply.github.com> Date: Fri, 8 Oct 2021 16:24:29 +1100 Subject: [PATCH] Try moving block supports styles to render via a utility function --- lib/block-supports/layout.php | 37 ++++++++--------------- lib/blocks.php | 56 +++++++++++++++++++++++++++++++++++ 2 files changed, 69 insertions(+), 24 deletions(-) diff --git a/lib/block-supports/layout.php b/lib/block-supports/layout.php index 77eb6c8ebf6c7..d997434081302 100644 --- a/lib/block-supports/layout.php +++ b/lib/block-supports/layout.php @@ -28,13 +28,12 @@ function gutenberg_register_layout_support( $block_type ) { /** * Generates the CSS corresponding to the provided layout. * - * @param string $selector CSS selector. * @param array $layout Layout object. The one that is passed has already checked the existance of default block layout. * @param boolean $has_block_gap_support Whether the theme has support for the block gap. * * @return string CSS style. */ -function gutenberg_get_layout_style( $selector, $layout, $has_block_gap_support = false ) { +function gutenberg_get_layout_style( $layout, $has_block_gap_support = false ) { $layout_type = isset( $layout['type'] ) ? $layout['type'] : 'default'; $style = ''; @@ -52,21 +51,21 @@ function gutenberg_get_layout_style( $selector, $layout, $has_block_gap_support $style = ''; if ( $content_size || $wide_size ) { - $style = "$selector > * {"; + $style = '.{{ placeholder }} > * {'; $style .= 'max-width: ' . esc_html( $all_max_width_value ) . ';'; $style .= 'margin-left: auto !important;'; $style .= 'margin-right: auto !important;'; $style .= '}'; - $style .= "$selector > .alignwide { max-width: " . esc_html( $wide_max_width_value ) . ';}'; - $style .= "$selector .alignfull { max-width: none; }"; + $style .= '.{{ placeholder }} > .alignwide { max-width: ' . esc_html( $wide_max_width_value ) . ';}'; + $style .= '.{{ placeholder }} .alignfull { max-width: none; }'; } - $style .= "$selector .alignleft { float: left; margin-right: 2em; }"; - $style .= "$selector .alignright { float: right; margin-left: 2em; }"; + $style .= '.{{ placeholder }} .alignleft { float: left; margin-right: 2em; }'; + $style .= '.{{ placeholder }} .alignright { float: right; margin-left: 2em; }'; if ( $has_block_gap_support ) { - $style .= "$selector > * { margin-top: 0; margin-bottom: 0; }"; - $style .= "$selector > * + * { margin-top: var( --wp--style--block-gap ); margin-bottom: 0; }"; + $style .= '.{{ placeholder }} > * { margin-top: 0; margin-bottom: 0; }'; + $style .= '.{{ placeholder }} > * + * { margin-top: var( --wp--style--block-gap ); margin-bottom: 0; }'; } } elseif ( 'flex' === $layout_type ) { $justify_content_options = array( @@ -76,7 +75,7 @@ function gutenberg_get_layout_style( $selector, $layout, $has_block_gap_support 'space-between' => 'space-between', ); - $style = "$selector {"; + $style = '.{{ placeholder }} {'; $style .= 'display: flex;'; if ( $has_block_gap_support ) { $style .= 'gap: var( --wp--style--block-gap, 0.5em );'; @@ -95,7 +94,7 @@ function gutenberg_get_layout_style( $selector, $layout, $has_block_gap_support } $style .= '}'; - $style .= "$selector > * { margin: 0; }"; + $style .= '{{ placeholder }} > * { margin: 0; }'; } return $style; @@ -129,27 +128,17 @@ function gutenberg_render_layout_support_flag( $block_content, $block ) { $used_layout = $default_layout; } - $id = uniqid(); - $style = gutenberg_get_layout_style( ".wp-container-$id", $used_layout, $has_block_gap_support ); + $style = gutenberg_get_layout_style( $used_layout, $has_block_gap_support ); + $class_name = gutenberg_render_block_support_style( 'wp-container-', '' ); // 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="wp-container-' . $id . ' ', + 'class="' . $class_name . ' ', $block_content, 1 ); - // Ideally styles should be loaded in the head, but blocks may be parsed - // after that, so loading in the footer for now. - // See https://core.trac.wordpress.org/ticket/53494. - add_action( - 'wp_footer', - function () use ( $style ) { - echo ''; - } - ); - return $content; } diff --git a/lib/blocks.php b/lib/blocks.php index 4cdd36d268c92..6373aa1fa73a1 100644 --- a/lib/blocks.php +++ b/lib/blocks.php @@ -620,3 +620,59 @@ function gutenberg_multiple_block_styles( $metadata ) { return $metadata; } add_filter( 'block_type_metadata', 'gutenberg_multiple_block_styles' ); + +/** + * Render block support styles and inject into wp_footer, and append + * to the end of post content for REST API requests. + * + * @param string $name The identified for a class name or id + * @param string $content The content to be rendered + * + * @return string The class name with an id appended + */ +function gutenberg_render_block_support_style( $name, $content, $action = 'wp_footer' ) { + $unique_name = $name . uniqid(); + + $output = str_replace( '{{ placeholder }}', $unique_name, $content ); + + // Ideally styles should be loaded in the head, but blocks may be parsed + // after that, so loading in the footer for now. + // See https://core.trac.wordpress.org/ticket/53494. + add_action( + $action, + function () use ( $output ) { + echo $output; + } + ); + + // For requests via the REST API, append the styles to the end of the content. + // This ensures that in situations where `wp_footer` is never called, the + // styles are still available. This fixes an issue where layout styles are + // otherwise not rendered for the Post Content block within the site editor. + if ( defined( 'REST_REQUEST' ) && REST_REQUEST ) { + add_filter( + 'wp_render_block_support_styles', + function ( $block_support_styles ) use ( $output ) { + return $block_support_styles . $output; + }, + 10, + 1 + ); + } + + return $unique_name; +} + +/** + * Append the rendered block support styles to the end of post content, if registered. + * + * This is used to ensure that in responses via the REST API, where `wp_footer` + * is not called, that styles are still available for blocks in post content. + * + * @param string $content Rendered post content. + * @return string Post content with layout styles appended. + */ +function gutenberg_append_block_support_styles_to_the_content( $content ) { + return $content . apply_filters( 'wp_render_block_support_styles', '' ); +} +add_filter( 'the_content', 'gutenberg_append_block_support_styles_to_the_content', 10, 1 );