Skip to content

Commit

Permalink
move template hierarchy calculation client side
Browse files Browse the repository at this point in the history
  • Loading branch information
ntsekouras committed Aug 3, 2022
1 parent 24a5509 commit d1eb0d0
Show file tree
Hide file tree
Showing 7 changed files with 277 additions and 50 deletions.
40 changes: 0 additions & 40 deletions lib/compat/wordpress-6.1/block-template-utils.php
Expand Up @@ -296,43 +296,3 @@ function gutenberg_build_block_template_result_from_post( $post ) {
}
return $template;
}

/**
* Helper function to get the Template Hierarchy for a given slug.
* We need to Handle special cases here like `front-page`, `singular` and `archive` templates.
*
* Noting that we always add `index` as the last fallback template.
*
* @param string $slug The slug from which to extract the template hierarchy.
* @return array<string> The template hierarchy.
*/
function gutenberg_get_template_hierarchy( $slug ) {
if ( 'front-page' === $slug ) {
return array( 'front-page', 'home', 'index' );
}
$limit = 2;
if ( strpos( $slug, 'single-' ) === 0 || strpos( $slug, 'taxonomy-' ) === 0 ) {
// E.g. `single-post-hello` or `taxonomy-recipes-vegetarian`.
$limit = 3;
}
$parts = explode( '-', $slug, $limit );
$type = array_shift( $parts );
$slugs = array( $type );
foreach ( $parts as $part ) {
array_unshift( $slugs, $slugs[0] . '-' . $part );
}
// Handle `archive` template.
if ( strpos( $slug, 'author' ) === 0 || strpos( $slug, 'category' ) === 0 || strpos( $slug, 'taxonomy' ) === 0 || strpos( $slug, 'tag' ) === 0 || 'date' === $slug ) {
$slugs[] = 'archive';
}
// Handle `single` template.
if ( 'attachment' === $slug ) {
$slugs[] = 'single';
}
// Handle `singular` template.
if ( strpos( $slug, 'single' ) === 0 || strpos( $slug, 'page' ) === 0 || 'attachment' === $slug ) {
$slugs[] = 'singular';
}
$slugs[] = 'index';
return $slugs;
}
Expand Up @@ -27,10 +27,17 @@ public function register_routes() {
'callback' => array( $this, 'get_template_fallback' ),
'permission_callback' => array( $this, 'get_items_permissions_check' ),
'args' => array(
'slug' => array(
'description' => __( 'The slug of the template to get the fallback content for', 'gutenberg' ),
'slug' => array(
'description' => __( 'The slug of the template to get the fallback for', 'gutenberg' ),
'type' => 'string',
),
'hierarchy' => array(
'description' => __( 'The template hierarchy to use to resolve the fallback template', 'gutenberg' ),
'type' => 'array',
'items' => array(
'type' => 'string',
),
),
),
),
)
Expand All @@ -53,8 +60,14 @@ public function get_template_fallback( $request ) {
array( 'status' => 400 )
);
}
$template_hierarchy = gutenberg_get_template_hierarchy( $request['slug'] );
$fallback_template = resolve_block_template( $request['slug'], $template_hierarchy, '' );
if ( empty( $request['hierarchy'] ) || ! is_array( $request['hierarchy'] ) ) {
return new WP_Error(
'rest_invalid_param',
__( 'Invalid hierarchy.', 'gutenberg' ),
array( 'status' => 400 )
);
}
$fallback_template = resolve_block_template( $request['slug'], $request['hierarchy'], '' );
return rest_ensure_response( $fallback_template );
}

