From dce4af152446a6dc64f62cf6371b2dc89a8e3d37 Mon Sep 17 00:00:00 2001 From: Jorge Date: Thu, 1 Dec 2022 22:10:37 +0000 Subject: [PATCH] Update: Remove need for template prefix in gutenberg_get_template_hierarchy. --- ...ss-gutenberg-rest-templates-controller.php | 2 +- .../wordpress-6.2/block-template-utils.php | 112 +++++++++++++++ lib/load.php | 1 + phpunit/block-template-utils-test.php | 135 +++++++++++++++--- 4 files changed, 226 insertions(+), 24 deletions(-) create mode 100644 lib/compat/wordpress-6.2/block-template-utils.php diff --git a/lib/compat/wordpress-6.1/class-gutenberg-rest-templates-controller.php b/lib/compat/wordpress-6.1/class-gutenberg-rest-templates-controller.php index e911b0f1e4d203..f0416e0a50e96f 100644 --- a/lib/compat/wordpress-6.1/class-gutenberg-rest-templates-controller.php +++ b/lib/compat/wordpress-6.1/class-gutenberg-rest-templates-controller.php @@ -55,7 +55,7 @@ public function register_routes() { * @return WP_REST_Response|WP_Error */ public function get_template_fallback( $request ) { - $hierarchy = get_template_hierarchy( $request['slug'], $request['is_custom'], $request['template_prefix'] ); + $hierarchy = gutenberg_get_template_hierarchy( $request['slug'], $request['is_custom'], $request['template_prefix'] ); $fallback_template = resolve_block_template( $request['slug'], $hierarchy, '' ); $response = $this->prepare_item_for_response( $fallback_template, $request ); return rest_ensure_response( $response ); diff --git a/lib/compat/wordpress-6.2/block-template-utils.php b/lib/compat/wordpress-6.2/block-template-utils.php new file mode 100644 index 00000000000000..832b9714dd13d3 --- /dev/null +++ b/lib/compat/wordpress-6.2/block-template-utils.php @@ -0,0 +1,112 @@ + The template hierarchy. + */ +function gutenberg_get_template_hierarchy( $slug, $is_custom = false, $template_prefix = '' ) { + if ( 'index' === $slug ) { + return array( 'index' ); + } + if ( $is_custom ) { + return array( 'page', 'singular', 'index' ); + } + if ( 'front-page' === $slug ) { + return array( 'front-page', 'home', 'index' ); + } + + $template_hierarchy = array( $slug ); + // Most default templates don't have `$template_prefix` assigned. + if ( ! empty( $template_prefix ) ) { + list($type) = explode( '-', $template_prefix ); + // 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 { + $matches = array(); + if ( preg_match( '/^(author|category|archive|tag|page)-(.+)$/', $slug, $matches ) ) { + $template_hierarchy[] = $matches[1]; + } elseif ( preg_match( '/^(single|taxonomy)-(.+)$/', $slug, $matches ) ) { + $type = $matches[1]; + $slug_remaining = $matches[2]; + if ( 'single' === $type ) { + $post_types = get_post_types(); + foreach ( $post_types as $post_type ) { + if ( str_starts_with( $slug_remaining, $post_type ) ) { + // If $slug_remaining is equal to $post_type we have the single-$post_type template. + if ( $slug_remaining === $post_type ) { + $template_hierarchy[] = 'single'; + break; + } + // If $slug_remaining is single-$post_type-$slug template. + if ( str_starts_with( $slug_remaining, $post_type . '-' ) && strlen( $slug_remaining ) > strlen( $post_type ) + 1 ) { + $template_hierarchy[] = "single-$post_type"; + $template_hierarchy[] = 'single'; + break; + } + } + } + } elseif ( 'taxonomy' === $type ) { + $taxonomies = get_taxonomies(); + foreach ( $taxonomies as $taxonomy ) { + if ( str_starts_with( $slug_remaining, $taxonomy ) ) { + // If $slug_remaining is equal to $taxonomy we have the taxonomy-$taxonomy template. + if ( $slug_remaining === $taxonomy ) { + $template_hierarchy[] = 'taxonomy'; + break; + } + // If $slug_remaining is taxonomy-$taxonomy-$term template. + if ( str_starts_with( $slug_remaining, $taxonomy . '-' ) && strlen( $slug_remaining ) > strlen( $taxonomy ) + 1 ) { + $template_hierarchy[] = "taxonomy-$taxonomy"; + $template_hierarchy[] = 'taxonomy'; + break; + } + } + } + } + } + } + // Handle `archive` template. + if ( + str_starts_with( $slug, 'author' ) || + str_starts_with( $slug, 'taxonomy' ) || + str_starts_with( $slug, 'category' ) || + str_starts_with( $slug, 'tag' ) || + 'date' === $slug + ) { + $template_hierarchy[] = 'archive'; + } + // Handle `single` template. + if ( 'attachment' === $slug ) { + $template_hierarchy[] = 'single'; + } + // Handle `singular` template. + if ( + str_starts_with( $slug, 'single' ) || + str_starts_with( $slug, 'page' ) || + 'attachment' === $slug + ) { + $template_hierarchy[] = 'singular'; + } + $template_hierarchy[] = 'index'; + return $template_hierarchy; +} diff --git a/lib/load.php b/lib/load.php index 11830fb9a0c4d3..36edb49432067a 100644 --- a/lib/load.php +++ b/lib/load.php @@ -102,6 +102,7 @@ function gutenberg_is_experiment_enabled( $name ) { // WordPress 6.2 compat. require __DIR__ . '/compat/wordpress-6.2/script-loader.php'; +require __DIR__ . '/compat/wordpress-6.2/block-template-utils.php'; require __DIR__ . '/compat/wordpress-6.2/get-global-styles-and-settings.php'; require __DIR__ . '/compat/wordpress-6.2/default-filters.php'; require __DIR__ . '/compat/wordpress-6.2/class-wp-theme-json-resolver-6-2.php'; diff --git a/phpunit/block-template-utils-test.php b/phpunit/block-template-utils-test.php index ceffe180d98707..ac2e4145cd0ed2 100644 --- a/phpunit/block-template-utils-test.php +++ b/phpunit/block-template-utils-test.php @@ -11,24 +11,40 @@ public function set_up() { switch_theme( 'emptytheme' ); } + public static function wpSetUpBeforeClass() { + register_post_type( + 'custom_book', + array( + 'public' => true, + 'show_in_rest' => true, + ) + ); + register_taxonomy( 'book_type', 'custom_book' ); + } + + public static function wpTearDownAfterClass() { + unregister_post_type( 'custom_book' ); + unregister_taxonomy( 'book_type' ); + } + public function test_get_template_hierarchy() { - $hierarchy = get_template_hierarchy( 'front-page' ); + $hierarchy = gutenberg_get_template_hierarchy( 'front-page' ); $this->assertEquals( array( 'front-page', 'home', 'index' ), $hierarchy ); // Custom templates. - $hierarchy = get_template_hierarchy( 'whatever-slug', true ); + $hierarchy = gutenberg_get_template_hierarchy( 'whatever-slug', true ); $this->assertEquals( array( 'page', 'singular', 'index' ), $hierarchy ); // Single slug templates(ex. page, tag, author, etc.. - $hierarchy = get_template_hierarchy( 'page' ); + $hierarchy = gutenberg_get_template_hierarchy( 'page' ); $this->assertEquals( array( 'page', 'singular', 'index' ), $hierarchy ); - $hierarchy = get_template_hierarchy( 'tag' ); + $hierarchy = gutenberg_get_template_hierarchy( 'tag' ); $this->assertEquals( array( 'tag', 'archive', 'index' ), $hierarchy ); - $hierarchy = get_template_hierarchy( 'author' ); + $hierarchy = gutenberg_get_template_hierarchy( 'author' ); $this->assertEquals( array( 'author', 'archive', 'index' ), $hierarchy ); - $hierarchy = get_template_hierarchy( 'date' ); + $hierarchy = gutenberg_get_template_hierarchy( 'date' ); $this->assertEquals( array( 'date', 'archive', 'index' ), $hierarchy ); - $hierarchy = get_template_hierarchy( 'taxonomy' ); + $hierarchy = gutenberg_get_template_hierarchy( 'taxonomy' ); $this->assertEquals( array( 'taxonomy', 'archive', 'index' ), $hierarchy ); - $hierarchy = get_template_hierarchy( 'attachment' ); + $hierarchy = gutenberg_get_template_hierarchy( 'attachment' ); $this->assertEquals( array( 'attachment', @@ -38,20 +54,34 @@ public function test_get_template_hierarchy() { ), $hierarchy ); - $hierarchy = get_template_hierarchy( 'singular' ); + $hierarchy = gutenberg_get_template_hierarchy( 'singular' ); $this->assertEquals( array( 'singular', 'index' ), $hierarchy ); - $hierarchy = get_template_hierarchy( 'single' ); + $hierarchy = gutenberg_get_template_hierarchy( 'single' ); $this->assertEquals( array( 'single', 'singular', 'index' ), $hierarchy ); - $hierarchy = get_template_hierarchy( 'archive' ); + $hierarchy = gutenberg_get_template_hierarchy( 'archive' ); $this->assertEquals( array( 'archive', 'index' ), $hierarchy ); - $hierarchy = get_template_hierarchy( 'index' ); + $hierarchy = gutenberg_get_template_hierarchy( 'index' ); $this->assertEquals( array( 'index' ), $hierarchy ); // Taxonomies. - $hierarchy = get_template_hierarchy( 'taxonomy-books', false, 'taxonomy-books' ); + $hierarchy = gutenberg_get_template_hierarchy( 'taxonomy-book_type', false ); + $this->assertEquals( array( 'taxonomy-book_type', 'taxonomy', 'archive', 'index' ), $hierarchy ); + + $hierarchy = gutenberg_get_template_hierarchy( 'taxonomy-books', false, 'taxonomy-books' ); $this->assertEquals( array( 'taxonomy-books', 'taxonomy', 'archive', 'index' ), $hierarchy ); // Single word category. - $hierarchy = get_template_hierarchy( 'category-fruits', false, 'category' ); + $hierarchy = gutenberg_get_template_hierarchy( 'category-fruits', false ); + $this->assertEquals( + array( + 'category-fruits', + 'category', + 'archive', + 'index', + ), + $hierarchy + ); + + $hierarchy = gutenberg_get_template_hierarchy( 'category-fruits', false, 'category' ); $this->assertEquals( array( 'category-fruits', @@ -62,7 +92,18 @@ public function test_get_template_hierarchy() { $hierarchy ); // Multi word category. - $hierarchy = get_template_hierarchy( 'category-fruits-yellow', false, 'category' ); + $hierarchy = gutenberg_get_template_hierarchy( 'category-fruits-yellow', false ); + $this->assertEquals( + array( + 'category-fruits-yellow', + 'category', + 'archive', + 'index', + ), + $hierarchy + ); + + $hierarchy = gutenberg_get_template_hierarchy( 'category-fruits-yellow', false, 'category' ); $this->assertEquals( array( 'category-fruits-yellow', @@ -73,7 +114,7 @@ public function test_get_template_hierarchy() { $hierarchy ); // Single word taxonomy. - $hierarchy = get_template_hierarchy( 'taxonomy-books-action', false, 'taxonomy-books' ); + $hierarchy = gutenberg_get_template_hierarchy( 'taxonomy-books-action', false, 'taxonomy-books' ); $this->assertEquals( array( 'taxonomy-books-action', @@ -84,7 +125,11 @@ public function test_get_template_hierarchy() { ), $hierarchy ); - $hierarchy = get_template_hierarchy( 'taxonomy-books-action-adventure', false, 'taxonomy-books' ); + + $hierarchy = gutenberg_get_template_hierarchy( 'taxonomy-book_type-adventure', false ); + $this->assertEquals( array( 'taxonomy-book_type-adventure', 'taxonomy-book_type', 'taxonomy', 'archive', 'index' ), $hierarchy ); + + $hierarchy = gutenberg_get_template_hierarchy( 'taxonomy-books-action-adventure', false, 'taxonomy-books' ); $this->assertEquals( array( 'taxonomy-books-action-adventure', @@ -96,7 +141,7 @@ public function test_get_template_hierarchy() { $hierarchy ); // Multi word taxonomy/terms. - $hierarchy = get_template_hierarchy( 'taxonomy-greek-books-action-adventure', false, 'taxonomy-greek-books' ); + $hierarchy = gutenberg_get_template_hierarchy( 'taxonomy-greek-books-action-adventure', false, 'taxonomy-greek-books' ); $this->assertEquals( array( 'taxonomy-greek-books-action-adventure', @@ -108,7 +153,7 @@ public function test_get_template_hierarchy() { $hierarchy ); // Post types. - $hierarchy = get_template_hierarchy( 'single-book', false, 'single-book' ); + $hierarchy = gutenberg_get_template_hierarchy( 'single-book', false, 'single-book' ); $this->assertEquals( array( 'single-book', @@ -118,7 +163,7 @@ public function test_get_template_hierarchy() { ), $hierarchy ); - $hierarchy = get_template_hierarchy( 'single-art-project', false, 'single-art-project' ); + $hierarchy = gutenberg_get_template_hierarchy( 'single-art-project', false, 'single-art-project' ); $this->assertEquals( array( 'single-art-project', @@ -128,7 +173,7 @@ public function test_get_template_hierarchy() { ), $hierarchy ); - $hierarchy = get_template_hierarchy( 'single-art-project-imagine', false, 'single-art-project' ); + $hierarchy = gutenberg_get_template_hierarchy( 'single-art-project-imagine', false, 'single-art-project' ); $this->assertEquals( array( 'single-art-project-imagine', @@ -139,7 +184,41 @@ public function test_get_template_hierarchy() { ), $hierarchy ); - $hierarchy = get_template_hierarchy( 'page-hi', false, 'page' ); + + $hierarchy = gutenberg_get_template_hierarchy( 'single-custom_book', false ); + $this->assertEquals( + array( + 'single-custom_book', + 'single', + 'singular', + 'index', + ), + $hierarchy + ); + + $hierarchy = gutenberg_get_template_hierarchy( 'single-custom_book-book-1', false ); + $this->assertEquals( + array( + 'single-custom_book-book-1', + 'single-custom_book', + 'single', + 'singular', + 'index', + ), + $hierarchy + ); + + $hierarchy = gutenberg_get_template_hierarchy( 'page-hi', false, 'page' ); + $this->assertEquals( + array( + 'page-hi', + 'page', + 'singular', + 'index', + ), + $hierarchy + ); + $hierarchy = gutenberg_get_template_hierarchy( 'page-hi', false ); $this->assertEquals( array( 'page-hi', @@ -150,7 +229,7 @@ public function test_get_template_hierarchy() { $hierarchy ); // Authors. - $hierarchy = get_template_hierarchy( 'author-rigas', false, 'author' ); + $hierarchy = gutenberg_get_template_hierarchy( 'author-rigas', false, 'author' ); $this->assertEquals( array( 'author-rigas', @@ -160,5 +239,15 @@ public function test_get_template_hierarchy() { ), $hierarchy ); + // Archive post types. + $hierarchy = gutenberg_get_template_hierarchy( 'archive-book', false ); + $this->assertEquals( + array( + 'archive-book', + 'archive', + 'index', + ), + $hierarchy + ); } }