Skip to content
This repository has been archived by the owner on Feb 23, 2024. It is now read-only.

Commit

Permalink
Fix custom templates with fallback being incorrectly attributed (#5447)
Browse files Browse the repository at this point in the history
* Fix custom templates with fallback being incorrectly attributed

Category and tags templates can fallback to the generic archive if, e.g., the theme
provides one for the latter but not for the former. However, since Gutenberg is not
aware of this fallback mechanism, it would incorrectly attribute the custom template
to the user instead of the theme.

Here we are explicitly setting the `has_theme_file` to make sure Gutenberg knows
we do, in fact, have a theme fail (if not what it expects).

Also skip the loop if template is duplicate but has no fallback

Fixes #5441
  • Loading branch information
sunyatasattva authored Dec 24, 2021
1 parent e49c6a2 commit 9a8f27f
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 18 deletions.
23 changes: 5 additions & 18 deletions src/BlockTemplatesController.php
Original file line number Diff line number Diff line change
Expand Up @@ -175,16 +175,10 @@ public function add_block_templates( $query_result, $query, $template_type ) {
// @todo: Add apply_filters to _gutenberg_get_template_files() in Gutenberg to prevent duplication of logic.
foreach ( $template_files as $template_file ) {

// Avoid adding the same template if it's already in the array of $query_result.
if (
array_filter(
$query_result,
function( $query_result_template ) use ( $template_file ) {
return $query_result_template->slug === $template_file->slug &&
$query_result_template->theme === $template_file->theme;
}
)
) {
// If we have a template which is eligible for a fallback, we need to explicitly tell Gutenberg that
// it has a theme file (because it is using the fallback template file). And then `continue` to avoid
// adding duplicates.
if ( BlockTemplateUtils::set_has_theme_file_if_fallback_is_available( $query_result, $template_file ) ) {
continue;
}

Expand Down Expand Up @@ -348,14 +342,7 @@ function ( $template ) use ( $template_slug ) {
}

// If the theme has an archive-product.html template, but not a taxonomy-product_cat.html template let's use the themes archive-product.html template.
if ( 'taxonomy-product_cat' === $template_slug && ! BlockTemplateUtils::theme_has_template( 'taxonomy-product_cat' ) && BlockTemplateUtils::theme_has_template( 'archive-product' ) ) {
$template_file = get_stylesheet_directory() . '/' . self::TEMPLATES_DIR_NAME . '/archive-product.html';
$templates[] = BlockTemplateUtils::create_new_block_template_object( $template_file, $template_type, $template_slug, true );
continue;
}

// If the theme has an archive-product.html template, but not a taxonomy-product_tag.html template let's use the themes archive-product.html template.
if ( 'taxonomy-product_tag' === $template_slug && ! BlockTemplateUtils::theme_has_template( 'taxonomy-product_tag' ) && BlockTemplateUtils::theme_has_template( 'archive-product' ) ) {
if ( BlockTemplateUtils::template_is_eligible_for_product_archive_fallback( $template_slug ) ) {
$template_file = get_stylesheet_directory() . '/' . self::TEMPLATES_DIR_NAME . '/archive-product.html';
$templates[] = BlockTemplateUtils::create_new_block_template_object( $template_file, $template_type, $template_slug, true );
continue;
Expand Down
51 changes: 51 additions & 0 deletions src/Utils/BlockTemplateUtils.php
Original file line number Diff line number Diff line change
Expand Up @@ -281,4 +281,55 @@ public static function supports_block_templates() {

return true;
}

/**
* Checks if we can fallback to the `archive-product` template for a given slug
*
* `taxonomy-product_cat` and `taxonomy-product_tag` templates can generally use the
* `archive-product` as a fallback if there are no specific overrides.
*
* @param string $template_slug Slug to check for fallbacks.
* @return boolean
*/
public static function template_is_eligible_for_product_archive_fallback( $template_slug ) {
$eligible_for_fallbacks = array( 'taxonomy-product_cat', 'taxonomy-product_tag' );

return in_array( $template_slug, $eligible_for_fallbacks, true )
&& ! self::theme_has_template( $template_slug )
&& self::theme_has_template( 'archive-product' );
}

/**
* Sets the `has_theme_file` to `true` for templates with fallbacks
*
* There are cases (such as tags and categories) in which fallback templates
* can be used; so, while *technically* the theme doesn't have a specific file
* for them, it is important that we tell Gutenberg that we do, in fact,
* have a theme file (i.e. the fallback one).
*
* **Note:** this function changes the array that has been passed.
*
* It returns `true` if anything was changed, `false` otherwise.
*
* @param array $query_result Array of template objects.
* @param array $template A specific template object which could have a fallback.
*
* @return boolean
*/
public static function set_has_theme_file_if_fallback_is_available( $query_result, $template ) {
foreach ( $query_result as &$query_result_template ) {
if (
$query_result_template->slug === $template->slug
&& $query_result_template->theme === $template->theme
) {
if ( self::template_is_eligible_for_product_archive_fallback( $template->slug ) ) {
$query_result_template->has_theme_file = true;
}

return true;
}
}

return false;
}
}

0 comments on commit 9a8f27f

Please sign in to comment.