Changeset 58614
- Timestamp:
- 07/02/2024 10:01:17 AM (2 months ago)
- Location:
- trunk
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/wp-includes/block-template-utils.php
r58409 r58614 607 607 } 608 608 609 $hooked_blocks = get_hooked_blocks(); 610 $has_hooked_blocks = ! empty( $hooked_blocks ) || has_filter( 'hooked_block_types' ); 609 611 $before_block_visitor = '_inject_theme_attribute_in_template_part_block'; 610 612 $after_block_visitor = null; 611 $hooked_blocks = get_hooked_blocks(); 612 if ( ! empty( $hooked_blocks ) || has_filter( 'hooked_block_types' )) {613 614 if ( $has_hooked_blocks ) { 613 615 $before_block_visitor = make_before_block_visitor( $hooked_blocks, $template, 'insert_hooked_blocks_and_set_ignored_hooked_blocks_metadata' ); 614 616 $after_block_visitor = make_after_block_visitor( $hooked_blocks, $template, 'insert_hooked_blocks_and_set_ignored_hooked_blocks_metadata' ); 615 617 } 616 $blocks = parse_blocks( $template->content ); 617 $template->content = traverse_and_serialize_blocks( $blocks, $before_block_visitor, $after_block_visitor ); 618 619 if ( 'wp_template_part' === $template->type && $has_hooked_blocks ) { 620 /** 621 * In order for hooked blocks to be inserted at positions first_child and last_child in a template part, 622 * we need to wrap its content a mock template part block and traverse it. 623 */ 624 $content = get_comment_delimited_block_content( 625 'core/template-part', 626 array(), 627 $template->content 628 ); 629 $content = traverse_and_serialize_blocks( parse_blocks( $content ), $before_block_visitor, $after_block_visitor ); 630 $template->content = remove_serialized_parent_block( $content ); 631 } else { 632 $template->content = traverse_and_serialize_blocks( 633 parse_blocks( $template->content ), 634 $before_block_visitor, 635 $after_block_visitor 636 ); 637 } 618 638 619 639 return $template; … … 999 1019 $before_block_visitor = make_before_block_visitor( $hooked_blocks, $template, 'insert_hooked_blocks_and_set_ignored_hooked_blocks_metadata' ); 1000 1020 $after_block_visitor = make_after_block_visitor( $hooked_blocks, $template, 'insert_hooked_blocks_and_set_ignored_hooked_blocks_metadata' ); 1001 $blocks = parse_blocks( $template->content ); 1002 $template->content = traverse_and_serialize_blocks( $blocks, $before_block_visitor, $after_block_visitor ); 1021 if ( 'wp_template_part' === $template->type ) { 1022 $existing_ignored_hooked_blocks = get_post_meta( $post->ID, '_wp_ignored_hooked_blocks', true ); 1023 $attributes = ! empty( $existing_ignored_hooked_blocks ) ? array( 'metadata' => array( 'ignoredHookedBlocks' => json_decode( $existing_ignored_hooked_blocks, true ) ) ) : array(); 1024 1025 /** 1026 * In order for hooked blocks to be inserted at positions first_child and last_child in a template part, 1027 * we need to wrap its content a mock template part block and traverse it. 1028 */ 1029 $content = get_comment_delimited_block_content( 1030 'core/template-part', 1031 $attributes, 1032 $template->content 1033 ); 1034 $content = traverse_and_serialize_blocks( parse_blocks( $content ), $before_block_visitor, $after_block_visitor ); 1035 $template->content = remove_serialized_parent_block( $content ); 1036 } else { 1037 $template->content = traverse_and_serialize_blocks( 1038 parse_blocks( $template->content ), 1039 $before_block_visitor, 1040 $after_block_visitor 1041 ); 1042 } 1003 1043 } 1004 1044 … … 1612 1652 } 1613 1653 1614 $changes->post_content = apply_block_hooks_to_content( $changes->post_content, $template, 'set_ignored_hooked_blocks_metadata' ); 1654 if ( 'wp_template_part' === $post->post_type ) { 1655 $attributes = array(); 1656 $existing_ignored_hooked_blocks = isset( $post->ID ) ? get_post_meta( $post->ID, '_wp_ignored_hooked_blocks', true ) : ''; 1657 1658 if ( ! empty( $existing_ignored_hooked_blocks ) ) { 1659 $attributes['metadata'] = array( 1660 'ignoredHookedBlocks' => json_decode( $existing_ignored_hooked_blocks, true ), 1661 ); 1662 } 1663 1664 $content = get_comment_delimited_block_content( 1665 'core/template-part', 1666 $attributes, 1667 $changes->post_content 1668 ); 1669 $content = apply_block_hooks_to_content( $content, $template, 'set_ignored_hooked_blocks_metadata' ); 1670 $changes->post_content = remove_serialized_parent_block( $content ); 1671 1672 $wrapper_block_markup = extract_serialized_parent_block( $content ); 1673 $wrapper_block = parse_blocks( $wrapper_block_markup )[0]; 1674 $ignored_hooked_blocks = $wrapper_block['attrs']['metadata']['ignoredHookedBlocks'] ?? array(); 1675 if ( ! empty( $ignored_hooked_blocks ) ) { 1676 if ( ! isset( $changes->meta_input ) ) { 1677 $changes->meta_input = array(); 1678 } 1679 $changes->meta_input['_wp_ignored_hooked_blocks'] = wp_json_encode( $ignored_hooked_blocks ); 1680 } 1681 } else { 1682 $changes->post_content = apply_block_hooks_to_content( $changes->post_content, $template, 'set_ignored_hooked_blocks_metadata' ); 1683 } 1615 1684 1616 1685 return $changes; -
trunk/src/wp-includes/blocks.php
r58578 r58614 1047 1047 1048 1048 /** 1049 * Accepts the serialized markup of a block and its inner blocks, and returns serialized markup of the wrapper block. 1050 * 1051 * @since 6.7.0 1052 * @access private 1053 * 1054 * @see remove_serialized_parent_block() 1055 * 1056 * @param string $serialized_block The serialized markup of a block and its inner blocks. 1057 * @return string The serialized markup of the wrapper block. 1058 */ 1059 function extract_serialized_parent_block( $serialized_block ) { 1060 $start = strpos( $serialized_block, '-->' ) + strlen( '-->' ); 1061 $end = strrpos( $serialized_block, '<!--' ); 1062 return substr( $serialized_block, 0, $start ) . substr( $serialized_block, $end ); 1063 } 1064 1065 /** 1049 1066 * Updates the wp_postmeta with the list of ignored hooked blocks where the inner blocks are stored as post content. 1050 1067 * Currently only supports `wp_navigation` post types. -
trunk/tests/phpunit/tests/block-templates/buildBlockTemplateResultFromFile.php
r57266 r58614 8 8 */ 9 9 class Tests_Block_Templates_BuildBlockTemplateResultFromFile extends WP_Block_Templates_UnitTestCase { 10 /** 11 * Tear down each test method. 12 * 13 * @since 6.7.0 14 */ 15 public function tear_down() { 16 $registry = WP_Block_Type_Registry::get_instance(); 17 18 if ( $registry->is_registered( 'tests/my-block' ) ) { 19 $registry->unregister( 'tests/my-block' ); 20 } 21 22 parent::tear_down(); 23 } 10 24 11 25 /** … … 179 193 $this->assertEmpty( $template->post_types ); 180 194 } 195 196 /** 197 * @ticket 60506 198 */ 199 public function test_should_inject_hooked_block_into_template_part() { 200 register_block_type( 201 'tests/my-block', 202 array( 203 'block_hooks' => array( 204 'core/paragraph' => 'after', 205 ), 206 ) 207 ); 208 209 $template_part = _build_block_template_result_from_file( 210 array( 211 'slug' => 'header', 212 'postTypes' => array( 'post' ), 213 'path' => DIR_TESTDATA . '/templates/template.html', 214 ), 215 'wp_template_part' 216 ); 217 $this->assertStringEndsWith( '<!-- wp:tests/my-block /-->', $template_part->content ); 218 } 219 220 /* 221 * @ticket 60506 222 * @ticket 60854 223 */ 224 public function test_should_injected_hooked_block_into_template_part_first_child() { 225 register_block_type( 226 'tests/my-block', 227 array( 228 'block_hooks' => array( 229 'core/template-part' => 'first_child', 230 ), 231 ) 232 ); 233 234 $template_part = _build_block_template_result_from_file( 235 array( 236 'slug' => 'header', 237 'postTypes' => array( 'post' ), 238 'path' => DIR_TESTDATA . '/templates/template.html', 239 ), 240 'wp_template_part' 241 ); 242 $this->assertStringStartsWith( '<!-- wp:tests/my-block /-->', $template_part->content ); 243 } 244 245 /* 246 * @ticket 60506 247 * @ticket 60854 248 */ 249 public function test_should_injected_hooked_block_into_template_part_last_child() { 250 register_block_type( 251 'tests/my-block', 252 array( 253 'block_hooks' => array( 254 'core/template-part' => 'last_child', 255 ), 256 ) 257 ); 258 259 $template_part = _build_block_template_result_from_file( 260 array( 261 'slug' => 'header', 262 'postTypes' => array( 'post' ), 263 'path' => DIR_TESTDATA . '/templates/template.html', 264 ), 265 'wp_template_part' 266 ); 267 $this->assertStringEndsWith( '<!-- wp:tests/my-block /-->', $template_part->content ); 268 } 181 269 } -
trunk/tests/phpunit/tests/block-templates/buildBlockTemplateResultFromPost.php
r57627 r58614 112 112 } 113 113 114 /* 115 * @ticket 59646 116 * @ticket 60506 117 * @ticket 60854 118 */ 119 public function test_should_injected_hooked_block_into_template_part_first_child() { 120 register_block_type( 121 'tests/my-block', 122 array( 123 'block_hooks' => array( 124 'core/template-part' => 'first_child', 125 ), 126 ) 127 ); 128 129 $template_part = _build_block_template_result_from_post( 130 self::$template_part_post, 131 'wp_template_part' 132 ); 133 $this->assertStringStartsWith( '<!-- wp:tests/my-block /-->', $template_part->content ); 134 } 135 136 /* 137 * @ticket 59646 138 * @ticket 60506 139 * @ticket 60854 140 */ 141 public function test_should_injected_hooked_block_into_template_part_last_child() { 142 register_block_type( 143 'tests/my-block', 144 array( 145 'block_hooks' => array( 146 'core/template-part' => 'last_child', 147 ), 148 ) 149 ); 150 151 $template_part = _build_block_template_result_from_post( 152 self::$template_part_post, 153 'wp_template_part' 154 ); 155 $this->assertStringEndsWith( '<!-- wp:tests/my-block /-->', $template_part->content ); 156 } 157 114 158 /** 115 159 * @ticket 59646 -
trunk/tests/phpunit/tests/block-templates/injectIgnoredHookedBlocksMetadataAttributes.php
r58042 r58614 18 18 unregister_block_type( 'tests/hooked-block' ); 19 19 } 20 delete_post_meta( self::$template_part_post->ID, '_wp_ignored_hooked_blocks' ); 20 21 21 22 parent::tear_down(); … … 39 40 inject_ignored_hooked_blocks_metadata_attributes( $changes ); 40 41 41 $args = $action->get_args(); 42 $anchor_block_type = end( $args )[2]; 43 $context = end( $args )[3]; 44 45 $this->assertSame( 'tests/anchor-block', $anchor_block_type ); 46 47 $this->assertInstanceOf( 'WP_Block_Template', $context ); 48 42 $args = $action->get_args(); 43 $relative_positions = array_column( $args, 1 ); 44 $anchor_block_types = array_column( $args, 2 ); 45 $contexts = array_column( $args, 3 ); 46 47 $this->assertSame( 48 array( 49 'before', 50 'after', 51 ), 52 $relative_positions, 53 'The relative positions passed to the hooked_block_types filter are incorrect.' 54 ); 55 56 $this->assertSame( 57 array( 58 'tests/anchor-block', 59 'tests/anchor-block', 60 ), 61 $anchor_block_types, 62 'The anchor block types passed to the hooked_block_types filter are incorrect.' 63 ); 64 65 $context = $contexts[0]; 66 $this->assertSame( 67 array_fill( 0, count( $contexts ), $context ), 68 $contexts, 69 'The context passed to the hooked_block_types filter should be the same for all calls.' 70 ); 49 71 $this->assertSame( 50 72 $changes->post_type, … … 70 92 /** 71 93 * @ticket 60754 94 * @ticket 60854 72 95 */ 73 96 public function test_hooked_block_types_filter_with_newly_created_template_part() { … … 86 109 inject_ignored_hooked_blocks_metadata_attributes( $changes ); 87 110 88 $args = $action->get_args(); 89 $anchor_block_type = end( $args )[2]; 90 $context = end( $args )[3]; 91 92 $this->assertSame( 'tests/anchor-block', $anchor_block_type ); 93 94 $this->assertInstanceOf( 'WP_Block_Template', $context ); 95 111 $args = $action->get_args(); 112 $relative_positions = array_column( $args, 1 ); 113 $anchor_block_types = array_column( $args, 2 ); 114 $contexts = array_column( $args, 3 ); 115 116 $this->assertSame( 117 array( 118 'before', 119 'after', 120 'first_child', 121 'before', 122 'after', 123 'last_child', 124 ), 125 $relative_positions, 126 'The relative positions passed to the hooked_block_types filter are incorrect.' 127 ); 128 129 $this->assertSame( 130 array( 131 'core/template-part', 132 'core/template-part', 133 'core/template-part', 134 'tests/anchor-block', 135 'tests/anchor-block', 136 'core/template-part', 137 ), 138 $anchor_block_types, 139 'The anchor block types passed to the hooked_block_types filter are incorrect.' 140 ); 141 142 $context = $contexts[0]; 143 $this->assertSame( 144 array_fill( 0, count( $contexts ), $context ), 145 $contexts, 146 'The context passed to the hooked_block_types filter should be the same for all calls.' 147 ); 148 $this->assertInstanceOf( 149 'WP_Block_Template', 150 $context, 151 'The context passed to the hooked_block_types filter is not an instance of WP_Block_Template.' 152 ); 96 153 $this->assertSame( 97 154 $changes->post_type, … … 141 198 inject_ignored_hooked_blocks_metadata_attributes( $changes ); 142 199 143 $args = $action->get_args(); 144 $anchor_block_type = end( $args )[2]; 145 $context = end( $args )[3]; 146 147 $this->assertSame( 'tests/anchor-block', $anchor_block_type ); 148 149 $this->assertInstanceOf( 'WP_Block_Template', $context ); 150 200 $args = $action->get_args(); 201 $relative_positions = array_column( $args, 1 ); 202 $anchor_block_types = array_column( $args, 2 ); 203 $contexts = array_column( $args, 3 ); 204 205 $this->assertSame( 206 array( 207 'before', 208 'after', 209 ), 210 $relative_positions, 211 'The relative positions passed to the hooked_block_types filter are incorrect.' 212 ); 213 214 $this->assertSame( 215 array( 216 'tests/anchor-block', 217 'tests/anchor-block', 218 ), 219 $anchor_block_types, 220 'The anchor block types passed to the hooked_block_types filter are incorrect.' 221 ); 222 223 $context = $contexts[0]; 224 $this->assertSame( 225 array_fill( 0, count( $contexts ), $context ), 226 $contexts, 227 'The context passed to the hooked_block_types filter should be the same for all calls.' 228 ); 151 229 $this->assertSame( 152 230 $changes->post_name, … … 182 260 /** 183 261 * @ticket 60754 262 * @ticket 60854 184 263 */ 185 264 public function test_hooked_block_types_filter_with_existing_template_part_file() { … … 202 281 inject_ignored_hooked_blocks_metadata_attributes( $changes ); 203 282 204 $args = $action->get_args(); 205 $anchor_block_type = end( $args )[2]; 206 $context = end( $args )[3]; 207 208 $this->assertSame( 'tests/anchor-block', $anchor_block_type ); 209 210 $this->assertInstanceOf( 'WP_Block_Template', $context ); 211 283 $args = $action->get_args(); 284 $relative_positions = array_column( $args, 1 ); 285 $anchor_block_types = array_column( $args, 2 ); 286 $contexts = array_column( $args, 3 ); 287 288 $this->assertSame( 289 array( 290 'before', 291 'after', 292 'first_child', 293 'before', 294 'after', 295 'last_child', 296 ), 297 $relative_positions, 298 'The relative positions passed to the hooked_block_types filter are incorrect.' 299 ); 300 301 $this->assertSame( 302 array( 303 'core/template-part', 304 'core/template-part', 305 'core/template-part', 306 'tests/anchor-block', 307 'tests/anchor-block', 308 'core/template-part', 309 ), 310 $anchor_block_types, 311 'The anchor block types passed to the hooked_block_types filter are incorrect.' 312 ); 313 314 $context = $contexts[0]; 315 $this->assertSame( 316 array_fill( 0, count( $contexts ), $context ), 317 $contexts, 318 'The context passed to the hooked_block_types filter should be the same for all calls.' 319 ); 320 $this->assertInstanceOf( 321 'WP_Block_Template', 322 $context, 323 'The context passed to the hooked_block_types filter is not an instance of WP_Block_Template.' 324 ); 212 325 $this->assertSame( 213 326 $changes->post_name, … … 260 373 inject_ignored_hooked_blocks_metadata_attributes( $changes ); 261 374 262 $args = $action->get_args(); 263 $anchor_block_type = end( $args )[2]; 264 $context = end( $args )[3]; 265 266 $this->assertSame( 'tests/anchor-block', $anchor_block_type ); 267 268 $this->assertInstanceOf( 'WP_Block_Template', $context ); 269 375 $args = $action->get_args(); 376 $relative_positions = array_column( $args, 1 ); 377 $anchor_block_types = array_column( $args, 2 ); 378 $contexts = array_column( $args, 3 ); 379 380 $this->assertSame( 381 array( 382 'before', 383 'after', 384 ), 385 $relative_positions, 386 'The relative positions passed to the hooked_block_types filter are incorrect.' 387 ); 388 389 $this->assertSame( 390 array( 391 'tests/anchor-block', 392 'tests/anchor-block', 393 ), 394 $anchor_block_types, 395 'The anchor block types passed to the hooked_block_types filter are incorrect.' 396 ); 397 398 $context = $contexts[0]; 399 $this->assertSame( 400 array_fill( 0, count( $contexts ), $context ), 401 $contexts, 402 'The context passed to the hooked_block_types filter should be the same for all calls.' 403 ); 270 404 $this->assertSame( 271 405 $changes->post_name, … … 303 437 /** 304 438 * @ticket 60754 439 * @ticket 60854 305 440 */ 306 441 public function test_hooked_block_types_filter_with_existing_template_part_post() { … … 319 454 inject_ignored_hooked_blocks_metadata_attributes( $changes ); 320 455 321 $args = $action->get_args(); 322 $anchor_block_type = end( $args )[2]; 323 $context = end( $args )[3]; 324 325 $this->assertSame( 'tests/anchor-block', $anchor_block_type ); 326 327 $this->assertInstanceOf( 'WP_Block_Template', $context ); 328 456 $args = $action->get_args(); 457 $relative_positions = array_column( $args, 1 ); 458 $anchor_block_types = array_column( $args, 2 ); 459 $contexts = array_column( $args, 3 ); 460 461 $this->assertSame( 462 array( 463 'before', 464 'after', 465 'first_child', 466 'before', 467 'after', 468 'last_child', 469 ), 470 $relative_positions, 471 'The relative positions passed to the hooked_block_types filter are incorrect.' 472 ); 473 474 $this->assertSame( 475 array( 476 'core/template-part', 477 'core/template-part', 478 'core/template-part', 479 'tests/anchor-block', 480 'tests/anchor-block', 481 'core/template-part', 482 ), 483 $anchor_block_types, 484 'The anchor block types passed to the hooked_block_types filter are incorrect.' 485 ); 486 487 $context = $contexts[0]; 488 $this->assertSame( 489 array_fill( 0, count( $contexts ), $context ), 490 $contexts, 491 'The context passed to the hooked_block_types filter should be the same for all calls.' 492 ); 493 $this->assertInstanceOf( 494 'WP_Block_Template', 495 $context, 496 'The context passed to the hooked_block_types filter is not an instance of WP_Block_Template.' 497 ); 329 498 $this->assertSame( 330 499 $changes->post_name, … … 420 589 ); 421 590 } 591 592 /** 593 * @ticket 60854 594 */ 595 public function test_inject_ignored_hooked_blocks_metadata_attributes_into_template_part_postmeta() { 596 register_block_type( 597 'tests/hooked-block', 598 array( 599 'block_hooks' => array( 600 'core/template-part' => 'last_child', 601 ), 602 ) 603 ); 604 605 $id = self::TEST_THEME . '//' . 'my_template_part'; 606 $template = get_block_template( $id, 'wp_template_part' ); 607 608 $changes = new stdClass(); 609 $changes->ID = $template->wp_id; 610 $changes->post_content = '<!-- wp:tests/anchor-block -->Hello<!-- /wp:tests/anchor-block -->'; 611 612 $post = inject_ignored_hooked_blocks_metadata_attributes( $changes ); 613 $this->assertSame( 614 array( 'tests/hooked-block' ), 615 json_decode( $post->meta_input['_wp_ignored_hooked_blocks'], true ), 616 'The hooked block was not injected into the wp_template_part\'s _wp_ignored_hooked_blocks postmeta.' 617 ); 618 $this->assertSame( 619 $changes->post_content, 620 $post->post_content, 621 'The template part\'s post content was modified.' 622 ); 623 } 422 624 }
Note: See TracChangeset
for help on using the changeset viewer.