Skip to content

Commit

Permalink
Full Site Editing: Add Support for Templates Default and Custom Title…
Browse files Browse the repository at this point in the history
…s and Descriptions (JS Side) (#27038)

- New templates created from the Site Editor sidebar will also automatically use the default template types definitions, and will be saved as `draft`. They will become `published` once saved the first time.
- The default definitions are used across the Site Editor as a fallback for templates without title or excerpt.
- Converted the `getTemplateInfo` utility into the `getTemplateInfo` selector, since it relies on the `core/editor` state.
  • Loading branch information
Copons authored Nov 20, 2020
1 parent c31e29d commit 3aeb89e
Show file tree
Hide file tree
Showing 17 changed files with 387 additions and 249 deletions.
21 changes: 21 additions & 0 deletions packages/edit-site/src/components/editor/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -105,8 +105,18 @@ function Editor() {
};
}, [] );
const { editEntityRecord } = useDispatch( 'core' );
const { updateEditorSettings } = useDispatch( 'core/editor' );
const { setPage, setIsInserterOpened } = useDispatch( 'core/edit-site' );

// Keep the defaultTemplateTypes in the core/editor settings too,
// so that they can be selected with core/editor selectors in any editor.
// This is needed because edit-site doesn't initialize with EditorProvider,
// which internally uses updateEditorSettings as well.
const { defaultTemplateTypes } = settings;
useEffect( () => {
updateEditorSettings( { defaultTemplateTypes } );
}, [ defaultTemplateTypes ] );

const inlineStyles = useResizeCanvas( deviceType );

