Move block templates and parts directories to the Gutenberg 12.1.0 convention (https://github.com/woocommerce/woocommerce-blocks/pull/5455)

Gutenberg 12.1.0 has changed the convention for the directory paths from
`block-templates` and `block-template-parts` to `templates` and `parts` respectively.

Allow compatibility with themes which follow both conventions and also make sure that
we remain backwards-compatible.

Fixes woocommerce/woocommerce-blocks#5450

Some of this fix has a dependency on WooCore

See: WooCommerce/woocommercewoocommerce/woocommerce-blocks#31522
This commit is contained in:
Lucio Giannotta 2021-12-28 23:32:15 +01:00 committed by GitHub
parent 4d616d7a76
commit 0367117d15
2 changed files with 77 additions and 7 deletions

View File

@ -343,7 +343,7 @@ class BlockTemplatesController {
// 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 ( BlockTemplateUtils::template_is_eligible_for_product_archive_fallback( $template_slug ) ) {
$template_file = get_stylesheet_directory() . '/' . self::TEMPLATES_DIR_NAME . '/archive-product.html';
$template_file = BlockTemplateUtils::get_theme_template_path( 'archive-product' );
$templates[] = BlockTemplateUtils::create_new_block_template_object( $template_file, $template_type, $template_slug, true );
continue;
}

View File

@ -6,6 +6,27 @@ namespace Automattic\WooCommerce\Blocks\Utils;
* IMPORTANT: These methods have been duplicated from Gutenberg/lib/full-site-editing/block-templates.php as those functions are not for public usage.
*/
class BlockTemplateUtils {
/**
* Directory names for block templates
*
* Directory names conventions for block templates have changed with Gutenberg 12.1.0,
* however, for backwards-compatibility, we also keep the older conventions, prefixed
* with `DEPRECATED_`.
*
* @var array {
* @var string DEPRECATED_TEMPLATES Old directory name of the block templates directory.
* @var string DEPRECATED_TEMPLATE_PARTS Old directory name of the block template parts directory.
* @var string TEMPLATES_DIR_NAME Directory name of the block templates directory.
* @var string TEMPLATE_PARTS_DIR_NAME Directory name of the block template parts directory.
* }
*/
const DIRECTORY_NAMES = array(
'DEPRECATED_TEMPLATES' => 'block-templates',
'DEPRECATED_TEMPLATE_PARTS' => 'block-template-parts',
'TEMPLATES' => 'templates',
'TEMPLATE_PARTS' => 'parts',
);
/**
* Returns an array containing the references of
* the passed blocks and their inner blocks.
@ -244,6 +265,57 @@ class BlockTemplateUtils {
);
}
/**
* Gets the first matching template part within themes directories
*
* Since [Gutenberg 12.1.0](https://github.com/WordPress/gutenberg/releases/tag/v12.1.0), the conventions for
* block templates and parts directory has changed from `block-templates` and `block-templates-parts`
* to `templates` and `parts` respectively.
*
* This function traverses all possible combinations of directory paths where a template or part
* could be located and returns the first one which is readable, prioritizing the new convention
* over the deprecated one, but maintaining that one for backwards compatibility.
*
* @param string $template_slug The slug of the template (i.e. without the file extension).
* @param string $template_type Either `wp_template` or `wp_template_part`.
*
* @return string|null The matched path or `null` if no match was found.
*/
public static function get_theme_template_path( $template_slug, $template_type = 'wp_template' ) {
$template_filename = $template_slug . '.html';
$possible_templates_dir = 'wp_template' === $template_type ? array(
self::DIRECTORY_NAMES['TEMPLATES'],
self::DIRECTORY_NAMES['DEPRECATED_TEMPLATES'],
) : array(
self::DIRECTORY_NAMES['TEMPLATE_PARTS'],
self::DIRECTORY_NAMES['DEPRECATED_TEMPLATE_PARTS'],
);
// Combine the possible root directory names with either the template directory
// or the stylesheet directory for child themes.
$possible_paths = array_reduce(
$possible_templates_dir,
function( $carry, $item ) use ( $template_filename ) {
$filepath = DIRECTORY_SEPARATOR . $item . DIRECTORY_SEPARATOR . $template_filename;
$carry[] = get_template_directory() . $filepath;
$carry[] = get_stylesheet_directory() . $filepath;
return $carry;
},
array()
);
// Return the first matching.
foreach ( $possible_paths as $path ) {
if ( is_readable( $path ) ) {
return $path;
}
}
return null;
}
/**
* Check if the theme has a template. So we know if to load our own in or not.
*
@ -251,8 +323,7 @@ class BlockTemplateUtils {
* @return boolean
*/
public static function theme_has_template( $template_name ) {
return is_readable( get_template_directory() . '/block-templates/' . $template_name . '.html' ) ||
is_readable( get_stylesheet_directory() . '/block-templates/' . $template_name . '.html' );
return ! ! self::get_theme_template_path( $template_name, 'wp_template' );
}
/**
@ -262,8 +333,7 @@ class BlockTemplateUtils {
* @return boolean
*/
public static function theme_has_template_part( $template_name ) {
return is_readable( get_template_directory() . '/block-template-parts/' . $template_name . '.html' ) ||
is_readable( get_stylesheet_directory() . '/block-template-parts/' . $template_name . '.html' );
return ! ! self::get_theme_template_path( $template_name, 'wp_template_part' );
}
/**
@ -311,8 +381,8 @@ class BlockTemplateUtils {
*
* 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.
* @param array $query_result Array of template objects.
* @param object $template A specific template object which could have a fallback.
*
* @return boolean
*/