wp/wp-includes/blocks/template-part.php
changeset 19 3d72ae0968f4
child 21 48c4eec2b7e6
equal deleted inserted replaced
18:be944660c56a 19:3d72ae0968f4
       
     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 
       
    22 	if (
       
    23 		isset( $attributes['slug'] ) &&
       
    24 		isset( $attributes['theme'] ) &&
       
    25 		wp_get_theme()->get_stylesheet() === $attributes['theme']
       
    26 	) {
       
    27 		$template_part_id    = $attributes['theme'] . '//' . $attributes['slug'];
       
    28 		$template_part_query = new WP_Query(
       
    29 			array(
       
    30 				'post_type'      => 'wp_template_part',
       
    31 				'post_status'    => 'publish',
       
    32 				'post_name__in'  => array( $attributes['slug'] ),
       
    33 				'tax_query'      => array(
       
    34 					array(
       
    35 						'taxonomy' => 'wp_theme',
       
    36 						'field'    => 'slug',
       
    37 						'terms'    => $attributes['theme'],
       
    38 					),
       
    39 				),
       
    40 				'posts_per_page' => 1,
       
    41 				'no_found_rows'  => true,
       
    42 			)
       
    43 		);
       
    44 		$template_part_post  = $template_part_query->have_posts() ? $template_part_query->next_post() : null;
       
    45 		if ( $template_part_post ) {
       
    46 			// A published post might already exist if this template part was customized elsewhere
       
    47 			// or if it's part of a customized template.
       
    48 			$content    = $template_part_post->post_content;
       
    49 			$area_terms = get_the_terms( $template_part_post, 'wp_template_part_area' );
       
    50 			if ( ! is_wp_error( $area_terms ) && false !== $area_terms ) {
       
    51 				$area = $area_terms[0]->name;
       
    52 			}
       
    53 			/**
       
    54 			 * Fires when a block template part is loaded from a template post stored in the database.
       
    55 			 *
       
    56 			 * @since 5.9.0
       
    57 			 *
       
    58 			 * @param string  $template_part_id   The requested template part namespaced to the theme.
       
    59 			 * @param array   $attributes         The block attributes.
       
    60 			 * @param WP_Post $template_part_post The template part post object.
       
    61 			 * @param string  $content            The template part content.
       
    62 			 */
       
    63 			do_action( 'render_block_core_template_part_post', $template_part_id, $attributes, $template_part_post, $content );
       
    64 		} else {
       
    65 			// Else, if the template part was provided by the active theme,
       
    66 			// render the corresponding file content.
       
    67 			$parent_theme_folders        = get_block_theme_folders( get_template() );
       
    68 			$child_theme_folders         = get_block_theme_folders( get_stylesheet() );
       
    69 			$child_theme_part_file_path  = get_theme_file_path( '/' . $child_theme_folders['wp_template_part'] . '/' . $attributes['slug'] . '.html' );
       
    70 			$parent_theme_part_file_path = get_theme_file_path( '/' . $parent_theme_folders['wp_template_part'] . '/' . $attributes['slug'] . '.html' );
       
    71 			$template_part_file_path     = 0 === validate_file( $attributes['slug'] ) && file_exists( $child_theme_part_file_path ) ? $child_theme_part_file_path : $parent_theme_part_file_path;
       
    72 			if ( 0 === validate_file( $attributes['slug'] ) && file_exists( $template_part_file_path ) ) {
       
    73 				$content = file_get_contents( $template_part_file_path );
       
    74 				$content = is_string( $content ) && '' !== $content
       
    75 						? _inject_theme_attribute_in_block_template_content( $content )
       
    76 						: '';
       
    77 			}
       
    78 
       
    79 			if ( '' !== $content && null !== $content ) {
       
    80 				/**
       
    81 				 * Fires when a block template part is loaded from a template part in the theme.
       
    82 				 *
       
    83 				 * @since 5.9.0
       
    84 				 *
       
    85 				 * @param string $template_part_id        The requested template part namespaced to the theme.
       
    86 				 * @param array  $attributes              The block attributes.
       
    87 				 * @param string $template_part_file_path Absolute path to the template path.
       
    88 				 * @param string $content                 The template part content.
       
    89 				 */
       
    90 				do_action( 'render_block_core_template_part_file', $template_part_id, $attributes, $template_part_file_path, $content );
       
    91 			} else {
       
    92 				/**
       
    93 				 * Fires when a requested block template part does not exist in the database nor in the theme.
       
    94 				 *
       
    95 				 * @since 5.9.0
       
    96 				 *
       
    97 				 * @param string $template_part_id        The requested template part namespaced to the theme.
       
    98 				 * @param array  $attributes              The block attributes.
       
    99 				 * @param string $template_part_file_path Absolute path to the not found template path.
       
   100 				 */
       
   101 				do_action( 'render_block_core_template_part_none', $template_part_id, $attributes, $template_part_file_path );
       
   102 			}
       
   103 		}
       
   104 	}
       
   105 
       
   106 	// WP_DEBUG_DISPLAY must only be honored when WP_DEBUG. This precedent
       
   107 	// is set in `wp_debug_mode()`.
       
   108 	$is_debug = defined( 'WP_DEBUG' ) && WP_DEBUG &&
       
   109 		defined( 'WP_DEBUG_DISPLAY' ) && WP_DEBUG_DISPLAY;
       
   110 
       
   111 	if ( is_null( $content ) && $is_debug ) {
       
   112 		if ( ! isset( $attributes['slug'] ) ) {
       
   113 			// If there is no slug this is a placeholder and we dont want to return any message.
       
   114 			return;
       
   115 		}
       
   116 		return sprintf(
       
   117 			/* translators: %s: Template part slug. */
       
   118 			__( 'Template part has been deleted or is unavailable: %s' ),
       
   119 			$attributes['slug']
       
   120 		);
       
   121 	}
       
   122 
       
   123 	if ( isset( $seen_ids[ $template_part_id ] ) ) {
       
   124 		return $is_debug ?
       
   125 			// translators: Visible only in the front end, this warning takes the place of a faulty block.
       
   126 			__( '[block rendering halted]' ) :
       
   127 			'';
       
   128 	}
       
   129 
       
   130 	// Run through the actions that are typically taken on the_content.
       
   131 	$seen_ids[ $template_part_id ] = true;
       
   132 	$content                       = do_blocks( $content );
       
   133 	unset( $seen_ids[ $template_part_id ] );
       
   134 	$content = wptexturize( $content );
       
   135 	$content = convert_smilies( $content );
       
   136 	$content = shortcode_unautop( $content );
       
   137 	$content = wp_filter_content_tags( $content );
       
   138 	$content = do_shortcode( $content );
       
   139 
       
   140 	// Handle embeds for block template parts.
       
   141 	global $wp_embed;
       
   142 	$content = $wp_embed->autoembed( $content );
       
   143 
       
   144 	if ( empty( $attributes['tagName'] ) ) {
       
   145 		$defined_areas = get_allowed_block_template_part_areas();
       
   146 		$area_tag      = 'div';
       
   147 		foreach ( $defined_areas as $defined_area ) {
       
   148 			if ( $defined_area['area'] === $area && isset( $defined_area['area_tag'] ) ) {
       
   149 				$area_tag = $defined_area['area_tag'];
       
   150 			}
       
   151 		}
       
   152 		$html_tag = $area_tag;
       
   153 	} else {
       
   154 		$html_tag = esc_attr( $attributes['tagName'] );
       
   155 	}
       
   156 	$wrapper_attributes = get_block_wrapper_attributes();
       
   157 
       
   158 	return "<$html_tag $wrapper_attributes>" . str_replace( ']]>', ']]&gt;', $content ) . "</$html_tag>";
       
   159 }
       
   160 
       
   161 /**
       
   162  * Returns an array of variation objects for the template part block.
       
   163  *
       
   164  * @return array Array containing the block variation objects.
       
   165  */
       
   166 function build_template_part_block_variations() {
       
   167 	$variations    = array();
       
   168 	$defined_areas = get_allowed_block_template_part_areas();
       
   169 	foreach ( $defined_areas as $area ) {
       
   170 		if ( 'uncategorized' !== $area['area'] ) {
       
   171 			$variations[] = array(
       
   172 				'name'        => $area['area'],
       
   173 				'title'       => $area['label'],
       
   174 				'description' => $area['description'],
       
   175 				'attributes'  => array(
       
   176 					'area' => $area['area'],
       
   177 				),
       
   178 				'scope'       => array( 'inserter' ),
       
   179 				'icon'        => $area['icon'],
       
   180 			);
       
   181 		}
       
   182 	}
       
   183 	return $variations;
       
   184 }
       
   185 
       
   186 /**
       
   187  * Registers the `core/template-part` block on the server.
       
   188  */
       
   189 function register_block_core_template_part() {
       
   190 	register_block_type_from_metadata(
       
   191 		__DIR__ . '/template-part',
       
   192 		array(
       
   193 			'render_callback' => 'render_block_core_template_part',
       
   194 			'variations'      => build_template_part_block_variations(),
       
   195 		)
       
   196 	);
       
   197 }
       
   198 add_action( 'init', 'register_block_core_template_part' );