[ Index ]

PHP Cross Reference of WordPress Trunk (Updated Daily)

Search

title

Body

[close]

/wp-includes/ -> block-patterns.php (source)

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


Generated : Thu Nov 21 08:20:01 2024 Cross-referenced by PHPXref