-
Notifications
You must be signed in to change notification settings - Fork 4.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Quick Edit: add Template field (#66591)
Co-authored-by: louwie17 <[email protected]> Co-authored-by: gigitux <[email protected]> Co-authored-by: youknowriad <[email protected]>
- Loading branch information
1 parent
6d40fb4
commit a5bfc41
Showing
13 changed files
with
305 additions
and
2 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
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
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
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
/** | ||
* WordPress dependencies | ||
*/ | ||
import type { Field } from '@wordpress/dataviews'; | ||
|
||
/** | ||
* Internal dependencies | ||
*/ | ||
import { __ } from '@wordpress/i18n'; | ||
import type { BasePost } from '../../types'; | ||
import { TemplateEdit } from './template-edit'; | ||
|
||
const templateField: Field< BasePost > = { | ||
id: 'template', | ||
type: 'text', | ||
label: __( 'Template' ), | ||
getValue: ( { item } ) => item.template, | ||
Edit: TemplateEdit, | ||
enableSorting: false, | ||
}; | ||
|
||
export default templateField; |
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,23 @@ | ||
.fields-controls__template-modal { | ||
z-index: z-index(".fields-controls__template-modal"); | ||
} | ||
|
||
.fields-controls__template-content .block-editor-block-patterns-list { | ||
column-count: 2; | ||
column-gap: $grid-unit-30; | ||
|
||
// Small top padding required to avoid cutting off the visible outline when hovering items | ||
padding-top: $border-width-focus-fallback; | ||
|
||
@include break-medium() { | ||
column-count: 3; | ||
} | ||
|
||
@include break-wide() { | ||
column-count: 4; | ||
} | ||
|
||
.block-editor-block-patterns-list__list-item { | ||
break-inside: avoid-column; | ||
} | ||
} |
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,210 @@ | ||
/** | ||
* WordPress dependencies | ||
*/ | ||
import { useCallback, useMemo, useState } from '@wordpress/element'; | ||
// @ts-ignore | ||
import { parse } from '@wordpress/blocks'; | ||
import type { WpTemplate } from '@wordpress/core-data'; | ||
import { store as coreStore } from '@wordpress/core-data'; | ||
import type { DataFormControlProps } from '@wordpress/dataviews'; | ||
|
||
/** | ||
* Internal dependencies | ||
*/ | ||
// @ts-expect-error block-editor is not typed correctly. | ||
import { __experimentalBlockPatternsList as BlockPatternsList } from '@wordpress/block-editor'; | ||
import { | ||
Button, | ||
Dropdown, | ||
MenuGroup, | ||
MenuItem, | ||
Modal, | ||
} from '@wordpress/components'; | ||
import { useAsyncList } from '@wordpress/compose'; | ||
import { useSelect } from '@wordpress/data'; | ||
import { decodeEntities } from '@wordpress/html-entities'; | ||
import { __ } from '@wordpress/i18n'; | ||
import { getItemTitle } from '../../actions/utils'; | ||
import type { BasePost } from '../../types'; | ||
import { unlock } from '../../lock-unlock'; | ||
|
||
export const TemplateEdit = ( { | ||
data, | ||
field, | ||
onChange, | ||
}: DataFormControlProps< BasePost > ) => { | ||
const { id } = field; | ||
const postType = data.type; | ||
const postId = | ||
typeof data.id === 'number' ? data.id : parseInt( data.id, 10 ); | ||
const slug = data.slug; | ||
|
||
const { availableTemplates, templates } = useSelect( | ||
( select ) => { | ||
const allTemplates = | ||
select( coreStore ).getEntityRecords< WpTemplate >( | ||
'postType', | ||
'wp_template', | ||
{ | ||
per_page: -1, | ||
post_type: postType, | ||
} | ||
) ?? []; | ||
|
||
const { getHomePage, getPostsPageId } = unlock( | ||
select( coreStore ) | ||
); | ||
|
||
const isPostsPage = getPostsPageId() === +postId; | ||
const isFrontPage = | ||
postType === 'page' && getHomePage()?.postId === +postId; | ||
|
||
const allowSwitchingTemplate = ! isPostsPage && ! isFrontPage; | ||
|
||
return { | ||
templates: allTemplates, | ||
availableTemplates: allowSwitchingTemplate | ||
? allTemplates.filter( | ||
( template ) => | ||
template.is_custom && | ||
template.slug !== data.template && | ||
!! template.content.raw // Skip empty templates. | ||
) | ||
: [], | ||
}; | ||
}, | ||
[ data.template, postId, postType ] | ||
); | ||
|
||
const templatesAsPatterns = useMemo( | ||
() => | ||
availableTemplates.map( ( template ) => ( { | ||
name: template.slug, | ||
blocks: parse( template.content.raw ), | ||
title: decodeEntities( template.title.rendered ), | ||
id: template.id, | ||
} ) ), | ||
[ availableTemplates ] | ||
); | ||
|
||
const shownTemplates = useAsyncList( templatesAsPatterns ); | ||
|
||
const value = field.getValue( { item: data } ); | ||
|
||
const currentTemplate = useSelect( | ||
( select ) => { | ||
const foundTemplate = templates?.find( | ||
( template ) => template.slug === value | ||
); | ||
|
||
if ( foundTemplate ) { | ||
return foundTemplate; | ||
} | ||
|
||
let slugToCheck; | ||
// In `draft` status we might not have a slug available, so we use the `single` | ||
// post type templates slug(ex page, single-post, single-product etc..). | ||
// Pages do not need the `single` prefix in the slug to be prioritized | ||
// through template hierarchy. | ||
if ( slug ) { | ||
slugToCheck = | ||
postType === 'page' | ||
? `${ postType }-${ slug }` | ||
: `single-${ postType }-${ slug }`; | ||
} else { | ||
slugToCheck = | ||
postType === 'page' ? 'page' : `single-${ postType }`; | ||
} | ||
|
||
if ( postType ) { | ||
const templateId = select( coreStore ).getDefaultTemplateId( { | ||
slug: slugToCheck, | ||
} ); | ||
|
||
return select( coreStore ).getEntityRecord( | ||
'postType', | ||
'wp_template', | ||
templateId | ||
); | ||
} | ||
}, | ||
[ postType, slug, templates, value ] | ||
); | ||
|
||
const [ showModal, setShowModal ] = useState( false ); | ||
|
||
const onChangeControl = useCallback( | ||
( newValue: string ) => | ||
onChange( { | ||
[ id ]: newValue, | ||
} ), | ||
[ id, onChange ] | ||
); | ||
|
||
return ( | ||
<fieldset className="fields-controls__template"> | ||
<Dropdown | ||
popoverProps={ { placement: 'bottom-start' } } | ||
renderToggle={ ( { onToggle } ) => ( | ||
<Button | ||
__next40pxDefaultSize | ||
variant="tertiary" | ||
size="compact" | ||
onClick={ onToggle } | ||
> | ||
{ currentTemplate | ||
? getItemTitle( currentTemplate ) | ||
: '' } | ||
</Button> | ||
) } | ||
renderContent={ ( { onToggle } ) => ( | ||
<MenuGroup> | ||
<MenuItem | ||
onClick={ () => { | ||
setShowModal( true ); | ||
onToggle(); | ||
} } | ||
> | ||
{ __( 'Swap template' ) } | ||
</MenuItem> | ||
{ | ||
// The default template in a post is indicated by an empty string | ||
value !== '' && ( | ||
<MenuItem | ||
onClick={ () => { | ||
onChangeControl( '' ); | ||
onToggle(); | ||
} } | ||
> | ||
{ __( 'Use default template' ) } | ||
</MenuItem> | ||
) | ||
} | ||
</MenuGroup> | ||
) } | ||
/> | ||
{ showModal && ( | ||
<Modal | ||
title={ __( 'Choose a template' ) } | ||
onRequestClose={ () => setShowModal( false ) } | ||
overlayClassName="fields-controls__template-modal" | ||
isFullScreen | ||
> | ||
<div className="fields-controls__template-content"> | ||
<BlockPatternsList | ||
label={ __( 'Templates' ) } | ||
blockPatterns={ templatesAsPatterns } | ||
shownPatterns={ shownTemplates } | ||
onClickPattern={ ( | ||
template: ( typeof templatesAsPatterns )[ 0 ] | ||
) => { | ||
onChangeControl( template.name ); | ||
setShowModal( false ); | ||
} } | ||
/> | ||
</div> | ||
</Modal> | ||
) } | ||
</fieldset> | ||
); | ||
}; |
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 |
---|---|---|
@@ -1,3 +1,4 @@ | ||
@import "./components/create-template-part-modal/style.scss"; | ||
@import "./fields/slug/style.scss"; | ||
@import "./fields/featured-image/style.scss"; | ||
@import "./fields/template/style.scss"; |
Oops, something went wrong.