Skip to content

Commit

Permalink
Editor: Add viewScriptModule handling to block.json metadata
Browse files Browse the repository at this point in the history
Syncing changes from the Gutenberg plugin: WordPress/gutenberg#57437.

Scripts and styles can be registered for blocks via `block.json` metadata. There is now a Modules API, but was no way to register or associate module assets with blocks via `block.json`.

Fixes #60233.
Props jonsurrell, gziolo, cbravobernal, luisherranz, youknowriad.


Built from https://develop.svn.wordpress.org/trunk@57565


git-svn-id: https://core.svn.wordpress.org/trunk@57066 1a063a9b-81f0-0310-95a4-ce76da25c4cd
  • Loading branch information
gziolo committed Feb 8, 2024
1 parent 35c9083 commit ffc1518
Show file tree
Hide file tree
Showing 5 changed files with 129 additions and 8 deletions.
109 changes: 102 additions & 7 deletions wp-includes/blocks.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ function remove_block_asset_path_prefix( $asset_handle_or_path ) {
*
* @since 5.5.0
* @since 6.1.0 Added `$index` parameter.
* @since 6.5.0 Added support for `viewScriptModule` field.
*
* @param string $block_name Name of the block.
* @param string $field_name Name of the metadata field.
Expand All @@ -52,19 +53,23 @@ function generate_block_asset_handle( $block_name, $field_name, $index = 0 ) {
if ( str_starts_with( $field_name, 'view' ) ) {
$asset_handle .= '-view';
}
if ( str_ends_with( strtolower( $field_name ), 'scriptmodule' ) ) {
$asset_handle .= '-script-module';
}
if ( $index > 0 ) {
$asset_handle .= '-' . ( $index + 1 );
}
return $asset_handle;
}

$field_mappings = array(
'editorScript' => 'editor-script',
'script' => 'script',
'viewScript' => 'view-script',
'editorStyle' => 'editor-style',
'style' => 'style',
'viewStyle' => 'view-style',
'editorScript' => 'editor-script',
'editorStyle' => 'editor-style',
'script' => 'script',
'style' => 'style',
'viewScript' => 'view-script',
'viewScriptModule' => 'view-script-module',
'viewStyle' => 'view-style',
);
$asset_handle = str_replace( '/', '-', $block_name ) .
'-' . $field_mappings[ $field_name ];
Expand Down Expand Up @@ -122,6 +127,62 @@ function get_block_asset_url( $path ) {
return plugins_url( basename( $path ), $path );
}

/**
* Finds a script module ID for the selected block metadata field. It detects
* when a path to file was provided and optionally finds a corresponding asset
* file with details necessary to register the script module under with an
* automatically generated module ID. It returns unprocessed script module
* ID otherwise.
*
* @since 6.5.0
*
* @param array $metadata Block metadata.
* @param string $field_name Field name to pick from metadata.
* @param int $index Optional. Index of the script module ID to register when multiple
* items passed. Default 0.
* @return string|false Script module ID or false on failure.
*/
function register_block_script_module_id( $metadata, $field_name, $index = 0 ) {
if ( empty( $metadata[ $field_name ] ) ) {
return false;
}

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

$module_path = remove_block_asset_path_prefix( $module_id );
if ( $module_id === $module_path ) {
return $module_id;
}

$path = dirname( $metadata['file'] );
$module_asset_raw_path = $path . '/' . substr_replace( $module_path, '.asset.php', - strlen( '.js' ) );
$module_id = generate_block_asset_handle( $metadata['name'], $field_name, $index );
$module_asset_path = wp_normalize_path(
realpath( $module_asset_raw_path )
);

$module_path_norm = wp_normalize_path( realpath( $path . '/' . $module_path ) );
$module_uri = get_block_asset_url( $module_path_norm );

$module_asset = ! empty( $module_asset_path ) ? require $module_asset_path : array();
$module_dependencies = isset( $module_asset['dependencies'] ) ? $module_asset['dependencies'] : array();

wp_register_script_module(
$module_id,
$module_uri,
$module_dependencies,
isset( $module_asset['version'] ) ? $module_asset['version'] : false
);

return $module_id;
}

/**
* Finds a script handle for the selected block metadata field. It detects
* when a path to file was provided and optionally finds a corresponding asset
Expand Down Expand Up @@ -314,7 +375,7 @@ function get_block_metadata_i18n_schema() {
* @since 6.1.0 Added support for `render` field.
* @since 6.3.0 Added `selectors` field.
* @since 6.4.0 Added support for `blockHooks` field.
* @since 6.5.0 Added support for `allowedBlocks` and `viewStyle` fields.
* @since 6.5.0 Added support for `allowedBlocks`, `viewScriptModule`, and `viewStyle` fields.
*
* @param string $file_or_folder Path to the JSON file with metadata definition for
* the block or path to the folder where the `block.json` file is located.
Expand Down Expand Up @@ -490,6 +551,40 @@ function register_block_type_from_metadata( $file_or_folder, $args = array() ) {
}
}

$module_fields = array(
'viewScriptModule' => 'view_script_module_ids',
);
foreach ( $module_fields as $metadata_field_name => $settings_field_name ) {
if ( ! empty( $settings[ $metadata_field_name ] ) ) {
$metadata[ $metadata_field_name ] = $settings[ $metadata_field_name ];
}
if ( ! empty( $metadata[ $metadata_field_name ] ) ) {
$modules = $metadata[ $metadata_field_name ];
$processed_modules = array();
if ( is_array( $modules ) ) {
for ( $index = 0; $index < count( $modules ); $index++ ) {
$result = register_block_script_module_id(
$metadata,
$metadata_field_name,
$index
);
if ( $result ) {
$processed_modules[] = $result;
}
}
} else {
$result = register_block_script_module_id(
$metadata,
$metadata_field_name
);
if ( $result ) {
$processed_modules[] = $result;
}
}
$settings[ $settings_field_name ] = $processed_modules;
}
}

$style_fields = array(
'editorStyle' => 'editor_style_handles',
'style' => 'style_handles',
Expand Down
8 changes: 8 additions & 0 deletions wp-includes/class-wp-block-type.php
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,14 @@ class WP_Block_Type {
*/
public $view_script_handles = array();

/**
* Block type front end only script module IDs.
*
* @since 6.5.0
* @var string[]
*/
public $view_script_module_ids = array();

/**
* Block type editor only style handles.
*
Expand Down
6 changes: 6 additions & 0 deletions wp-includes/class-wp-block.php
Original file line number Diff line number Diff line change
Expand Up @@ -470,6 +470,12 @@ public function render( $options = array() ) {
}
}

if ( ! empty( $this->block_type->view_script_module_ids ) ) {
foreach ( $this->block_type->view_script_module_ids as $view_script_module_id ) {
wp_enqueue_script_module( $view_script_module_id );
}
}

if ( ( ! empty( $this->block_type->style_handles ) ) ) {
foreach ( $this->block_type->style_handles as $style_handle ) {
wp_enqueue_style( $style_handle );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,7 @@ public function get_item( $request ) {
* @since 5.5.0
* @since 5.9.0 Renamed `$block_type` to `$item` to match parent class for PHP 8 named parameter support.
* @since 6.3.0 Added `selectors` field.
* @since 6.5.0 Added `view_script_module_ids` field.
*
* @param WP_Block_Type $item Block type data.
* @param WP_REST_Request $request Full details about the request.
Expand Down Expand Up @@ -291,6 +292,7 @@ public function prepare_item_for_response( $item, $request ) {
'editor_script_handles',
'script_handles',
'view_script_handles',
'view_script_module_ids',
'editor_style_handles',
'style_handles',
'view_style_handles',
Expand Down Expand Up @@ -584,6 +586,16 @@ public function get_item_schema() {
'context' => array( 'embed', 'view', 'edit' ),
'readonly' => true,
),
'view_script_module_ids' => array(
'description' => __( 'Public facing script module IDs.' ),
'type' => array( 'array' ),
'default' => array(),
'items' => array(
'type' => 'string',
),
'context' => array( 'embed', 'view', 'edit' ),
'readonly' => true,
),
'editor_style_handles' => array(
'description' => __( 'Editor style handles.' ),
'type' => array( 'array' ),
Expand Down
2 changes: 1 addition & 1 deletion wp-includes/version.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
*
* @global string $wp_version
*/
$wp_version = '6.5-alpha-57564';
$wp_version = '6.5-alpha-57565';

/**
* Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.
Expand Down

0 comments on commit ffc1518

Please sign in to comment.