From 5d294d5440d1475674bd47a892a95b0862b56a99 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Tue, 6 Feb 2024 13:42:57 +0100 Subject: [PATCH 1/4] Add viewScriptModule block.json support --- lib/experimental/script-modules.php | 45 ++++++++++++++++++++--------- 1 file changed, 31 insertions(+), 14 deletions(-) diff --git a/lib/experimental/script-modules.php b/lib/experimental/script-modules.php index 1f481a8098b20..c91efc6033db0 100644 --- a/lib/experimental/script-modules.php +++ b/lib/experimental/script-modules.php @@ -10,7 +10,9 @@ */ function gutenberg_filter_block_type_metadata_settings_register_modules( $settings, $metadata = null ) { $module_fields = array( - 'viewModule' => 'view_module_ids', + // @todo remove viewModule support in Gutenberg >= 17.8 (replaced by viewScriptModule). + 'viewModule' => 'view_script_module_ids', + 'viewScriptModule' => 'view_script_module_ids', ); foreach ( $module_fields as $metadata_field_name => $settings_field_name ) { if ( ! empty( $settings[ $metadata_field_name ] ) ) { @@ -49,11 +51,11 @@ function gutenberg_filter_block_type_metadata_settings_register_modules( $settin * @param array $parsed_block The full block, including name and attributes. * @param WP_Block $block_instance The block instance. */ -function gutenberg_filter_render_block_enqueue_view_modules( $block_content, $parsed_block, $block_instance ) { +function gutenberg_filter_render_block_enqueue_view_script_modules( $block_content, $parsed_block, $block_instance ) { $block_type = $block_instance->block_type; - if ( ! empty( $block_type->view_module_ids ) ) { - foreach ( $block_type->view_module_ids as $module_id ) { + if ( ! empty( $block_type->view_script_module_ids ) ) { + foreach ( $block_type->view_script_module_ids as $module_id ) { wp_enqueue_script_module( $module_id ); } } @@ -61,7 +63,7 @@ function gutenberg_filter_render_block_enqueue_view_modules( $block_content, $pa return $block_content; } -add_filter( 'render_block', 'gutenberg_filter_render_block_enqueue_view_modules', 10, 3 ); +add_filter( 'render_block', 'gutenberg_filter_render_block_enqueue_view_script_modules', 10, 3 ); /** * Finds a module ID for the selected block metadata field. It detects @@ -159,7 +161,9 @@ function gutenberg_generate_block_asset_module_id( $block_name, $field_name, $in } $field_mappings = array( - 'viewModule' => 'view-module', + // @todo remove viewModule support in Gutenberg >= 17.8 (replaced by viewScriptModule). + 'viewModule' => 'view-script-module', + 'viewScriptModule' => 'view-script-module', ); $asset_handle = str_replace( '/', '-', $block_name ) . '-' . $field_mappings[ $field_name ]; @@ -172,21 +176,34 @@ function gutenberg_generate_block_asset_module_id( $block_name, $field_name, $in /** * Registers a REST field for block types to provide view module IDs. * - * Adds the `view_module_ids` field to block type objects in the REST API, which + * Adds the `view_script_module_ids` and `view_module_ids` (deprecated) field to block type objects in the REST API, which * lists the script module IDs for any script modules associated with the - * block's viewModule(s) key. - * - * @since 6.5.0 + * block's viewScriptModule key. */ -function gutenberg_register_view_module_ids_rest_field() { +function gutenberg_register_view_script_module_ids_rest_field() { + // @todo remove view_module_ids support in Gutenberg >= 17.8 (replaced by view_script_module_ids). register_rest_field( 'block-type', 'view_module_ids', array( 'get_callback' => function ( $item ) { $block_type = WP_Block_Type_Registry::get_instance()->get_registered( $item['name'] ); - if ( isset( $block_type->view_module_ids ) ) { - return $block_type->view_module_ids; + if ( isset( $block_type->view_script_module_ids ) ) { + return $block_type->view_script_module_ids; + } + return array(); + }, + ) + ); + + register_rest_field( + 'block-type', + 'view_script_module_ids', + array( + 'get_callback' => function ( $item ) { + $block_type = WP_Block_Type_Registry::get_instance()->get_registered( $item['name'] ); + if ( isset( $block_type->view_script_module_ids ) ) { + return $block_type->view_script_module_ids; } return array(); }, @@ -194,7 +211,7 @@ function gutenberg_register_view_module_ids_rest_field() { ); } -add_action( 'rest_api_init', 'gutenberg_register_view_module_ids_rest_field' ); +add_action( 'rest_api_init', 'gutenberg_register_view_script_module_ids_rest_field' ); /** * Registers the module if no module with that module identifier has already From 288b14ed3cc629e6334039a64f78fa26eb70578c Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Tue, 6 Feb 2024 14:29:16 +0100 Subject: [PATCH 2/4] Lints --- lib/experimental/script-modules.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/experimental/script-modules.php b/lib/experimental/script-modules.php index c91efc6033db0..b24164d4d35fe 100644 --- a/lib/experimental/script-modules.php +++ b/lib/experimental/script-modules.php @@ -11,7 +11,7 @@ function gutenberg_filter_block_type_metadata_settings_register_modules( $settings, $metadata = null ) { $module_fields = array( // @todo remove viewModule support in Gutenberg >= 17.8 (replaced by viewScriptModule). - 'viewModule' => 'view_script_module_ids', + 'viewModule' => 'view_script_module_ids', 'viewScriptModule' => 'view_script_module_ids', ); foreach ( $module_fields as $metadata_field_name => $settings_field_name ) { @@ -162,7 +162,7 @@ function gutenberg_generate_block_asset_module_id( $block_name, $field_name, $in $field_mappings = array( // @todo remove viewModule support in Gutenberg >= 17.8 (replaced by viewScriptModule). - 'viewModule' => 'view-script-module', + 'viewModule' => 'view-script-module', 'viewScriptModule' => 'view-script-module', ); $asset_handle = str_replace( '/', '-', $block_name ) . From 0491cf5fc0acf1de6070086ce749e74266510744 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Wed, 7 Feb 2024 11:03:21 +0100 Subject: [PATCH 3/4] Add docs about `viewScriptModule` --- .../block-api/block-metadata.md | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/docs/reference-guides/block-api/block-metadata.md b/docs/reference-guides/block-api/block-metadata.md index 63512c5303fd2..037bc0869e01b 100644 --- a/docs/reference-guides/block-api/block-metadata.md +++ b/docs/reference-guides/block-api/block-metadata.md @@ -527,6 +527,26 @@ It's possible to pass a script handle registered with the [`wp_register_script`] _Note: An option to pass also an array of view scripts exists since WordPress `6.1.0`._ +### View script + +- Type: `WPDefinedAsset`|`WPDefinedAsset[]` ([learn more](#wpdefinedasset)) +- Optional +- Localized: No +- Property: `viewScript` +- Since: `WordPress 5.9.0` + +```json +{ "viewScriptModule": [ "file:./view.js", "example-shared-script-module-id" ] } +``` + +Block type frontend script module definition. They will be enqueued only when viewing the content on the front of the site. + +It's possible to pass a script module ID registered with the [`wp_register_script_module`](https://developer.wordpress.org/reference/functions/wp_register_script_module/) function, a path to a JavaScript module relative to the `block.json` file, or a list with a mix of both ([learn more](#wpdefinedasset)). + +WordPress scripts and WordPress script modules are not compatible at the moment. If frontend view assets depend on WordPress scripts, `viewScript` should be used. If they depend on WordPress script modules —the Interactivity API at this time— `viewScriptModule` should be used. In the future, it will be possible to depend on scripts from script modules. + +_Note: Available since WordPress `6.5.0`._ + ### Editor style - Type: `WPDefinedAsset`|`WPDefinedAsset[]` ([learn more](#wpdefinedasset)) From 287559dcb7d3f6c630bdedaf8534dfc4c2766c91 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Wed, 7 Feb 2024 11:21:52 +0100 Subject: [PATCH 4/4] Update WPDefinedAsset to account for modules --- docs/reference-guides/block-api/block-metadata.md | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/docs/reference-guides/block-api/block-metadata.md b/docs/reference-guides/block-api/block-metadata.md index 037bc0869e01b..8be4cba093482 100644 --- a/docs/reference-guides/block-api/block-metadata.md +++ b/docs/reference-guides/block-api/block-metadata.md @@ -645,7 +645,7 @@ In `block.json`: ### `WPDefinedAsset` -It extends `WPDefinedPath` for JavaScript and CSS files. An alternative to the file path would be a script or style handle name referencing an already registered asset using WordPress helpers. +It extends `WPDefinedPath` for JavaScript and CSS files. An alternative to the file path would be a script handle, script module ID, or style handle referencing an already registered asset using WordPress helpers. **Example:** @@ -655,21 +655,24 @@ In `block.json`: { "editorScript": "file:./index.js", "script": "file:./script.js", - "viewScript": [ "file:./view.js", "example-shared-view-script" ], + "viewScriptModule": [ + "file:./view.js", + "example-registered-script-module-id" + ], "editorStyle": "file:./index.css", "style": [ "file:./style.css", "example-shared-style" ], "viewStyle": [ "file:./view.css", "example-view-style" ] } ``` -In the context of WordPress, when a block is registered with PHP, it will automatically register all scripts and styles that are found in the `block.json` file and use file paths rather than asset handles. +In the context of WordPress, when a block is registered with PHP, it will automatically register all scripts, script modules, and styles that are found in the `block.json` file and use file paths rather than asset handles. -That's why, the `WPDefinedAsset` type has to offer a way to mirror also the shape of params necessary to register scripts and styles using [`wp_register_script`](https://developer.wordpress.org/reference/functions/wp_register_script/) and [`wp_register_style`](https://developer.wordpress.org/reference/functions/wp_register_style/), and then assign these as handles associated with your block using the `script`, `style`, `editor_script`, and `editor_style` block type registration settings. +That's why the `WPDefinedAsset` type has to offer a way to mirror the parameters necessary to register scripts, script modules, and styles using [`wp_register_script`](https://developer.wordpress.org/reference/functions/wp_register_script/), [`wp_register_script_module`](https://developer.wordpress.org/reference/functions/wp_register_script_module/), and [`wp_register_style`](https://developer.wordpress.org/reference/functions/wp_register_style/), and then assign these as handles or script module IDs associated with the block. It's possible to provide an object which takes the following shape: - `handle` (`string`) - the name of the script. If omitted, it will be auto-generated. -- `dependencies` (`string[]`) - an array of registered script handles this script depends on. Default value: `[]`. +- `dependencies` (`string[]`|`{ id: string, import?: 'dynamic'|'static' }[]`) - an array of registered script handles this script depends on. Script modules may use a simple string for static dependencies or the object form to indicate a dynamic dependency. Dynamic dependencies are dependencies that may or may not be used at runtime and are typically used with the dynamic `import('module-id')` syntax. Default value: `[]`. - `version` (`string`|`false`|`null`) - string specifying the script version number, if it has one, which is added to the URL as a query string for cache busting purposes. If the version is set to `false`, a version number is automatically added equal to current installed WordPress version. If set to `null`, no version is added. Default value: `false`. The definition is stored inside separate PHP file which ends with `.asset.php` and is located next to the JS/CSS file listed in `block.json`. WordPress will automatically detect this file through pattern matching. This option is the preferred one as it is expected it will become an option to auto-generate those asset files with `@wordpress/scripts` package.