[ Index ] |
PHP Cross Reference of WordPress Trunk (Updated Daily) |
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * Blocks API: WP_Block_Patterns_Registry class 4 * 5 * @package WordPress 6 * @subpackage Blocks 7 * @since 5.5.0 8 */ 9 10 /** 11 * Class used for interacting with block patterns. 12 * 13 * @since 5.5.0 14 */ 15 #[AllowDynamicProperties] 16 final class WP_Block_Patterns_Registry { 17 /** 18 * Registered block patterns array. 19 * 20 * @since 5.5.0 21 * @var array[] 22 */ 23 private $registered_patterns = array(); 24 25 /** 26 * Patterns registered outside the `init` action. 27 * 28 * @since 6.0.0 29 * @var array[] 30 */ 31 private $registered_patterns_outside_init = array(); 32 33 /** 34 * Container for the main instance of the class. 35 * 36 * @since 5.5.0 37 * @var WP_Block_Patterns_Registry|null 38 */ 39 private static $instance = null; 40 41 /** 42 * Registers a block pattern. 43 * 44 * @since 5.5.0 45 * @since 5.8.0 Added support for the `blockTypes` property. 46 * @since 6.1.0 Added support for the `postTypes` property. 47 * @since 6.2.0 Added support for the `templateTypes` property. 48 * @since 6.5.0 Added support for the `filePath` property. 49 * 50 * @param string $pattern_name Block pattern name including namespace. 51 * @param array $pattern_properties { 52 * List of properties for the block pattern. 53 * 54 * @type string $title Required. A human-readable title for the pattern. 55 * @type string $content Optional. Block HTML markup for the pattern. 56 * If not provided, the content will be retrieved from the `filePath` if set. 57 * If both `content` and `filePath` are not set, the pattern will not be registered. 58 * @type string $description Optional. Visually hidden text used to describe the pattern 59 * in the inserter. A description is optional, but is strongly 60 * encouraged when the title does not fully describe what the 61 * pattern does. The description will help users discover the 62 * pattern while searching. 63 * @type int $viewportWidth Optional. The intended width of the pattern to allow for a scaled 64 * preview within the pattern inserter. 65 * @type bool $inserter Optional. Determines whether the pattern is visible in inserter. 66 * To hide a pattern so that it can only be inserted programmatically, 67 * set this to false. Default true. 68 * @type string[] $categories Optional. A list of registered pattern categories used to group 69 * block patterns. Block patterns can be shown on multiple categories. 70 * A category must be registered separately in order to be used here. 71 * @type string[] $keywords Optional. A list of aliases or keywords that help users discover 72 * the pattern while searching. 73 * @type string[] $blockTypes Optional. A list of block names including namespace that could use 74 * the block pattern in certain contexts (placeholder, transforms). 75 * The block pattern is available in the block editor inserter 76 * regardless of this list of block names. 77 * Certain blocks support further specificity besides the block name 78 * (e.g. for `core/template-part` you can specify areas 79 * like `core/template-part/header` or `core/template-part/footer`). 80 * @type string[] $postTypes Optional. An array of post types that the pattern is restricted 81 * to be used with. The pattern will only be available when editing one 82 * of the post types passed on the array. For all the other post types 83 * not part of the array the pattern is not available at all. 84 * @type string[] $templateTypes Optional. An array of template types where the pattern fits. 85 * @type string $filePath Optional. The full path to the file containing the block pattern content. 86 * } 87 * @return bool True if the pattern was registered with success and false otherwise. 88 */ 89 public function register( $pattern_name, $pattern_properties ) { 90 if ( ! isset( $pattern_name ) || ! is_string( $pattern_name ) ) { 91 _doing_it_wrong( 92 __METHOD__, 93 __( 'Pattern name must be a string.' ), 94 '5.5.0' 95 ); 96 return false; 97 } 98 99 if ( ! isset( $pattern_properties['title'] ) || ! is_string( $pattern_properties['title'] ) ) { 100 _doing_it_wrong( 101 __METHOD__, 102 __( 'Pattern title must be a string.' ), 103 '5.5.0' 104 ); 105 return false; 106 } 107 108 if ( ! isset( $pattern_properties['filePath'] ) ) { 109 if ( ! isset( $pattern_properties['content'] ) || ! is_string( $pattern_properties['content'] ) ) { 110 _doing_it_wrong( 111 __METHOD__, 112 __( 'Pattern content must be a string.' ), 113 '5.5.0' 114 ); 115 return false; 116 } 117 } 118 119 $pattern = array_merge( 120 $pattern_properties, 121 array( 'name' => $pattern_name ) 122 ); 123 124 $this->registered_patterns[ $pattern_name ] = $pattern; 125 126 // If the pattern is registered inside an action other than `init`, store it 127 // also to a dedicated array. Used to detect deprecated registrations inside 128 // `admin_init` or `current_screen`. 129 if ( current_action() && 'init' !== current_action() ) { 130 $this->registered_patterns_outside_init[ $pattern_name ] = $pattern; 131 } 132 133 return true; 134 } 135 136 /** 137 * Unregisters a block pattern. 138 * 139 * @since 5.5.0 140 * 141 * @param string $pattern_name Block pattern name including namespace. 142 * @return bool True if the pattern was unregistered with success and false otherwise. 143 */ 144 public function unregister( $pattern_name ) { 145 if ( ! $this->is_registered( $pattern_name ) ) { 146 _doing_it_wrong( 147 __METHOD__, 148 /* translators: %s: Pattern name. */ 149 sprintf( __( 'Pattern "%s" not found.' ), $pattern_name ), 150 '5.5.0' 151 ); 152 return false; 153 } 154 155 unset( $this->registered_patterns[ $pattern_name ] ); 156 unset( $this->registered_patterns_outside_init[ $pattern_name ] ); 157 158 return true; 159 } 160 161 /** 162 * Prepares the content of a block pattern. If hooked blocks are registered, they get injected into the pattern, 163 * when they met the defined criteria. 164 * 165 * @since 6.4.0 166 * 167 * @param array $pattern Registered pattern properties. 168 * @param array $hooked_blocks The list of hooked blocks. 169 * @return string The content of the block pattern. 170 */ 171 private function prepare_content( $pattern, $hooked_blocks ) { 172 $content = $pattern['content']; 173 174 $before_block_visitor = '_inject_theme_attribute_in_template_part_block'; 175 $after_block_visitor = null; 176 if ( ! empty( $hooked_blocks ) || has_filter( 'hooked_block_types' ) ) { 177 $before_block_visitor = make_before_block_visitor( $hooked_blocks, $pattern ); 178 $after_block_visitor = make_after_block_visitor( $hooked_blocks, $pattern ); 179 } 180 $blocks = parse_blocks( $content ); 181 $content = traverse_and_serialize_blocks( $blocks, $before_block_visitor, $after_block_visitor ); 182 183 return $content; 184 } 185 186 /** 187 * Retrieves the content of a registered block pattern. 188 * 189 * @since 6.5.0 190 * 191 * @param string $pattern_name Block pattern name including namespace. 192 * @param bool $outside_init_only Optional. Return only patterns registered outside the `init` action. Default false. 193 * @return string The content of the block pattern. 194 */ 195 private function get_content( $pattern_name, $outside_init_only = false ) { 196 if ( $outside_init_only ) { 197 $patterns = &$this->registered_patterns_outside_init; 198 } else { 199 $patterns = &$this->registered_patterns; 200 } 201 if ( ! isset( $patterns[ $pattern_name ]['content'] ) && isset( $patterns[ $pattern_name ]['filePath'] ) ) { 202 ob_start(); 203 include $patterns[ $pattern_name ]['filePath']; 204 $patterns[ $pattern_name ]['content'] = ob_get_clean(); 205 unset( $patterns[ $pattern_name ]['filePath'] ); 206 } 207 return $patterns[ $pattern_name ]['content']; 208 } 209 210 /** 211 * Retrieves an array containing the properties of a registered block pattern. 212 * 213 * @since 5.5.0 214 * 215 * @param string $pattern_name Block pattern name including namespace. 216 * @return array Registered pattern properties. 217 */ 218 public function get_registered( $pattern_name ) { 219 if ( ! $this->is_registered( $pattern_name ) ) { 220 return null; 221 } 222 223 $pattern = $this->registered_patterns[ $pattern_name ]; 224 $pattern['content'] = $this->get_content( $pattern_name ); 225 $pattern['content'] = $this->prepare_content( $pattern, get_hooked_blocks() ); 226 227 return $pattern; 228 } 229 230 /** 231 * Retrieves all registered block patterns. 232 * 233 * @since 5.5.0 234 * 235 * @param bool $outside_init_only Return only patterns registered outside the `init` action. 236 * @return array[] Array of arrays containing the registered block patterns properties, 237 * and per style. 238 */ 239 public function get_all_registered( $outside_init_only = false ) { 240 $patterns = $outside_init_only 241 ? $this->registered_patterns_outside_init 242 : $this->registered_patterns; 243 $hooked_blocks = get_hooked_blocks(); 244 245 foreach ( $patterns as $index => $pattern ) { 246 $pattern['content'] = $this->get_content( $pattern['name'], $outside_init_only ); 247 $patterns[ $index ]['content'] = $this->prepare_content( $pattern, $hooked_blocks ); 248 } 249 250 return array_values( $patterns ); 251 } 252 253 /** 254 * Checks if a block pattern is registered. 255 * 256 * @since 5.5.0 257 * 258 * @param string $pattern_name Block pattern name including namespace. 259 * @return bool True if the pattern is registered, false otherwise. 260 */ 261 public function is_registered( $pattern_name ) { 262 return isset( $this->registered_patterns[ $pattern_name ] ); 263 } 264 265 public function __wakeup() { 266 if ( ! $this->registered_patterns ) { 267 return; 268 } 269 if ( ! is_array( $this->registered_patterns ) ) { 270 throw new UnexpectedValueException(); 271 } 272 foreach ( $this->registered_patterns as $value ) { 273 if ( ! is_array( $value ) ) { 274 throw new UnexpectedValueException(); 275 } 276 } 277 $this->registered_patterns_outside_init = array(); 278 } 279 280 /** 281 * Utility method to retrieve the main instance of the class. 282 * 283 * The instance will be created if it does not exist yet. 284 * 285 * @since 5.5.0 286 * 287 * @return WP_Block_Patterns_Registry The main instance. 288 */ 289 public static function get_instance() { 290 if ( null === self::$instance ) { 291 self::$instance = new self(); 292 } 293 294 return self::$instance; 295 } 296 } 297 298 /** 299 * Registers a new block pattern. 300 * 301 * @since 5.5.0 302 * 303 * @param string $pattern_name Block pattern name including namespace. 304 * @param array $pattern_properties List of properties for the block pattern. 305 * See WP_Block_Patterns_Registry::register() for accepted arguments. 306 * @return bool True if the pattern was registered with success and false otherwise. 307 */ 308 function register_block_pattern( $pattern_name, $pattern_properties ) { 309 return WP_Block_Patterns_Registry::get_instance()->register( $pattern_name, $pattern_properties ); 310 } 311 312 /** 313 * Unregisters a block pattern. 314 * 315 * @since 5.5.0 316 * 317 * @param string $pattern_name Block pattern name including namespace. 318 * @return bool True if the pattern was unregistered with success and false otherwise. 319 */ 320 function unregister_block_pattern( $pattern_name ) { 321 return WP_Block_Patterns_Registry::get_instance()->unregister( $pattern_name ); 322 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated : Fri Apr 19 08:20:01 2024 | Cross-referenced by PHPXref |