ru-se.com

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

block-template.php (7053B)


      1 <?php
      2 /**
      3  * Block template loader functions.
      4  *
      5  * @package WordPress
      6  */
      7 
      8 /**
      9  * Find a block template with equal or higher specificity than a given PHP template file.
     10  *
     11  * Internally, this communicates the block content that needs to be used by the template canvas through a global variable.
     12  *
     13  * @since 5.8.0
     14  *
     15  * @global string $_wp_current_template_content
     16  *
     17  * @param string $template  Path to the template. See locate_template().
     18  * @param string $type      Sanitized filename without extension.
     19  * @param array  $templates A list of template candidates, in descending order of priority.
     20  * @return string The path to the Full Site Editing template canvas file, or the fallback PHP template.
     21  */
     22 function locate_block_template( $template, $type, array $templates ) {
     23 	global $_wp_current_template_content;
     24 
     25 	if ( $template ) {
     26 		/*
     27 		 * locate_template() has found a PHP template at the path specified by $template.
     28 		 * That means that we have a fallback candidate if we cannot find a block template
     29 		 * with higher specificity.
     30 		 *
     31 		 * Thus, before looking for matching block themes, we shorten our list of candidate
     32 		 * templates accordingly.
     33 		 */
     34 
     35 		// Locate the index of $template (without the theme directory path) in $templates.
     36 		$relative_template_path = str_replace(
     37 			array( get_stylesheet_directory() . '/', get_template_directory() . '/' ),
     38 			'',
     39 			$template
     40 		);
     41 		$index                  = array_search( $relative_template_path, $templates, true );
     42 
     43 		// If the template hiearchy algorithm has successfully located a PHP template file,
     44 		// we will only consider block templates with higher or equal specificity.
     45 		$templates = array_slice( $templates, 0, $index + 1 );
     46 	}
     47 
     48 	$block_template = resolve_block_template( $type, $templates );
     49 
     50 	if ( $block_template ) {
     51 		if ( empty( $block_template->content ) && is_user_logged_in() ) {
     52 			$_wp_current_template_content =
     53 			sprintf(
     54 				/* translators: %s: Template title */
     55 				__( 'Empty template: %s' ),
     56 				$block_template->title
     57 			);
     58 		} elseif ( ! empty( $block_template->content ) ) {
     59 			$_wp_current_template_content = $block_template->content;
     60 		}
     61 		if ( isset( $_GET['_wp-find-template'] ) ) {
     62 			wp_send_json_success( $block_template );
     63 		}
     64 	} else {
     65 		if ( $template ) {
     66 			return $template;
     67 		}
     68 
     69 		if ( 'index' === $type ) {
     70 			if ( isset( $_GET['_wp-find-template'] ) ) {
     71 				wp_send_json_error( array( 'message' => __( 'No matching template found.' ) ) );
     72 			}
     73 		} else {
     74 			return ''; // So that the template loader keeps looking for templates.
     75 		}
     76 	}
     77 
     78 	// Add hooks for template canvas.
     79 	// Add viewport meta tag.
     80 	add_action( 'wp_head', '_block_template_viewport_meta_tag', 0 );
     81 
     82 	// Render title tag with content, regardless of whether theme has title-tag support.
     83 	remove_action( 'wp_head', '_wp_render_title_tag', 1 );    // Remove conditional title tag rendering...
     84 	add_action( 'wp_head', '_block_template_render_title_tag', 1 ); // ...and make it unconditional.
     85 
     86 	// This file will be included instead of the theme's template file.
     87 	return ABSPATH . WPINC . '/template-canvas.php';
     88 }
     89 
     90 /**
     91  * Return the correct 'wp_template' to render for the request template type.
     92  *
     93  * @access private
     94  * @since 5.8.0
     95  *
     96  * @param string   $template_type      The current template type.
     97  * @param string[] $template_hierarchy The current template hierarchy, ordered by priority.
     98  * @return WP_Block_Template|null template A template object, or null if none could be found.
     99  */
    100 function resolve_block_template( $template_type, $template_hierarchy ) {
    101 	if ( ! $template_type ) {
    102 		return null;
    103 	}
    104 
    105 	if ( empty( $template_hierarchy ) ) {
    106 		$template_hierarchy = array( $template_type );
    107 	}
    108 
    109 	$slugs = array_map(
    110 		'_strip_template_file_suffix',
    111 		$template_hierarchy
    112 	);
    113 
    114 	// Find all potential templates 'wp_template' post matching the hierarchy.
    115 	$query     = array(
    116 		'theme'    => wp_get_theme()->get_stylesheet(),
    117 		'slug__in' => $slugs,
    118 	);
    119 	$templates = get_block_templates( $query );
    120 
    121 	// Order these templates per slug priority.
    122 	// Build map of template slugs to their priority in the current hierarchy.
    123 	$slug_priorities = array_flip( $slugs );
    124 
    125 	usort(
    126 		$templates,
    127 		function ( $template_a, $template_b ) use ( $slug_priorities ) {
    128 			return $slug_priorities[ $template_a->slug ] - $slug_priorities[ $template_b->slug ];
    129 		}
    130 	);
    131 
    132 	return count( $templates ) ? $templates[0] : null;
    133 }
    134 
    135 /**
    136  * Displays title tag with content, regardless of whether theme has title-tag support.
    137  *
    138  * @access private
    139  * @since 5.8.0
    140  *
    141  * @see _wp_render_title_tag()
    142  */
    143 function _block_template_render_title_tag() {
    144 	echo '<title>' . wp_get_document_title() . '</title>' . "\n";
    145 }
    146 
    147 /**
    148  * Returns the markup for the current template.
    149  *
    150  * @access private
    151  * @since 5.8.0
    152  *
    153  * @global string   $_wp_current_template_content
    154  * @global WP_Embed $wp_embed
    155  *
    156  * @return string Block template markup.
    157  */
    158 function get_the_block_template_html() {
    159 	global $_wp_current_template_content;
    160 	global $wp_embed;
    161 
    162 	if ( ! $_wp_current_template_content ) {
    163 		if ( is_user_logged_in() ) {
    164 			return '<h1>' . esc_html__( 'No matching template found' ) . '</h1>';
    165 		}
    166 		return;
    167 	}
    168 
    169 	$content = $wp_embed->run_shortcode( $_wp_current_template_content );
    170 	$content = $wp_embed->autoembed( $content );
    171 	$content = do_blocks( $content );
    172 	$content = wptexturize( $content );
    173 	$content = wp_filter_content_tags( $content );
    174 	$content = str_replace( ']]>', ']]&gt;', $content );
    175 
    176 	// Wrap block template in .wp-site-blocks to allow for specific descendant styles
    177 	// (e.g. `.wp-site-blocks > *`).
    178 	return '<div class="wp-site-blocks">' . $content . '</div>';
    179 }
    180 
    181 /**
    182  * Renders a 'viewport' meta tag.
    183  *
    184  * This is hooked into {@see 'wp_head'} to decouple its output from the default template canvas.
    185  *
    186  * @access private
    187  * @since 5.8.0
    188  */
    189 function _block_template_viewport_meta_tag() {
    190 	echo '<meta name="viewport" content="width=device-width, initial-scale=1" />' . "\n";
    191 }
    192 
    193 /**
    194  * Strips .php or .html suffix from template file names.
    195  *
    196  * @access private
    197  * @since 5.8.0
    198  *
    199  * @param string $template_file Template file name.
    200  * @return string Template file name without extension.
    201  */
    202 function _strip_template_file_suffix( $template_file ) {
    203 	return preg_replace( '/\.(php|html)$/', '', $template_file );
    204 }
    205 
    206 /**
    207  * Removes post details from block context when rendering a block template.
    208  *
    209  * @access private
    210  * @since 5.8.0
    211  *
    212  * @param array $context Default context.
    213  *
    214  * @return array Filtered context.
    215  */
    216 function _block_template_render_without_post_block_context( $context ) {
    217 	/*
    218 	 * When loading a template directly and not through a page that resolves it,
    219 	 * the top-level post ID and type context get set to that of the template.
    220 	 * Templates are just the structure of a site, and they should not be available
    221 	 * as post context because blocks like Post Content would recurse infinitely.
    222 	 */
    223 	if ( isset( $context['postType'] ) && 'wp_template' === $context['postType'] ) {
    224 		unset( $context['postId'] );
    225 		unset( $context['postType'] );
    226 	}
    227 
    228 	return $context;
    229 }