Editor: resolve patterns server side.
See https://github.com/WordPress/gutenberg/pull/60349. See https://github.com/WordPress/gutenberg/pull/61757. See https://github.com/WordPress/wordpress-develop/pull/6673. Fixes #61228. Props ellatrix, antonvlasenko. Built from https://develop.svn.wordpress.org/trunk@58303 git-svn-id: http://core.svn.wordpress.org/trunk@57760 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This commit is contained in:
parent
c6d62b17e1
commit
db68e46662
|
@ -1518,6 +1518,83 @@ function traverse_and_serialize_block( $block, $pre_callback = null, $post_callb
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Replaces patterns in a block tree with their content.
|
||||||
|
*
|
||||||
|
* @since 6.6.0
|
||||||
|
*
|
||||||
|
* @param array $blocks An array blocks.
|
||||||
|
*
|
||||||
|
* @return array An array of blocks with patterns replaced by their content.
|
||||||
|
*/
|
||||||
|
function resolve_pattern_blocks( $blocks ) {
|
||||||
|
static $inner_content;
|
||||||
|
// Keep track of seen references to avoid infinite loops.
|
||||||
|
static $seen_refs = array();
|
||||||
|
$i = 0;
|
||||||
|
while ( $i < count( $blocks ) ) {
|
||||||
|
if ( 'core/pattern' === $blocks[ $i ]['blockName'] ) {
|
||||||
|
$attrs = $blocks[ $i ]['attrs'];
|
||||||
|
|
||||||
|
if ( empty( $attrs['slug'] ) ) {
|
||||||
|
++$i;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$slug = $attrs['slug'];
|
||||||
|
|
||||||
|
if ( isset( $seen_refs[ $slug ] ) ) {
|
||||||
|
// Skip recursive patterns.
|
||||||
|
array_splice( $blocks, $i, 1 );
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$registry = WP_Block_Patterns_Registry::get_instance();
|
||||||
|
$pattern = $registry->get_registered( $slug );
|
||||||
|
|
||||||
|
// Skip unknown patterns.
|
||||||
|
if ( ! $pattern ) {
|
||||||
|
++$i;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$blocks_to_insert = parse_blocks( $pattern['content'] );
|
||||||
|
$seen_refs[ $slug ] = true;
|
||||||
|
$prev_inner_content = $inner_content;
|
||||||
|
$inner_content = null;
|
||||||
|
$blocks_to_insert = resolve_pattern_blocks( $blocks_to_insert );
|
||||||
|
$inner_content = $prev_inner_content;
|
||||||
|
unset( $seen_refs[ $slug ] );
|
||||||
|
array_splice( $blocks, $i, 1, $blocks_to_insert );
|
||||||
|
|
||||||
|
// If we have inner content, we need to insert nulls in the
|
||||||
|
// inner content array, otherwise serialize_blocks will skip
|
||||||
|
// blocks.
|
||||||
|
if ( $inner_content ) {
|
||||||
|
$null_indices = array_keys( $inner_content, null, true );
|
||||||
|
$content_index = $null_indices[ $i ];
|
||||||
|
$nulls = array_fill( 0, count( $blocks_to_insert ), null );
|
||||||
|
array_splice( $inner_content, $content_index, 1, $nulls );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Skip inserted blocks.
|
||||||
|
$i += count( $blocks_to_insert );
|
||||||
|
} else {
|
||||||
|
if ( ! empty( $blocks[ $i ]['innerBlocks'] ) ) {
|
||||||
|
$prev_inner_content = $inner_content;
|
||||||
|
$inner_content = $blocks[ $i ]['innerContent'];
|
||||||
|
$blocks[ $i ]['innerBlocks'] = resolve_pattern_blocks(
|
||||||
|
$blocks[ $i ]['innerBlocks']
|
||||||
|
);
|
||||||
|
$blocks[ $i ]['innerContent'] = $inner_content;
|
||||||
|
$inner_content = $prev_inner_content;
|
||||||
|
}
|
||||||
|
++$i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $blocks;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Given an array of parsed block trees, applies callbacks before and after serializing them and
|
* Given an array of parsed block trees, applies callbacks before and after serializing them and
|
||||||
* returns their concatenated output.
|
* returns their concatenated output.
|
||||||
|
|
|
@ -162,6 +162,12 @@ class WP_REST_Block_Patterns_Controller extends WP_REST_Controller {
|
||||||
* @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
|
* @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
|
||||||
*/
|
*/
|
||||||
public function prepare_item_for_response( $item, $request ) {
|
public function prepare_item_for_response( $item, $request ) {
|
||||||
|
// Resolve pattern blocks so they don't need to be resolved client-side
|
||||||
|
// in the editor, improving performance.
|
||||||
|
$blocks = parse_blocks( $item['content'] );
|
||||||
|
$blocks = resolve_pattern_blocks( $blocks );
|
||||||
|
$item['content'] = serialize_blocks( $blocks );
|
||||||
|
|
||||||
$fields = $this->get_fields_for_response( $request );
|
$fields = $this->get_fields_for_response( $request );
|
||||||
$keys = array(
|
$keys = array(
|
||||||
'name' => 'name',
|
'name' => 'name',
|
||||||
|
|
|
@ -668,6 +668,12 @@ class WP_REST_Templates_Controller extends WP_REST_Controller {
|
||||||
* @return WP_REST_Response Response object.
|
* @return WP_REST_Response Response object.
|
||||||
*/
|
*/
|
||||||
public function prepare_item_for_response( $item, $request ) {
|
public function prepare_item_for_response( $item, $request ) {
|
||||||
|
// Resolve pattern blocks so they don't need to be resolved client-side
|
||||||
|
// in the editor, improving performance.
|
||||||
|
$blocks = parse_blocks( $item->content );
|
||||||
|
$blocks = resolve_pattern_blocks( $blocks );
|
||||||
|
$item->content = serialize_blocks( $blocks );
|
||||||
|
|
||||||
// Restores the more descriptive, specific name for use within this method.
|
// Restores the more descriptive, specific name for use within this method.
|
||||||
$template = $item;
|
$template = $item;
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
*
|
*
|
||||||
* @global string $wp_version
|
* @global string $wp_version
|
||||||
*/
|
*/
|
||||||
$wp_version = '6.6-alpha-58299';
|
$wp_version = '6.6-alpha-58303';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.
|
* Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.
|
||||||
|
|
Loading…
Reference in New Issue