Skip to content

Commit

Permalink
Site editor - try redirecting to homepage before the react render (#3…
Browse files Browse the repository at this point in the history
…7248)

* Replace showHomepage with a selector and dedicate redirect component

* Remove show homepage

* Remove component based redirect, instead use an async function prior to rendering app

* Use a default export

* Pass siteUrl in as a param
  • Loading branch information
talldan authored and Mamaduka committed Feb 16, 2022
1 parent 621c3c2 commit efb8268
Show file tree
Hide file tree
Showing 5 changed files with 83 additions and 160 deletions.
71 changes: 71 additions & 0 deletions packages/edit-site/src/components/routes/redirect-to-homepage.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/**
* WordPress dependencies
*/
import apiFetch from '@wordpress/api-fetch';
import { addQueryArgs } from '@wordpress/url';

/**
* Internal dependencies
*/
import history from '../../utils/history';
import getIsListPage from '../../utils/get-is-list-page';

function getNeedsHomepageRedirect( params ) {
const { postType } = params;
return (
! getIsListPage( params ) &&
! [ 'post', 'page', 'wp_template', 'wp_template_part' ].includes(
postType
)
);
}

async function getHomepageParams( siteUrl ) {
const siteSettings = await apiFetch( { path: '/wp/v2/settings' } );
if ( ! siteSettings ) {
return;
}

const {
show_on_front: showOnFront,
page_on_front: frontpageId,
} = siteSettings;

// If the user has set a page as the homepage, use those details.
if ( showOnFront === 'page' ) {
return {
postType: 'page',
postId: frontpageId,
};
}

// Else get the home template.
// This matches the logic in `__experimentalGetTemplateForLink`.
// (packages/core-data/src/resolvers.js)
const template = await window
.fetch( addQueryArgs( siteUrl, { '_wp-find-template': true } ) )
.then( ( res ) => res.json() )
.then( ( { data } ) => data );

if ( ! template?.id ) {
return;
}

return {
postType: 'wp_template',
postId: template.id,
};
}

export default async function redirectToHomepage( siteUrl ) {
const searchParams = new URLSearchParams( history.location.search );
const params = Object.fromEntries( searchParams.entries() );

if ( getNeedsHomepageRedirect( params ) ) {
const homepageParams = await getHomepageParams( siteUrl );

if ( homepageParams ) {
history.replace( homepageParams );
}
}
}
38 changes: 3 additions & 35 deletions packages/edit-site/src/components/url-query-controller/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,63 +2,31 @@
* WordPress dependencies
*/
import { useEffect } from '@wordpress/element';
import { useDispatch, useSelect } from '@wordpress/data';
import { useDispatch } from '@wordpress/data';

/**
* Internal dependencies
*/
import { useLocation, useHistory } from '../routes';
import { useLocation } from '../routes';
import { store as editSiteStore } from '../../store';

