Skip to content

Commit

Permalink
Refactor to use the "style" item in block.json
Browse files Browse the repository at this point in the history
  • Loading branch information
aristath committed May 20, 2022
1 parent 516bb86 commit b277223
Show file tree
Hide file tree
Showing 3 changed files with 106 additions and 55 deletions.
109 changes: 71 additions & 38 deletions lib/blocks.php
Original file line number Diff line number Diff line change
Expand Up @@ -354,43 +354,40 @@ function gutenberg_register_legacy_social_link_blocks() {
if ( ! function_exists( 'wp_maybe_inline_block_style_parts' ) ) {
/**
* Inlines tree-shaked CSS for blocks, instead of a single file.
* Filters the settings determined from the block type metadata.
*
* @param array $settings Array of determined settings for registering a block type.
* @param array $metadata Metadata provided for registering a block type.
*/
function wp_maybe_inline_block_style_parts( $settings, $metadata ) {
function wp_maybe_inline_block_style_parts( $metadata ) {

// Bail early if wp_should_load_separate_core_block_assets() is false.
if ( ! wp_should_load_separate_core_block_assets() ) {
return $settings;
// Bail early if style is empty or not an array.
if ( ! isset( $metadata['style'] ) || ! is_array( $metadata['style'] ) ) {
return $metadata;
}

// Bail early if `styledClasses` is not set.
if ( empty( $metadata['styledClasses'] ) ) {
return $settings;
}
// Compile an array of style-parts.
$styled_parts = array();
foreach ( $metadata['style'] as $key => $style ) {
// Skip item if "parts" and "style" are not set, or empty.
if ( empty( $style['parts'] ) || empty( $style['handle'] ) ) {
continue;
}

// Add the stylesheet to the array to be used below.
$styled_parts[ $style['handle'] ] = $style['parts'];

// Bail early if the block doesn't have a "style" defined.
if ( empty( $settings['style'] ) ) {
return $settings;
// Convert $metadata['style'] to an array removing the "parts" and "handle" keys.
$metadata['style'][ $key ] = $style['handle'];
}

// Get the stylesheet handle.
$handle = $settings['style'];

global $wp_styles;
// Remove the default style. We'll be adding style-parts depending on the block content.
$wp_styles->registered[ $handle ]->src = '';
// Get the block's folder path which will be later used to get the individual files.
// Use the folder-path of the style.css file if available, otherwise fallback to the block.json parent folder.
$block_path = dirname( $metadata['file'] );
if ( ! empty( $wp_styles->registered[ $handle ]->extra['path'] ) ) {
$block_path = dirname( $wp_styles->registered[ $handle ]->extra['path'] );
// Bail early if wp_should_load_separate_core_block_assets() is false.
if ( ! wp_should_load_separate_core_block_assets() ) {
return $metadata;
}

// Unset the default style's path to prevent inlining the whole file.
unset( $wp_styles->registered[ $handle ]->extra['path'] );
// Bail early if there are no styled parts.
if ( empty( $styled_parts ) ) {
return $metadata;
}

/**
* Callback to add the style-parts to the block.
Expand All @@ -399,30 +396,66 @@ function wp_maybe_inline_block_style_parts( $settings, $metadata ) {
* @param array $block Block object.
* @return string Filtered block content.
*/
$callback = static function( $block_content, $block ) use ( $handle, $block_path, $metadata ) {
$callback = static function( $block_content, $block ) use ( $metadata, $styled_parts ) {
// Check that we're on the right block.
if ( $block['blockName'] !== $metadata['name'] ) {
return $block_content;
}

// Use a static variable to avoid adding the same part more than once.
static $style_parts_added = array();
if ( ! isset( $style_parts_added[ $block['blockName'] ] ) ) {
$style_parts_added[ $block['blockName'] ] = array();
}

// Add inline styles for the class-names that exist in the content.
foreach ( $metadata['styledClasses'] as $class_name ) {
if ( false === strpos( $block_content, $class_name ) ) {
continue;
foreach ( $styled_parts as $handle => $styled_parts ) {

global $wp_styles;
// Remove the default style. We'll be adding style-parts depending on the block content.
$wp_styles->registered[ $handle ]->src = '';
// Get the block's folder path which will be later used to get the individual files.
// Use the folder-path of the style.css file if available, otherwise fallback to the block.json parent folder.
$block_path = dirname( $metadata['file'] );
if ( ! empty( $wp_styles->registered[ $handle ]->extra['path'] ) ) {
$block_path = dirname( $wp_styles->registered[ $handle ]->extra['path'] );
}
$file = $block_path . "/styles/{$class_name}.css";
if ( is_rtl() && file_exists( $block_path . "/styles/{$class_name}-rtl.css" ) ) {
$file = $block_path . "/styles/{$class_name}-rtl.css";

// Unset the default style's path to prevent inlining the whole file.
unset( $wp_styles->registered[ $handle ]->extra['path'] );

// Add the style-parts to the block.
foreach ( $styled_parts as $part ) {

// Make sure this part has not already been added.
if ( in_array( $part, $style_parts_added[ $block['blockName'] ], true ) ) {
continue;
}

// Skip item if the block does not contain the defined string.
if ( false === strpos( $block_content, $part ) ) {
continue;
}

$file = $block_path . "/styles/{$part}.css";
if ( is_rtl() && file_exists( $block_path . "/styles/{$part}-rtl.css" ) ) {
$file = $block_path . "/styles/{$part}-rtl.css";
}
wp_add_inline_style( $handle, file_get_contents( $file ) );

// Add the part to the array of added parts.
$style_parts_added[ $block['blockName'] ][] = $part;
}
wp_add_inline_style( $handle, file_get_contents( $file ) );
}
return $block_content;
};

// Add the callback to the block's render callback.
add_filter( 'render_block', $callback, 10, 2 );

return $settings;
return $metadata;
}
}
add_filter( 'block_type_metadata_settings', 'wp_maybe_inline_block_style_parts', 10, 2 );
/*
* Add the filter. Using a priority of 1 ensures that this filter runs before others,
* so the "style" metadata can be properly formatted for subsequent filters.
*/
add_filter( 'block_type_metadata', 'wp_maybe_inline_block_style_parts', 1, 2 );
22 changes: 13 additions & 9 deletions packages/block-library/src/paragraph/block.json
Original file line number Diff line number Diff line change
Expand Up @@ -55,14 +55,18 @@
"__unstablePasteTextInline": true
},
"editorStyle": "wp-block-paragraph-editor",
"style": "wp-block-paragraph",
"styledClasses": [
"has-background",
"has-drop-cap",
"has-text-color",
"is-large-text",
"is-larger-text",
"is-regular-text",
"is-small-text"
"style": [
{
"handle": "wp-block-paragraph",
"parts": [
"has-background",
"has-drop-cap",
"has-text-color",
"is-large-text",
"is-larger-text",
"is-regular-text",
"is-small-text"
]
}
]
}
30 changes: 22 additions & 8 deletions schemas/json/block.json
Original file line number Diff line number Diff line change
Expand Up @@ -473,17 +473,31 @@
{
"type": "array",
"items": {
"type": "string"
"oneOf": [
{
"type": "string"
},
{
"type": "object",
"properties": {
"handle": {
"description": "The stylesheet handle.",
"type": "string"
},
"parts": {
"description": "An array of class names that have individual stylesheets. If defined, overrides the 'handle' property on the frontend, loading styles only when the class is present.",
"type": "array",
"items": {
"type": "string"
}
}
},
"required": [ "handle", "parts" ]
}
]
}
}
]
},
"styledClasses": {
"description": "An array of class names that have individual stylesheets. If defined, overrides the 'style' property on the frontend, loading styles only when the class is present.",
"type": "array",
"items": {
"type": "string"
}
}
},
"required": [ "name", "title" ],
Expand Down

0 comments on commit b277223

Please sign in to comment.