Skip to content

Commit

Permalink
Site Editor: Fix template resolution for templates assigned as home p…
Browse files Browse the repository at this point in the history
…age (#56418)

Co-authored-by: ntsekouras <[email protected]>
Co-authored-by: Ramon <[email protected]>
  • Loading branch information
3 people authored Nov 23, 2023
1 parent 9e63f56 commit 996004b
Show file tree
Hide file tree
Showing 3 changed files with 92 additions and 29 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,25 @@ export function useEditedPostContext() {
);
}

export function useIsPostsPage() {
export function useAllowSwitchingTemplates() {
const { postId } = useEditedPostContext();
return useSelect(
( select ) =>
+postId ===
select( coreStore ).getEntityRecord( 'root', 'site' )
?.page_for_posts,
( select ) => {
const { getEntityRecord, getEntityRecords } = select( coreStore );
const siteSettings = getEntityRecord( 'root', 'site' );
const templates = getEntityRecords(
'postType',
TEMPLATE_POST_TYPE,
{ per_page: -1 }
);
const isPostsPage = +postId === siteSettings?.page_for_posts;
// If current page is set front page or posts page, we also need
// to check if the current theme has a template for it. If not
const isFrontPage =
+postId === siteSettings?.page_on_front &&
templates?.some( ( { slug } ) => slug === 'front-page' );
return ! isPostsPage && ! isFrontPage;
},
[ postId ]
);
}
Expand All @@ -46,19 +58,18 @@ function useTemplates() {

export function useAvailableTemplates() {
const currentTemplateSlug = useCurrentTemplateSlug();
const isPostsPage = useIsPostsPage();
const allowSwitchingTemplate = useAllowSwitchingTemplates();
const templates = useTemplates();
return useMemo(
() =>
// The posts page template cannot be changed.
! isPostsPage &&
allowSwitchingTemplate &&
templates?.filter(
( template ) =>
template.is_custom &&
template.slug !== currentTemplateSlug &&
!! template.content.raw // Skip empty templates.
),
[ templates, currentTemplateSlug, isPostsPage ]
[ templates, currentTemplateSlug, allowSwitchingTemplate ]
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,18 @@ import { store as coreStore } from '@wordpress/core-data';
* Internal dependencies
*/
import {
useAllowSwitchingTemplates,
useCurrentTemplateSlug,
useEditedPostContext,
useIsPostsPage,
} from './hooks';

export default function ResetDefaultTemplate( { onClick } ) {
const currentTemplateSlug = useCurrentTemplateSlug();
const isPostsPage = useIsPostsPage();
const allowSwitchingTemplate = useAllowSwitchingTemplates();
const { postType, postId } = useEditedPostContext();
const { editEntityRecord } = useDispatch( coreStore );
// The default template in a post is indicated by an empty string.
if ( ! currentTemplateSlug || isPostsPage ) {
if ( ! currentTemplateSlug || ! allowSwitchingTemplate ) {
return null;
}
return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,21 +28,46 @@ const postTypesWithoutParentTemplate = [
];

function useResolveEditedEntityAndContext( { postId, postType } ) {
const { isRequestingSite, homepageId, url } = useSelect( ( select ) => {
const { getSite, getUnstableBase } = select( coreDataStore );
const siteData = getSite();
const base = getUnstableBase();

return {
isRequestingSite: ! base,
homepageId:
siteData?.show_on_front === 'page'
? siteData.page_on_front
: null,
url: base?.home,
};
}, [] );
const { hasLoadedAllDependencies, homepageId, url, frontPageTemplateId } =
useSelect( ( select ) => {
const { getSite, getUnstableBase, getEntityRecords } =
select( coreDataStore );
const siteData = getSite();
const base = getUnstableBase();
const templates = getEntityRecords(
'postType',
TEMPLATE_POST_TYPE,
{
per_page: -1,
}
);
let _frontPateTemplateId;
if ( templates ) {
const frontPageTemplate = templates.find(
( t ) => t.slug === 'front-page'
);
_frontPateTemplateId = frontPageTemplate
? frontPageTemplate.id
: false;
}

return {
hasLoadedAllDependencies: !! base && !! siteData,
homepageId:
siteData?.show_on_front === 'page'
? siteData.page_on_front.toString()
: null,
url: base?.home,
frontPageTemplateId: _frontPateTemplateId,
};
}, [] );

/**
* This is a hook that recreates the logic to resolve a template for a given WordPress postID postTypeId
* in order to match the frontend as closely as possible in the site editor.
*
* It is not possible to rely on the server logic because there maybe unsaved changes that impact the template resolution.
*/
const resolvedTemplateId = useSelect(
( select ) => {
// If we're rendering a post type that doesn't have a template
Expand All @@ -62,6 +87,22 @@ function useResolveEditedEntityAndContext( { postId, postType } ) {
postTypeToResolve,
postIdToResolve
) {
// For the front page, we always use the front page template if existing.
if (
postTypeToResolve === 'page' &&
homepageId === postIdToResolve
) {
// We're still checking whether the front page template exists.
// Don't resolve the template yet.
if ( frontPageTemplateId === undefined ) {
return undefined;
}

if ( !! frontPageTemplateId ) {
return frontPageTemplateId;
}
}

const editedEntity = getEditedEntityRecord(
'postType',
postTypeToResolve,
Expand Down Expand Up @@ -91,6 +132,10 @@ function useResolveEditedEntityAndContext( { postId, postType } ) {
} );
}

if ( ! hasLoadedAllDependencies ) {
return undefined;
}

// If we're rendering a specific page, post... we need to resolve its template.
if ( postType && postId ) {
return resolveTemplateForPostTypeAndId( postType, postId );
Expand All @@ -102,12 +147,19 @@ function useResolveEditedEntityAndContext( { postId, postType } ) {
}

// If we're not rendering a specific page, use the front page template.
if ( ! isRequestingSite && url ) {
if ( url ) {
const template = __experimentalGetTemplateForLink( url );
return template?.id;
}
},
[ homepageId, isRequestingSite, url, postId, postType ]
[
homepageId,
hasLoadedAllDependencies,
url,
postId,
postType,
frontPageTemplateId,
]
);

const context = useMemo( () => {
Expand All @@ -130,7 +182,7 @@ function useResolveEditedEntityAndContext( { postId, postType } ) {
return { isReady: true, postType, postId, context };
}

if ( ( postType && postId ) || homepageId || ! isRequestingSite ) {
if ( hasLoadedAllDependencies ) {
return {
isReady: resolvedTemplateId !== undefined,
postType: TEMPLATE_POST_TYPE,
Expand Down

0 comments on commit 996004b

Please sign in to comment.