Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Template part 'replace' flow - don't show currently used template part as option. #31720

Merged
merged 12 commits into from
May 19, 2021
30 changes: 25 additions & 5 deletions packages/block-library/src/template-part/edit/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,15 @@ import TemplatePartPlaceholder from './placeholder';
import TemplatePartSelection from './selection';
import { TemplatePartAdvancedControls } from './advanced-controls';
import TemplatePartInnerBlocks from './inner-blocks';
import { createTemplatePartId } from './utils/create-template-part-id';

export default function TemplatePartEdit( {
attributes,
setAttributes,
clientId,
} ) {
const { slug, theme, tagName, layout = {} } = attributes;
const templatePartId = theme && slug ? theme + '//' + slug : null;
const templatePartId = createTemplatePartId( theme, slug );

const [ hasAlreadyRendered, RecursionProvider ] = useNoRecursiveRenders(
templatePartId
Expand All @@ -48,11 +49,14 @@ export default function TemplatePartEdit( {
isMissing,
defaultWrapper,
area,
enableSelection,
} = useSelect(
( select ) => {
const { getEditedEntityRecord, hasFinishedResolution } = select(
coreStore
);
const {
getEditedEntityRecord,
getEntityRecords,
hasFinishedResolution,
} = select( coreStore );
const { getBlocks } = select( blockEditorStore );

const getEntityArgs = [
Expand All @@ -65,6 +69,19 @@ export default function TemplatePartEdit( {
: null;
const _area = entityRecord?.area || attributes.area;

// Check whether other entities exist for switching/selection.
const availableReplacementArgs = [
'postType',
'wp_template_part',
_area && 'uncategorized' !== _area && { area: _area },
];
const matchingReplacements = getEntityRecords(
...availableReplacementArgs
);
const _enableSelection = templatePartId
? matchingReplacements?.length > 1
: matchingReplacements?.length > 0;

const hasResolvedEntity = templatePartId
? hasFinishedResolution(
'getEditedEntityRecord',
Expand All @@ -82,6 +99,7 @@ export default function TemplatePartEdit( {
isMissing: hasResolvedEntity && ! entityRecord,
defaultWrapper: defaultWrapperElement || 'div',
area: _area,
enableSelection: _enableSelection,
};
},
[ templatePartId, clientId ]
Expand Down Expand Up @@ -138,10 +156,11 @@ export default function TemplatePartEdit( {
area={ attributes.area }
clientId={ clientId }
setAttributes={ setAttributes }
enableSelection={ enableSelection }
/>
</TagName>
) }
{ isEntityAvailable && (
{ isEntityAvailable && enableSelection && (
<BlockControls>
<ToolbarGroup className="wp-block-template-part__block-control-group">
<Dropdown
Expand All @@ -164,6 +183,7 @@ export default function TemplatePartEdit( {
setAttributes={ setAttributes }
onClose={ onClose }
area={ area }
templatePartId={ templatePartId }
/>
) }
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ export default function TemplatePartPlaceholder( {
area,
clientId,
setAttributes,
enableSelection,
} ) {
const { saveEntityRecord } = useDispatch( coreStore );
const [ step, setStep ] = useState( PLACEHOLDER_STEPS.initial );
Expand Down Expand Up @@ -72,13 +73,15 @@ export default function TemplatePartPlaceholder( {
position="bottom right left"
renderToggle={ ( { isOpen, onToggle } ) => (
<>
<Button
isPrimary
onClick={ onToggle }
aria-expanded={ isOpen }
>
{ __( 'Choose existing' ) }
</Button>
{ enableSelection && (
<Button
isPrimary
onClick={ onToggle }
aria-expanded={ isOpen }
>
{ __( 'Choose existing' ) }
</Button>
) }
<Button
isTertiary
onClick={ () =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ export default function TemplatePartSelection( {
setAttributes,
onClose,
area,
templatePartId = null,
} ) {
const [ filterValue, setFilterValue ] = useState( '' );
return (
Expand All @@ -44,6 +45,7 @@ export default function TemplatePartSelection( {
filterValue={ filterValue }
onClose={ onClose }
area={ area }
templatePartId={ templatePartId }
/>
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/**
* External dependencies
*/
import { groupBy, deburr } from 'lodash';
import { groupBy, deburr, flatten } from 'lodash';

/**
* WordPress dependencies
Expand All @@ -22,7 +22,18 @@ import { useAsyncList } from '@wordpress/compose';
import { store as noticesStore } from '@wordpress/notices';
import { store as coreStore } from '@wordpress/core-data';
import { store as editorStore } from '@wordpress/editor';
/**
* Internal dependencies
*/
import { createTemplatePartId } from '../utils/create-template-part-id';

function getAreaGroupTitle( areaLabel ) {
return sprintf(
// Translators: %s for the area the template part is assigned to (Header, Footer, General, etc.)
__( 'Area: %s' ),
areaLabel
);
}
function PreviewPlaceholder() {
return (
<div
Expand Down Expand Up @@ -111,23 +122,50 @@ function TemplatePartsByArea( {
area = 'uncategorized',
labelsByArea,
} ) {
const templatePartsByArea = useMemo( () => {
return Object.values( groupBy( templateParts, 'area' ) );
const { templatePartsByArea, templatePartsToShow } = useMemo( () => {
const _templatePartsToShow =
templateParts.filter(
( templatePart ) =>
'uncategorized' === area || templatePart.area === area
) || [];
const _templatePartsByArea = Object.values(
groupBy( _templatePartsToShow, 'area' )
);
const orderedTemplatePartsToShow = flatten( _templatePartsToShow );
return {
templatePartsByArea: _templatePartsByArea,
templatePartsToShow: orderedTemplatePartsToShow,
};
}, [ templateParts, area ] );
const currentShownTPs = useAsyncList( templateParts );

const currentShownTPs = useAsyncList( templatePartsToShow );

if ( ! templatePartsToShow.length ) {
return (
<PanelGroup
title={ getAreaGroupTitle(
labelsByArea[ area ] || labelsByArea.uncategorized
) }
>
{ sprintf(
// Translators: %s for the template part variation ("Header", "Footer", "Template Part").
'There is no other %s available. If you are looking for another type of template part, try searching for it using the input above.',
area && area !== 'uncategorized'
? labelsByArea[ area ] || area
: __( 'Template Part' )
) }
</PanelGroup>
);
}

return templatePartsByArea.map( ( templatePartList ) => {
// Only return corresponding area if block/entity is not uncategorized/general version.
if ( 'uncategorized' !== area && templatePartList[ 0 ].area !== area ) {
return null;
}
return (
<PanelGroup
key={ templatePartList[ 0 ].area }
title={
title={ getAreaGroupTitle(
labelsByArea[ templatePartList[ 0 ].area ] ||
__( 'General' )
}
labelsByArea.uncategorized
) }
>
{ templatePartList.map( ( templatePart ) => {
return currentShownTPs.includes( templatePart ) ? (
Expand Down Expand Up @@ -222,7 +260,9 @@ function TemplatePartSearchResults( {
return groupedResults.map( ( group ) => (
<PanelGroup
key={ group[ 0 ].id }
title={ labelsByArea[ group[ 0 ].area ] || __( 'General' ) }
title={ getAreaGroupTitle(
labelsByArea[ group[ 0 ].area ] || labelsByArea.uncategorized
) }
>
{ group.map( ( templatePart ) =>
currentShownTPs.includes( templatePart ) ? (
Expand All @@ -246,18 +286,26 @@ export default function TemplatePartPreviews( {
filterValue,
onClose,
area,
templatePartId,
} ) {
const composite = useCompositeState();

const { templateParts, labelsByArea } = useSelect( ( select ) => {
const _templateParts =
const _templateParts = (
select( coreStore ).getEntityRecords(
'postType',
'wp_template_part',
{
per_page: -1,
}
) || [];
) || []
).filter(
( templatePart ) =>
createTemplatePartId(
templatePart.theme,
templatePart.slug
) !== templatePartId
);

const definedAreas = select(
editorStore
Expand All @@ -274,7 +322,11 @@ export default function TemplatePartPreviews( {
}, [] );

if ( ! templateParts || ! templateParts.length ) {
return null;
return (
<PanelGroup>
{ __( 'There are no existing template parts to select.' ) }
</PanelGroup>
);
}

if ( filterValue ) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/**
* Generates a template part Id based on slug and theme inputs.
*
* @param {string} theme the template part's theme.
* @param {string} slug the template part's slug
* @return {string|null} the template part's Id.
*/
export function createTemplatePartId( theme, slug ) {
return theme && slug ? theme + '//' + slug : null;
}