diff --git a/lib/experimental/block-bindings/block-bindings.php b/lib/compat/wordpress-6.5/block-bindings/block-bindings.php similarity index 100% rename from lib/experimental/block-bindings/block-bindings.php rename to lib/compat/wordpress-6.5/block-bindings/block-bindings.php diff --git a/lib/experimental/block-bindings/class-wp-block-bindings.php b/lib/compat/wordpress-6.5/block-bindings/class-wp-block-bindings.php similarity index 100% rename from lib/experimental/block-bindings/class-wp-block-bindings.php rename to lib/compat/wordpress-6.5/block-bindings/class-wp-block-bindings.php diff --git a/lib/experimental/block-bindings/sources/pattern.php b/lib/compat/wordpress-6.5/block-bindings/sources/pattern.php similarity index 100% rename from lib/experimental/block-bindings/sources/pattern.php rename to lib/compat/wordpress-6.5/block-bindings/sources/pattern.php diff --git a/lib/experimental/block-bindings/sources/post-meta.php b/lib/compat/wordpress-6.5/block-bindings/sources/post-meta.php similarity index 100% rename from lib/experimental/block-bindings/sources/post-meta.php rename to lib/compat/wordpress-6.5/block-bindings/sources/post-meta.php diff --git a/lib/compat/wordpress-6.5/blocks.php b/lib/compat/wordpress-6.5/blocks.php index f5a9968f9210be..dccaeba5cc3352 100644 --- a/lib/compat/wordpress-6.5/blocks.php +++ b/lib/compat/wordpress-6.5/blocks.php @@ -45,3 +45,82 @@ function gutenberg_register_metadata_attribute( $args ) { return $args; } add_filter( 'register_block_type_args', 'gutenberg_register_metadata_attribute' ); + + +if ( ! function_exists( 'gutenberg_process_block_bindings' ) ) { + /** + * Process the block bindings attribute. + * + * @param string $block_content Block Content. + * @param array $block Block attributes. + * @param WP_Block $block_instance The block instance. + */ + function gutenberg_process_block_bindings( $block_content, $block, $block_instance ) { + + // Allowed blocks that support block bindings. + // TODO: Look for a mechanism to opt-in for this. Maybe adding a property to block attributes? + $allowed_blocks = array( + 'core/paragraph' => array( 'content' ), + 'core/heading' => array( 'content' ), + 'core/image' => array( 'url', 'title', 'alt' ), + 'core/button' => array( 'url', 'text', 'linkTarget' ), + ); + + // If the block doesn't have the bindings property or isn't one of the allowed block types, return. + if ( ! isset( $block['attrs']['metadata']['bindings'] ) || ! isset( $allowed_blocks[ $block_instance->name ] ) ) { + return $block_content; + } + + /* + * Assuming the following format for the bindings property of the "metadata" attribute: + * + * "bindings": { + * "title": { + * "source": { + * "name": "post_meta", + * "attributes": { "value": "text_custom_field" } + * } + * }, + * "url": { + * "source": { + * "name": "post_meta", + * "attributes": { "value": "text_custom_field" } + * } + * } + * } + */ + + $block_bindings_sources = wp_block_bindings_get_sources(); + $modified_block_content = $block_content; + foreach ( $block['attrs']['metadata']['bindings'] as $binding_attribute => $binding_source ) { + + // If the attribute is not in the list, process next attribute. + if ( ! in_array( $binding_attribute, $allowed_blocks[ $block_instance->name ], true ) ) { + continue; + } + // If no source is provided, or that source is not registered, process next attribute. + if ( ! isset( $binding_source['source'] ) || ! isset( $binding_source['source']['name'] ) || ! isset( $block_bindings_sources[ $binding_source['source']['name'] ] ) ) { + continue; + } + + $source_callback = $block_bindings_sources[ $binding_source['source']['name'] ]['apply']; + // Get the value based on the source. + if ( ! isset( $binding_source['source']['attributes'] ) ) { + $source_args = array(); + } else { + $source_args = $binding_source['source']['attributes']; + } + $source_value = $source_callback( $source_args, $block_instance, $binding_attribute ); + // If the value is null, process next attribute. + if ( is_null( $source_value ) ) { + continue; + } + + // Process the HTML based on the block and the attribute. + $modified_block_content = wp_block_bindings_replace_html( $modified_block_content, $block_instance->name, $binding_attribute, $source_value ); + } + return $modified_block_content; + } +} + +add_filter( 'render_block', 'gutenberg_process_block_bindings', 20, 3 ); diff --git a/lib/experimental/block-bindings/index.php b/lib/experimental/block-bindings/index.php deleted file mode 100644 index cf9cc318b1c929..00000000000000 --- a/lib/experimental/block-bindings/index.php +++ /dev/null @@ -1,17 +0,0 @@ - array( 'content' ), - 'core/heading' => array( 'content' ), - 'core/image' => array( 'url', 'title', 'alt' ), - 'core/button' => array( 'url', 'text', 'linkTarget' ), - ); - - // If the block doesn't have the bindings property or isn't one of the allowed block types, return. - if ( ! isset( $block['attrs']['metadata']['bindings'] ) || ! isset( $allowed_blocks[ $block_instance->name ] ) ) { - return $block_content; - } - - // Assuming the following format for the bindings property of the "metadata" attribute: - // - // "bindings": { - // "title": { - // "source": { - // "name": "post_meta", - // "attributes": { "value": "text_custom_field" } - // } - // }, - // "url": { - // "source": { - // "name": "post_meta", - // "attributes": { "value": "text_custom_field" } - // } - // } - // } - // - - $block_bindings_sources = wp_block_bindings_get_sources(); - $modified_block_content = $block_content; - foreach ( $block['attrs']['metadata']['bindings'] as $binding_attribute => $binding_source ) { - - // If the attribute is not in the list, process next attribute. - if ( ! in_array( $binding_attribute, $allowed_blocks[ $block_instance->name ], true ) ) { - continue; - } - // If no source is provided, or that source is not registered, process next attribute. - if ( ! isset( $binding_source['source'] ) || ! isset( $binding_source['source']['name'] ) || ! isset( $block_bindings_sources[ $binding_source['source']['name'] ] ) ) { - continue; - } - - $source_callback = $block_bindings_sources[ $binding_source['source']['name'] ]['apply']; - // Get the value based on the source. - if ( ! isset( $binding_source['source']['attributes'] ) ) { - $source_args = array(); - } else { - $source_args = $binding_source['source']['attributes']; - } - $source_value = $source_callback( $source_args, $block_instance, $binding_attribute ); - // If the value is null, process next attribute. - if ( is_null( $source_value ) ) { - continue; - } - - // Process the HTML based on the block and the attribute. - $modified_block_content = wp_block_bindings_replace_html( $modified_block_content, $block_instance->name, $binding_attribute, $source_value ); - } - return $modified_block_content; - } - } - - add_filter( 'render_block', 'gutenberg_process_block_bindings', 20, 3 ); -} diff --git a/lib/experimental/editor-settings.php b/lib/experimental/editor-settings.php index 24590c5cf3eb0e..37774e07b27691 100644 --- a/lib/experimental/editor-settings.php +++ b/lib/experimental/editor-settings.php @@ -25,11 +25,6 @@ function gutenberg_enable_experiments() { if ( $gutenberg_experiments && array_key_exists( 'gutenberg-group-grid-variation', $gutenberg_experiments ) ) { wp_add_inline_script( 'wp-block-editor', 'window.__experimentalEnableGroupGridVariation = true', 'before' ); } - - if ( $gutenberg_experiments && array_key_exists( 'gutenberg-block-bindings', $gutenberg_experiments ) ) { - wp_add_inline_script( 'wp-block-editor', 'window.__experimentalBlockBindings = true', 'before' ); - } - if ( gutenberg_is_experiment_enabled( 'gutenberg-no-tinymce' ) ) { wp_add_inline_script( 'wp-block-library', 'window.__experimentalDisableTinymce = true', 'before' ); } diff --git a/lib/experiments-page.php b/lib/experiments-page.php index a38b5c4f11fadb..bccbed2195958b 100644 --- a/lib/experiments-page.php +++ b/lib/experiments-page.php @@ -126,18 +126,6 @@ function gutenberg_initialize_experiments_settings() { ) ); - add_settings_field( - 'gutenberg-custom-fields', - __( 'Block Bindings & Custom Fields', 'gutenberg' ), - 'gutenberg_display_experiment_field', - 'gutenberg-experiments', - 'gutenberg_experiments_section', - array( - 'label' => __( 'Test connecting block attributes to different sources like custom fields', 'gutenberg' ), - 'id' => 'gutenberg-block-bindings', - ) - ); - register_setting( 'gutenberg-experiments', 'gutenberg-experiments' diff --git a/lib/load.php b/lib/load.php index ea443544d5be4c..223a817cc51d0b 100644 --- a/lib/load.php +++ b/lib/load.php @@ -109,6 +109,11 @@ function gutenberg_is_experiment_enabled( $name ) { require __DIR__ . '/compat/wordpress-6.5/kses.php'; require __DIR__ . '/compat/wordpress-6.5/class-wp-script-modules.php'; require __DIR__ . '/compat/wordpress-6.5/scripts-modules.php'; +require __DIR__ . '/compat/wordpress-6.5/block-bindings/class-wp-block-bindings.php'; +require __DIR__ . '/compat/wordpress-6.5/block-bindings/block-bindings.php'; +require __DIR__ . '/compat/wordpress-6.5/block-bindings/sources/post-meta.php'; +require __DIR__ . '/compat/wordpress-6.5/block-bindings/sources/pattern.php'; + // Experimental features. require __DIR__ . '/experimental/block-editor-settings-mobile.php'; diff --git a/test/e2e/specs/editor/various/pattern-overrides.spec.js b/test/e2e/specs/editor/various/pattern-overrides.spec.js index 56c6b2a7c15f46..ee60091e057c02 100644 --- a/test/e2e/specs/editor/various/pattern-overrides.spec.js +++ b/test/e2e/specs/editor/various/pattern-overrides.spec.js @@ -7,9 +7,6 @@ test.describe( 'Pattern Overrides', () => { test.beforeAll( async ( { requestUtils } ) => { await Promise.all( [ requestUtils.activateTheme( 'emptytheme' ), - requestUtils.setGutenbergExperiments( [ - 'gutenberg-block-bindings', - ] ), requestUtils.deleteAllBlocks(), ] ); } ); @@ -20,7 +17,6 @@ test.describe( 'Pattern Overrides', () => { test.afterAll( async ( { requestUtils } ) => { await Promise.all( [ - requestUtils.setGutenbergExperiments( [] ), requestUtils.activateTheme( 'twentytwentyone' ), ] ); } );