| [ Index ] |
PHP Cross Reference of WordPress Trunk (Updated Daily) |
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * Register the block patterns and block patterns categories 4 * 5 * @package WordPress 6 * @since 5.5.0 7 */ 8 9 add_theme_support( 'core-block-patterns' ); 10 11 /** 12 * Registers a new block pattern. 13 * 14 * @since 5.5.0 15 * 16 * @param string $pattern_name Block pattern name including namespace. 17 * @param array $pattern_properties List of properties for the block pattern. 18 * See WP_Block_Patterns_Registry::register() for accepted arguments. 19 * @return bool True if the pattern was registered with success and false otherwise. 20 */ 21 function register_block_pattern( $pattern_name, $pattern_properties ) { 22 return WP_Block_Patterns_Registry::get_instance()->register( $pattern_name, $pattern_properties ); 23 } 24 25 /** 26 * Unregisters a block pattern. 27 * 28 * @since 5.5.0 29 * 30 * @param string $pattern_name Block pattern name including namespace. 31 * @return bool True if the pattern was unregistered with success and false otherwise. 32 */ 33 function unregister_block_pattern( $pattern_name ) { 34 return WP_Block_Patterns_Registry::get_instance()->unregister( $pattern_name ); 35 } 36 37 /** 38 * Registers a new pattern category. 39 * 40 * @since 5.5.0 41 * 42 * @param string $category_name Pattern category name including namespace. 43 * @param array $category_properties List of properties for the block pattern. 44 * See WP_Block_Pattern_Categories_Registry::register() for 45 * accepted arguments. 46 * @return bool True if the pattern category was registered with success and false otherwise. 47 */ 48 function register_block_pattern_category( $category_name, $category_properties ) { 49 return WP_Block_Pattern_Categories_Registry::get_instance()->register( $category_name, $category_properties ); 50 } 51 52 /** 53 * Unregisters a pattern category. 54 * 55 * @since 5.5.0 56 * 57 * @param string $category_name Pattern category name including namespace. 58 * @return bool True if the pattern category was unregistered with success and false otherwise. 59 */ 60 function unregister_block_pattern_category( $category_name ) { 61 return WP_Block_Pattern_Categories_Registry::get_instance()->unregister( $category_name ); 62 } 63 64 /** 65 * Registers the core block patterns and categories. 66 * 67 * @since 5.5.0 68 * @since 6.3.0 Added source to core block patterns. 69 * @access private 70 */ 71 function _register_core_block_patterns_and_categories() { 72 $should_register_core_patterns = get_theme_support( 'core-block-patterns' ); 73 74 if ( $should_register_core_patterns ) { 75 $core_block_patterns = array( 76 'query-standard-posts', 77 'query-medium-posts', 78 'query-small-posts', 79 'query-grid-posts', 80 'query-large-title-posts', 81 'query-offset-posts', 82 'navigation-overlay', 83 'navigation-overlay-black-bg', 84 'navigation-overlay-accent-bg', 85 'navigation-overlay-centered', 86 'navigation-overlay-centered-with-extras', 87 ); 88 89 foreach ( $core_block_patterns as $core_block_pattern ) { 90 $pattern = require __DIR__ . '/block-patterns/' . $core_block_pattern . '.php'; 91 $pattern['source'] = 'core'; 92 register_block_pattern( 'core/' . $core_block_pattern, $pattern ); 93 } 94 } 95 96 register_block_pattern_category( 97 'banner', 98 array( 99 'label' => _x( 'Banners', 'Block pattern category' ), 100 'description' => __( 'Bold sections designed to showcase key content.' ), 101 ) 102 ); 103 register_block_pattern_category( 104 'buttons', 105 array( 106 'label' => _x( 'Buttons', 'Block pattern category' ), 107 'description' => __( 'Patterns that contain buttons and call to actions.' ), 108 ) 109 ); 110 register_block_pattern_category( 111 'columns', 112 array( 113 'label' => _x( 'Columns', 'Block pattern category' ), 114 'description' => __( 'Multi-column patterns with more complex layouts.' ), 115 ) 116 ); 117 register_block_pattern_category( 118 'text', 119 array( 120 'label' => _x( 'Text', 'Block pattern category' ), 121 'description' => __( 'Patterns containing mostly text.' ), 122 ) 123 ); 124 register_block_pattern_category( 125 'query', 126 array( 127 'label' => _x( 'Posts', 'Block pattern category' ), 128 'description' => __( 'Display your latest posts in lists, grids or other layouts.' ), 129 ) 130 ); 131 register_block_pattern_category( 132 'featured', 133 array( 134 'label' => _x( 'Featured', 'Block pattern category' ), 135 'description' => __( 'A set of high quality curated patterns.' ), 136 ) 137 ); 138 register_block_pattern_category( 139 'call-to-action', 140 array( 141 'label' => _x( 'Call to action', 'Block pattern category' ), 142 'description' => __( 'Sections whose purpose is to trigger a specific action.' ), 143 ) 144 ); 145 register_block_pattern_category( 146 'team', 147 array( 148 'label' => _x( 'Team', 'Block pattern category' ), 149 'description' => __( 'A variety of designs to display your team members.' ), 150 ) 151 ); 152 register_block_pattern_category( 153 'testimonials', 154 array( 155 'label' => _x( 'Testimonials', 'Block pattern category' ), 156 'description' => __( 'Share reviews and feedback about your brand/business.' ), 157 ) 158 ); 159 register_block_pattern_category( 160 'services', 161 array( 162 'label' => _x( 'Services', 'Block pattern category' ), 163 'description' => __( 'Briefly describe what your business does and how you can help.' ), 164 ) 165 ); 166 register_block_pattern_category( 167 'contact', 168 array( 169 'label' => _x( 'Contact', 'Block pattern category' ), 170 'description' => __( 'Display your contact information.' ), 171 ) 172 ); 173 register_block_pattern_category( 174 'about', 175 array( 176 'label' => _x( 'About', 'Block pattern category' ), 177 'description' => __( 'Introduce yourself.' ), 178 ) 179 ); 180 register_block_pattern_category( 181 'portfolio', 182 array( 183 'label' => _x( 'Portfolio', 'Block pattern category' ), 184 'description' => __( 'Showcase your latest work.' ), 185 ) 186 ); 187 register_block_pattern_category( 188 'gallery', 189 array( 190 'label' => _x( 'Gallery', 'Block pattern category' ), 191 'description' => __( 'Different layouts for displaying images.' ), 192 ) 193 ); 194 register_block_pattern_category( 195 'media', 196 array( 197 'label' => _x( 'Media', 'Block pattern category' ), 198 'description' => __( 'Different layouts containing video or audio.' ), 199 ) 200 ); 201 register_block_pattern_category( 202 'videos', 203 array( 204 'label' => _x( 'Videos', 'Block pattern category' ), 205 'description' => __( 'Different layouts containing videos.' ), 206 ) 207 ); 208 register_block_pattern_category( 209 'audio', 210 array( 211 'label' => _x( 'Audio', 'Block pattern category' ), 212 'description' => __( 'Different layouts containing audio.' ), 213 ) 214 ); 215 register_block_pattern_category( 216 'posts', 217 array( 218 'label' => _x( 'Posts', 'Block pattern category' ), 219 'description' => __( 'Display your latest posts in lists, grids or other layouts.' ), 220 ) 221 ); 222 register_block_pattern_category( 223 'footer', 224 array( 225 'label' => _x( 'Footers', 'Block pattern category' ), 226 'description' => __( 'A variety of footer designs displaying information and site navigation.' ), 227 ) 228 ); 229 register_block_pattern_category( 230 'header', 231 array( 232 'label' => _x( 'Headers', 'Block pattern category' ), 233 'description' => __( 'A variety of header designs displaying your site title and navigation.' ), 234 ) 235 ); 236 register_block_pattern_category( 237 'navigation', 238 array( 239 'label' => _x( 'Navigation', 'Block pattern category' ), 240 'description' => __( 'A variety of designs displaying site navigation.' ), 241 ) 242 ); 243 } 244 245 /** 246 * Normalize the pattern properties to camelCase. 247 * 248 * The API's format is snake_case, `register_block_pattern()` expects camelCase. 249 * 250 * @since 6.2.0 251 * @access private 252 * 253 * @param array $pattern Pattern as returned from the Pattern Directory API. 254 * @return array Normalized pattern. 255 */ 256 function wp_normalize_remote_block_pattern( $pattern ) { 257 if ( isset( $pattern['block_types'] ) ) { 258 $pattern['blockTypes'] = $pattern['block_types']; 259 unset( $pattern['block_types'] ); 260 } 261 262 if ( isset( $pattern['viewport_width'] ) ) { 263 $pattern['viewportWidth'] = $pattern['viewport_width']; 264 unset( $pattern['viewport_width'] ); 265 } 266 267 return (array) $pattern; 268 } 269 270 /** 271 * Register Core's official patterns from wordpress.org/patterns. 272 * 273 * @since 5.8.0 274 * @since 5.9.0 The $current_screen argument was removed. 275 * @since 6.2.0 Normalize the pattern from the API (snake_case) to the 276 * format expected by `register_block_pattern` (camelCase). 277 * @since 6.3.0 Add 'pattern-directory/core' to the pattern's 'source'. 278 * 279 * @param WP_Screen $deprecated Unused. Formerly the screen that the current request was triggered from. 280 */ 281 function _load_remote_block_patterns( $deprecated = null ) { 282 if ( ! empty( $deprecated ) ) { 283 _deprecated_argument( __FUNCTION__, '5.9.0' ); 284 $current_screen = $deprecated; 285 if ( ! $current_screen->is_block_editor ) { 286 return; 287 } 288 } 289 290 $supports_core_patterns = get_theme_support( 'core-block-patterns' ); 291 292 /** 293 * Filter to disable remote block patterns. 294 * 295 * @since 5.8.0 296 * 297 * @param bool $should_load_remote 298 */ 299 $should_load_remote = apply_filters( 'should_load_remote_block_patterns', true ); 300 301 if ( $supports_core_patterns && $should_load_remote ) { 302 $request = new WP_REST_Request( 'GET', '/wp/v2/pattern-directory/patterns' ); 303 $core_keyword_id = 11; // 11 is the ID for "core". 304 $request->set_param( 'keyword', $core_keyword_id ); 305 $response = rest_do_request( $request ); 306 if ( $response->is_error() ) { 307 return; 308 } 309 $patterns = $response->get_data(); 310 311 foreach ( $patterns as $pattern ) { 312 $pattern['source'] = 'pattern-directory/core'; 313 $normalized_pattern = wp_normalize_remote_block_pattern( $pattern ); 314 $pattern_name = 'core/' . sanitize_title( $normalized_pattern['title'] ); 315 register_block_pattern( $pattern_name, $normalized_pattern ); 316 } 317 } 318 } 319 320 /** 321 * Register `Featured` (category) patterns from wordpress.org/patterns. 322 * 323 * @since 5.9.0 324 * @since 6.2.0 Normalized the pattern from the API (snake_case) to the 325 * format expected by `register_block_pattern()` (camelCase). 326 * @since 6.3.0 Add 'pattern-directory/featured' to the pattern's 'source'. 327 */ 328 function _load_remote_featured_patterns() { 329 $supports_core_patterns = get_theme_support( 'core-block-patterns' ); 330 331 /** This filter is documented in wp-includes/block-patterns.php */ 332 $should_load_remote = apply_filters( 'should_load_remote_block_patterns', true ); 333 334 if ( ! $should_load_remote || ! $supports_core_patterns ) { 335 return; 336 } 337 338 $request = new WP_REST_Request( 'GET', '/wp/v2/pattern-directory/patterns' ); 339 $featured_cat_id = 26; // This is the `Featured` category id from pattern directory. 340 $request->set_param( 'category', $featured_cat_id ); 341 $response = rest_do_request( $request ); 342 if ( $response->is_error() ) { 343 return; 344 } 345 $patterns = $response->get_data(); 346 $registry = WP_Block_Patterns_Registry::get_instance(); 347 foreach ( $patterns as $pattern ) { 348 $pattern['source'] = 'pattern-directory/featured'; 349 $normalized_pattern = wp_normalize_remote_block_pattern( $pattern ); 350 $pattern_name = sanitize_title( $normalized_pattern['title'] ); 351 // Some patterns might be already registered as core patterns with the `core` prefix. 352 $is_registered = $registry->is_registered( $pattern_name ) || $registry->is_registered( "core/$pattern_name" ); 353 if ( ! $is_registered ) { 354 register_block_pattern( $pattern_name, $normalized_pattern ); 355 } 356 } 357 } 358 359 /** 360 * Registers patterns from Pattern Directory provided by a theme's 361 * `theme.json` file. 362 * 363 * @since 6.0.0 364 * @since 6.2.0 Normalized the pattern from the API (snake_case) to the 365 * format expected by `register_block_pattern()` (camelCase). 366 * @since 6.3.0 Add 'pattern-directory/theme' to the pattern's 'source'. 367 * @access private 368 */ 369 function _register_remote_theme_patterns() { 370 /** This filter is documented in wp-includes/block-patterns.php */ 371 if ( ! apply_filters( 'should_load_remote_block_patterns', true ) ) { 372 return; 373 } 374 375 if ( ! wp_theme_has_theme_json() ) { 376 return; 377 } 378 379 $pattern_settings = wp_get_theme_directory_pattern_slugs(); 380 if ( empty( $pattern_settings ) ) { 381 return; 382 } 383 384 $request = new WP_REST_Request( 'GET', '/wp/v2/pattern-directory/patterns' ); 385 $request['slug'] = $pattern_settings; 386 $response = rest_do_request( $request ); 387 if ( $response->is_error() ) { 388 return; 389 } 390 $patterns = $response->get_data(); 391 $patterns_registry = WP_Block_Patterns_Registry::get_instance(); 392 foreach ( $patterns as $pattern ) { 393 $pattern['source'] = 'pattern-directory/theme'; 394 $normalized_pattern = wp_normalize_remote_block_pattern( $pattern ); 395 $pattern_name = sanitize_title( $normalized_pattern['title'] ); 396 // Some patterns might be already registered as core patterns with the `core` prefix. 397 $is_registered = $patterns_registry->is_registered( $pattern_name ) || $patterns_registry->is_registered( "core/$pattern_name" ); 398 if ( ! $is_registered ) { 399 register_block_pattern( $pattern_name, $normalized_pattern ); 400 } 401 } 402 } 403 404 /** 405 * Register any patterns that the active theme may provide under its 406 * `./patterns/` directory. 407 * 408 * @since 6.0.0 409 * @since 6.1.0 The `postTypes` property was added. 410 * @since 6.2.0 The `templateTypes` property was added. 411 * @since 6.4.0 Uses the `WP_Theme::get_block_patterns` method. 412 * @access private 413 */ 414 function _register_theme_block_patterns() { 415 416 /* 417 * During the bootstrap process, a check for active and valid themes is run. 418 * If no themes are returned, the theme's functions.php file will not be loaded, 419 * which can lead to errors if patterns expect some variables or constants to 420 * already be set at this point, so bail early if that is the case. 421 */ 422 if ( empty( wp_get_active_and_valid_themes() ) ) { 423 return; 424 } 425 426 /* 427 * Register patterns for the active theme. If the theme is a child theme, 428 * let it override any patterns from the parent theme that shares the same slug. 429 */ 430 $themes = array(); 431 $theme = wp_get_theme(); 432 $themes[] = $theme; 433 if ( $theme->parent() ) { 434 $themes[] = $theme->parent(); 435 } 436 $registry = WP_Block_Patterns_Registry::get_instance(); 437 438 foreach ( $themes as $theme ) { 439 $patterns = $theme->get_block_patterns(); 440 $dirpath = $theme->get_stylesheet_directory() . '/patterns/'; 441 $text_domain = $theme->get( 'TextDomain' ); 442 443 foreach ( $patterns as $file => $pattern_data ) { 444 if ( $registry->is_registered( $pattern_data['slug'] ) ) { 445 continue; 446 } 447 448 $file_path = $dirpath . $file; 449 450 if ( ! file_exists( $file_path ) ) { 451 _doing_it_wrong( 452 __FUNCTION__, 453 sprintf( 454 /* translators: %s: file name. */ 455 __( 'Could not register file "%s" as a block pattern as the file does not exist.' ), 456 $file 457 ), 458 '6.4.0' 459 ); 460 $theme->delete_pattern_cache(); 461 continue; 462 } 463 464 $pattern_data['filePath'] = $file_path; 465 466 // Translate the pattern metadata. 467 // phpcs:ignore WordPress.WP.I18n.NonSingularStringLiteralText,WordPress.WP.I18n.NonSingularStringLiteralDomain,WordPress.WP.I18n.LowLevelTranslationFunction 468 $pattern_data['title'] = translate_with_gettext_context( $pattern_data['title'], 'Pattern title', $text_domain ); 469 if ( ! empty( $pattern_data['description'] ) ) { 470 // phpcs:ignore WordPress.WP.I18n.NonSingularStringLiteralText,WordPress.WP.I18n.NonSingularStringLiteralDomain,WordPress.WP.I18n.LowLevelTranslationFunction 471 $pattern_data['description'] = translate_with_gettext_context( $pattern_data['description'], 'Pattern description', $text_domain ); 472 } 473 474 register_block_pattern( $pattern_data['slug'], $pattern_data ); 475 } 476 } 477 } 478 add_action( 'init', '_register_theme_block_patterns' );
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
| Generated : Wed Jun 24 08:20:11 2026 | Cross-referenced by PHPXref |