Changeset 56649
- Timestamp:
- 09/21/2023 04:16:05 PM (12 months ago)
- Location:
- trunk
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/wp-includes/block-template-utils.php
r56644 r56649 602 602 } 603 603 604 $blocks = parse_blocks( $template_content ); 605 $template->content = traverse_and_serialize_blocks( $blocks, '_inject_theme_attribute_in_template_part_block' ); 604 $blocks = parse_blocks( $template_content ); 605 $before_block_visitor = make_before_block_visitor( $template ); 606 $after_block_visitor = make_after_block_visitor( $template ); 607 $template->content = traverse_and_serialize_blocks( $blocks, $before_block_visitor, $after_block_visitor ); 606 608 607 609 return $template; -
trunk/src/wp-includes/blocks.php
r56644 r56649 752 752 $hooked_blocks = array(); 753 753 foreach ( $block_types as $block_type ) { 754 if ( ! property_exists( $block_type, 'block_hooks' ) || ! is_array( $block_type->block_hooks ) ) { 755 continue; 756 } 754 757 foreach ( $block_type->block_hooks as $anchor_block_type => $relative_position ) { 755 758 if ( $anchor_block_type === $name ) { … … 759 762 } 760 763 return $hooked_blocks; 764 } 765 766 /** 767 * Returns a function that injects the theme attribute into, and hooked blocks before, a given block. 768 * 769 * The returned function can be used as `$pre_callback` argument to `traverse_and_serialize_block(s)`, 770 * where it will inject the `theme` attribute into all Template Part blocks, and prepend the markup for 771 * any blocks hooked `before` the given block and as its parent's `first_child`, respectively. 772 * 773 * @since 6.4.0 774 * @access private 775 * 776 * @param WP_Block_Template|array $context A block template, template part, or pattern that the blocks belong to. 777 * @return callable A function that returns the serialized markup for the given block, 778 * including the markup for any hooked blocks before it. 779 */ 780 function make_before_block_visitor( $context ) { 781 /** 782 * Injects hooked blocks before the given block, injects the `theme` attribute into Template Part blocks, and returns the serialized markup. 783 * 784 * If the current block is a Template Part block, inject the `theme` attribute. 785 * Furthermore, prepend the markup for any blocks hooked `before` the given block and as its parent's 786 * `first_child`, respectively, to the serialized markup for the given block. 787 * 788 * @param array $block The block to inject the theme attribute into, and hooked blocks before. 789 * @param array $parent The parent block of the given block. 790 * @param array $prev The previous sibling block of the given block. 791 * @return string The serialized markup for the given block, with the markup for any hooked blocks prepended to it. 792 */ 793 return function( &$block, $parent = null, $prev = null ) use ( $context ) { 794 _inject_theme_attribute_in_template_part_block( $block ); 795 796 $markup = ''; 797 798 if ( $parent && ! $prev ) { 799 // Candidate for first-child insertion. 800 $hooked_blocks_for_parent = get_hooked_blocks( $parent['blockName'] ); 801 foreach ( $hooked_blocks_for_parent as $hooked_block_type => $relative_position ) { 802 if ( 'first_child' === $relative_position ) { 803 $hooked_block_markup = get_comment_delimited_block_content( $hooked_block_type, array(), '' ); 804 /** This filter is documented in wp-includes/blocks.php */ 805 $markup .= apply_filters( 'inject_hooked_block_markup', $hooked_block_markup, $hooked_block_type, $relative_position, $parent, $context ); 806 } 807 } 808 } 809 810 $hooked_blocks = get_hooked_blocks( $block['blockName'] ); 811 foreach ( $hooked_blocks as $hooked_block_type => $relative_position ) { 812 if ( 'before' === $relative_position ) { 813 $hooked_block_markup = get_comment_delimited_block_content( $hooked_block_type, array(), '' ); 814 /** 815 * Filters the serialized markup of a hooked block. 816 * 817 * @since 6.4.0 818 * 819 * @param string $hooked_block_markup The serialized markup of the hooked block. 820 * @param string $hooked_block_type The type of the hooked block. 821 * @param string $relative_position The relative position of the hooked block. 822 * Can be one of 'before', 'after', 'first_child', or 'last_child'. 823 * @param array $block The anchor block. 824 * @param WP_Block_Template|array $context The block template, template part, or pattern that the anchor block belongs to. 825 */ 826 $markup .= apply_filters( 'inject_hooked_block_markup', $hooked_block_markup, $hooked_block_type, $relative_position, $block, $context ); 827 } 828 } 829 830 return $markup; 831 }; 832 } 833 834 /** 835 * Returns a function that injects the hooked blocks after a given block. 836 * 837 * The returned function can be used as `$post_callback` argument to `traverse_and_serialize_block(s)`, 838 * where it will append the markup for any blocks hooked `after` the given block and as its parent's 839 * `last_child`, respectively. 840 * 841 * @since 6.4.0 842 * @access private 843 * 844 * @param WP_Block_Template|array $context A block template, template part, or pattern that the blocks belong to. 845 * @return callable A function that returns the serialized markup for the given block, 846 * including the markup for any hooked blocks after it. 847 */ 848 function make_after_block_visitor( $context ) { 849 /** 850 * Injects hooked blocks after the given block, and returns the serialized markup. 851 * 852 * Append the markup for any blocks hooked `after` the given block and as its parent's 853 * `last_child`, respectively, to the serialized markup for the given block. 854 * 855 * @param array $block The block to inject the hooked blocks after. 856 * @param array $parent The parent block of the given block. 857 * @param array $next The next sibling block of the given block. 858 * @return string The serialized markup for the given block, with the markup for any hooked blocks appended to it. 859 */ 860 return function( &$block, $parent = null, $next = null ) use ( $context ) { 861 $markup = ''; 862 863 $hooked_blocks = get_hooked_blocks( $block['blockName'] ); 864 foreach ( $hooked_blocks as $hooked_block_type => $relative_position ) { 865 if ( 'after' === $relative_position ) { 866 $hooked_block_markup = get_comment_delimited_block_content( $hooked_block_type, array(), '' ); 867 /** This filter is documented in wp-includes/blocks.php */ 868 $markup .= apply_filters( 'inject_hooked_block_markup', $hooked_block_markup, $hooked_block_type, $relative_position, $block, $context ); 869 } 870 } 871 872 if ( $parent && ! $next ) { 873 // Candidate for last-child insertion. 874 $hooked_blocks_for_parent = get_hooked_blocks( $parent['blockName'] ); 875 foreach ( $hooked_blocks_for_parent as $hooked_block_type => $relative_position ) { 876 if ( 'last_child' === $relative_position ) { 877 $hooked_block_markup = get_comment_delimited_block_content( $hooked_block_type, array(), '' ); 878 /** This filter is documented in wp-includes/blocks.php */ 879 $markup .= apply_filters( 'inject_hooked_block_markup', $hooked_block_markup, $hooked_block_type, $relative_position, $parent, $context ); 880 } 881 } 882 } 883 884 return $markup; 885 }; 761 886 } 762 887 -
trunk/src/wp-includes/class-wp-block-patterns-registry.php
r55693 r56649 166 166 } 167 167 168 return $this->registered_patterns[ $pattern_name ]; 168 $pattern = $this->registered_patterns[ $pattern_name ]; 169 $blocks = parse_blocks( $pattern['content'] ); 170 $before_block_visitor = make_before_block_visitor( $pattern ); 171 $after_block_visitor = make_after_block_visitor( $pattern ); 172 $pattern['content'] = traverse_and_serialize_blocks( $blocks, $before_block_visitor, $after_block_visitor ); 173 174 return $pattern; 169 175 } 170 176 … … 179 185 */ 180 186 public function get_all_registered( $outside_init_only = false ) { 181 returnarray_values(187 $patterns = array_values( 182 188 $outside_init_only 183 189 ? $this->registered_patterns_outside_init 184 190 : $this->registered_patterns 185 191 ); 192 193 foreach ( $patterns as $index => $pattern ) { 194 $blocks = parse_blocks( $pattern['content'] ); 195 $before_block_visitor = make_before_block_visitor( $pattern ); 196 $after_block_visitor = make_after_block_visitor( $pattern ); 197 $patterns[ $index ]['content'] = traverse_and_serialize_blocks( $blocks, $before_block_visitor, $after_block_visitor ); 198 } 199 return $patterns; 186 200 } 187 201 -
trunk/tests/phpunit/tests/blocks/serialize.php
r56644 r56649 63 63 * @covers ::traverse_and_serialize_blocks 64 64 */ 65 public function test_traverse_and_serialize_blocks () {65 public function test_traverse_and_serialize_blocks_pre_callback_modifies_current_block() { 66 66 $markup = "<!-- wp:outer --><!-- wp:inner {\"key\":\"value\"} -->Example.<!-- /wp:inner -->\n\nExample.\n\n<!-- wp:void /--><!-- /wp:outer -->"; 67 67 $blocks = parse_blocks( $markup ); … … 82 82 83 83 /** 84 * @ticket 59313 85 * 86 * @covers ::traverse_and_serialize_blocks 87 */ 88 public function test_traverse_and_serialize_blocks_pre_callback_prepends_to_inner_block() { 89 $markup = "<!-- wp:outer --><!-- wp:inner {\"key\":\"value\"} -->Example.<!-- /wp:inner -->\n\nExample.\n\n<!-- wp:void /--><!-- /wp:outer -->"; 90 $blocks = parse_blocks( $markup ); 91 92 $actual = traverse_and_serialize_blocks( $blocks, array( __CLASS__, 'insert_next_to_inner_block_callback' ) ); 93 94 $this->assertSame( 95 "<!-- wp:outer --><!-- wp:tests/inserted-block /--><!-- wp:inner {\"key\":\"value\"} -->Example.<!-- /wp:inner -->\n\nExample.\n\n<!-- wp:void /--><!-- /wp:outer -->", 96 $actual 97 ); 98 } 99 100 /** 101 * @ticket 59313 102 * 103 * @covers ::traverse_and_serialize_blocks 104 */ 105 public function test_traverse_and_serialize_blocks_post_callback_appends_to_inner_block() { 106 $markup = "<!-- wp:outer --><!-- wp:inner {\"key\":\"value\"} -->Example.<!-- /wp:inner -->\n\nExample.\n\n<!-- wp:void /--><!-- /wp:outer -->"; 107 $blocks = parse_blocks( $markup ); 108 109 $actual = traverse_and_serialize_blocks( $blocks, null, array( __CLASS__, 'insert_next_to_inner_block_callback' ) ); 110 111 $this->assertSame( 112 "<!-- wp:outer --><!-- wp:inner {\"key\":\"value\"} -->Example.<!-- /wp:inner --><!-- wp:tests/inserted-block /-->\n\nExample.\n\n<!-- wp:void /--><!-- /wp:outer -->", 113 $actual 114 ); 115 } 116 117 public static function insert_next_to_inner_block_callback( $block ) { 118 if ( 'core/inner' !== $block['blockName'] ) { 119 return ''; 120 } 121 122 return get_comment_delimited_block_content( 'tests/inserted-block', array(), '' ); 123 } 124 125 /** 126 * @ticket 59313 127 * 128 * @covers ::traverse_and_serialize_blocks 129 */ 130 public function test_traverse_and_serialize_blocks_pre_callback_prepends_to_child_blocks() { 131 $markup = "<!-- wp:outer --><!-- wp:inner {\"key\":\"value\"} -->Example.<!-- /wp:inner -->\n\nExample.\n\n<!-- wp:void /--><!-- /wp:outer -->"; 132 $blocks = parse_blocks( $markup ); 133 134 $actual = traverse_and_serialize_blocks( $blocks, array( __CLASS__, 'insert_next_to_child_blocks_callback' ) ); 135 136 $this->assertSame( 137 "<!-- wp:outer --><!-- wp:tests/inserted-block {\"parent\":\"core/outer\"} /--><!-- wp:inner {\"key\":\"value\"} -->Example.<!-- /wp:inner -->\n\nExample.\n\n<!-- wp:tests/inserted-block {\"parent\":\"core/outer\"} /--><!-- wp:void /--><!-- /wp:outer -->", 138 $actual 139 ); 140 } 141 142 /** 143 * @ticket 59313 144 * 145 * @covers ::traverse_and_serialize_blocks 146 */ 147 public function test_traverse_and_serialize_blocks_post_callback_appends_to_child_blocks() { 148 $markup = "<!-- wp:outer --><!-- wp:inner {\"key\":\"value\"} -->Example.<!-- /wp:inner -->\n\nExample.\n\n<!-- wp:void /--><!-- /wp:outer -->"; 149 $blocks = parse_blocks( $markup ); 150 151 $actual = traverse_and_serialize_blocks( $blocks, null, array( __CLASS__, 'insert_next_to_child_blocks_callback' ) ); 152 153 $this->assertSame( 154 "<!-- wp:outer --><!-- wp:inner {\"key\":\"value\"} -->Example.<!-- /wp:inner --><!-- wp:tests/inserted-block {\"parent\":\"core/outer\"} /-->\n\nExample.\n\n<!-- wp:void /--><!-- wp:tests/inserted-block {\"parent\":\"core/outer\"} /--><!-- /wp:outer -->", 155 $actual 156 ); 157 } 158 159 public static function insert_next_to_child_blocks_callback( $block, $parent_block ) { 160 if ( ! isset( $parent_block ) ) { 161 return ''; 162 } 163 164 return get_comment_delimited_block_content( 165 'tests/inserted-block', 166 array( 167 'parent' => $parent_block['blockName'], 168 ), 169 '' 170 ); 171 } 172 173 /** 174 * @ticket 59313 175 * 176 * @covers ::traverse_and_serialize_blocks 177 */ 178 public function test_traverse_and_serialize_blocks_pre_callback_prepends_if_prev_block() { 179 $markup = "<!-- wp:outer --><!-- wp:inner {\"key\":\"value\"} -->Example.<!-- /wp:inner -->\n\nExample.\n\n<!-- wp:void /--><!-- /wp:outer -->"; 180 $blocks = parse_blocks( $markup ); 181 182 $actual = traverse_and_serialize_blocks( $blocks, array( __CLASS__, 'insert_next_to_if_prev_or_next_block_callback' ) ); 183 184 $this->assertSame( 185 "<!-- wp:outer --><!-- wp:inner {\"key\":\"value\"} -->Example.<!-- /wp:inner -->\n\nExample.\n\n<!-- wp:tests/inserted-block {\"prev_or_next\":\"core/inner\"} /--><!-- wp:void /--><!-- /wp:outer -->", 186 $actual 187 ); 188 } 189 190 /** 191 * @ticket 59313 192 * 193 * @covers ::traverse_and_serialize_blocks 194 */ 195 public function test_traverse_and_serialize_blocks_post_callback_appends_if_prev_block() { 196 $markup = "<!-- wp:outer --><!-- wp:inner {\"key\":\"value\"} -->Example.<!-- /wp:inner -->\n\nExample.\n\n<!-- wp:void /--><!-- /wp:outer -->"; 197 $blocks = parse_blocks( $markup ); 198 199 $actual = traverse_and_serialize_blocks( $blocks, null, array( __CLASS__, 'insert_next_to_if_prev_or_next_block_callback' ) ); 200 201 $this->assertSame( 202 "<!-- wp:outer --><!-- wp:inner {\"key\":\"value\"} -->Example.<!-- /wp:inner --><!-- wp:tests/inserted-block {\"prev_or_next\":\"core/void\"} /-->\n\nExample.\n\n<!-- wp:void /--><!-- /wp:outer -->", 203 $actual 204 ); 205 } 206 207 public static function insert_next_to_if_prev_or_next_block_callback( $block, $parent_block, $prev_or_next ) { 208 if ( ! isset( $prev_or_next ) ) { 209 return ''; 210 } 211 212 return get_comment_delimited_block_content( 213 'tests/inserted-block', 214 array( 215 'prev_or_next' => $prev_or_next['blockName'], 216 ), 217 '' 218 ); 219 } 220 221 /** 84 222 * @ticket 59327 85 223 * @ticket 59412 -
trunk/tests/phpunit/tests/rest-api/rest-block-type-controller.php
r56588 r56649 63 63 self::delete_user( self::$subscriber_id ); 64 64 unregister_block_type( 'fake/test' ); 65 unregister_block_type( 'fake/invalid' ); 66 unregister_block_type( 'fake/false' ); 65 67 } 66 68
Note: See TracChangeset
for help on using the changeset viewer.