const [
Expand All @@ -121,9 +131,20 @@ function Editor() {
( entitiesToSave ) => {
if ( entitiesToSave ) {
const { getEditedEntityRecord } = select( 'core' );
const {
__experimentalGetTemplateInfo: getTemplateInfo,
} = select( 'core/editor' );
entitiesToSave.forEach( ( { kind, name, key } ) => {
const record = getEditedEntityRecord( kind, name, key );

if ( 'postType' === kind && name === 'wp_template' ) {
const { title } = getTemplateInfo( record );
return editEntityRecord( kind, name, key, {
status: 'publish',
title,
} );
}

const edits = record.slug
? { status: 'publish', title: record.slug }
: { status: 'publish' };
Expand Down
66 changes: 38 additions & 28 deletions packages/edit-site/src/components/header/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,13 @@ import UndoButton from './undo-redo/undo';
import RedoButton from './undo-redo/redo';
import DocumentActions from './document-actions';
import TemplateDetails from '../template-details';
import { getTemplateInfo } from '../../utils';

export default function Header( { openEntitiesSavedStates } ) {
const {
deviceType,
entityTitle,
hasFixedToolbar,
template,
templatePart,
templateType,
isInserterOpen,
} = useSelect( ( select ) => {
Expand All @@ -43,20 +42,33 @@ export default function Header( { openEntitiesSavedStates } ) {
isInserterOpened,
} = select( 'core/edit-site' );
const { getEntityRecord } = select( 'core' );
const { __experimentalGetTemplateInfo: getTemplateInfo } = select(
'core/editor'
);

const templatePartId = getTemplatePartId();
const templateId = getTemplateId();
const _templateType = getTemplateType();
const _template = getEntityRecord(
'postType',
'wp_template',
getTemplateId()
);
const _templatePart = getEntityRecord(
'postType',
'wp_template_part',
getTemplatePartId()
);

const _entityTitle =
'wp_template' === _templateType
? getTemplateInfo( _template ).title
: _templatePart?.slug;

return {
deviceType: __experimentalGetPreviewDeviceType(),
entityTitle: _entityTitle,
hasFixedToolbar: isFeatureActive( 'fixedToolbar' ),
template: getEntityRecord( 'postType', 'wp_template', templateId ),
templatePart: getEntityRecord(
'postType',
'wp_template_part',
templatePartId
),
templateType: getTemplateType(),
template: _template,
templateType: _templateType,
isInserterOpen: isInserterOpened(),
};
}, [] );
Expand All @@ -70,11 +82,6 @@ export default function Header( { openEntitiesSavedStates } ) {
const displayBlockToolbar =
! isLargeViewport || deviceType !== 'Desktop' || hasFixedToolbar;

let { title } = getTemplateInfo( template );
if ( 'wp_template_part' === templateType ) {
title = templatePart?.slug;
}

return (
<div className="edit-site-header">
<div className="edit-site-header_start">
Expand Down Expand Up @@ -109,22 +116,25 @@ export default function Header( { openEntitiesSavedStates } ) {
</div>

<div className="edit-site-header_center">
<DocumentActions
entityTitle={ title }
entityLabel={
templateType === 'wp_template'
? 'template'
: 'template part'
}
>
{ templateType === 'wp_template' &&
( ( { onClose } ) => (
{ 'wp_template' === templateType && (
<DocumentActions
entityTitle={ entityTitle }
entityLabel="template"
>
{ ( { onClose } ) => (
<TemplateDetails
template={ template }
onClose={ onClose }
/>
) ) }
</DocumentActions>
) }
</DocumentActions>
) }
{ 'wp_template_part' === templateType && (
<DocumentActions
entityTitle={ entityTitle }
entityLabel="template part"
/>
) }
</div>

<div className="edit-site-header_end">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ export const TEMPLATES_GENERAL = [

export const TEMPLATES_POSTS = [ 'home', 'single' ];

export const TEMPLATES_STATUSES = [ 'publish', 'draft', 'auto-draft' ];

export const MENU_ROOT = 'root';
export const MENU_CONTENT_CATEGORIES = 'content-categories';
export const MENU_CONTENT_PAGES = 'content-pages';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import {
MENU_TEMPLATES_PAGES,
MENU_TEMPLATES_POSTS,
TEMPLATES_GENERAL,
TEMPLATES_STATUSES,
} from '../constants';
import TemplatesAllMenu from './templates-all';
import NewTemplateDropdown from '../new-template-dropdown';
Expand All @@ -34,7 +35,7 @@ export default function TemplatesMenu() {
const templates = useSelect(
( select ) =>
select( 'core' ).getEntityRecords( 'postType', 'wp_template', {
status: [ 'publish', 'auto-draft' ],
status: TEMPLATES_STATUSES,
per_page: -1,
} ),
[]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/**
* External dependencies
*/
import { map, filter, includes } from 'lodash';
import { filter, find, includes, map } from 'lodash';

/**
* WordPress dependencies
Expand All @@ -20,36 +20,45 @@ import { Icon, plus } from '@wordpress/icons';
* Internal dependencies
*/
import getClosestAvailableTemplate from '../../../utils/get-closest-available-template';
import { TEMPLATES_DEFAULT_DETAILS } from '../../../utils/get-template-info/constants';
import { TEMPLATES_STATUSES } from './constants';

export default function NewTemplateDropdown() {
const templates = useSelect(
( select ) =>
select( 'core' ).getEntityRecords( 'postType', 'wp_template', {
status: [ 'publish', 'auto-draft' ],
per_page: -1,
} ),
[]
);
const { defaultTemplateTypes, templates } = useSelect( ( select ) => {
const {
__experimentalGetDefaultTemplateTypes: getDefaultTemplateTypes,
} = select( 'core/editor' );
const templateEntities = select( 'core' ).getEntityRecords(
'postType',
'wp_template',
{ status: TEMPLATES_STATUSES, per_page: -1 }
);
return {
defaultTemplateTypes: getDefaultTemplateTypes(),
templates: templateEntities,
};
}, [] );
const { addTemplate } = useDispatch( 'core/edit-site' );

const createTemplate = ( slug ) => {
const closestAvailableTemplate = getClosestAvailableTemplate(
slug,
templates
);
const { title, description } = find( defaultTemplateTypes, { slug } );
addTemplate( {
content: closestAvailableTemplate.content.raw,
slug,
title: slug,
excerpt: description,
// Slugs need to be strings, so this is for template `404`
slug: slug.toString(),
status: 'draft',
title,
} );
};

const existingTemplateSlugs = map( templates, 'slug' );

const missingTemplates = filter(
TEMPLATES_DEFAULT_DETAILS,
defaultTemplateTypes,
( template ) => ! includes( existingTemplateSlugs, template.slug )
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,11 @@
}
}

.edit-site-navigation-panel__template-item-title {
em {
margin-right: 1ch;
}
}
.edit-site-navigation-panel__template-item-description {
padding-top: $grid-unit-05;
font-size: 12px;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,30 @@ import {
Button,
__experimentalNavigationItem as NavigationItem,
} from '@wordpress/components';
import { useDispatch } from '@wordpress/data';
import { useDispatch, useSelect } from '@wordpress/data';
import { useState } from '@wordpress/element';
import { __ } from '@wordpress/i18n';

/**
* Internal dependencies
*/
import TemplatePreview from './template-preview';
import { NavigationPanelPreviewFill } from '../index';
import { getTemplateInfo } from '../../../utils';

export default function TemplateNavigationItem( { item } ) {
const { title, description } = useSelect(
( select ) =>
'wp_template' === item.type
? select( 'core/editor' ).__experimentalGetTemplateInfo( item )
: { title: item?.slug, description: '' },
[]
);
const { setTemplate, setTemplatePart } = useDispatch( 'core/edit-site' );
const [ isPreviewVisible, setIsPreviewVisible ] = useState( false );

const { title, description } = getTemplateInfo( item );
if ( ! item ) {
return null;
}

const onActivateItem = () =>
'wp_template' === item.type
Expand All @@ -37,7 +46,10 @@ export default function TemplateNavigationItem( { item } ) {
onMouseEnter={ () => setIsPreviewVisible( true ) }
onMouseLeave={ () => setIsPreviewVisible( false ) }
>
{ title }
<div className="edit-site-navigation-panel__template-item-title">
{ 'draft' === item.status && <em>{ __( '[Draft]' ) }</em> }
{ title }
</div>
{ description && (
<div className="edit-site-navigation-panel__template-item-description">
{ description }
Expand Down
11 changes: 7 additions & 4 deletions packages/edit-site/src/components/template-details/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,25 @@
*/
import { __, sprintf } from '@wordpress/i18n';
import { Button, __experimentalText as Text } from '@wordpress/components';
import { useDispatch } from '@wordpress/data';
import { useDispatch, useSelect } from '@wordpress/data';

/**
* Internal dependencies
*/
import { getTemplateInfo } from '../../utils';
import { MENU_TEMPLATES } from '../navigation-sidebar/navigation-panel/constants';

export default function TemplateDetails( { template, onClose } ) {
const { title, description } = useSelect(
( select ) =>
select( 'core/editor' ).__experimentalGetTemplateInfo( template ),
[]
);
const { openNavigationPanelToMenu } = useDispatch( 'core/edit-site' );

if ( ! template ) {
return null;
}

const { title, description } = getTemplateInfo( template );

const showTemplateInSidebar = () => {
onClose();
openNavigationPanelToMenu( MENU_TEMPLATES );
Expand Down
32 changes: 20 additions & 12 deletions packages/edit-site/src/utils/get-closest-available-template.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,28 @@
import { find } from 'lodash';

export default function getClosestAvailableTemplate( slug, templates ) {
if ( 'front-page' === slug ) {
const homeTemplate = find( templates, { slug: 'home' } );
if ( homeTemplate ) {
return homeTemplate;
}
const template = find( templates, { slug } );
if ( template ) {
return template;
}

if ( 'single' === slug || 'page' === slug ) {
const singularTemplate = find( templates, { slug: 'singular' } );
if ( singularTemplate ) {
return singularTemplate;
}
switch ( slug ) {
case 'single':
case 'page':
return getClosestAvailableTemplate( 'singular', templates );
case 'author':
case 'category':
case 'taxonomy':
case 'date':
case 'tag':
return getClosestAvailableTemplate( 'archive', templates );
case 'front-page':
return getClosestAvailableTemplate( 'home', templates );
case 'attachment':
return getClosestAvailableTemplate( 'single', templates );
case 'privacy-policy':
return getClosestAvailableTemplate( 'page', templates );
}

const indexTemplate = find( templates, { slug: 'index' } );
return indexTemplate;
return find( templates, { slug: 'index' } );
}
Loading

0 comments on commit 3aeb89e

Please sign in to comment.