[ Index ]

PHP Cross Reference of WordPress Trunk (Updated Daily)

Search

title

Body

[close]

/wp-includes/blocks/ -> template-part.php (source)

   1  <?php
   2  /**
   3   * Server-side rendering of the `core/template-part` block.
   4   *
   5   * @package WordPress
   6   */
   7  
   8  /**
   9   * Renders the `core/template-part` block on the server.
  10   *
  11   * @param array $attributes The block attributes.
  12   *
  13   * @return string The render.
  14   */
  15  function render_block_core_template_part( $attributes ) {
  16      static $seen_ids = array();
  17  
  18      $template_part_id = null;
  19      $content          = null;
  20      $area             = WP_TEMPLATE_PART_AREA_UNCATEGORIZED;
  21      $theme            = isset( $attributes['theme'] ) ? $attributes['theme'] : get_stylesheet();
  22  
  23      if ( isset( $attributes['slug'] ) && get_stylesheet() === $theme ) {
  24          $template_part_id    = $theme . '//' . $attributes['slug'];
  25          $template_part_query = new WP_Query(
  26              array(
  27                  'post_type'           => 'wp_template_part',
  28                  'post_status'         => 'publish',
  29                  'post_name__in'       => array( $attributes['slug'] ),
  30                  'tax_query'           => array(
  31                      array(
  32                          'taxonomy' => 'wp_theme',
  33                          'field'    => 'name',
  34                          'terms'    => $theme,
  35                      ),
  36                  ),
  37                  'posts_per_page'      => 1,
  38                  'no_found_rows'       => true,
  39                  'lazy_load_term_meta' => false, // Do not lazy load term meta, as template parts only have one term.
  40              )
  41          );
  42          $template_part_post  = $template_part_query->have_posts() ? $template_part_query->next_post() : null;
  43          if ( $template_part_post ) {
  44              // A published post might already exist if this template part was customized elsewhere
  45              // or if it's part of a customized template.
  46              $block_template = _build_block_template_result_from_post( $template_part_post );
  47              $content        = $block_template->content;
  48              if ( isset( $block_template->area ) ) {
  49                  $area = $block_template->area;
  50              }
  51              /**
  52               * Fires when a block template part is loaded from a template post stored in the database.
  53               *
  54               * @since 5.9.0
  55               *
  56               * @param string  $template_part_id   The requested template part namespaced to the theme.
  57               * @param array   $attributes         The block attributes.
  58               * @param WP_Post $template_part_post The template part post object.
  59               * @param string  $content            The template part content.
  60               */
  61              do_action( 'render_block_core_template_part_post', $template_part_id, $attributes, $template_part_post, $content );
  62          } else {
  63              $template_part_file_path = '';
  64              // Else, if the template part was provided by the active theme,
  65              // render the corresponding file content.
  66              if ( 0 === validate_file( $attributes['slug'] ) ) {
  67                  $block_template = get_block_file_template( $template_part_id, 'wp_template_part' );
  68  
  69                  $content = $block_template->content;
  70                  if ( isset( $block_template->area ) ) {
  71                      $area = $block_template->area;
  72                  }
  73  
  74                  // Needed for the `render_block_core_template_part_file` and `render_block_core_template_part_none` actions below.
  75                  $block_template_file = _get_block_template_file( 'wp_template_part', $attributes['slug'] );
  76                  if ( $block_template_file ) {
  77                      $template_part_file_path = $block_template_file['path'];
  78                  }
  79              }
  80  
  81              if ( '' !== $content && null !== $content ) {
  82                  /**
  83                   * Fires when a block template part is loaded from a template part in the theme.
  84                   *
  85                   * @since 5.9.0
  86                   *
  87                   * @param string $template_part_id        The requested template part namespaced to the theme.
  88                   * @param array  $attributes              The block attributes.
  89                   * @param string $template_part_file_path Absolute path to the template path.
  90                   * @param string $content                 The template part content.
  91                   */
  92                  do_action( 'render_block_core_template_part_file', $template_part_id, $attributes, $template_part_file_path, $content );
  93              } else {
  94                  /**
  95                   * Fires when a requested block template part does not exist in the database nor in the theme.
  96                   *
  97                   * @since 5.9.0
  98                   *
  99                   * @param string $template_part_id        The requested template part namespaced to the theme.
 100                   * @param array  $attributes              The block attributes.
 101                   * @param string $template_part_file_path Absolute path to the not found template path.
 102                   */
 103                  do_action( 'render_block_core_template_part_none', $template_part_id, $attributes, $template_part_file_path );
 104              }
 105          }
 106      }
 107  
 108      // WP_DEBUG_DISPLAY must only be honored when WP_DEBUG. This precedent
 109      // is set in `wp_debug_mode()`.
 110      $is_debug = WP_DEBUG && WP_DEBUG_DISPLAY;
 111  
 112      if ( is_null( $content ) ) {
 113          if ( $is_debug && isset( $attributes['slug'] ) ) {
 114              return sprintf(
 115                  /* translators: %s: Template part slug. */
 116                  __( 'Template part has been deleted or is unavailable: %s' ),
 117                  $attributes['slug']
 118              );
 119          }
 120  
 121          return '';
 122      }
 123  
 124      if ( isset( $seen_ids[ $template_part_id ] ) ) {
 125          return $is_debug ?
 126              // translators: Visible only in the front end, this warning takes the place of a faulty block.
 127              __( '[block rendering halted]' ) :
 128              '';
 129      }
 130  
 131      // Look up area definition.
 132      $area_definition = null;
 133      $defined_areas   = get_allowed_block_template_part_areas();
 134      foreach ( $defined_areas as $defined_area ) {
 135          if ( $defined_area['area'] === $area ) {
 136              $area_definition = $defined_area;
 137              break;
 138          }
 139      }
 140  
 141      // If $area is not allowed, set it back to the uncategorized default.
 142      if ( ! $area_definition ) {
 143          $area = WP_TEMPLATE_PART_AREA_UNCATEGORIZED;
 144      }
 145  
 146      // Run through the actions that are typically taken on the_content.
 147      $content                       = shortcode_unautop( $content );
 148      $content                       = do_shortcode( $content );
 149      $seen_ids[ $template_part_id ] = true;
 150      $content                       = do_blocks( $content );
 151      unset( $seen_ids[ $template_part_id ] );
 152      $content = wptexturize( $content );
 153      $content = convert_smilies( $content );
 154      $content = wp_filter_content_tags( $content, "template_part_{$area}" );
 155  
 156      // Handle embeds for block template parts.
 157      global $wp_embed;
 158      $content = $wp_embed->autoembed( $content );
 159  
 160      if ( empty( $attributes['tagName'] ) ) {
 161          $area_tag = 'div';
 162          if ( $area_definition && isset( $area_definition['area_tag'] ) ) {
 163              $area_tag = $area_definition['area_tag'];
 164          }
 165          $html_tag = $area_tag;
 166      } else {
 167          $html_tag = esc_attr( $attributes['tagName'] );
 168      }
 169      $wrapper_attributes = get_block_wrapper_attributes();
 170  
 171      return "<$html_tag $wrapper_attributes>" . str_replace( ']]>', ']]&gt;', $content ) . "</$html_tag>";
 172  }
 173  
 174  /**
 175   * Returns an array of area variation objects for the template part block.
 176   *
 177   * @param array $instance_variations The variations for instances.
 178   *
 179   * @return array Array containing the block variation objects.
 180   */
 181  function build_template_part_block_area_variations( $instance_variations ) {
 182      $variations    = array();
 183      $defined_areas = get_allowed_block_template_part_areas();
 184  
 185      foreach ( $defined_areas as $area ) {
 186          if ( 'uncategorized' !== $area['area'] ) {
 187              $has_instance_for_area = false;
 188              foreach ( $instance_variations as $variation ) {
 189                  if ( $variation['attributes']['area'] === $area['area'] ) {
 190                      $has_instance_for_area = true;
 191                      break;
 192                  }
 193              }
 194  
 195              $scope = $has_instance_for_area ? array() : array( 'inserter' );
 196  
 197              $variations[] = array(
 198                  'name'        => 'area_' . $area['area'],
 199                  'title'       => $area['label'],
 200                  'description' => $area['description'],
 201                  'attributes'  => array(
 202                      'area' => $area['area'],
 203                  ),
 204                  'scope'       => $scope,
 205                  'icon'        => $area['icon'],
 206              );
 207          }
 208      }
 209      return $variations;
 210  }
 211  
 212  /**
 213   * Returns an array of instance variation objects for the template part block
 214   *
 215   * @return array Array containing the block variation objects.
 216   */
 217  function build_template_part_block_instance_variations() {
 218      // Block themes are unavailable during installation.
 219      if ( wp_installing() ) {
 220          return array();
 221      }
 222  
 223      if ( ! current_theme_supports( 'block-templates' ) && ! current_theme_supports( 'block-template-parts' ) ) {
 224          return array();
 225      }
 226  
 227      $variations     = array();
 228      $template_parts = get_block_templates(
 229          array(
 230              'post_type' => 'wp_template_part',
 231          ),
 232          'wp_template_part'
 233      );
 234  
 235      $defined_areas = get_allowed_block_template_part_areas();
 236      $icon_by_area  = array_combine( array_column( $defined_areas, 'area' ), array_column( $defined_areas, 'icon' ) );
 237  
 238      foreach ( $template_parts as $template_part ) {
 239          $variations[] = array(
 240              'name'        => 'instance_' . sanitize_title( $template_part->slug ),
 241              'title'       => $template_part->title,
 242              // If there's no description for the template part don't show the
 243              // block description. This is a bit hacky, but prevent the fallback
 244              // by using a non-breaking space so that the value of description
 245              // isn't falsey.
 246              'description' => $template_part->description || '&nbsp;',
 247              'attributes'  => array(
 248                  'slug'  => $template_part->slug,
 249                  'theme' => $template_part->theme,
 250                  'area'  => $template_part->area,
 251              ),
 252              'scope'       => array( 'inserter' ),
 253              'icon'        => isset( $icon_by_area[ $template_part->area ] ) ? $icon_by_area[ $template_part->area ] : null,
 254              'example'     => array(
 255                  'attributes' => array(
 256                      'slug'  => $template_part->slug,
 257                      'theme' => $template_part->theme,
 258                      'area'  => $template_part->area,
 259                  ),
 260              ),
 261          );
 262      }
 263      return $variations;
 264  }
 265  
 266  /**
 267   * Returns an array of all template part block variations.
 268   *
 269   * @return array Array containing the block variation objects.
 270   */
 271  function build_template_part_block_variations() {
 272      $instance_variations = build_template_part_block_instance_variations();
 273      $area_variations     = build_template_part_block_area_variations( $instance_variations );
 274      return array_merge( $area_variations, $instance_variations );
 275  }
 276  
 277  /**
 278   * Registers the `core/template-part` block on the server.
 279   */
 280  function register_block_core_template_part() {
 281      register_block_type_from_metadata(
 282          __DIR__ . '/template-part',
 283          array(
 284              'render_callback'    => 'render_block_core_template_part',
 285              'variation_callback' => 'build_template_part_block_variations',
 286          )
 287      );
 288  }
 289  add_action( 'init', 'register_block_core_template_part' );


Generated : Fri Apr 26 08:20:02 2024 Cross-referenced by PHPXref