Skip to content

Commit

Permalink
Blocks: Allow registering multiple items for all supported asset types
Browse files Browse the repository at this point in the history
Follow-up #54337, [52069]. Part of WordPress/gutenberg#41236. More details in WordPress/gutenberg#33542.

Allow passing more than one script per block for `editorScript`, `script`, and `viewScript` fields in the `block.json` metadata file. This aligns with the previously added changes for `style` and `editorStyle` fields.

This change impacts the `WP_Block_Type` class and the REST API endpoint for block types. To ensure backward compatibiliy old names were soft deprecated in favor of new fields that work with array values and have `_handles` suffix.

Props zieladam, dlh, timothyblynjacobs, aristath, bernhard-reiter.
Fixes #56408.


Built from https://develop.svn.wordpress.org/trunk@54155
  • Loading branch information
gziolo committed Sep 14, 2022
1 parent a96d35d commit c9deebc
Show file tree
Hide file tree
Showing 8 changed files with 410 additions and 220 deletions.
19 changes: 9 additions & 10 deletions wp-includes/block-editor.php
Original file line number Diff line number Diff line change
Expand Up @@ -324,17 +324,16 @@ function _wp_get_iframed_editor_assets() {
$block_registry = WP_Block_Type_Registry::get_instance();

foreach ( $block_registry->get_all_registered() as $block_type ) {
if ( ! empty( $block_type->style ) ) {
$style_handles[] = $block_type->style;
}

if ( ! empty( $block_type->editor_style ) ) {
$style_handles[] = $block_type->editor_style;
}
$style_handles = array_merge(
$style_handles,
$block_type->style_handles,
$block_type->editor_style_handles
);

if ( ! empty( $block_type->script ) ) {
$script_handles[] = $block_type->script;
}
$script_handles = array_merge(
$script_handles,
$block_type->script_handles
);
}

$style_handles = array_unique( $style_handles );
Expand Down
198 changes: 111 additions & 87 deletions wp-includes/blocks.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,15 @@ function remove_block_asset_path_prefix( $asset_handle_or_path ) {
* and the field name provided.
*
* @since 5.5.0
* @since 6.1.0 Added `$index` parameter.
*
* @param string $block_name Name of the block.
* @param string $field_name Name of the metadata field.
* @param int $index Optional. Index of the asset when multiple items passed.
* Default 0.
* @return string Generated asset name for the block's field.
*/
function generate_block_asset_handle( $block_name, $field_name ) {
function generate_block_asset_handle( $block_name, $field_name, $index = 0 ) {
if ( 0 === strpos( $block_name, 'core/' ) ) {
$asset_handle = str_replace( 'core/', 'wp-block-', $block_name );
if ( 0 === strpos( $field_name, 'editor' ) ) {
Expand All @@ -49,6 +52,9 @@ function generate_block_asset_handle( $block_name, $field_name ) {
if ( 0 === strpos( $field_name, 'view' ) ) {
$asset_handle .= '-view';
}
if ( $index > 0 ) {
$asset_handle .= '-' . ( $index + 1 );
}
return $asset_handle;
}

Expand All @@ -59,8 +65,12 @@ function generate_block_asset_handle( $block_name, $field_name ) {
'editorStyle' => 'editor-style',
'style' => 'style',
);
return str_replace( '/', '-', $block_name ) .
$asset_handle = str_replace( '/', '-', $block_name ) .
'-' . $field_mappings[ $field_name ];
if ( $index > 0 ) {
$asset_handle .= '-' . ( $index + 1 );
}
return $asset_handle;
}

/**
Expand All @@ -70,23 +80,34 @@ function generate_block_asset_handle( $block_name, $field_name ) {
* generated handle name. It returns unprocessed script handle otherwise.
*
* @since 5.5.0
* @since 6.1.0 Added `$index` parameter.
*
* @param array $metadata Block metadata.
* @param string $field_name Field name to pick from metadata.
* @param int $index Optional. Index of the script to register when multiple items passed.
* Default 0.
* @return string|false Script handle provided directly or created through
* script's registration, or false on failure.
*/
function register_block_script_handle( $metadata, $field_name ) {
function register_block_script_handle( $metadata, $field_name, $index = 0 ) {
if ( empty( $metadata[ $field_name ] ) ) {
return false;
}

$script_handle = $metadata[ $field_name ];
$script_path = remove_block_asset_path_prefix( $metadata[ $field_name ] );
if ( is_array( $script_handle ) ) {
if ( empty( $script_handle[ $index ] ) ) {
return false;
}
$script_handle = $script_handle[ $index ];
}

$script_path = remove_block_asset_path_prefix( $script_handle );
if ( $script_handle === $script_path ) {
return $script_handle;
}

$script_handle = generate_block_asset_handle( $metadata['name'], $field_name );
$script_handle = generate_block_asset_handle( $metadata['name'], $field_name, $index );
$script_asset_path = wp_normalize_path(
realpath(
dirname( $metadata['file'] ) . '/' .
Expand Down Expand Up @@ -145,33 +166,49 @@ function register_block_script_handle( $metadata, $field_name ) {
* generated handle name. It returns unprocessed style handle otherwise.
*
* @since 5.5.0
* @since 6.1.0 Added `$index` parameter.
*
* @param array $metadata Block metadata.
* @param string $field_name Field name to pick from metadata.
* @param int $index Optional. Index of the style to register when multiple items passed.
* Default 0.
* @return string|false Style handle provided directly or created through
* style's registration, or false on failure.
*/
function register_block_style_handle( $metadata, $field_name ) {
function register_block_style_handle( $metadata, $field_name, $index = 0 ) {
if ( empty( $metadata[ $field_name ] ) ) {
return false;
}

$wpinc_path_norm = wp_normalize_path( realpath( ABSPATH . WPINC ) );
$theme_path_norm = wp_normalize_path( get_theme_file_path() );
$is_core_block = isset( $metadata['file'] ) && 0 === strpos( $metadata['file'], $wpinc_path_norm );
// Skip registering individual styles for each core block when a bundled version provided.
if ( $is_core_block && ! wp_should_load_separate_core_block_assets() ) {
return false;
}

// Check whether styles should have a ".min" suffix or not.
$suffix = SCRIPT_DEBUG ? '' : '.min';

$style_handle = $metadata[ $field_name ];
$style_path = remove_block_asset_path_prefix( $metadata[ $field_name ] );
if ( is_array( $style_handle ) ) {
if ( empty( $style_handle[ $index ] ) ) {
return false;
}
$style_handle = $style_handle[ $index ];
}

if ( $style_handle === $style_path && ! $is_core_block ) {
$style_path = remove_block_asset_path_prefix( $style_handle );
$is_style_handle = $style_handle === $style_path;
// Allow only passing style handles for core blocks.
if ( $is_core_block && ! $is_style_handle ) {
return false;
}
// Return the style handle unless it's the first item for every core block that requires special treatment.
if ( $is_style_handle && ! ( $is_core_block && 0 === $index ) ) {
return $style_handle;
}

// Check whether styles should have a ".min" suffix or not.
$suffix = SCRIPT_DEBUG ? '' : '.min';
$style_uri = plugins_url( $style_path, $metadata['file'] );
if ( $is_core_block ) {
$style_path = "style$suffix.css";
Expand All @@ -185,9 +222,9 @@ function register_block_style_handle( $metadata, $field_name ) {
$style_uri = get_theme_file_uri( str_replace( $theme_path_norm, '', $style_path_norm ) );
}

$style_handle = generate_block_asset_handle( $metadata['name'], $field_name );
$style_handle = generate_block_asset_handle( $metadata['name'], $field_name, $index );
$block_dir = dirname( $metadata['file'] );
$style_file = realpath( "$block_dir/$style_path" );
$style_file = wp_normalize_path( realpath( "$block_dir/$style_path" ) );
$has_style_file = false !== $style_file;
$version = ! $is_core_block && isset( $metadata['version'] ) ? $metadata['version'] : false;
$style_uri = $has_style_file ? $style_uri : false;
Expand Down Expand Up @@ -311,39 +348,69 @@ function register_block_type_from_metadata( $file_or_folder, $args = array() ) {
}
}

if ( ! empty( $metadata['editorScript'] ) ) {
$settings['editor_script'] = register_block_script_handle(
$metadata,
'editorScript'
);
}

if ( ! empty( $metadata['script'] ) ) {
$settings['script'] = register_block_script_handle(
$metadata,
'script'
);
}

if ( ! empty( $metadata['viewScript'] ) ) {
$settings['view_script'] = register_block_script_handle(
$metadata,
'viewScript'
);
}

if ( ! empty( $metadata['editorStyle'] ) ) {
$settings['editor_style'] = register_block_style_handle(
$metadata,
'editorStyle'
);
$script_fields = array(
'editorScript' => 'editor_script_handles',
'script' => 'script_handles',
'viewScript' => 'view_script_handles',
);
foreach ( $script_fields as $metadata_field_name => $settings_field_name ) {
if ( ! empty( $metadata[ $metadata_field_name ] ) ) {
$scripts = $metadata[ $metadata_field_name ];
$processed_scripts = array();
if ( is_array( $scripts ) ) {
for ( $index = 0; $index < count( $scripts ); $index++ ) {
$result = register_block_script_handle(
$metadata,
$metadata_field_name,
$index
);
if ( $result ) {
$processed_scripts[] = $result;
}
}
} else {
$result = register_block_script_handle(
$metadata,
$metadata_field_name
);
if ( $result ) {
$processed_scripts[] = $result;
}
}
$settings[ $settings_field_name ] = $processed_scripts;
}
}

if ( ! empty( $metadata['style'] ) ) {
$settings['style'] = register_block_style_handle(
$metadata,
'style'
);
$style_fields = array(
'editorStyle' => 'editor_style_handles',
'style' => 'style_handles',
);
foreach ( $style_fields as $metadata_field_name => $settings_field_name ) {
if ( ! empty( $metadata[ $metadata_field_name ] ) ) {
$styles = $metadata[ $metadata_field_name ];
$processed_styles = array();
if ( is_array( $styles ) ) {
for ( $index = 0; $index < count( $styles ); $index++ ) {
$result = register_block_style_handle(
$metadata,
$metadata_field_name,
$index
);
if ( $result ) {
$processed_styles[] = $result;
}
}
} else {
$result = register_block_style_handle(
$metadata,
$metadata_field_name
);
if ( $result ) {
$processed_styles[] = $result;
}
}
$settings[ $settings_field_name ] = $processed_styles;
}
}

if ( ! empty( $metadata['render'] ) ) {
Expand Down Expand Up @@ -1261,49 +1328,6 @@ function get_query_pagination_arrow( $block, $is_next ) {
return null;
}

/**
* Allows multiple block styles.
*
* @since 5.9.0
*
* @param array $metadata Metadata for registering a block type.
* @return array Metadata for registering a block type.
*/
function _wp_multiple_block_styles( $metadata ) {
foreach ( array( 'style', 'editorStyle' ) as $key ) {
if ( ! empty( $metadata[ $key ] ) && is_array( $metadata[ $key ] ) ) {
$default_style = array_shift( $metadata[ $key ] );
foreach ( $metadata[ $key ] as $handle ) {
$args = array( 'handle' => $handle );
if ( 0 === strpos( $handle, 'file:' ) && isset( $metadata['file'] ) ) {
$style_path = remove_block_asset_path_prefix( $handle );
$theme_path_norm = wp_normalize_path( get_theme_file_path() );
$style_path_norm = wp_normalize_path( realpath( dirname( $metadata['file'] ) . '/' . $style_path ) );
$is_theme_block = isset( $metadata['file'] ) && 0 === strpos( $metadata['file'], $theme_path_norm );

$style_uri = plugins_url( $style_path, $metadata['file'] );

if ( $is_theme_block ) {
$style_uri = get_theme_file_uri( str_replace( $theme_path_norm, '', $style_path_norm ) );
}

$args = array(
'handle' => sanitize_key( "{$metadata['name']}-{$style_path}" ),
'src' => $style_uri,
);
}

wp_enqueue_block_style( $metadata['name'], $args );
}

// Only return the 1st item in the array.
$metadata[ $key ] = $default_style;
}
}
return $metadata;
}
add_filter( 'block_type_metadata', '_wp_multiple_block_styles' );

/**
* Helper function that constructs a comment query vars array from the passed
* block properties.
Expand Down
Loading

0 comments on commit c9deebc

Please sign in to comment.