export default function URLQueryController() {
const { setTemplate, setTemplatePart, showHomepage, setPage } = useDispatch(
const { setTemplate, setTemplatePart, setPage } = useDispatch(
editSiteStore
);
const history = useHistory();
const {
params: { postId, postType },
} = useLocation();
const { getPage, getEditedPostId, getEditedPostType } = useSelect(
editSiteStore
);

// Set correct entity on page navigation.
useEffect( () => {
let isMounted = true;

if ( 'page' === postType || 'post' === postType ) {
setPage( { context: { postType, postId } } ); // Resolves correct template based on ID.
} else if ( 'wp_template' === postType ) {
setTemplate( postId );
} else if ( 'wp_template_part' === postType ) {
setTemplatePart( postId );
} else {
showHomepage().then( () => {
if ( ! isMounted ) {
return;
}

const page = getPage();
const editedPostId = getEditedPostId();
const editedPostType = getEditedPostType();

if ( page?.context?.postId && page?.context?.postType ) {
history.replace( {
postId: page.context.postId,
postType: page.context.postType,
} );
} else if ( editedPostId && editedPostType ) {
history.replace( {
postId: editedPostId,
postType: editedPostType,
} );
}
} );
}

return () => {
isMounted = false;
};
}, [ postId, postType ] );

return null;
Expand Down
10 changes: 9 additions & 1 deletion packages/edit-site/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import './hooks';
import { store as editSiteStore } from './store';
import EditSiteApp from './components/app';
import getIsListPage from './utils/get-is-list-page';
import redirectToHomepage from './components/routes/redirect-to-homepage';

/**
* Reinitializes the editor after the user chooses to reboot the editor after
Expand All @@ -33,7 +34,13 @@ import getIsListPage from './utils/get-is-list-page';
* @param {Element} target DOM node in which editor is rendered.
* @param {?Object} settings Editor settings object.
*/
export function reinitializeEditor( target, settings ) {
export async function reinitializeEditor( target, settings ) {
// The site editor relies on `postType` and `postId` params in the URL to
// define what's being edited. When visiting via the dashboard link, these
// won't be present. Do a client side redirect to the 'homepage' if that's
// the case.
await redirectToHomepage( settings.siteUrl );

// This will be a no-op if the target doesn't have any React nodes.
unmountComponentAtNode( target );
const reboot = reinitializeEditor.bind( null, target, settings );
Expand All @@ -42,6 +49,7 @@ export function reinitializeEditor( target, settings ) {
// so that we won't trigger unnecessary re-renders with useEffect.
{
dispatch( editSiteStore ).updateSettings( settings );

// 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,
Expand Down
34 changes: 0 additions & 34 deletions packages/edit-site/src/store/actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -230,40 +230,6 @@ export function* setPage( page ) {
return templateId;
}

/**
* Displays the site homepage for editing in the editor.
*/
export function* showHomepage() {
const {
show_on_front: showOnFront,
page_on_front: frontpageId,
} = yield controls.resolveSelect(
coreStore,
'getEntityRecord',
'root',
'site'
);

const { siteUrl } = yield controls.select(
editSiteStoreName,
'getSettings'
);

const page = {
path: siteUrl,
context:
showOnFront === 'page'
? {
postType: 'page',
postId: frontpageId,
}
: {},
};

const homeTemplate = yield* setPage( page );
yield setHomeTemplateId( homeTemplate );
}

/**
* Returns an action object used to set the active navigation panel menu.
*
Expand Down
90 changes: 0 additions & 90 deletions packages/edit-site/src/store/test/actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import {
addTemplate,
setTemplatePart,
setPage,
showHomepage,
setHomeTemplateId,
setIsListViewOpened,
} from '../actions';
Expand Down Expand Up @@ -105,95 +104,6 @@ describe( 'actions', () => {
} );
} );

describe( 'showHomepage', () => {
it( 'should calculate and set the homepage if it is set to show posts', () => {
const it = showHomepage();

expect( it.next().value ).toEqual( {
args: [ 'root', 'site' ],
selectorName: 'getEntityRecord',
storeKey: 'core',
type: '@@data/RESOLVE_SELECT',
} );

expect( it.next( { show_on_front: 'posts' } ).value ).toEqual( {
args: [],
selectorName: 'getSettings',
storeKey: 'core/edit-site',
type: '@@data/SELECT',
} );

const page = {
path: 'http:/my-site',
context: {},
};

expect( it.next( { siteUrl: 'http:/my-site' } ).value ).toEqual( {
type: '@@data/RESOLVE_SELECT',
storeKey: 'core',
selectorName: '__experimentalGetTemplateForLink',
args: [ page.path ],
} );
expect( it.next( { id: 'theme//slug' } ).value ).toEqual( {
type: 'SET_PAGE',
page,
templateId: 'theme//slug',
} );
expect( it.next( 'theme//slug' ).value ).toEqual( {
type: 'SET_HOME_TEMPLATE',
homeTemplateId: 'theme//slug',
} );
expect( it.next().done ).toBe( true );
} );

it( 'should calculate and set the homepage if it is set to show a page', () => {
const pageId = 2;

const it = showHomepage();

expect( it.next().value ).toEqual( {
args: [ 'root', 'site' ],
selectorName: 'getEntityRecord',
storeKey: 'core',
type: '@@data/RESOLVE_SELECT',
} );

expect(
it.next( { show_on_front: 'page', page_on_front: pageId } )
.value
).toEqual( {
args: [],
selectorName: 'getSettings',
storeKey: 'core/edit-site',
type: '@@data/SELECT',
} );

const page = {
path: 'http:/my-site',
context: {
postType: 'page',
postId: pageId,
},
};
expect( it.next( { siteUrl: 'http:/my-site' } ).value ).toEqual( {
type: '@@data/RESOLVE_SELECT',
storeKey: 'core',
selectorName: '__experimentalGetTemplateForLink',
args: [ page.path ],
} );
expect( it.next( { id: 'theme//slug' } ).value ).toEqual( {
type: 'SET_PAGE',
page,
templateId: 'theme//slug',
} );
expect( it.next( 'theme//slug' ).value ).toEqual( {
type: 'SET_HOME_TEMPLATE',
homeTemplateId: 'theme//slug',
} );
expect( it.next().done ).toBe( true );
} );
} );

describe( 'setHomeTemplateId', () => {
it( 'should return the SET_HOME_TEMPLATE action', () => {
const homeTemplateId = 90;
Expand Down

0 comments on commit efb8268

Please sign in to comment.