Expand Down
Expand Up @@ -192,9 +192,18 @@ function AddCustomTemplateModal( { onClose, onSelect, entityForSuggestions } ) {
isBlock
as={ Button }
onClick={ () => {
const { slug, title, description } =
entityForSuggestions.template;
onSelect( { slug, title, description } );
const {
slug,
title,
description,
templatePrefix,
} = entityForSuggestions.template;
onSelect( {
slug,
title,
description,
templatePrefix,
} );
} }
>
<Text as="span" weight={ 600 }>
Expand Down
Expand Up @@ -41,6 +41,7 @@ import {
useTaxonomiesMenuItems,
usePostTypeMenuItems,
useAuthorMenuItem,
getTemplateHierarchy,
} from './utils';
import AddCustomGenericTemplateModal from './add-custom-generic-template-modal';
import { useHistory } from '../routes';
Expand Down Expand Up @@ -93,13 +94,18 @@ export default function NewTemplate( { postType } ) {

async function createTemplate( template, isWPSuggestion = true ) {
try {
const { title, description, slug } = template;
const { title, description, slug, templatePrefix } = template;
let templateContent = template.content;
// Try to find fallback content from existing templates.
if ( ! templateContent ) {
const templateHierarchy = getTemplateHierarchy( slug, {
templatePrefix,
isCustom: ! isWPSuggestion,
} );
const fallbackTemplate = await apiFetch( {
path: addQueryArgs( '/wp/v2/templates/lookup', {
slug,
hierarchy: templateHierarchy,
} ),
} );
templateContent = fallbackTemplate.content;
Expand Down
165 changes: 165 additions & 0 deletions packages/edit-site/src/components/add-new-template/test/utils.js
@@ -0,0 +1,165 @@
/**
* Internal dependencies
*/
/**
* Internal dependencies
*/
import { getTemplateHierarchy } from '../utils';

describe( 'add new template utils', () => {
describe( 'getTemplateHierarchy', () => {
it( 'front-page', () => {
const result = getTemplateHierarchy( 'front-page' );
expect( result ).toEqual( [ 'front-page', 'home', 'index' ] );
} );
it( 'custom templates', () => {
const result = getTemplateHierarchy( 'whatever-slug', {
isCustom: true,
} );
expect( result ).toEqual( [ 'page', 'singular', 'index' ] );
} );
it( 'single slug templates(ex. page, tag, author, etc..)', () => {
let result = getTemplateHierarchy( 'page' );
expect( result ).toEqual( [ 'page', 'singular', 'index' ] );
result = getTemplateHierarchy( 'tag' );
expect( result ).toEqual( [ 'tag', 'archive', 'index' ] );
result = getTemplateHierarchy( 'author' );
expect( result ).toEqual( [ 'author', 'archive', 'index' ] );
result = getTemplateHierarchy( 'date' );
expect( result ).toEqual( [ 'date', 'archive', 'index' ] );
result = getTemplateHierarchy( 'taxonomy' );
expect( result ).toEqual( [ 'taxonomy', 'archive', 'index' ] );
result = getTemplateHierarchy( 'attachment' );
expect( result ).toEqual( [
'attachment',
'single',
'singular',
'index',
] );
result = getTemplateHierarchy( 'singular' );
expect( result ).toEqual( [ 'singular', 'index' ] );
result = getTemplateHierarchy( 'single' );
expect( result ).toEqual( [ 'single', 'singular', 'index' ] );
result = getTemplateHierarchy( 'archive' );
expect( result ).toEqual( [ 'archive', 'index' ] );
result = getTemplateHierarchy( 'index' );
expect( result ).toEqual( [ 'index' ] );
} );
it( 'taxonomies', () => {
let result = getTemplateHierarchy( 'taxonomy-books', {
templatePrefix: 'taxonomy-books',
} );
expect( result ).toEqual( [
'taxonomy-books',
'taxonomy',
'archive',
'index',
] );
// Single word category.
result = getTemplateHierarchy( 'category-fruits', {
templatePrefix: 'category',
} );
expect( result ).toEqual( [
'category-fruits',
'category',
'archive',
'index',
] );
// Multi word category.
result = getTemplateHierarchy( 'category-fruits-yellow', {
templatePrefix: 'category',
} );
expect( result ).toEqual( [
'category-fruits-yellow',
'category',
'archive',
'index',
] );
// Single word taxonomy.
result = getTemplateHierarchy( 'taxonomy-books-action', {
templatePrefix: 'taxonomy-books',
} );
expect( result ).toEqual( [
'taxonomy-books-action',
'taxonomy-books',
'taxonomy',
'archive',
'index',
] );
result = getTemplateHierarchy( 'taxonomy-books-action-adventure', {
templatePrefix: 'taxonomy-books',
} );
expect( result ).toEqual( [
'taxonomy-books-action-adventure',
'taxonomy-books',
'taxonomy',
'archive',
'index',
] );
// Multi word taxonomy/terms.
result = getTemplateHierarchy(
'taxonomy-greek-books-action-adventure',
{
templatePrefix: 'taxonomy-greek-books',
}
);
expect( result ).toEqual( [
'taxonomy-greek-books-action-adventure',
'taxonomy-greek-books',
'taxonomy',
'archive',
'index',
] );
} );
it( 'post types', () => {
let result = getTemplateHierarchy( 'single-book', {
templatePrefix: 'single-book',
} );
expect( result ).toEqual( [
'single-book',
'single',
'singular',
'index',
] );
result = getTemplateHierarchy( 'single-art-project', {
templatePrefix: 'single-art-project',
} );
expect( result ).toEqual( [
'single-art-project',
'single',
'singular',
'index',
] );
result = getTemplateHierarchy( 'single-art-project-imagine', {
templatePrefix: 'single-art-project',
} );
expect( result ).toEqual( [
'single-art-project-imagine',
'single-art-project',
'single',
'singular',
'index',
] );
result = getTemplateHierarchy( 'page-hi', {
templatePrefix: 'page',
} );
expect( result ).toEqual( [
'page-hi',
'page',
'singular',
'index',
] );
} );
it( 'authors', () => {
const result = getTemplateHierarchy( 'author-rigas', {
templatePrefix: 'author',
} );
expect( result ).toEqual( [
'author-rigas',
'author',
'archive',
'index',
] );
} );
} );
} );

0 comments on commit d1eb0d0

Please sign in to comment.