diff --git a/src/wp-includes/block-template-utils.php b/src/wp-includes/block-template-utils.php index 66c48db7f1305..acbb7724c5325 100644 --- a/src/wp-includes/block-template-utils.php +++ b/src/wp-includes/block-template-utils.php @@ -1325,20 +1325,46 @@ function get_template_hierarchy( $slug, $is_custom = false, $template_prefix = ' return array( 'front-page', 'home', 'index' ); } - $template_hierarchy = array( $slug ); + $matches = array(); + $template_hierarchy = array( $slug ); // Most default templates don't have `$template_prefix` assigned. - if ( $template_prefix ) { + if ( ! empty( $template_prefix ) ) { list( $type ) = explode( '-', $template_prefix ); - // These checks are needed because the `$slug` above is always added. + // We need these checks because we always add the `$slug` above. if ( ! in_array( $template_prefix, array( $slug, $type ), true ) ) { $template_hierarchy[] = $template_prefix; } if ( $slug !== $type ) { $template_hierarchy[] = $type; } - } + } else if ( preg_match( '/^(author|category|archive|tag|page)-.+$/', $slug, $matches ) ) { + $template_hierarchy[] = $matches[1]; + } else if ( preg_match( '/^(taxonomy|single)-(.+)$/', $slug, $matches ) ) { + $type = $matches[1]; + $slug_remaining = $matches[2]; + + $items = 'single' === $type ? get_post_types() : get_taxonomies(); + foreach ( $items as $item ) { + if ( ! str_starts_with( $slug_remaining, $item ) ) { + continue; + } + + // If $slug_remaining is equal to $post_type or $taxonomy we have + // the single-$post_type template or the taxonomy-$taxonomy template. + if ( $slug_remaining === $item ) { + $template_hierarchy[] = $type; + break; + } + // If $slug_remaining is single-$post_type-$slug template. + if ( strlen( $slug_remaining ) > strlen( $item ) + 1 ) { + $template_hierarchy[] = "$type-$item"; + $template_hierarchy[] = $type; + break; + } + } + } // Handle `archive` template. if ( str_starts_with( $slug, 'author' ) || @@ -1353,7 +1379,6 @@ function get_template_hierarchy( $slug, $is_custom = false, $template_prefix = ' if ( 'attachment' === $slug ) { $template_hierarchy[] = 'single'; } - // Handle `singular` template. if ( str_starts_with( $slug, 'single' ) || @@ -1362,8 +1387,6 @@ function get_template_hierarchy( $slug, $is_custom = false, $template_prefix = ' ) { $template_hierarchy[] = 'singular'; } - $template_hierarchy[] = 'index'; - return $template_hierarchy; } diff --git a/tests/phpunit/tests/block-templates/getTemplateHierarchy.php b/tests/phpunit/tests/block-templates/getTemplateHierarchy.php index e550b22778417..fab91786650bf 100644 --- a/tests/phpunit/tests/block-templates/getTemplateHierarchy.php +++ b/tests/phpunit/tests/block-templates/getTemplateHierarchy.php @@ -8,6 +8,26 @@ */ class Tests_Block_Templates_GetTemplate_Hierarchy extends WP_Block_Templates_UnitTestCase { + public function set_up() { + parent::set_up(); + register_post_type( + 'custom_book', + array( + 'public' => true, + 'show_in_rest' => true, + ) + ); + register_taxonomy( 'book_type', 'custom_book' ); + register_taxonomy( 'books', 'custom_book' ); + } + + public function tear_down() { + unregister_post_type( 'custom_book' ); + unregister_taxonomy( 'book_type' ); + unregister_taxonomy( 'books' ); + parent::tear_down(); + } + /** * @dataProvider data_get_template_hierarchy * @@ -83,14 +103,26 @@ public function data_get_template_hierarchy() { 'args' => array( 'category-fruits', false, 'category' ), 'expected' => array( 'category-fruits', 'category', 'archive', 'index' ), ), + 'single word categories no prefix' => array( + 'args' => array( 'category-fruits', false ), + 'expected' => array( 'category-fruits', 'category', 'archive', 'index' ), + ), 'multi word categories' => array( 'args' => array( 'category-fruits-yellow', false, 'category' ), 'expected' => array( 'category-fruits-yellow', 'category', 'archive', 'index' ), ), + 'multi word categories no prefix' => array( + 'args' => array( 'category-fruits-yellow', false ), + 'expected' => array( 'category-fruits-yellow', 'category', 'archive', 'index' ), + ), 'single word taxonomy and term' => array( 'args' => array( 'taxonomy-books-action', false, 'taxonomy-books' ), 'expected' => array( 'taxonomy-books-action', 'taxonomy-books', 'taxonomy', 'archive', 'index' ), ), + 'single word taxonomy and term no prefix' => array( + 'args' => array( 'taxonomy-books-action', false ), + 'expected' => array( 'taxonomy-books-action', 'taxonomy-books', 'taxonomy', 'archive', 'index' ), + ), 'single word taxonomy and multi word term' => array( 'args' => array( 'taxonomy-books-action-adventure', false, 'taxonomy-books' ), 'expected' => array( 'taxonomy-books-action-adventure', 'taxonomy-books', 'taxonomy', 'archive', 'index' ), @@ -119,6 +151,46 @@ public function data_get_template_hierarchy() { 'args' => array( 'author-rigas', false, 'author' ), 'expected' => array( 'author-rigas', 'author', 'archive', 'index' ), ), + 'multiple word taxonomy no prefix' => array( + 'args' => array( 'taxonomy-book_type-adventure', false ), + 'expected' => array( 'taxonomy-book_type-adventure', 'taxonomy-book_type', 'taxonomy', 'archive', 'index' ), + ), + 'single post type no prefix' => array( + 'args' => array( 'single-custom_book', false ), + 'expected' => array( + 'single-custom_book', + 'single', + 'singular', + 'index', + ), + ), + 'single post and post type no prefix' => array( + 'args' => array( 'single-custom_book-book-1', false ), + 'expected' => array( + 'single-custom_book-book-1', + 'single-custom_book', + 'single', + 'singular', + 'index', + ), + ), + 'page no prefix' => array( + 'args' => array( 'page-hi', false ), + 'expected' => array( + 'page-hi', + 'page', + 'singular', + 'index', + ), + ), + 'post type archive no prefix' => array( + 'args' => array( 'archive-book', false ), + 'expected' => array( + 'archive-book', + 'archive', + 'index', + ), + ), ); } }