Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FSE: Simplify template loader logic #31604

Merged
merged 3 commits into from
May 13, 2021
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 30 additions & 54 deletions lib/full-site-editing/template-loader.php
Original file line number Diff line number Diff line change
Expand Up @@ -64,72 +64,48 @@ function get_template_hierarchy( $template_type ) {
*/
function gutenberg_override_query_template( $template, $type, array $templates ) {
global $_wp_current_template_content;
$current_template = gutenberg_resolve_template( $type, $templates );

// Allow falling back to a PHP template if it has a higher priority than the block template.
$current_template_slug = str_replace(
array( trailingslashit( get_stylesheet_directory() ), trailingslashit( get_template_directory() ), '.php' ),
'',
$template
);
$current_block_template_slug = is_object( $current_template ) ? $current_template->slug : false;
foreach ( $templates as $template_item ) {

$template_item_slug = gutenberg_strip_php_suffix( $template_item );

// Break the loop if the block-template matches the template slug.
if ( $current_block_template_slug === $template_item_slug ) {

// if the theme is a child theme we want to check if a php template exists.
if ( is_child_theme() ) {

$has_php_template = file_exists( get_stylesheet_directory() . '/' . $current_template_slug . '.php' );
$block_template = _gutenberg_get_template_file( 'wp_template', $current_block_template_slug );
$has_block_template = false;

if ( null !== $block_template && wp_get_theme()->get_stylesheet() === $block_template['theme'] ) {
$has_block_template = true;
}
// and that a corresponding block template from the theme and not the parent doesn't exist.
if ( $has_php_template && ! $has_block_template ) {
return $template;
}
}

break;
}

// Is this a custom template?
// This check should be removed when merged in core.
// Instead, wp_templates should be considered valid in locate_template.
$is_custom_template = 0 === strpos( $current_block_template_slug, 'wp-custom-template-' );

// Don't override the template if we find a template matching the slug we look for
// and which does not match a block template slug.
if (
! $is_custom_template &&
$current_template_slug !== $current_block_template_slug &&
$current_template_slug === $template_item_slug
) {
return $template;
}
Comment on lines -109 to -115
Copy link
Contributor Author

@ockham ockham May 7, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We're iterating over candidate $templates.

  1. The slug for the fallback PHP $template is in $current_template_slug.
  2. The slug for the best block template match for candidate $templates is in $current_block_template_slug.
  3. The slug for the current item in the $templates iteration loop (without .php suffix) is in $template_item_slug.

We return the PHP $template (1.) rather than the block template (2.) if:

  • The block template part of the regular template hierarchy (and not a custom page template), and
  • the block and PHP templates have different slugs -- meaning they apply to different items in the candidate $templates list, and
  • the PHP template is for the item in the candidate $templates list that we're currently iterating over.

Room for optimization mostly comes from the fact that we only want to consider block templates with higher specificity than the candidate PHP $template (instead of the inequality check found here; the higher specificity is implicitly handled here by the loop-breaking logic in L81-L100).

if ( $template ) {
// locate_template() has found a PHP template at the path specified by $template.
// That means that we have a fallback candidate if we cannot find a block template
// with higher specificity.
// Thus, before looking for matching block themes, we shorten our list of candidate
// templates accordingly.

// Locate the index of $template (without the theme directory path) in $templates.
$relative_template_path = str_replace(
array( get_stylesheet_directory() . '/', get_template_directory() . '/' ),
'',
$template
);
$index = array_search( $relative_template_path, $templates, true );

// If the template hiearchy algorithm has successfully located a PHP template file,
// we will only consider block templates with higher or equal specificity.
$templates = array_slice( $templates, 0, $index + 1 );
}

if ( $current_template ) {
if ( empty( $current_template->content ) && is_user_logged_in() ) {
$block_template = gutenberg_resolve_template( $type, $templates );

if ( $block_template ) {
if ( empty( $block_template->content ) && is_user_logged_in() ) {
$_wp_current_template_content =
sprintf(
/* translators: %s: Template title */
__( 'Empty template: %s', 'gutenberg' ),
$current_template->title
$block_template->title
);
} elseif ( ! empty( $current_template->content ) ) {
$_wp_current_template_content = $current_template->content;
} elseif ( ! empty( $block_template->content ) ) {
$_wp_current_template_content = $block_template->content;
}
if ( isset( $_GET['_wp-find-template'] ) ) {
wp_send_json_success( $current_template );
wp_send_json_success( $block_template );
}
} else {
if ( $template ) {
return $template;
}

if ( 'index' === $type ) {
if ( isset( $_GET['_wp-find-template'] ) ) {
wp_send_json_error( array( 'message' => __( 'No matching template found.', 'gutenberg' ) ) );
Expand Down