wp/wp-includes/block-template.php
changeset 19 3d72ae0968f4
parent 18 be944660c56a
child 21 48c4eec2b7e6
equal deleted inserted replaced
18:be944660c56a 19:3d72ae0968f4
     4  *
     4  *
     5  * @package WordPress
     5  * @package WordPress
     6  */
     6  */
     7 
     7 
     8 /**
     8 /**
       
     9  * Adds necessary filters to use 'wp_template' posts instead of theme template files.
       
    10  *
       
    11  * @access private
       
    12  * @since 5.9.0
       
    13  */
       
    14 function _add_template_loader_filters() {
       
    15 	if ( ! current_theme_supports( 'block-templates' ) ) {
       
    16 		return;
       
    17 	}
       
    18 
       
    19 	$template_types = array_keys( get_default_block_template_types() );
       
    20 	foreach ( $template_types as $template_type ) {
       
    21 		// Skip 'embed' for now because it is not a regular template type.
       
    22 		if ( 'embed' === $template_type ) {
       
    23 			continue;
       
    24 		}
       
    25 		add_filter( str_replace( '-', '', $template_type ) . '_template', 'locate_block_template', 20, 3 );
       
    26 	}
       
    27 
       
    28 	// Request to resolve a template.
       
    29 	if ( isset( $_GET['_wp-find-template'] ) ) {
       
    30 		add_filter( 'pre_get_posts', '_resolve_template_for_new_post' );
       
    31 	}
       
    32 }
       
    33 
       
    34 /**
     9  * Find a block template with equal or higher specificity than a given PHP template file.
    35  * Find a block template with equal or higher specificity than a given PHP template file.
    10  *
    36  *
    11  * Internally, this communicates the block content that needs to be used by the template canvas through a global variable.
    37  * Internally, this communicates the block content that needs to be used by the template canvas through a global variable.
    12  *
    38  *
    13  * @since 5.8.0
    39  * @since 5.8.0
    14  *
    40  *
    15  * @global string $_wp_current_template_content
    41  * @global string $_wp_current_template_content
    16  *
    42  *
    17  * @param string $template  Path to the template. See locate_template().
    43  * @param string   $template  Path to the template. See locate_template().
    18  * @param string $type      Sanitized filename without extension.
    44  * @param string   $type      Sanitized filename without extension.
    19  * @param array  $templates A list of template candidates, in descending order of priority.
    45  * @param string[] $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.
    46  * @return string The path to the Full Site Editing template canvas file, or the fallback PHP template.
    21  */
    47  */
    22 function locate_block_template( $template, $type, array $templates ) {
    48 function locate_block_template( $template, $type, array $templates ) {
    23 	global $_wp_current_template_content;
    49 	global $_wp_current_template_content;
       
    50 
       
    51 	if ( ! current_theme_supports( 'block-templates' ) ) {
       
    52 		return $template;
       
    53 	}
    24 
    54 
    25 	if ( $template ) {
    55 	if ( $template ) {
    26 		/*
    56 		/*
    27 		 * locate_template() has found a PHP template at the path specified by $template.
    57 		 * 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
    58 		 * That means that we have a fallback candidate if we cannot find a block template
    38 			'',
    68 			'',
    39 			$template
    69 			$template
    40 		);
    70 		);
    41 		$index                  = array_search( $relative_template_path, $templates, true );
    71 		$index                  = array_search( $relative_template_path, $templates, true );
    42 
    72 
    43 		// If the template hiearchy algorithm has successfully located a PHP template file,
    73 		// If the template hierarchy algorithm has successfully located a PHP template file,
    44 		// we will only consider block templates with higher or equal specificity.
    74 		// we will only consider block templates with higher or equal specificity.
    45 		$templates = array_slice( $templates, 0, $index + 1 );
    75 		$templates = array_slice( $templates, 0, $index + 1 );
    46 	}
    76 	}
    47 
    77 
    48 	$block_template = resolve_block_template( $type, $templates );
    78 	$block_template = resolve_block_template( $type, $templates, $template );
    49 
    79 
    50 	if ( $block_template ) {
    80 	if ( $block_template ) {
    51 		if ( empty( $block_template->content ) && is_user_logged_in() ) {
    81 		if ( empty( $block_template->content ) && is_user_logged_in() ) {
    52 			$_wp_current_template_content =
    82 			$_wp_current_template_content =
    53 			sprintf(
    83 			sprintf(
    90 /**
   120 /**
    91  * Return the correct 'wp_template' to render for the request template type.
   121  * Return the correct 'wp_template' to render for the request template type.
    92  *
   122  *
    93  * @access private
   123  * @access private
    94  * @since 5.8.0
   124  * @since 5.8.0
       
   125  * @since 5.9.0 Added the `$fallback_template` parameter.
    95  *
   126  *
    96  * @param string   $template_type      The current template type.
   127  * @param string   $template_type      The current template type.
    97  * @param string[] $template_hierarchy The current template hierarchy, ordered by priority.
   128  * @param string[] $template_hierarchy The current template hierarchy, ordered by priority.
       
   129  * @param string   $fallback_template  A PHP fallback template to use if no matching block template is found.
    98  * @return WP_Block_Template|null template A template object, or null if none could be found.
   130  * @return WP_Block_Template|null template A template object, or null if none could be found.
    99  */
   131  */
   100 function resolve_block_template( $template_type, $template_hierarchy ) {
   132 function resolve_block_template( $template_type, $template_hierarchy, $fallback_template ) {
   101 	if ( ! $template_type ) {
   133 	if ( ! $template_type ) {
   102 		return null;
   134 		return null;
   103 	}
   135 	}
   104 
   136 
   105 	if ( empty( $template_hierarchy ) ) {
   137 	if ( empty( $template_hierarchy ) ) {
   122 	// Build map of template slugs to their priority in the current hierarchy.
   154 	// Build map of template slugs to their priority in the current hierarchy.
   123 	$slug_priorities = array_flip( $slugs );
   155 	$slug_priorities = array_flip( $slugs );
   124 
   156 
   125 	usort(
   157 	usort(
   126 		$templates,
   158 		$templates,
   127 		function ( $template_a, $template_b ) use ( $slug_priorities ) {
   159 		static function ( $template_a, $template_b ) use ( $slug_priorities ) {
   128 			return $slug_priorities[ $template_a->slug ] - $slug_priorities[ $template_b->slug ];
   160 			return $slug_priorities[ $template_a->slug ] - $slug_priorities[ $template_b->slug ];
   129 		}
   161 		}
   130 	);
   162 	);
       
   163 
       
   164 	$theme_base_path        = get_stylesheet_directory() . DIRECTORY_SEPARATOR;
       
   165 	$parent_theme_base_path = get_template_directory() . DIRECTORY_SEPARATOR;
       
   166 
       
   167 	// Is the active theme a child theme, and is the PHP fallback template part of it?
       
   168 	if (
       
   169 		strpos( $fallback_template, $theme_base_path ) === 0 &&
       
   170 		strpos( $fallback_template, $parent_theme_base_path ) === false
       
   171 	) {
       
   172 		$fallback_template_slug = substr(
       
   173 			$fallback_template,
       
   174 			// Starting position of slug.
       
   175 			strpos( $fallback_template, $theme_base_path ) + strlen( $theme_base_path ),
       
   176 			// Remove '.php' suffix.
       
   177 			-4
       
   178 		);
       
   179 
       
   180 		// Is our candidate block template's slug identical to our PHP fallback template's?
       
   181 		if (
       
   182 			count( $templates ) &&
       
   183 			$fallback_template_slug === $templates[0]->slug &&
       
   184 			'theme' === $templates[0]->source
       
   185 		) {
       
   186 			// Unfortunately, we cannot trust $templates[0]->theme, since it will always
       
   187 			// be set to the active theme's slug by _build_block_template_result_from_file(),
       
   188 			// even if the block template is really coming from the active theme's parent.
       
   189 			// (The reason for this is that we want it to be associated with the active theme
       
   190 			// -- not its parent -- once we edit it and store it to the DB as a wp_template CPT.)
       
   191 			// Instead, we use _get_block_template_file() to locate the block template file.
       
   192 			$template_file = _get_block_template_file( 'wp_template', $fallback_template_slug );
       
   193 			if ( $template_file && get_template() === $template_file['theme'] ) {
       
   194 				// The block template is part of the parent theme, so we
       
   195 				// have to give precedence to the child theme's PHP template.
       
   196 				array_shift( $templates );
       
   197 			}
       
   198 		}
       
   199 	}
   131 
   200 
   132 	return count( $templates ) ? $templates[0] : null;
   201 	return count( $templates ) ? $templates[0] : null;
   133 }
   202 }
   134 
   203 
   135 /**
   204 /**
   168 
   237 
   169 	$content = $wp_embed->run_shortcode( $_wp_current_template_content );
   238 	$content = $wp_embed->run_shortcode( $_wp_current_template_content );
   170 	$content = $wp_embed->autoembed( $content );
   239 	$content = $wp_embed->autoembed( $content );
   171 	$content = do_blocks( $content );
   240 	$content = do_blocks( $content );
   172 	$content = wptexturize( $content );
   241 	$content = wptexturize( $content );
       
   242 	$content = convert_smilies( $content );
       
   243 	$content = shortcode_unautop( $content );
   173 	$content = wp_filter_content_tags( $content );
   244 	$content = wp_filter_content_tags( $content );
       
   245 	$content = do_shortcode( $content );
   174 	$content = str_replace( ']]>', ']]>', $content );
   246 	$content = str_replace( ']]>', ']]>', $content );
   175 
   247 
   176 	// Wrap block template in .wp-site-blocks to allow for specific descendant styles
   248 	// Wrap block template in .wp-site-blocks to allow for specific descendant styles
   177 	// (e.g. `.wp-site-blocks > *`).
   249 	// (e.g. `.wp-site-blocks > *`).
   178 	return '<div class="wp-site-blocks">' . $content . '</div>';
   250 	return '<div class="wp-site-blocks">' . $content . '</div>';
   225 		unset( $context['postType'] );
   297 		unset( $context['postType'] );
   226 	}
   298 	}
   227 
   299 
   228 	return $context;
   300 	return $context;
   229 }
   301 }
       
   302 
       
   303 /**
       
   304  * Sets the current WP_Query to return auto-draft posts.
       
   305  *
       
   306  * The auto-draft status indicates a new post, so allow the the WP_Query instance to
       
   307  * return an auto-draft post for template resolution when editing a new post.
       
   308  *
       
   309  * @access private
       
   310  * @since 5.9.0
       
   311  *
       
   312  * @param WP_Query $wp_query Current WP_Query instance, passed by reference.
       
   313  */
       
   314 function _resolve_template_for_new_post( $wp_query ) {
       
   315 	if ( ! $wp_query->is_main_query() ) {
       
   316 		return;
       
   317 	}
       
   318 
       
   319 	remove_filter( 'pre_get_posts', '_resolve_template_for_new_post' );
       
   320 
       
   321 	// Pages.
       
   322 	$page_id = isset( $wp_query->query['page_id'] ) ? $wp_query->query['page_id'] : null;
       
   323 
       
   324 	// Posts, including custom post types.
       
   325 	$p = isset( $wp_query->query['p'] ) ? $wp_query->query['p'] : null;
       
   326 
       
   327 	$post_id = $page_id ? $page_id : $p;
       
   328 	$post    = get_post( $post_id );
       
   329 
       
   330 	if (
       
   331 		$post &&
       
   332 		'auto-draft' === $post->post_status &&
       
   333 		current_user_can( 'edit_post', $post->ID )
       
   334 	) {
       
   335 		$wp_query->set( 'post_status', 'auto-draft' );
       
   336 	}
       
   337 }
       
   338 
       
   339 /**
       
   340  * Returns the correct template for the site's home page.
       
   341  *
       
   342  * @access private
       
   343  * @since 6.0.0
       
   344  *
       
   345  * @return array|null A template object, or null if none could be found.
       
   346  */
       
   347 function _resolve_home_block_template() {
       
   348 	$show_on_front = get_option( 'show_on_front' );
       
   349 	$front_page_id = get_option( 'page_on_front' );
       
   350 
       
   351 	if ( 'page' === $show_on_front && $front_page_id ) {
       
   352 		return array(
       
   353 			'postType' => 'page',
       
   354 			'postId'   => $front_page_id,
       
   355 		);
       
   356 	}
       
   357 
       
   358 	$hierarchy = array( 'front-page', 'home', 'index' );
       
   359 	$template  = resolve_block_template( 'home', $hierarchy, '' );
       
   360 
       
   361 	if ( ! $template ) {
       
   362 		return null;
       
   363 	}
       
   364 
       
   365 	return array(
       
   366 		'postType' => 'wp_template',
       
   367 		'postId'   => $template->id,
       
   368 	);
       
   369 }