Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add "Add New" feature for templates list in Site Editor
- Loading branch information
1 parent
28e7eb3
commit 256a1ef
Showing
13 changed files
with
415 additions
and
162 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
30 changes: 30 additions & 0 deletions
30
packages/edit-site/src/components/add-new-template/index.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
/** | ||
* WordPress dependencies | ||
*/ | ||
import { useSelect } from '@wordpress/data'; | ||
import { store as coreStore } from '@wordpress/core-data'; | ||
|
||
/** | ||
* Internal dependencies | ||
*/ | ||
import NewTemplate from './new-template'; | ||
import NewTemplatePart from './new-template-part'; | ||
|
||
export default function AddNewTemplate( { templateType = 'wp_template' } ) { | ||
const postType = useSelect( | ||
( select ) => select( coreStore ).getPostType( templateType ), | ||
[ templateType ] | ||
); | ||
|
||
if ( ! postType ) { | ||
return null; | ||
} | ||
|
||
if ( templateType === 'wp_template' ) { | ||
return <NewTemplate postType={ postType } />; | ||
} else if ( templateType === 'wp_template_part' ) { | ||
return <NewTemplatePart postType={ postType } />; | ||
} | ||
|
||
return null; | ||
} |
66 changes: 66 additions & 0 deletions
66
packages/edit-site/src/components/add-new-template/new-template-part.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
/** | ||
* External dependencies | ||
*/ | ||
import { kebabCase } from 'lodash'; | ||
|
||
/** | ||
* WordPress dependencies | ||
*/ | ||
import { useState } from '@wordpress/element'; | ||
import { Button } from '@wordpress/components'; | ||
import { useDispatch } from '@wordpress/data'; | ||
import { store as coreStore } from '@wordpress/core-data'; | ||
import { addQueryArgs } from '@wordpress/url'; | ||
|
||
/** | ||
* Internal dependencies | ||
*/ | ||
import CreateTemplatePartModal from '../create-template-part-modal'; | ||
|
||
export default function NewTemplatePart( { postType } ) { | ||
const [ isModalOpen, setIsModalOpen ] = useState( false ); | ||
const { saveEntityRecord } = useDispatch( coreStore ); | ||
|
||
async function createTemplatePart( { title, area } ) { | ||
if ( ! title || ! area ) { | ||
return; | ||
} | ||
|
||
const templatePart = await saveEntityRecord( | ||
'postType', | ||
'wp_template_part', | ||
{ | ||
slug: kebabCase( title ), | ||
title, | ||
content: '', | ||
area, | ||
} | ||
); | ||
|
||
// Navigate to the created template part editor. | ||
window.location.search = addQueryArgs( '', { | ||
page: 'gutenberg-edit-site', | ||
postId: templatePart.id, | ||
postType: 'wp_template_part', | ||
} ); | ||
} | ||
|
||
return ( | ||
<> | ||
<Button | ||
variant="primary" | ||
onClick={ () => { | ||
setIsModalOpen( true ); | ||
} } | ||
> | ||
{ postType.labels.add_new } | ||
</Button> | ||
{ isModalOpen && ( | ||
<CreateTemplatePartModal | ||
closeModal={ () => setIsModalOpen( false ) } | ||
onCreate={ createTemplatePart } | ||
/> | ||
) } | ||
</> | ||
); | ||
} |
118 changes: 118 additions & 0 deletions
118
packages/edit-site/src/components/add-new-template/new-template.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
/** | ||
* External dependencies | ||
*/ | ||
import { filter, find, includes, map } from 'lodash'; | ||
|
||
/** | ||
* WordPress dependencies | ||
*/ | ||
import { | ||
DropdownMenu, | ||
MenuGroup, | ||
MenuItem, | ||
NavigableMenu, | ||
} from '@wordpress/components'; | ||
import { useDispatch, useSelect } from '@wordpress/data'; | ||
import { store as coreStore } from '@wordpress/core-data'; | ||
import { store as editorStore } from '@wordpress/editor'; | ||
import { addQueryArgs } from '@wordpress/url'; | ||
|
||
/** | ||
* Internal dependencies | ||
*/ | ||
import { store as editSiteStore } from '../../store'; | ||
|
||
const DEFAULT_TEMPLATE_SLUGS = [ | ||
'front-page', | ||
'single-post', | ||
'page', | ||
'archive', | ||
'search', | ||
'404', | ||
'index', | ||
]; | ||
|
||
export default function NewTemplate( { postType } ) { | ||
const { templates, defaultTemplateTypes } = useSelect( | ||
( select ) => ( { | ||
templates: select( coreStore ).getEntityRecords( | ||
'postType', | ||
'wp_template' | ||
), | ||
defaultTemplateTypes: select( | ||
editorStore | ||
).__experimentalGetDefaultTemplateTypes(), | ||
} ), | ||
[] | ||
); | ||
const { addTemplate } = useDispatch( editSiteStore ); | ||
|
||
async function createTemplate( slug ) { | ||
const { title, description } = find( defaultTemplateTypes, { slug } ); | ||
|
||
const { templateId } = await addTemplate( { | ||
excerpt: description, | ||
// Slugs need to be strings, so this is for template `404` | ||
slug: slug.toString(), | ||
status: 'publish', | ||
title, | ||
} ); | ||
|
||
// Navigate to the created template editor. | ||
window.location.search = addQueryArgs( '', { | ||
page: 'gutenberg-edit-site', | ||
postId: templateId, | ||
postType: 'wp_template', | ||
} ); | ||
} | ||
|
||
const existingTemplateSlugs = map( templates, 'slug' ); | ||
|
||
const missingTemplates = filter( | ||
defaultTemplateTypes, | ||
( template ) => | ||
includes( DEFAULT_TEMPLATE_SLUGS, template.slug ) && | ||
! includes( existingTemplateSlugs, template.slug ) | ||
); | ||
|
||
if ( ! missingTemplates.length ) { | ||
return null; | ||
} | ||
|
||
return ( | ||
<DropdownMenu | ||
className="edit-site-new-template-dropdown" | ||
icon={ null } | ||
text={ postType.labels.add_new } | ||
label={ postType.labels.add_new_item } | ||
popoverProps={ { | ||
noArrow: false, | ||
} } | ||
toggleProps={ { | ||
variant: 'primary', | ||
} } | ||
> | ||
{ ( { onClose } ) => ( | ||
<NavigableMenu className="edit-site-new-template-dropdown__popover"> | ||
<MenuGroup label={ postType.labels.add_new_item }> | ||
{ map( | ||
missingTemplates, | ||
( { title, description, slug } ) => ( | ||
<MenuItem | ||
info={ description } | ||
key={ slug } | ||
onClick={ () => { | ||
createTemplate( slug ); | ||
onClose(); | ||
} } | ||
> | ||
{ title } | ||
</MenuItem> | ||
) | ||
) } | ||
</MenuGroup> | ||
</NavigableMenu> | ||
) } | ||
</DropdownMenu> | ||
); | ||
} |
11 changes: 11 additions & 0 deletions
11
packages/edit-site/src/components/add-new-template/style.scss
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
.edit-site-new-template-dropdown { | ||
.components-dropdown-menu__toggle { | ||
padding: 6px 12px; | ||
} | ||
|
||
.edit-site-new-template-dropdown__popover { | ||
@include break-small() { | ||
min-width: 300px; | ||
} | ||
} | ||
} |
Oops, something went wrong.