From 15f1913174b571889780ab451cf44de6d857161f Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Thu, 21 Nov 2024 11:56:14 +0100 Subject: [PATCH 01/26] Site Editor: Use permalinks instead of query args and site-editor.php based urls --- lib/experimental/site-editor-permalinks.php | 11 ++ lib/load.php | 1 + package-lock.json | 9 +- .../src/components/add-new-pattern/index.js | 26 +-- .../src/components/add-new-template/index.js | 8 +- .../edit-site/src/components/app/index.js | 15 +- .../block-editor/use-editor-iframe-props.js | 9 +- .../use-navigate-to-entity-record.js | 4 +- .../block-editor/use-site-editor-settings.js | 12 +- .../src/components/dataviews-actions/index.js | 6 +- .../edit-site/src/components/editor/index.js | 73 +++++--- .../editor/use-resolve-edited-entity.js | 17 +- .../components/global-styles-sidebar/index.js | 8 +- .../edit-site/src/components/layout/index.js | 7 +- .../edit-site/src/components/layout/router.js | 31 +--- .../delete-category-menu-item.js | 7 +- .../src/components/page-patterns/fields.js | 23 +-- .../src/components/page-patterns/index.js | 30 +-- .../src/components/page-templates/fields.js | 19 +- .../src/components/page-templates/index.js | 31 ++-- .../src/components/post-list/index.js | 78 ++++---- .../src/components/resizable-frame/index.js | 13 +- .../edit-site/src/components/routes/link.js | 68 ------- .../src/components/save-panel/index.js | 4 +- .../sidebar-dataviews/add-new-view.js | 18 +- .../sidebar-dataviews/dataview-item.js | 13 +- .../src/components/sidebar-dataviews/index.js | 4 +- .../sidebar-global-styles-wrapper/index.js | 54 +++--- .../sidebar-navigation-item/index.js | 12 +- .../index.js | 26 +-- .../sidebar-navigation-screen-main/index.js | 13 +- .../more-menu.js | 8 +- .../use-navigation-menu-handlers.js | 4 +- .../index.js | 12 +- .../leaf-more-menu.js | 30 +-- .../category-item.js | 25 +-- .../index.js | 7 +- .../content.js | 41 ++-- .../index.js | 15 +- .../sidebar-navigation-screen/index.js | 2 +- .../site-editor-routes/home-edit.js | 17 -- .../{home-view.js => home.js} | 9 +- .../components/site-editor-routes/index.js | 56 +++--- .../site-editor-routes/navigation-edit.js | 22 --- .../navigation-item-edit.js | 26 --- .../navigation-item-view.js | 25 --- .../site-editor-routes/navigation-item.js | 42 +++++ .../site-editor-routes/navigation-view.js | 21 --- .../site-editor-routes/navigation.js | 34 ++++ .../{pages-edit.js => page-item.js} | 20 +- .../pages-list-view-quick-edit.js | 56 ------ .../site-editor-routes/pages-list-view.js | 44 ----- .../pages-view-quick-edit.js | 53 ------ .../site-editor-routes/pages-view.js | 39 ---- .../components/site-editor-routes/pages.js | 66 +++++++ .../site-editor-routes/pattern-item.js | 15 ++ .../site-editor-routes/patterns-edit.js | 24 --- .../site-editor-routes/patterns-view.js | 22 --- .../components/site-editor-routes/patterns.js | 15 ++ .../{styles-view.js => styles.js} | 14 +- .../site-editor-routes/template-item.js | 15 ++ .../site-editor-routes/template-part-item.js | 15 ++ .../site-editor-routes/templates-edit.js | 22 --- .../site-editor-routes/templates-list-view.js | 28 --- .../site-editor-routes/templates-view.js | 22 --- .../site-editor-routes/templates.js | 45 +++++ .../src/components/site-hub/index.js | 2 +- .../src/hooks/commands/use-common-commands.js | 86 ++------- .../hooks/commands/use-set-command-context.js | 4 +- .../edit-site/src/store/private-actions.js | 7 + packages/edit-site/src/store/reducer.js | 2 + packages/router/package.json | 3 +- packages/router/src/history.ts | 99 ---------- packages/router/src/link.tsx | 44 +++++ packages/router/src/private-apis.ts | 3 + packages/router/src/router.tsx | 175 ++++++++++++++++-- 76 files changed, 860 insertions(+), 1126 deletions(-) create mode 100644 lib/experimental/site-editor-permalinks.php delete mode 100644 packages/edit-site/src/components/routes/link.js delete mode 100644 packages/edit-site/src/components/site-editor-routes/home-edit.js rename packages/edit-site/src/components/site-editor-routes/{home-view.js => home.js} (66%) delete mode 100644 packages/edit-site/src/components/site-editor-routes/navigation-edit.js delete mode 100644 packages/edit-site/src/components/site-editor-routes/navigation-item-edit.js delete mode 100644 packages/edit-site/src/components/site-editor-routes/navigation-item-view.js create mode 100644 packages/edit-site/src/components/site-editor-routes/navigation-item.js delete mode 100644 packages/edit-site/src/components/site-editor-routes/navigation-view.js create mode 100644 packages/edit-site/src/components/site-editor-routes/navigation.js rename packages/edit-site/src/components/site-editor-routes/{pages-edit.js => page-item.js} (54%) delete mode 100644 packages/edit-site/src/components/site-editor-routes/pages-list-view-quick-edit.js delete mode 100644 packages/edit-site/src/components/site-editor-routes/pages-list-view.js delete mode 100644 packages/edit-site/src/components/site-editor-routes/pages-view-quick-edit.js delete mode 100644 packages/edit-site/src/components/site-editor-routes/pages-view.js create mode 100644 packages/edit-site/src/components/site-editor-routes/pages.js create mode 100644 packages/edit-site/src/components/site-editor-routes/pattern-item.js delete mode 100644 packages/edit-site/src/components/site-editor-routes/patterns-edit.js delete mode 100644 packages/edit-site/src/components/site-editor-routes/patterns-view.js create mode 100644 packages/edit-site/src/components/site-editor-routes/patterns.js rename packages/edit-site/src/components/site-editor-routes/{styles-view.js => styles.js} (58%) create mode 100644 packages/edit-site/src/components/site-editor-routes/template-item.js create mode 100644 packages/edit-site/src/components/site-editor-routes/template-part-item.js delete mode 100644 packages/edit-site/src/components/site-editor-routes/templates-edit.js delete mode 100644 packages/edit-site/src/components/site-editor-routes/templates-list-view.js delete mode 100644 packages/edit-site/src/components/site-editor-routes/templates-view.js create mode 100644 packages/edit-site/src/components/site-editor-routes/templates.js delete mode 100644 packages/router/src/history.ts create mode 100644 packages/router/src/link.tsx diff --git a/lib/experimental/site-editor-permalinks.php b/lib/experimental/site-editor-permalinks.php new file mode 100644 index 0000000000000..c7950d2cbbf23 --- /dev/null +++ b/lib/experimental/site-editor-permalinks.php @@ -0,0 +1,11 @@ +=10.0.0" } }, + "node_modules/route-recognizer": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/route-recognizer/-/route-recognizer-0.3.4.tgz", + "integrity": "sha512-2+MhsfPhvauN1O8KaXpXAOfR/fwe8dnUXVM+xw7yt40lJRfPVQxV6yryZm0cgRvAj5fMF/mdRZbL2ptwbs5i2g==", + "license": "MIT" + }, "node_modules/rrweb-cssom": { "version": "0.7.1", "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.7.1.tgz", @@ -55566,7 +55572,8 @@ "@wordpress/element": "*", "@wordpress/private-apis": "*", "@wordpress/url": "*", - "history": "^5.3.0" + "history": "^5.3.0", + "route-recognizer": "^0.3.4" }, "engines": { "node": ">=18.12.0", diff --git a/packages/edit-site/src/components/add-new-pattern/index.js b/packages/edit-site/src/components/add-new-pattern/index.js index bb9e53da6a566..63452691c1c37 100644 --- a/packages/edit-site/src/components/add-new-pattern/index.js +++ b/packages/edit-site/src/components/add-new-pattern/index.js @@ -69,23 +69,16 @@ export default function AddNewPattern() { function handleCreatePattern( { pattern } ) { setShowPatternModal( false ); - - history.push( { - postId: pattern.id, - postType: PATTERN_TYPES.user, - canvas: 'edit', - } ); + history.navigate( + `/${ PATTERN_TYPES.user }/${ pattern.id }?canvas=edit` + ); } function handleCreateTemplatePart( templatePart ) { setShowTemplatePartModal( false ); - - // Navigate to the created template part editor. - history.push( { - postId: templatePart.id, - postType: TEMPLATE_PART_POST_TYPE, - canvas: 'edit', - } ); + history.navigate( + `/${ TEMPLATE_PART_POST_TYPE }/${ templatePart.id }?canvas=edit` + ); } function handleError() { @@ -203,10 +196,9 @@ export default function AddNewPattern() { ! currentCategoryId && categoryId !== 'my-patterns' ) { - history.push( { - postType: PATTERN_TYPES.user, - categoryId: PATTERN_DEFAULT_CATEGORY, - } ); + history.navigate( + `/pattern?categoryId=${ PATTERN_DEFAULT_CATEGORY }` + ); } createSuccessNotice( diff --git a/packages/edit-site/src/components/add-new-template/index.js b/packages/edit-site/src/components/add-new-template/index.js index 1a2d9ea727fa8..5f06ecae6824a 100644 --- a/packages/edit-site/src/components/add-new-template/index.js +++ b/packages/edit-site/src/components/add-new-template/index.js @@ -203,11 +203,9 @@ function NewTemplateModal( { onClose } ) { ); // Navigate to the created template editor. - history.push( { - postId: newTemplate.id, - postType: TEMPLATE_POST_TYPE, - canvas: 'edit', - } ); + history.navigate( + `/${ TEMPLATE_POST_TYPE }/${ newTemplate.id }?canvas=edit` + ); createSuccessNotice( sprintf( diff --git a/packages/edit-site/src/components/app/index.js b/packages/edit-site/src/components/app/index.js index 7e4c50d7d00f0..464edea1615aa 100644 --- a/packages/edit-site/src/components/app/index.js +++ b/packages/edit-site/src/components/app/index.js @@ -2,7 +2,7 @@ * WordPress dependencies */ import { store as noticesStore } from '@wordpress/notices'; -import { useDispatch } from '@wordpress/data'; +import { useDispatch, useSelect } from '@wordpress/data'; import { __, sprintf } from '@wordpress/i18n'; import { PluginArea } from '@wordpress/plugins'; import { privateApis as routerPrivateApis } from '@wordpress/router'; @@ -12,8 +12,8 @@ import { privateApis as routerPrivateApis } from '@wordpress/router'; */ import Layout from '../layout'; import { unlock } from '../../lock-unlock'; +import { store as editSiteStore } from '../../store'; import { useCommonCommands } from '../../hooks/commands/use-common-commands'; -import useActiveRoute from '../layout/router'; import useSetCommandContext from '../../hooks/commands/use-set-command-context'; import { useRegisterSiteEditorRoutes } from '../site-editor-routes'; @@ -22,15 +22,16 @@ const { RouterProvider } = unlock( routerPrivateApis ); function AppLayout() { useCommonCommands(); useSetCommandContext(); - useRegisterSiteEditorRoutes(); - const route = useActiveRoute(); - return ; + return ; } export default function App() { + useRegisterSiteEditorRoutes(); const { createErrorNotice } = useDispatch( noticesStore ); - + const routes = useSelect( ( select ) => { + return unlock( select( editSiteStore ) ).getRoutes(); + }, [] ); function onPluginAreaError( name ) { createErrorNotice( sprintf( @@ -44,7 +45,7 @@ export default function App() { } return ( - + diff --git a/packages/edit-site/src/components/block-editor/use-editor-iframe-props.js b/packages/edit-site/src/components/block-editor/use-editor-iframe-props.js index 7c88fee0d5b72..1c70c85aed08d 100644 --- a/packages/edit-site/src/components/block-editor/use-editor-iframe-props.js +++ b/packages/edit-site/src/components/block-editor/use-editor-iframe-props.js @@ -12,6 +12,7 @@ import { useState, useEffect } from '@wordpress/element'; import { __ } from '@wordpress/i18n'; import { store as editorStore } from '@wordpress/editor'; import { privateApis as routerPrivateApis } from '@wordpress/router'; +import { addQueryArgs } from '@wordpress/url'; /** * Internal dependencies @@ -21,9 +22,9 @@ import { unlock } from '../../lock-unlock'; const { useLocation, useHistory } = unlock( routerPrivateApis ); export default function useEditorIframeProps() { - const { params } = useLocation(); + const { query, path } = useLocation(); const history = useHistory(); - const { canvas = 'view' } = params; + const { canvas = 'view' } = query; const currentPostIsTrashed = useSelect( ( select ) => { return ( select( editorStore ).getCurrentPostAttribute( 'status' ) === @@ -55,13 +56,13 @@ export default function useEditorIframeProps() { ! currentPostIsTrashed ) { event.preventDefault(); - history.push( { ...params, canvas: 'edit' }, undefined, { + history.navigate( addQueryArgs( path, { canvas: 'edit' } ), { transition: 'canvas-mode-edit-transition', } ); } }, onClick: () => - history.push( { ...params, canvas: 'edit' }, undefined, { + history.navigate( addQueryArgs( path, { canvas: 'edit' } ), { transition: 'canvas-mode-edit-transition', } ), onClickCapture: ( event ) => { diff --git a/packages/edit-site/src/components/block-editor/use-navigate-to-entity-record.js b/packages/edit-site/src/components/block-editor/use-navigate-to-entity-record.js index 120b15b8551d3..8cc7fdaefe2d9 100644 --- a/packages/edit-site/src/components/block-editor/use-navigate-to-entity-record.js +++ b/packages/edit-site/src/components/block-editor/use-navigate-to-entity-record.js @@ -16,7 +16,9 @@ export default function useNavigateToEntityRecord() { const onNavigateToEntityRecord = useCallback( ( params ) => { - history.push( { ...params, focusMode: true, canvas: 'edit' } ); + history.navigate( + `/${ params.postType }/${ params.id }?canvas=edit&focusMode=true` + ); }, [ history ] ); diff --git a/packages/edit-site/src/components/block-editor/use-site-editor-settings.js b/packages/edit-site/src/components/block-editor/use-site-editor-settings.js index 186f4aacf7923..d37987dc3dc42 100644 --- a/packages/edit-site/src/components/block-editor/use-site-editor-settings.js +++ b/packages/edit-site/src/components/block-editor/use-site-editor-settings.js @@ -22,11 +22,11 @@ function useNavigateToPreviousEntityRecord() { const history = useHistory(); const goBack = useMemo( () => { const isFocusMode = - location.params.focusMode || - ( location.params.postId && - FOCUSABLE_ENTITIES.includes( location.params.postType ) ); + location.query.focusMode || + ( location?.params?.postId && + FOCUSABLE_ENTITIES.includes( location?.params?.postType ) ); const didComeFromEditorCanvas = - previousLocation?.params.canvas === 'edit'; + previousLocation?.query.canvas === 'edit'; const showBackButton = isFocusMode && didComeFromEditorCanvas; return showBackButton ? () => history.back() : undefined; // `previousLocation` changes when the component updates for any reason, not @@ -37,8 +37,8 @@ function useNavigateToPreviousEntityRecord() { } export function useSpecificEditorSettings() { - const { params } = useLocation(); - const { canvas = 'view' } = params; + const { query } = useLocation(); + const { canvas = 'view' } = query; const onNavigateToEntityRecord = useNavigateToEntityRecord(); const { settings } = useSelect( ( select ) => { const { getSettings } = select( editSiteStore ); diff --git a/packages/edit-site/src/components/dataviews-actions/index.js b/packages/edit-site/src/components/dataviews-actions/index.js index 09b7597c6cb34..0a7b20c712c82 100644 --- a/packages/edit-site/src/components/dataviews-actions/index.js +++ b/packages/edit-site/src/components/dataviews-actions/index.js @@ -31,11 +31,7 @@ export const useEditPostAction = () => { }, callback( items ) { const post = items[ 0 ]; - history.push( { - postId: post.id, - postType: post.type, - canvas: 'edit', - } ); + history.navigate( `/${ post.type }/${ post.id }?canvas=edit` ); }, } ), [ history ] diff --git a/packages/edit-site/src/components/editor/index.js b/packages/edit-site/src/components/editor/index.js index 1d115dca7518d..75d6c1d3cc486 100644 --- a/packages/edit-site/src/components/editor/index.js +++ b/packages/edit-site/src/components/editor/index.js @@ -83,10 +83,26 @@ const siteIconVariants = { }, }; +function getListPathForPostType( postType ) { + switch ( postType ) { + case 'navigation': + return '/navigation'; + case 'wp_block': + return '/pattern?postType=wp_block'; + case 'wp_template_part': + return '/pattern?postType=wp_template_part'; + case 'wp_template': + return '/template'; + case 'page': + return '/page'; + } + throw 'Unknown post type'; +} + export default function EditSiteEditor( { isPostsList = false } ) { const disableMotion = useReducedMotion(); - const { params } = useLocation(); - const { canvas = 'view' } = params; + const { query } = useLocation(); + const { canvas = 'view' } = query; const isLoading = useIsSiteEditorLoading(); useAdaptEditorToCanvas( canvas ); const entity = useResolveEditedEntity(); @@ -157,9 +173,11 @@ export default function EditSiteEditor( { isPostsList = false } ) { case 'move-to-trash': case 'delete-post': { - history.push( { - postType: items[ 0 ].type, - } ); + history.navigate( + getListPathForPostType( + postWithTemplate ? context.postType : postType + ) + ); } break; case 'duplicate-post': @@ -182,11 +200,9 @@ export default function EditSiteEditor( { isPostsList = false } ) { { label: __( 'Edit' ), onClick: () => { - history.push( { - postId: newItem.id, - postType: newItem.type, - canvas: 'edit', - } ); + history.navigate( + `/${ newItem.type }/${ newItem.id }?canvas=edit` + ); }, }, ], @@ -196,7 +212,13 @@ export default function EditSiteEditor( { isPostsList = false } ) { break; } }, - [ history, createSuccessNotice ] + [ + postType, + context?.postType, + postWithTemplate, + history, + createSuccessNotice, + ] ); // Replace the title and icon displayed in the DocumentBar when there's an overlay visible. @@ -268,26 +290,19 @@ export default function EditSiteEditor( { isPostsList = false } ) { // come here through `posts list` and are in focus mode editing a template, template part etc.. if ( isPostsList && - params?.focusMode + query?.focusMode ) { - history.push( - { - page: 'gutenberg-posts-dashboard', - postType: 'post', - }, - undefined, - { - transition: - 'canvas-mode-view-transition', - } - ); + history.navigate( '/', { + transition: + 'canvas-mode-view-transition', + } ); } else { - history.push( - { - ...params, - canvas: undefined, - }, - undefined, + history.navigate( + getListPathForPostType( + postWithTemplate + ? context.postType + : postType + ), { transition: 'canvas-mode-view-transition', diff --git a/packages/edit-site/src/components/editor/use-resolve-edited-entity.js b/packages/edit-site/src/components/editor/use-resolve-edited-entity.js index 4f87373870414..336a77f6ba88a 100644 --- a/packages/edit-site/src/components/editor/use-resolve-edited-entity.js +++ b/packages/edit-site/src/components/editor/use-resolve-edited-entity.js @@ -30,8 +30,21 @@ const postTypesWithoutParentTemplate = [ const authorizedPostTypes = [ 'page', 'post' ]; export function useResolveEditedEntity() { - const { params = {} } = useLocation(); - const { postId, postType } = params; + const { name, params = {}, query } = useLocation(); + const { postId = query?.postId } = params; // Fallback to query param for postId for list view routes. + let postType; + if ( name === 'navigation-item' ) { + postType = NAVIGATION_POST_TYPE; + } else if ( name === 'pattern-item' ) { + postType = PATTERN_TYPES.user; + } else if ( name === 'template-part-item' ) { + postType = TEMPLATE_PART_POST_TYPE; + } else if ( name === 'template-item' || name === 'templates' ) { + postType = TEMPLATE_POST_TYPE; + } else if ( name === 'page-item' || name === 'pages' ) { + postType = 'page'; + } + const homePage = useSelect( ( select ) => { const { getHomePage } = unlock( select( coreDataStore ) ); return getHomePage(); diff --git a/packages/edit-site/src/components/global-styles-sidebar/index.js b/packages/edit-site/src/components/global-styles-sidebar/index.js index d46346b50dae3..02a29dac5c0b7 100644 --- a/packages/edit-site/src/components/global-styles-sidebar/index.js +++ b/packages/edit-site/src/components/global-styles-sidebar/index.js @@ -28,8 +28,8 @@ const { interfaceStore } = unlock( editorPrivateApis ); const { useLocation } = unlock( routerPrivateApis ); export default function GlobalStylesSidebar() { - const { params } = useLocation(); - const { canvas = 'view', path } = params; + const { query } = useLocation(); + const { canvas = 'view', name } = query; const { shouldClearCanvasContainerView, isStyleBookOpened, @@ -133,14 +133,14 @@ export default function GlobalStylesSidebar() { const previousActiveAreaRef = useRef( null ); useEffect( () => { - if ( path?.startsWith( '/wp_global_styles' ) && canvas === 'edit' ) { + if ( name === 'styles' && canvas === 'edit' ) { previousActiveAreaRef.current = getActiveComplementaryArea( 'core' ); enableComplementaryArea( 'core', 'edit-site/global-styles' ); } else if ( previousActiveAreaRef.current ) { enableComplementaryArea( 'core', previousActiveAreaRef.current ); } - }, [ path, enableComplementaryArea, canvas, getActiveComplementaryArea ] ); + }, [ name, enableComplementaryArea, canvas, getActiveComplementaryArea ] ); return ( { @@ -60,27 +59,3 @@ function useRedirectOldPaths() { } }, [ history, params ] ); } - -export default function useActiveRoute() { - const { params } = useLocation(); - useRedirectOldPaths(); - const routes = useSelect( ( select ) => { - return unlock( select( editSiteStore ) ).getRoutes(); - }, [] ); - return useMemo( () => { - const matchedRoute = routes.find( ( route ) => route.match( params ) ); - if ( ! matchedRoute ) { - return { - key: 404, - areas: {}, - widths: {}, - }; - } - - return { - name: matchedRoute.name, - areas: matchedRoute.areas, - widths: matchedRoute.widths, - }; - }, [ routes, params ] ); -} diff --git a/packages/edit-site/src/components/page-patterns/delete-category-menu-item.js b/packages/edit-site/src/components/page-patterns/delete-category-menu-item.js index d87737c55326c..ca7bbf2fa7322 100644 --- a/packages/edit-site/src/components/page-patterns/delete-category-menu-item.js +++ b/packages/edit-site/src/components/page-patterns/delete-category-menu-item.js @@ -59,10 +59,9 @@ export default function DeleteCategoryMenuItem( { category, onClose } ) { ); onClose?.(); - history.push( { - postType: PATTERN_TYPES.user, - categoryId: PATTERN_DEFAULT_CATEGORY, - } ); + history.navigate( + `/pattern?categoryId=${ PATTERN_DEFAULT_CATEGORY }` + ); } catch ( error ) { const errorMessage = error.message && error.code !== 'unknown_error' diff --git a/packages/edit-site/src/components/page-patterns/fields.js b/packages/edit-site/src/components/page-patterns/fields.js index e016dca6cd855..60e37844b2edb 100644 --- a/packages/edit-site/src/components/page-patterns/fields.js +++ b/packages/edit-site/src/components/page-patterns/fields.js @@ -21,6 +21,7 @@ import { import { Icon, lockSmall } from '@wordpress/icons'; import { parse } from '@wordpress/blocks'; import { decodeEntities } from '@wordpress/html-entities'; +import { privateApis as routerPrivateApis } from '@wordpress/router'; /** * Internal dependencies @@ -32,10 +33,10 @@ import { OPERATOR_IS, } from '../../utils/constants'; import { unlock } from '../../lock-unlock'; -import { useLink } from '../routes/link'; import { useAddedBy } from '../page-templates/hooks'; import { defaultGetTitle } from './search-items'; +const { useLink } = unlock( routerPrivateApis ); const { useGlobalStyle } = unlock( blockEditorPrivateApis ); function PreviewWrapper( { item, onClick, ariaDescribedBy, children } ) { @@ -59,11 +60,11 @@ function PreviewField( { item } ) { const isUserPattern = item.type === PATTERN_TYPES.user; const isTemplatePart = item.type === TEMPLATE_PART_POST_TYPE; const [ backgroundColor ] = useGlobalStyle( 'color.background' ); - const { onClick } = useLink( { - postType: item.type, - postId: isUserPattern || isTemplatePart ? item.id : item.name, - canvas: 'edit', - } ); + const { onClick } = useLink( + `/${ item.type }/${ + isUserPattern || isTemplatePart ? item.id : item.name + }?canvas=edit` + ); const blocks = useMemo( () => { return ( item.blocks ?? @@ -114,11 +115,11 @@ export const previewField = { function TitleField( { item } ) { const isUserPattern = item.type === PATTERN_TYPES.user; const isTemplatePart = item.type === TEMPLATE_PART_POST_TYPE; - const { onClick } = useLink( { - postType: item.type, - postId: isUserPattern || isTemplatePart ? item.id : item.name, - canvas: 'edit', - } ); + const { onClick } = useLink( + `/${ item.type }/${ + isUserPattern || isTemplatePart ? item.id : item.name + }?canvas=edit` + ); const title = decodeEntities( defaultGetTitle( item ) ); return ( diff --git a/packages/edit-site/src/components/page-patterns/index.js b/packages/edit-site/src/components/page-patterns/index.js index 69ebf66093806..b675333488757 100644 --- a/packages/edit-site/src/components/page-patterns/index.js +++ b/packages/edit-site/src/components/page-patterns/index.js @@ -72,17 +72,16 @@ const DEFAULT_VIEW = { export default function DataviewsPatterns() { const { - params: { postType, categoryId: categoryIdFromURL }, + query: { postType = 'wp_block', categoryId: categoryIdFromURL }, } = useLocation(); - const type = postType || PATTERN_TYPES.user; const categoryId = categoryIdFromURL || PATTERN_DEFAULT_CATEGORY; const [ view, setView ] = useState( DEFAULT_VIEW ); const previousCategoryId = usePrevious( categoryId ); - const previousPostType = usePrevious( type ); + const previousPostType = usePrevious( postType ); const viewSyncStatus = view.filters?.find( ( { field } ) => field === 'sync-status' )?.value; - const { patterns, isResolving } = usePatterns( type, categoryId, { + const { patterns, isResolving } = usePatterns( postType, categoryId, { search: view.search, syncStatus: viewSyncStatus, } ); @@ -108,9 +107,9 @@ export default function DataviewsPatterns() { const fields = useMemo( () => { const _fields = [ previewField, titleField ]; - if ( type === PATTERN_TYPES.user ) { + if ( postType === PATTERN_TYPES.user ) { _fields.push( patternStatusField ); - } else if ( type === TEMPLATE_PART_POST_TYPE ) { + } else if ( postType === TEMPLATE_PART_POST_TYPE ) { _fields.push( { ...templatePartAuthorField, elements: authors, @@ -118,24 +117,27 @@ export default function DataviewsPatterns() { } return _fields; - }, [ type, authors ] ); + }, [ postType, authors ] ); // Reset the page number when the category changes. useEffect( () => { - if ( previousCategoryId !== categoryId || previousPostType !== type ) { + if ( + previousCategoryId !== categoryId || + previousPostType !== postType + ) { setView( ( prevView ) => ( { ...prevView, page: 1 } ) ); } - }, [ categoryId, previousCategoryId, previousPostType, type ] ); + }, [ categoryId, previousCategoryId, previousPostType, postType ] ); const { data, paginationInfo } = useMemo( () => { // Search is managed server-side as well as filters for patterns. // However, the author filter in template parts is done client-side. const viewWithoutFilters = { ...view }; delete viewWithoutFilters.search; - if ( type !== TEMPLATE_PART_POST_TYPE ) { + if ( postType !== TEMPLATE_PART_POST_TYPE ) { viewWithoutFilters.filters = []; } return filterSortAndPaginate( patterns, viewWithoutFilters, fields ); - }, [ patterns, view, fields, type ] ); + }, [ patterns, view, fields, postType ] ); const dataWithPermissions = useAugmentPatternsWithPermissions( data ); @@ -150,11 +152,11 @@ export default function DataviewsPatterns() { const editAction = useEditPostAction(); const actions = useMemo( () => { - if ( type === TEMPLATE_PART_POST_TYPE ) { + if ( postType === TEMPLATE_PART_POST_TYPE ) { return [ editAction, ...templatePartActions ].filter( Boolean ); } return [ editAction, ...patternActions ].filter( Boolean ); - }, [ editAction, type, templatePartActions, patternActions ] ); + }, [ editAction, postType, templatePartActions, patternActions ] ); const id = useId(); const settings = usePatternSettings(); // Wrap everything in a block editor provider. @@ -169,7 +171,7 @@ export default function DataviewsPatterns() { > diff --git a/packages/edit-site/src/components/page-templates/fields.js b/packages/edit-site/src/components/page-templates/fields.js index 69e0596bf49d4..35d7b9714d5be 100644 --- a/packages/edit-site/src/components/page-templates/fields.js +++ b/packages/edit-site/src/components/page-templates/fields.js @@ -16,16 +16,16 @@ import { privateApis as blockEditorPrivateApis, } from '@wordpress/block-editor'; import { EditorProvider } from '@wordpress/editor'; +import { privateApis as routerPrivateApis } from '@wordpress/router'; /** * Internal dependencies */ -import { default as Link, useLink } from '../routes/link'; import { useAddedBy } from './hooks'; - import usePatternSettings from '../page-patterns/use-pattern-settings'; import { unlock } from '../../lock-unlock'; +const { useLink, Link } = unlock( routerPrivateApis ); const { useGlobalStyle } = unlock( blockEditorPrivateApis ); function PreviewField( { item } ) { @@ -34,11 +34,7 @@ function PreviewField( { item } ) { const blocks = useMemo( () => { return parse( item.content.raw ); }, [ item.content.raw ] ); - const { onClick } = useLink( { - postId: item.id, - postType: item.type, - canvas: 'edit', - } ); + const { onClick } = useLink( `/${ item.type }/${ item.id }?canvas=edit` ); const isEmpty = ! blocks?.length; // Wrap everything in a block editor provider to ensure 'styles' that are needed @@ -80,15 +76,8 @@ export const previewField = { }; function TitleField( { item } ) { - const linkProps = { - params: { - postId: item.id, - postType: item.type, - canvas: 'edit', - }, - }; return ( - + { decodeEntities( item.title?.rendered ) || __( '(no title)' ) } ); diff --git a/packages/edit-site/src/components/page-templates/index.js b/packages/edit-site/src/components/page-templates/index.js index ea026ca53566e..828867e6f283d 100644 --- a/packages/edit-site/src/components/page-templates/index.js +++ b/packages/edit-site/src/components/page-templates/index.js @@ -7,6 +7,7 @@ import { privateApis as corePrivateApis } from '@wordpress/core-data'; import { DataViews, filterSortAndPaginate } from '@wordpress/dataviews'; import { privateApis as routerPrivateApis } from '@wordpress/router'; import { privateApis as editorPrivateApis } from '@wordpress/editor'; +import { addQueryArgs } from '@wordpress/url'; /** * Internal dependencies @@ -93,8 +94,8 @@ const DEFAULT_VIEW = { }; export default function PageTemplates() { - const { params } = useLocation(); - const { activeView = 'all', layout, postId } = params; + const { path, query } = useLocation(); + const { activeView = 'all', layout, postId } = query; const [ selection, setSelection ] = useState( [ postId ] ); const defaultView = useMemo( () => { @@ -118,8 +119,10 @@ export default function PageTemplates() { }, [ layout, activeView ] ); const [ view, setView ] = useState( defaultView ); useEffect( () => { + const usedType = layout ?? DEFAULT_VIEW.type; setView( ( currentView ) => ( { ...currentView, + type: usedType, filters: activeView !== 'all' ? [ @@ -131,7 +134,7 @@ export default function PageTemplates() { ] : [], } ) ); - }, [ activeView ] ); + }, [ activeView, layout ] ); const { records, isResolving: isLoadingData } = useEntityRecordsWithPermissions( 'postType', TEMPLATE_POST_TYPE, { @@ -142,13 +145,14 @@ export default function PageTemplates() { ( items ) => { setSelection( items ); if ( view?.type === LAYOUT_LIST ) { - history.push( { - ...params, - postId: items.length === 1 ? items[ 0 ] : undefined, - } ); + history.navigate( + addQueryArgs( path, { + postId: items.length === 1 ? items[ 0 ] : undefined, + } ) + ); } }, - [ history, params, view?.type ] + [ history, path, view?.type ] ); const authors = useMemo( () => { @@ -195,15 +199,16 @@ export default function PageTemplates() { const onChangeView = useCallback( ( newView ) => { if ( newView.type !== view.type ) { - history.push( { - ...params, - layout: newView.type, - } ); + history.navigate( + addQueryArgs( path, { + layout: newView.type, + } ) + ); } setView( newView ); }, - [ view.type, setView, history, params ] + [ view.type, setView, history, path ] ); return ( diff --git a/packages/edit-site/src/components/post-list/index.js b/packages/edit-site/src/components/post-list/index.js index 975809b2ad610..d58ddbe50758c 100644 --- a/packages/edit-site/src/components/post-list/index.js +++ b/packages/edit-site/src/components/post-list/index.js @@ -13,6 +13,8 @@ import { DataViews, filterSortAndPaginate } from '@wordpress/dataviews'; import { privateApis as editorPrivateApis } from '@wordpress/editor'; import { __ } from '@wordpress/i18n'; import { drawerRight } from '@wordpress/icons'; +import { usePrevious } from '@wordpress/compose'; +import { addQueryArgs } from '@wordpress/url'; /** * Internal dependencies @@ -31,7 +33,6 @@ import { import AddNewPostModal from '../add-new-post'; import { unlock } from '../../lock-unlock'; import { useEditPostAction } from '../dataviews-actions'; -import { usePrevious } from '@wordpress/compose'; const { usePostActions, usePostFields } = unlock( editorPrivateApis ); const { useLocation, useHistory } = unlock( routerPrivateApis ); @@ -70,7 +71,8 @@ const getCustomView = ( editedEntityRecord ) => { */ function useView( postType ) { const { - params: { activeView = 'all', isCustom = 'false', layout }, + path, + query: { activeView = 'all', isCustom = 'false', layout }, } = useLocation(); const history = useHistory(); @@ -112,16 +114,15 @@ function useView( postType ) { const setViewWithUrlUpdate = useCallback( ( newView ) => { - const { params } = history.getLocationWithParams(); - - if ( newView.type === LAYOUT_LIST && ! params?.layout ) { + if ( newView.type === LAYOUT_LIST && ! layout ) { // Skip updating the layout URL param if // it is not present and the newView.type is LAYOUT_LIST. - } else if ( newView.type !== params?.layout ) { - history.push( { - ...params, - layout: newView.type, - } ); + } else if ( newView.type !== layout ) { + history.navigate( + addQueryArgs( path, { + layout: newView.type, + } ) + ); } setView( newView ); @@ -137,7 +138,14 @@ function useView( postType ) { ); } }, - [ history, isCustom, editEntityRecord, editedEntityRecord?.id ] + [ + history, + isCustom, + editEntityRecord, + editedEntityRecord?.id, + layout, + path, + ] ); // When layout URL param changes, update the view type @@ -186,20 +194,20 @@ export default function PostList( { postType } ) { quickEdit = false, isCustom, activeView = 'all', - } = location.params; + } = location.query; const [ selection, setSelection ] = useState( postId?.split( ',' ) ?? [] ); const onChangeSelection = useCallback( ( items ) => { setSelection( items ); - const { params } = history.getLocationWithParams(); - if ( ( params.isCustom ?? 'false' ) === 'false' ) { - history.push( { - ...params, - postId: items.join( ',' ), - } ); + if ( ( location.query.isCustom ?? 'false' ) === 'false' ) { + history.navigate( + addQueryArgs( location.path, { + postId: items.join( ',' ), + } ) + ); } }, - [ history ] + [ location.path, location.query.isCustom, history ] ); const getActiveViewFilters = ( views, match ) => { @@ -311,12 +319,13 @@ export default function PostList( { postType } ) { useEffect( () => { if ( postIdWasDeleted ) { - history.push( { - ...history.getLocationWithParams().params, - postId: undefined, - } ); + history.navigate( + addQueryArgs( location.path, { + postId: undefined, + } ) + ); } - }, [ postIdWasDeleted, history ] ); + }, [ history, postIdWasDeleted, location.path ] ); const paginationInfo = useMemo( () => ( { @@ -355,11 +364,7 @@ export default function PostList( { postType } ) { const openModal = () => setShowAddPostModal( true ); const closeModal = () => setShowAddPostModal( false ); const handleNewPage = ( { type, id } ) => { - history.push( { - postId: id, - postType: type, - canvas: 'edit', - } ); + history.navigate( `/${ type }/${ id }?canvas=edit` ); closeModal(); }; @@ -401,11 +406,7 @@ export default function PostList( { postType } ) { onChangeSelection={ onChangeSelection } isItemClickable={ ( item ) => item.status !== 'trash' } onClickItem={ ( { id } ) => { - history.push( { - postId: id, - postType, - canvas: 'edit', - } ); + history.navigate( `/${ postType }/${ id }?canvas=edit` ); } } getItemId={ getItemId } defaultLayouts={ defaultLayouts } @@ -419,10 +420,11 @@ export default function PostList( { postType } ) { icon={ drawerRight } label={ __( 'Details' ) } onClick={ () => { - history.push( { - ...location.params, - quickEdit: quickEdit ? undefined : true, - } ); + history.navigate( + addQueryArgs( location.path, { + quickEdit: quickEdit ? undefined : true, + } ) + ); } } /> ) diff --git a/packages/edit-site/src/components/resizable-frame/index.js b/packages/edit-site/src/components/resizable-frame/index.js index 95ccfe4fdd966..99f650971112f 100644 --- a/packages/edit-site/src/components/resizable-frame/index.js +++ b/packages/edit-site/src/components/resizable-frame/index.js @@ -20,6 +20,7 @@ import { privateApis as routerPrivateApis } from '@wordpress/router'; * Internal dependencies */ import { unlock } from '../../lock-unlock'; +import { addQueryArgs } from '@wordpress/url'; const { useLocation, useHistory } = unlock( routerPrivateApis ); @@ -88,8 +89,8 @@ function ResizableFrame( { innerContentStyle, } ) { const history = useHistory(); - const { params } = useLocation(); - const { canvas = 'view' } = params; + const { path, query } = useLocation(); + const { canvas = 'view' } = query; const disableMotion = useReducedMotion(); const [ frameSize, setFrameSize ] = useState( INITIAL_FRAME_SIZE ); // The width of the resizable frame when a new resize gesture starts. @@ -158,12 +159,10 @@ function ResizableFrame( { setFrameSize( INITIAL_FRAME_SIZE ); } else { // Trigger full screen if the frame is resized far enough to the left. - history.push( - { - ...params, + history.navigate( + addQueryArgs( path, { canvas: 'edit', - }, - undefined, + } ), { transition: 'canvas-mode-edit-transition', } diff --git a/packages/edit-site/src/components/routes/link.js b/packages/edit-site/src/components/routes/link.js deleted file mode 100644 index a34b37943a079..0000000000000 --- a/packages/edit-site/src/components/routes/link.js +++ /dev/null @@ -1,68 +0,0 @@ -/** - * WordPress dependencies - */ -import { addQueryArgs, getQueryArgs, removeQueryArgs } from '@wordpress/url'; -import { privateApis as routerPrivateApis } from '@wordpress/router'; - -/** - * Internal dependencies - */ -import { unlock } from '../../lock-unlock'; -import { - isPreviewingTheme, - currentlyPreviewingTheme, -} from '../../utils/is-previewing-theme'; - -const { useHistory } = unlock( routerPrivateApis ); - -export function useLink( params, state, shouldReplace = false ) { - const history = useHistory(); - function onClick( event ) { - event?.preventDefault(); - - if ( shouldReplace ) { - history.replace( params, state ); - } else { - history.push( params, state ); - } - } - - const currentArgs = getQueryArgs( window.location.href ); - const currentUrlWithoutArgs = removeQueryArgs( - window.location.href, - ...Object.keys( currentArgs ) - ); - - let extraParams = {}; - if ( isPreviewingTheme() ) { - extraParams = { - wp_theme_preview: currentlyPreviewingTheme(), - }; - } - - const newUrl = addQueryArgs( currentUrlWithoutArgs, { - ...params, - ...extraParams, - } ); - - return { - href: newUrl, - onClick, - }; -} - -export default function Link( { - params = {}, - state, - replace: shouldReplace = false, - children, - ...props -} ) { - const { href, onClick } = useLink( params, state, shouldReplace ); - - return ( - - { children } - - ); -} diff --git a/packages/edit-site/src/components/save-panel/index.js b/packages/edit-site/src/components/save-panel/index.js index b77e5a9a1a10b..81a0f99557df0 100644 --- a/packages/edit-site/src/components/save-panel/index.js +++ b/packages/edit-site/src/components/save-panel/index.js @@ -90,8 +90,8 @@ const _EntitiesSavedStates = ( { onClose, renderDialog = undefined } ) => { }; export default function SavePanel() { - const { params } = useLocation(); - const { canvas = 'view' } = params; + const { query } = useLocation(); + const { canvas = 'view' } = query; const { isSaveViewOpen, isDirty, isSaving } = useSelect( ( select ) => { const { __experimentalGetDirtyEntityRecords, diff --git a/packages/edit-site/src/components/sidebar-dataviews/add-new-view.js b/packages/edit-site/src/components/sidebar-dataviews/add-new-view.js index 62956ccd18960..815de181a9dde 100644 --- a/packages/edit-site/src/components/sidebar-dataviews/add-new-view.js +++ b/packages/edit-site/src/components/sidebar-dataviews/add-new-view.js @@ -14,6 +14,7 @@ import { store as coreStore } from '@wordpress/core-data'; import { useState } from '@wordpress/element'; import { plus } from '@wordpress/icons'; import { privateApis as routerPrivateApis } from '@wordpress/router'; +import { addQueryArgs } from '@wordpress/url'; /** * Internal dependencies @@ -22,10 +23,11 @@ import SidebarNavigationItem from '../sidebar-navigation-item'; import { useDefaultViews } from './default-views'; import { unlock } from '../../lock-unlock'; -const { useHistory } = unlock( routerPrivateApis ); +const { useLocation, useHistory } = unlock( routerPrivateApis ); function AddNewItemModalContent( { type, setIsAdding } ) { const history = useHistory(); + const { path } = useLocation(); const { saveEntityRecord } = useDispatch( coreStore ); const [ title, setTitle ] = useState( '' ); const [ isSaving, setIsSaving ] = useState( false ); @@ -64,14 +66,12 @@ function AddNewItemModalContent( { type, setIsAdding } ) { content: JSON.stringify( defaultViews[ 0 ].view ), } ); - const { - params: { postType }, - } = history.getLocationWithParams(); - history.push( { - postType, - activeView: savedRecord.id, - isCustom: 'true', - } ); + history.navigate( + addQueryArgs( path, { + activeView: savedRecord.id, + isCustom: 'true', + } ) + ); setIsSaving( false ); setIsAdding( false ); } } diff --git a/packages/edit-site/src/components/sidebar-dataviews/dataview-item.js b/packages/edit-site/src/components/sidebar-dataviews/dataview-item.js index 1e12d6706d81b..b98f8b80938d6 100644 --- a/packages/edit-site/src/components/sidebar-dataviews/dataview-item.js +++ b/packages/edit-site/src/components/sidebar-dataviews/dataview-item.js @@ -9,11 +9,11 @@ import clsx from 'clsx'; import { privateApis as routerPrivateApis } from '@wordpress/router'; import { __experimentalHStack as HStack } from '@wordpress/components'; import { VIEW_LAYOUTS } from '@wordpress/dataviews'; +import { addQueryArgs } from '@wordpress/url'; /** * Internal dependencies */ -import { useLink } from '../routes/link'; import SidebarNavigationItem from '../sidebar-navigation-item'; import { unlock } from '../../lock-unlock'; const { useLocation } = unlock( routerPrivateApis ); @@ -28,9 +28,7 @@ export default function DataViewItem( { isCustom, suffix, } ) { - const { - params: { postType }, - } = useLocation(); + const { path } = useLocation(); const iconToUse = icon || VIEW_LAYOUTS.find( ( v ) => v.type === type ).icon; @@ -39,12 +37,11 @@ export default function DataViewItem( { if ( activeView === 'all' ) { activeView = undefined; } - const linkInfo = useLink( { - postType, + const query = { layout: type, activeView, isCustom: isCustom ? 'true' : undefined, - } ); + }; return ( { title } diff --git a/packages/edit-site/src/components/sidebar-dataviews/index.js b/packages/edit-site/src/components/sidebar-dataviews/index.js index 86420c4eec1d1..410767650c6f3 100644 --- a/packages/edit-site/src/components/sidebar-dataviews/index.js +++ b/packages/edit-site/src/components/sidebar-dataviews/index.js @@ -14,9 +14,9 @@ import CustomDataViewsList from './custom-dataviews-list'; const { useLocation } = unlock( routerPrivateApis ); -export default function DataViewsSidebarContent() { +export default function DataViewsSidebarContent( { postType } ) { const { - params: { postType, activeView = 'all', isCustom = 'false' }, + query: { activeView = 'all', isCustom = 'false' }, } = useLocation(); const defaultViews = useDefaultViews( { postType } ); if ( ! postType ) { diff --git a/packages/edit-site/src/components/sidebar-global-styles-wrapper/index.js b/packages/edit-site/src/components/sidebar-global-styles-wrapper/index.js index 342fb1b5db52d..d868b5baba0c2 100644 --- a/packages/edit-site/src/components/sidebar-global-styles-wrapper/index.js +++ b/packages/edit-site/src/components/sidebar-global-styles-wrapper/index.js @@ -9,6 +9,7 @@ import { Button, privateApis as componentsPrivateApis, } from '@wordpress/components'; +import { addQueryArgs } from '@wordpress/url'; /** * Internal dependencies @@ -21,7 +22,6 @@ import { STYLE_BOOK_COLOR_GROUPS } from '../style-book/constants'; const { useLocation, useHistory } = unlock( routerPrivateApis ); const { Menu } = unlock( componentsPrivateApis ); -const GLOBAL_STYLES_PATH_PREFIX = '/wp_global_styles'; const GlobalStylesPageActions = ( { isStyleBookOpened, @@ -63,28 +63,23 @@ const GlobalStylesPageActions = ( { }; export default function GlobalStylesUIWrapper() { - const { params } = useLocation(); + const { path, query } = useLocation(); const history = useHistory(); - const { canvas = 'view' } = params; + const { canvas = 'view' } = query; const [ isStyleBookOpened, setIsStyleBookOpened ] = useState( false ); const isMobileViewport = useViewportMatch( 'medium', '<' ); - const pathWithPrefix = params.path; - const [ path, onPathChange ] = useMemo( () => { - const processedPath = pathWithPrefix.substring( - GLOBAL_STYLES_PATH_PREFIX.length - ); + const [ section, onChangeSection ] = useMemo( () => { return [ - processedPath ? processedPath : '/', - ( newPath ) => { - history.push( { - path: - ! newPath || newPath === '/' - ? GLOBAL_STYLES_PATH_PREFIX - : `${ GLOBAL_STYLES_PATH_PREFIX }${ newPath }`, - } ); + query.section ?? '/', + ( updatedSection ) => { + history.navigation( + addQueryArgs( path, { + section: updatedSection, + } ) + ); }, ]; - }, [ pathWithPrefix, history ] ); + }, [ path, query.section, history ] ); return ( <> @@ -100,7 +95,10 @@ export default function GlobalStylesUIWrapper() { className="edit-site-styles" title={ __( 'Styles' ) } > - + { canvas === 'view' && isStyleBookOpened && ( { if ( STYLE_BOOK_COLOR_GROUPS.find( @@ -129,17 +123,17 @@ export default function GlobalStylesUIWrapper() { ) ) { // Go to color palettes Global Styles. - onPathChange( '/colors/palette' ); + onChangeSection( '/colors/palette' ); return; } if ( blockName === 'typography' ) { // Go to typography Global Styles. - onPathChange( '/typography' ); + onChangeSection( '/typography' ); return; } // Now go to the selected block. - onPathChange( + onChangeSection( `/blocks/${ encodeURIComponent( blockName ) }` ); } } diff --git a/packages/edit-site/src/components/sidebar-navigation-item/index.js b/packages/edit-site/src/components/sidebar-navigation-item/index.js index 80f06d7e93133..4bde94dcbbeb4 100644 --- a/packages/edit-site/src/components/sidebar-navigation-item/index.js +++ b/packages/edit-site/src/components/sidebar-navigation-item/index.js @@ -22,7 +22,7 @@ import { useContext } from '@wordpress/element'; import { unlock } from '../../lock-unlock'; import { SidebarNavigationContext } from '../sidebar'; -const { useHistory } = unlock( routerPrivateApis ); +const { useHistory, useLink } = unlock( routerPrivateApis ); export default function SidebarNavigationItem( { className, @@ -30,7 +30,7 @@ export default function SidebarNavigationItem( { withChevron = false, suffix, uid, - params, + to, onClick, children, ...props @@ -42,12 +42,13 @@ export default function SidebarNavigationItem( { if ( onClick ) { onClick( e ); navigate( 'forward' ); - } else if ( params ) { + } else if ( to ) { e.preventDefault(); - history.push( params ); + history.navigate( to ); navigate( 'forward', `[id="${ uid }"]` ); } } + const linkProps = useLink( to ); return ( diff --git a/packages/edit-site/src/components/sidebar-navigation-screen-global-styles/index.js b/packages/edit-site/src/components/sidebar-navigation-screen-global-styles/index.js index 72671714479ac..4023ba436b865 100644 --- a/packages/edit-site/src/components/sidebar-navigation-screen-global-styles/index.js +++ b/packages/edit-site/src/components/sidebar-navigation-screen-global-styles/index.js @@ -7,6 +7,7 @@ import { store as coreStore } from '@wordpress/core-data'; import { useCallback } from '@wordpress/element'; import { store as preferencesStore } from '@wordpress/preferences'; import { privateApis as routerPrivateApis } from '@wordpress/router'; +import { addQueryArgs } from '@wordpress/url'; /** * Internal dependencies @@ -22,7 +23,7 @@ import { MainSidebarNavigationContent } from '../sidebar-navigation-screen-main' const { useLocation, useHistory } = unlock( routerPrivateApis ); export function SidebarNavigationItemGlobalStyles( props ) { - const { params } = useLocation(); + const { name } = useLocation(); const hasGlobalStyleVariations = useSelect( ( select ) => !! select( @@ -34,11 +35,9 @@ export function SidebarNavigationItemGlobalStyles( props ) { return ( ); } @@ -47,7 +46,7 @@ export function SidebarNavigationItemGlobalStyles( props ) { export default function SidebarNavigationScreenGlobalStyles() { const history = useHistory(); - const { params } = useLocation(); + const { path } = useLocation(); const { revisions, isLoading: isLoadingRevisions, @@ -60,21 +59,14 @@ export default function SidebarNavigationScreenGlobalStyles() { const { set: setPreference } = useDispatch( preferencesStore ); const openGlobalStyles = useCallback( async () => { - history.push( - { - ...params, - canvas: 'edit', - }, - undefined, - { - transition: 'canvas-mode-edit-transition', - } - ); + history.navigate( addQueryArgs( path, { canvas: 'edit' } ), { + transition: 'canvas-mode-edit-transition', + } ); return Promise.all( [ setPreference( 'core', 'distractionFree', false ), openGeneralSidebar( 'edit-site/global-styles' ), ] ); - }, [ history, params, openGeneralSidebar, setPreference ] ); + }, [ path, history, openGeneralSidebar, setPreference ] ); const openRevisions = useCallback( async () => { await openGlobalStyles(); diff --git a/packages/edit-site/src/components/sidebar-navigation-screen-main/index.js b/packages/edit-site/src/components/sidebar-navigation-screen-main/index.js index 49e60d4404732..1db651631c53d 100644 --- a/packages/edit-site/src/components/sidebar-navigation-screen-main/index.js +++ b/packages/edit-site/src/components/sidebar-navigation-screen-main/index.js @@ -15,18 +15,13 @@ import SidebarNavigationItem from '../sidebar-navigation-item'; import { SidebarNavigationItemGlobalStyles } from '../sidebar-navigation-screen-global-styles'; import { unlock } from '../../lock-unlock'; import { store as editSiteStore } from '../../store'; -import { - NAVIGATION_POST_TYPE, - TEMPLATE_POST_TYPE, - PATTERN_TYPES, -} from '../../utils/constants'; export function MainSidebarNavigationContent() { return ( @@ -40,7 +35,7 @@ export function MainSidebarNavigationContent() { @@ -48,7 +43,7 @@ export function MainSidebarNavigationContent() { @@ -56,7 +51,7 @@ export function MainSidebarNavigationContent() { diff --git a/packages/edit-site/src/components/sidebar-navigation-screen-navigation-menu/more-menu.js b/packages/edit-site/src/components/sidebar-navigation-screen-navigation-menu/more-menu.js index 6b85e088817ed..a07167413ae11 100644 --- a/packages/edit-site/src/components/sidebar-navigation-screen-navigation-menu/more-menu.js +++ b/packages/edit-site/src/components/sidebar-navigation-screen-navigation-menu/more-menu.js @@ -58,11 +58,9 @@ export default function ScreenNavigationMoreMenu( props ) { { - history.push( { - postId: menuId, - postType: 'wp_navigation', - canvas: 'edit', - } ); + history.navigate( + `/wp_navigation/${ menuId }?canvas=edit` + ); } } > { __( 'Edit' ) } diff --git a/packages/edit-site/src/components/sidebar-navigation-screen-navigation-menu/use-navigation-menu-handlers.js b/packages/edit-site/src/components/sidebar-navigation-screen-navigation-menu/use-navigation-menu-handlers.js index 4a7e1deddc6d9..11635c6c6abb1 100644 --- a/packages/edit-site/src/components/sidebar-navigation-screen-navigation-menu/use-navigation-menu-handlers.js +++ b/packages/edit-site/src/components/sidebar-navigation-screen-navigation-menu/use-navigation-menu-handlers.js @@ -42,7 +42,7 @@ function useDeleteNavigationMenu() { type: 'snackbar', } ); - history.push( { postType: 'wp_navigation' } ); + history.navivate( '/navigation' ); } catch ( error ) { createErrorNotice( sprintf( @@ -165,7 +165,7 @@ function useDuplicateNavigationMenu() { createSuccessNotice( __( 'Duplicated Navigation Menu' ), { type: 'snackbar', } ); - history.push( { postType, postId: savedRecord.id } ); + history.navigate( `/wp_navigation/${ savedRecord.id }` ); } } catch ( error ) { createErrorNotice( diff --git a/packages/edit-site/src/components/sidebar-navigation-screen-navigation-menus/index.js b/packages/edit-site/src/components/sidebar-navigation-screen-navigation-menus/index.js index ece549f57378b..dc3dd87961184 100644 --- a/packages/edit-site/src/components/sidebar-navigation-screen-navigation-menus/index.js +++ b/packages/edit-site/src/components/sidebar-navigation-screen-navigation-menus/index.js @@ -18,7 +18,6 @@ import { navigation } from '@wordpress/icons'; import SidebarNavigationScreen from '../sidebar-navigation-screen'; import SidebarNavigationItem from '../sidebar-navigation-item'; import { PRELOADED_NAVIGATION_MENUS_QUERY } from './constants'; -import { useLink } from '../routes/link'; import SingleNavigationMenu from '../sidebar-navigation-screen-navigation-menu/single-navigation-menu'; import useNavigationMenuHandlers from '../sidebar-navigation-screen-navigation-menu/use-navigation-menu-handlers'; import { unlock } from '../../lock-unlock'; @@ -152,9 +151,10 @@ export function SidebarNavigationScreenWrapper( { } const NavMenuItem = ( { postId, ...props } ) => { - const linkInfo = useLink( { - postId, - postType: 'wp_navigation', - } ); - return ; + return ( + + ); }; diff --git a/packages/edit-site/src/components/sidebar-navigation-screen-navigation-menus/leaf-more-menu.js b/packages/edit-site/src/components/sidebar-navigation-screen-navigation-menus/leaf-more-menu.js index 568ec291f9ed1..ba01faab0291c 100644 --- a/packages/edit-site/src/components/sidebar-navigation-screen-navigation-menus/leaf-more-menu.js +++ b/packages/edit-site/src/components/sidebar-navigation-screen-navigation-menus/leaf-more-menu.js @@ -20,10 +20,11 @@ const POPOVER_PROPS = { */ import { unlock } from '../../lock-unlock'; -const { useHistory } = unlock( routerPrivateApis ); +const { useHistory, useLocation } = unlock( routerPrivateApis ); export default function LeafMoreMenu( props ) { const history = useHistory(); + const { path } = useLocation(); const { block } = props; const { clientId } = block; const { moveBlocksDown, moveBlocksUp, removeBlocks } = @@ -59,33 +60,20 @@ export default function LeafMoreMenu( props ) { attributes.type && history ) { - const { params } = history.getLocationWithParams(); - history.push( + history.navigate( + `/${ attributes.type }/${ attributes.id }?canvas=edit`, { - postType: attributes.type, - postId: attributes.id, - canvas: 'edit', - }, - { - backPath: params, + state: { backPath: path }, } ); } if ( name === 'core/page-list-item' && attributes.id && history ) { - const { params } = history.getLocationWithParams(); - history.push( - { - postType: 'page', - postId: attributes.id, - canvas: 'edit', - }, - { - backPath: params, - } - ); + history.navigate( `/page/${ attributes.id }?canvas=edit`, { + state: { backPath: path }, + } ); } }, - [ history ] + [ path, history ] ); return ( diff --git a/packages/edit-site/src/components/sidebar-navigation-screen-patterns/category-item.js b/packages/edit-site/src/components/sidebar-navigation-screen-patterns/category-item.js index 9c193304b99fc..4e92af1d84f50 100644 --- a/packages/edit-site/src/components/sidebar-navigation-screen-patterns/category-item.js +++ b/packages/edit-site/src/components/sidebar-navigation-screen-patterns/category-item.js @@ -2,13 +2,6 @@ * Internal dependencies */ import SidebarNavigationItem from '../sidebar-navigation-item'; -import { useLink } from '../routes/link'; -import { - TEMPLATE_PART_POST_TYPE, - TEMPLATE_PART_ALL_AREAS_CATEGORY, - PATTERN_DEFAULT_CATEGORY, - PATTERN_TYPES, -} from '../../utils/constants'; export default function CategoryItem( { count, @@ -18,28 +11,20 @@ export default function CategoryItem( { label, type, } ) { - const linkInfo = useLink( { - categoryId: - id !== TEMPLATE_PART_ALL_AREAS_CATEGORY && - id !== PATTERN_DEFAULT_CATEGORY - ? id - : undefined, - postType: - type === TEMPLATE_PART_POST_TYPE - ? TEMPLATE_PART_POST_TYPE - : PATTERN_TYPES.user, - } ); - if ( ! count ) { return; } + const queryArgs = [ `postType=${ type }` ]; + if ( id ) { + queryArgs.push( `categoryId=${ id }` ); + } return ( { count } } aria-current={ isActive ? 'true' : undefined } + to={ `/pattern?${ queryArgs.join( '&' ) }` } > { label } diff --git a/packages/edit-site/src/components/sidebar-navigation-screen-patterns/index.js b/packages/edit-site/src/components/sidebar-navigation-screen-patterns/index.js index eeec513cb99af..d63389ad3be31 100644 --- a/packages/edit-site/src/components/sidebar-navigation-screen-patterns/index.js +++ b/packages/edit-site/src/components/sidebar-navigation-screen-patterns/index.js @@ -104,12 +104,11 @@ function CategoriesGroup( { export default function SidebarNavigationScreenPatterns( { backPath } ) { const { - params: { postType, categoryId }, + query: { postType = 'wp_block', categoryId }, } = useLocation(); - const currentType = postType || PATTERN_TYPES.user; const currentCategory = categoryId || - ( currentType === PATTERN_TYPES.user + ( postType === PATTERN_TYPES.user ? PATTERN_DEFAULT_CATEGORY : TEMPLATE_PART_ALL_AREAS_CATEGORY ); @@ -143,7 +142,7 @@ export default function SidebarNavigationScreenPatterns( { backPath } ) { templatePartAreas={ templatePartAreas } patternCategories={ patternCategories } currentCategory={ currentCategory } - currentType={ currentType } + currentType={ postType } /> ) } diff --git a/packages/edit-site/src/components/sidebar-navigation-screen-templates-browse/content.js b/packages/edit-site/src/components/sidebar-navigation-screen-templates-browse/content.js index 5a07adf62d9b3..5d3819eac0ee3 100644 --- a/packages/edit-site/src/components/sidebar-navigation-screen-templates-browse/content.js +++ b/packages/edit-site/src/components/sidebar-navigation-screen-templates-browse/content.js @@ -4,35 +4,40 @@ import { useEntityRecords } from '@wordpress/core-data'; import { useMemo } from '@wordpress/element'; import { __experimentalItemGroup as ItemGroup } from '@wordpress/components'; +import { __ } from '@wordpress/i18n'; +import { privateApis as routerPrivateApis } from '@wordpress/router'; /** * Internal dependencies */ -import DataViewItem from '../sidebar-dataviews/dataview-item'; +import SidebarNavigationItem from '../sidebar-navigation-item'; import { useAddedBy } from '../page-templates/hooks'; import { layout } from '@wordpress/icons'; import { TEMPLATE_POST_TYPE } from '../../utils/constants'; +import { unlock } from '../../lock-unlock'; + +const { useLocation } = unlock( routerPrivateApis ); const EMPTY_ARRAY = []; function TemplateDataviewItem( { template, isActive } ) { const { text, icon } = useAddedBy( template.type, template.id ); + return ( - + aria-current={ isActive } + > + { text } + ); } -export default function DataviewsTemplatesSidebarContent( { - activeView, - title, -} ) { +export default function DataviewsTemplatesSidebarContent() { + const { + query: { activeView = 'all' }, + } = useLocation(); const { records } = useEntityRecords( 'postType', TEMPLATE_POST_TYPE, { per_page: -1, } ); @@ -52,13 +57,13 @@ export default function DataviewsTemplatesSidebarContent( { return ( - + aria-current={ activeView === 'all' } + > + { __( 'All templates' ) } + { firstItemPerAuthorText.map( ( template ) => { return ( - } + content={ } /> ); } diff --git a/packages/edit-site/src/components/sidebar-navigation-screen/index.js b/packages/edit-site/src/components/sidebar-navigation-screen/index.js index 0080964310525..f3bcb2b242b71 100644 --- a/packages/edit-site/src/components/sidebar-navigation-screen/index.js +++ b/packages/edit-site/src/components/sidebar-navigation-screen/index.js @@ -83,7 +83,7 @@ export default function SidebarNavigationScreen( { { ! isRoot && ( { - history.push( backPath ); + history.navigate( backPath ); navigate( 'back' ); } } icon={ icon } diff --git a/packages/edit-site/src/components/site-editor-routes/home-edit.js b/packages/edit-site/src/components/site-editor-routes/home-edit.js deleted file mode 100644 index f6e6499254082..0000000000000 --- a/packages/edit-site/src/components/site-editor-routes/home-edit.js +++ /dev/null @@ -1,17 +0,0 @@ -/** - * Internal dependencies - */ -import Editor from '../editor'; -import SidebarNavigationScreenMain from '../sidebar-navigation-screen-main'; - -export const homeEditRoute = { - name: 'home-edit', - match: ( params ) => { - return params.canvas === 'edit'; - }, - areas: { - sidebar: , - preview: , - mobile: , - }, -}; diff --git a/packages/edit-site/src/components/site-editor-routes/home-view.js b/packages/edit-site/src/components/site-editor-routes/home.js similarity index 66% rename from packages/edit-site/src/components/site-editor-routes/home-view.js rename to packages/edit-site/src/components/site-editor-routes/home.js index 63d3d021e8208..3b6230e6b6c38 100644 --- a/packages/edit-site/src/components/site-editor-routes/home-view.js +++ b/packages/edit-site/src/components/site-editor-routes/home.js @@ -4,13 +4,12 @@ import Editor from '../editor'; import SidebarNavigationScreenMain from '../sidebar-navigation-screen-main'; -export const homeViewRoute = { - name: 'home-view', - match: ( params ) => { - return params.canvas !== 'edit'; - }, +export const homeRoute = { + name: 'home', + path: '/', areas: { sidebar: , preview: , + mobile: , }, }; diff --git a/packages/edit-site/src/components/site-editor-routes/index.js b/packages/edit-site/src/components/site-editor-routes/index.js index 4887436dc2ed1..bac2fa302b5cf 100644 --- a/packages/edit-site/src/components/site-editor-routes/index.js +++ b/packages/edit-site/src/components/site-editor-routes/index.js @@ -9,42 +9,30 @@ import { useEffect } from '@wordpress/element'; */ import { unlock } from '../../lock-unlock'; import { store as siteEditorStore } from '../../store'; -import { homeViewRoute } from './home-view'; -import { homeEditRoute } from './home-edit'; -import { navigationViewRoute } from './navigation-view'; -import { navigationEditRoute } from './navigation-edit'; -import { navigationItemEditRoute } from './navigation-item-edit'; -import { navigationItemViewRoute } from './navigation-item-view'; -import { stylesViewRoute } from './styles-view'; -import { patternsEditRoute } from './patterns-edit'; -import { patternsViewRoute } from './patterns-view'; -import { templatesEditRoute } from './templates-edit'; -import { templatesListViewRoute } from './templates-list-view'; -import { templatesViewRoute } from './templates-view'; -import { pagesViewRoute } from './pages-view'; -import { pagesEditRoute } from './pages-edit'; -import { pagesListViewRoute } from './pages-list-view'; -import { pagesListViewQuickEditRoute } from './pages-list-view-quick-edit'; -import { pagesViewQuickEditRoute } from './pages-view-quick-edit'; +import { homeRoute } from './home'; +import { stylesRoute } from './styles'; +import { navigationRoute } from './navigation'; +import { navigationItemRoute } from './navigation-item'; +import { patternsRoute } from './patterns'; +import { patternItemRoute } from './pattern-item'; +import { templatePartItemRoute } from './template-part-item'; +import { templatesRoute } from './templates'; +import { templateItemRoute } from './template-item'; +import { pagesRoute } from './pages'; +import { pageItemRoute } from './page-item'; const routes = [ - pagesListViewQuickEditRoute, - pagesListViewRoute, - pagesViewQuickEditRoute, - pagesViewRoute, - pagesEditRoute, - templatesEditRoute, - templatesListViewRoute, - templatesViewRoute, - patternsViewRoute, - patternsEditRoute, - stylesViewRoute, - navigationItemViewRoute, - navigationItemEditRoute, - navigationViewRoute, - navigationEditRoute, - homeViewRoute, - homeEditRoute, + pageItemRoute, + pagesRoute, + templateItemRoute, + templatesRoute, + templatePartItemRoute, + patternItemRoute, + patternsRoute, + navigationItemRoute, + navigationRoute, + stylesRoute, + homeRoute, ]; export function useRegisterSiteEditorRoutes() { diff --git a/packages/edit-site/src/components/site-editor-routes/navigation-edit.js b/packages/edit-site/src/components/site-editor-routes/navigation-edit.js deleted file mode 100644 index fdba963c41d0c..0000000000000 --- a/packages/edit-site/src/components/site-editor-routes/navigation-edit.js +++ /dev/null @@ -1,22 +0,0 @@ -/** - * Internal dependencies - */ -import { NAVIGATION_POST_TYPE } from '../../utils/constants'; -import Editor from '../editor'; -import SidebarNavigationScreenNavigationMenus from '../sidebar-navigation-screen-navigation-menus'; - -export const navigationEditRoute = { - name: 'navigation-edit', - match: ( params ) => { - return ( - params.postType === NAVIGATION_POST_TYPE && - ! params.postId && - params.canvas === 'edit' - ); - }, - areas: { - sidebar: , - preview: , - mobile: , - }, -}; diff --git a/packages/edit-site/src/components/site-editor-routes/navigation-item-edit.js b/packages/edit-site/src/components/site-editor-routes/navigation-item-edit.js deleted file mode 100644 index b03cdbd995ac7..0000000000000 --- a/packages/edit-site/src/components/site-editor-routes/navigation-item-edit.js +++ /dev/null @@ -1,26 +0,0 @@ -/** - * Internal dependencies - */ -import { NAVIGATION_POST_TYPE } from '../../utils/constants'; -import Editor from '../editor'; -import SidebarNavigationScreenNavigationMenu from '../sidebar-navigation-screen-navigation-menu'; - -export const navigationItemEditRoute = { - name: 'navigation-item-edit', - match: ( params ) => { - return ( - params.postType === NAVIGATION_POST_TYPE && - !! params.postId && - params.canvas === 'edit' - ); - }, - areas: { - sidebar: ( - - ), - preview: , - mobile: , - }, -}; diff --git a/packages/edit-site/src/components/site-editor-routes/navigation-item-view.js b/packages/edit-site/src/components/site-editor-routes/navigation-item-view.js deleted file mode 100644 index d04a03a8f9df3..0000000000000 --- a/packages/edit-site/src/components/site-editor-routes/navigation-item-view.js +++ /dev/null @@ -1,25 +0,0 @@ -/** - * Internal dependencies - */ -import { NAVIGATION_POST_TYPE } from '../../utils/constants'; -import Editor from '../editor'; -import SidebarNavigationScreenNavigationMenu from '../sidebar-navigation-screen-navigation-menu'; - -export const navigationItemViewRoute = { - name: 'navigation-item-view', - match: ( params ) => { - return ( - params.postType === NAVIGATION_POST_TYPE && - !! params.postId && - params.canvas !== 'edit' - ); - }, - areas: { - sidebar: ( - - ), - preview: , - }, -}; diff --git a/packages/edit-site/src/components/site-editor-routes/navigation-item.js b/packages/edit-site/src/components/site-editor-routes/navigation-item.js new file mode 100644 index 0000000000000..fbfec1ac3eefa --- /dev/null +++ b/packages/edit-site/src/components/site-editor-routes/navigation-item.js @@ -0,0 +1,42 @@ +/** + * WordPress dependencies + */ +import { privateApis as routerPrivateApis } from '@wordpress/router'; + +/** + * Internal dependencies + */ +import { NAVIGATION_POST_TYPE } from '../../utils/constants'; +import Editor from '../editor'; +import SidebarNavigationScreenNavigationMenu from '../sidebar-navigation-screen-navigation-menu'; +import { unlock } from '../../lock-unlock'; + +const { useLocation } = unlock( routerPrivateApis ); + +function MobileNavigationItemView() { + const { query = {} } = useLocation(); + const { canvas = 'view' } = query; + + return canvas === 'edit' ? ( + + ) : ( + + ); +} + +export const navigationItemRoute = { + name: 'navigation-item', + path: '/wp_navigation/:postId', + match: ( params ) => { + return params.postType === NAVIGATION_POST_TYPE && !! params.postId; + }, + areas: { + sidebar: ( + + ), + preview: , + mobile: MobileNavigationItemView, + }, +}; diff --git a/packages/edit-site/src/components/site-editor-routes/navigation-view.js b/packages/edit-site/src/components/site-editor-routes/navigation-view.js deleted file mode 100644 index 59c38a2f1d099..0000000000000 --- a/packages/edit-site/src/components/site-editor-routes/navigation-view.js +++ /dev/null @@ -1,21 +0,0 @@ -/** - * Internal dependencies - */ -import { NAVIGATION_POST_TYPE } from '../../utils/constants'; -import Editor from '../editor'; -import SidebarNavigationScreenNavigationMenus from '../sidebar-navigation-screen-navigation-menus'; - -export const navigationViewRoute = { - name: 'navigation-view', - match: ( params ) => { - return ( - params.postType === NAVIGATION_POST_TYPE && - ! params.postId && - params.canvas !== 'edit' - ); - }, - areas: { - sidebar: , - preview: , - }, -}; diff --git a/packages/edit-site/src/components/site-editor-routes/navigation.js b/packages/edit-site/src/components/site-editor-routes/navigation.js new file mode 100644 index 0000000000000..4c435e78a495f --- /dev/null +++ b/packages/edit-site/src/components/site-editor-routes/navigation.js @@ -0,0 +1,34 @@ +/** + * WordPress dependencies + */ +import { privateApis as routerPrivateApis } from '@wordpress/router'; + +/** + * Internal dependencies + */ +import Editor from '../editor'; +import SidebarNavigationScreenNavigationMenus from '../sidebar-navigation-screen-navigation-menus'; +import { unlock } from '../../lock-unlock'; + +const { useLocation } = unlock( routerPrivateApis ); + +function MobileNavigationView() { + const { query = {} } = useLocation(); + const { canvas = 'view' } = query; + + return canvas === 'edit' ? ( + + ) : ( + + ); +} + +export const navigationRoute = { + name: 'navigation', + path: '/navigation', + areas: { + sidebar: , + preview: , + mobile: , + }, +}; diff --git a/packages/edit-site/src/components/site-editor-routes/pages-edit.js b/packages/edit-site/src/components/site-editor-routes/page-item.js similarity index 54% rename from packages/edit-site/src/components/site-editor-routes/pages-edit.js rename to packages/edit-site/src/components/site-editor-routes/page-item.js index ef4c7efbfb09c..c20720316b10e 100644 --- a/packages/edit-site/src/components/site-editor-routes/pages-edit.js +++ b/packages/edit-site/src/components/site-editor-routes/page-item.js @@ -6,29 +6,21 @@ import { __ } from '@wordpress/i18n'; /** * Internal dependencies */ -import PostList from '../post-list'; +import Editor from '../editor'; import DataViewsSidebarContent from '../sidebar-dataviews'; import SidebarNavigationScreen from '../sidebar-navigation-screen'; -import Editor from '../editor'; -function PageList() { - return ; -} - -export const pagesEditRoute = { - name: 'pages-edit', - match: ( params ) => { - return params.postType === 'page' && params.canvas === 'edit'; - }, +export const pageItemRoute = { + name: 'page-item', + path: '/page/:postId', areas: { sidebar: ( } + backPath="/" + content={ } /> ), - content: , mobile: , preview: , }, diff --git a/packages/edit-site/src/components/site-editor-routes/pages-list-view-quick-edit.js b/packages/edit-site/src/components/site-editor-routes/pages-list-view-quick-edit.js deleted file mode 100644 index 9eb33e05a99bb..0000000000000 --- a/packages/edit-site/src/components/site-editor-routes/pages-list-view-quick-edit.js +++ /dev/null @@ -1,56 +0,0 @@ -/** - * WordPress dependencies - */ -import { __ } from '@wordpress/i18n'; -import { privateApis as routerPrivateApis } from '@wordpress/router'; - -/** - * Internal dependencies - */ -import PostList from '../post-list'; -import DataViewsSidebarContent from '../sidebar-dataviews'; -import SidebarNavigationScreen from '../sidebar-navigation-screen'; -import { unlock } from '../../lock-unlock'; -import { PostEdit } from '../post-edit'; -import Editor from '../editor'; - -const { useLocation } = unlock( routerPrivateApis ); - -function PageList() { - return ; -} - -function PageQuickEdit() { - const { params } = useLocation(); - return ; -} - -export const pagesListViewQuickEditRoute = { - name: 'pages-list-view-quick-edit', - match: ( params ) => { - return ( - params.isCustom !== 'true' && - ( params.layout ?? 'list' ) === 'list' && - !! params.quickEdit && - params.postType === 'page' && - params.canvas !== 'edit' - ); - }, - areas: { - sidebar: ( - } - /> - ), - content: , - mobile: , - preview: , - edit: , - }, - widths: { - content: 380, - edit: 380, - }, -}; diff --git a/packages/edit-site/src/components/site-editor-routes/pages-list-view.js b/packages/edit-site/src/components/site-editor-routes/pages-list-view.js deleted file mode 100644 index 74b39848e83f2..0000000000000 --- a/packages/edit-site/src/components/site-editor-routes/pages-list-view.js +++ /dev/null @@ -1,44 +0,0 @@ -/** - * WordPress dependencies - */ -import { __ } from '@wordpress/i18n'; - -/** - * Internal dependencies - */ -import PostList from '../post-list'; -import DataViewsSidebarContent from '../sidebar-dataviews'; -import SidebarNavigationScreen from '../sidebar-navigation-screen'; -import Editor from '../editor'; - -function PageList() { - return ; -} - -export const pagesListViewRoute = { - name: 'pages-list-view', - match: ( params ) => { - return ( - params.isCustom !== 'true' && - ( params.layout ?? 'list' ) === 'list' && - ! params.quickEdit && - params.postType === 'page' && - params.canvas !== 'edit' - ); - }, - areas: { - sidebar: ( - } - /> - ), - content: , - preview: , - mobile: , - }, - widths: { - content: 380, - }, -}; diff --git a/packages/edit-site/src/components/site-editor-routes/pages-view-quick-edit.js b/packages/edit-site/src/components/site-editor-routes/pages-view-quick-edit.js deleted file mode 100644 index 907054364c8a9..0000000000000 --- a/packages/edit-site/src/components/site-editor-routes/pages-view-quick-edit.js +++ /dev/null @@ -1,53 +0,0 @@ -/** - * WordPress dependencies - */ -import { __ } from '@wordpress/i18n'; -import { privateApis as routerPrivateApis } from '@wordpress/router'; - -/** - * Internal dependencies - */ -import PostList from '../post-list'; -import DataViewsSidebarContent from '../sidebar-dataviews'; -import SidebarNavigationScreen from '../sidebar-navigation-screen'; -import { unlock } from '../../lock-unlock'; -import { PostEdit } from '../post-edit'; - -const { useLocation } = unlock( routerPrivateApis ); - -function PageList() { - return ; -} - -function PageQuickEdit() { - const { params } = useLocation(); - return ; -} - -export const pagesViewQuickEditRoute = { - name: 'pages-view-quick-edit', - match: ( params ) => { - return ( - ( params.isCustom === 'true' || - ( params.layout ?? 'list' ) !== 'list' ) && - !! params.quickEdit && - params.postType === 'page' && - params.canvas !== 'edit' - ); - }, - areas: { - sidebar: ( - } - /> - ), - content: , - mobile: , - edit: , - }, - widths: { - edit: 380, - }, -}; diff --git a/packages/edit-site/src/components/site-editor-routes/pages-view.js b/packages/edit-site/src/components/site-editor-routes/pages-view.js deleted file mode 100644 index df7e211022cac..0000000000000 --- a/packages/edit-site/src/components/site-editor-routes/pages-view.js +++ /dev/null @@ -1,39 +0,0 @@ -/** - * WordPress dependencies - */ -import { __ } from '@wordpress/i18n'; - -/** - * Internal dependencies - */ -import PostList from '../post-list'; -import DataViewsSidebarContent from '../sidebar-dataviews'; -import SidebarNavigationScreen from '../sidebar-navigation-screen'; - -function PageList() { - return ; -} - -export const pagesViewRoute = { - name: 'pages-view', - match: ( params ) => { - return ( - ( params.isCustom === 'true' || - ( params.layout ?? 'list' ) !== 'list' ) && - ! params.quickEdit && - params.postType === 'page' && - params.canvas !== 'edit' - ); - }, - areas: { - sidebar: ( - } - /> - ), - content: , - mobile: , - }, -}; diff --git a/packages/edit-site/src/components/site-editor-routes/pages.js b/packages/edit-site/src/components/site-editor-routes/pages.js new file mode 100644 index 0000000000000..e8c55cd10307e --- /dev/null +++ b/packages/edit-site/src/components/site-editor-routes/pages.js @@ -0,0 +1,66 @@ +/** + * WordPress dependencies + */ +import { privateApis as routerPrivateApis } from '@wordpress/router'; +import { __ } from '@wordpress/i18n'; + +/** + * Internal dependencies + */ +import Editor from '../editor'; +import SidebarNavigationScreen from '../sidebar-navigation-screen'; +import DataViewsSidebarContent from '../sidebar-dataviews'; +import PostList from '../post-list'; +import { unlock } from '../../lock-unlock'; +import { PostEdit } from '../post-edit'; + +const { useLocation } = unlock( routerPrivateApis ); + +function MobilePagesView() { + const { query = {} } = useLocation(); + const { canvas = 'view' } = query; + + return canvas === 'edit' ? : ; +} + +export const pagesRoute = { + name: 'pages', + path: '/page', + areas: { + sidebar: ( + } + /> + ), + content: , + preview( { query } ) { + const isListView = + ( query.layout === 'list' || ! query.layout ) && + query.isCustom !== 'true'; + return isListView ? : undefined; + }, + mobile: , + edit( { query } ) { + const hasQuickEdit = + ( query.layout ?? 'list' ) === 'list' && !! query.quickEdit; + return hasQuickEdit ? ( + + ) : undefined; + }, + }, + widths: { + content( { query } ) { + const isListView = + ( query.layout === 'list' || ! query.layout ) && + query.isCustom !== 'true'; + return isListView ? 380 : undefined; + }, + edit( { query } ) { + const hasQuickEdit = + ( query.layout ?? 'list' ) === 'list' && !! query.quickEdit; + return hasQuickEdit ? 380 : undefined; + }, + }, +}; diff --git a/packages/edit-site/src/components/site-editor-routes/pattern-item.js b/packages/edit-site/src/components/site-editor-routes/pattern-item.js new file mode 100644 index 0000000000000..c4cbcf871f368 --- /dev/null +++ b/packages/edit-site/src/components/site-editor-routes/pattern-item.js @@ -0,0 +1,15 @@ +/** + * Internal dependencies + */ +import Editor from '../editor'; +import SidebarNavigationScreenPatterns from '../sidebar-navigation-screen-patterns'; + +export const patternItemRoute = { + name: 'pattern-item', + path: '/wp_block/:postId', + areas: { + sidebar: , + mobile: , + preview: , + }, +}; diff --git a/packages/edit-site/src/components/site-editor-routes/patterns-edit.js b/packages/edit-site/src/components/site-editor-routes/patterns-edit.js deleted file mode 100644 index eaf1fd6802018..0000000000000 --- a/packages/edit-site/src/components/site-editor-routes/patterns-edit.js +++ /dev/null @@ -1,24 +0,0 @@ -/** - * Internal dependencies - */ -import Editor from '../editor'; -import SidebarNavigationScreenPatterns from '../sidebar-navigation-screen-patterns'; -import PagePatterns from '../page-patterns'; -import { PATTERN_TYPES, TEMPLATE_PART_POST_TYPE } from '../../utils/constants'; - -export const patternsEditRoute = { - name: 'patterns-edit', - match: ( params ) => { - return ( - [ TEMPLATE_PART_POST_TYPE, PATTERN_TYPES.user ].includes( - params.postType - ) && params.canvas === 'edit' - ); - }, - areas: { - sidebar: , - content: , - mobile: , - preview: , - }, -}; diff --git a/packages/edit-site/src/components/site-editor-routes/patterns-view.js b/packages/edit-site/src/components/site-editor-routes/patterns-view.js deleted file mode 100644 index 468f7f14abc13..0000000000000 --- a/packages/edit-site/src/components/site-editor-routes/patterns-view.js +++ /dev/null @@ -1,22 +0,0 @@ -/** - * Internal dependencies - */ -import SidebarNavigationScreenPatterns from '../sidebar-navigation-screen-patterns'; -import PagePatterns from '../page-patterns'; -import { PATTERN_TYPES, TEMPLATE_PART_POST_TYPE } from '../../utils/constants'; - -export const patternsViewRoute = { - name: 'patterns-view', - match: ( params ) => { - return ( - [ TEMPLATE_PART_POST_TYPE, PATTERN_TYPES.user ].includes( - params.postType - ) && params.canvas !== 'edit' - ); - }, - areas: { - sidebar: , - content: , - mobile: , - }, -}; diff --git a/packages/edit-site/src/components/site-editor-routes/patterns.js b/packages/edit-site/src/components/site-editor-routes/patterns.js new file mode 100644 index 0000000000000..48207cfe1c1d2 --- /dev/null +++ b/packages/edit-site/src/components/site-editor-routes/patterns.js @@ -0,0 +1,15 @@ +/** + * Internal dependencies + */ +import SidebarNavigationScreenPatterns from '../sidebar-navigation-screen-patterns'; +import PagePatterns from '../page-patterns'; + +export const patternsRoute = { + name: 'patterns', + path: '/pattern', + areas: { + sidebar: , + content: , + mobile: , + }, +}; diff --git a/packages/edit-site/src/components/site-editor-routes/styles-view.js b/packages/edit-site/src/components/site-editor-routes/styles.js similarity index 58% rename from packages/edit-site/src/components/site-editor-routes/styles-view.js rename to packages/edit-site/src/components/site-editor-routes/styles.js index cc9411eb8144c..17e4a3c064d02 100644 --- a/packages/edit-site/src/components/site-editor-routes/styles-view.js +++ b/packages/edit-site/src/components/site-editor-routes/styles.js @@ -5,18 +5,12 @@ import Editor from '../editor'; import SidebarNavigationScreenGlobalStyles from '../sidebar-navigation-screen-global-styles'; import GlobalStylesUIWrapper from '../sidebar-global-styles-wrapper'; -export const stylesViewRoute = { - name: 'styles-view', - match: ( params ) => { - return ( - params.path && - params.path.startsWith( '/wp_global_styles' ) && - params.canvas !== 'edit' - ); - }, +export const stylesRoute = { + name: 'styles', + path: '/styles', areas: { content: , - sidebar: , + sidebar: , preview: , mobile: , }, diff --git a/packages/edit-site/src/components/site-editor-routes/template-item.js b/packages/edit-site/src/components/site-editor-routes/template-item.js new file mode 100644 index 0000000000000..8ad3ab2b69990 --- /dev/null +++ b/packages/edit-site/src/components/site-editor-routes/template-item.js @@ -0,0 +1,15 @@ +/** + * Internal dependencies + */ +import Editor from '../editor'; +import SidebarNavigationScreenTemplatesBrowse from '../sidebar-navigation-screen-templates-browse'; + +export const templateItemRoute = { + name: 'template-item', + path: '/wp_template/*postId', + areas: { + sidebar: , + mobile: , + preview: , + }, +}; diff --git a/packages/edit-site/src/components/site-editor-routes/template-part-item.js b/packages/edit-site/src/components/site-editor-routes/template-part-item.js new file mode 100644 index 0000000000000..a2b21cf23f808 --- /dev/null +++ b/packages/edit-site/src/components/site-editor-routes/template-part-item.js @@ -0,0 +1,15 @@ +/** + * Internal dependencies + */ +import Editor from '../editor'; +import SidebarNavigationScreenPatterns from '../sidebar-navigation-screen-patterns'; + +export const templatePartItemRoute = { + name: 'template-part-item', + path: '/wp_template_part/*postId', + areas: { + sidebar: , + mobile: , + preview: , + }, +}; diff --git a/packages/edit-site/src/components/site-editor-routes/templates-edit.js b/packages/edit-site/src/components/site-editor-routes/templates-edit.js deleted file mode 100644 index 488e9decc1888..0000000000000 --- a/packages/edit-site/src/components/site-editor-routes/templates-edit.js +++ /dev/null @@ -1,22 +0,0 @@ -/** - * Internal dependencies - */ -import { TEMPLATE_POST_TYPE } from '../../utils/constants'; -import PageTemplates from '../page-templates'; -import Editor from '../editor'; -import SidebarNavigationScreenTemplatesBrowse from '../sidebar-navigation-screen-templates-browse'; - -export const templatesEditRoute = { - name: 'templates-edit', - match: ( params ) => { - return ( - params.postType === TEMPLATE_POST_TYPE && params.canvas === 'edit' - ); - }, - areas: { - sidebar: , - content: , - mobile: , - preview: , - }, -}; diff --git a/packages/edit-site/src/components/site-editor-routes/templates-list-view.js b/packages/edit-site/src/components/site-editor-routes/templates-list-view.js deleted file mode 100644 index 7cdda1b13c0b4..0000000000000 --- a/packages/edit-site/src/components/site-editor-routes/templates-list-view.js +++ /dev/null @@ -1,28 +0,0 @@ -/** - * Internal dependencies - */ -import { TEMPLATE_POST_TYPE } from '../../utils/constants'; -import PageTemplates from '../page-templates'; -import Editor from '../editor'; -import SidebarNavigationScreenTemplatesBrowse from '../sidebar-navigation-screen-templates-browse'; - -export const templatesListViewRoute = { - name: 'templates-list-view', - match: ( params ) => { - return ( - params.isCustom !== 'true' && - params.layout === 'list' && - params.postType === TEMPLATE_POST_TYPE && - params.canvas !== 'edit' - ); - }, - areas: { - sidebar: , - content: , - mobile: , - preview: , - }, - widths: { - content: 380, - }, -}; diff --git a/packages/edit-site/src/components/site-editor-routes/templates-view.js b/packages/edit-site/src/components/site-editor-routes/templates-view.js deleted file mode 100644 index 40fd88c0e60a6..0000000000000 --- a/packages/edit-site/src/components/site-editor-routes/templates-view.js +++ /dev/null @@ -1,22 +0,0 @@ -/** - * Internal dependencies - */ -import { TEMPLATE_POST_TYPE } from '../../utils/constants'; -import PageTemplates from '../page-templates'; -import SidebarNavigationScreenTemplatesBrowse from '../sidebar-navigation-screen-templates-browse'; - -export const templatesViewRoute = { - name: 'templates-view', - match: ( params ) => { - return ( - ( params.isCustom === 'true' || params.layout !== 'list' ) && - params.postType === TEMPLATE_POST_TYPE && - params.canvas !== 'edit' - ); - }, - areas: { - sidebar: , - content: , - mobile: , - }, -}; diff --git a/packages/edit-site/src/components/site-editor-routes/templates.js b/packages/edit-site/src/components/site-editor-routes/templates.js new file mode 100644 index 0000000000000..06ba07fcd0659 --- /dev/null +++ b/packages/edit-site/src/components/site-editor-routes/templates.js @@ -0,0 +1,45 @@ +/** + * WordPress dependencies + */ +import { privateApis as routerPrivateApis } from '@wordpress/router'; + +/** + * Internal dependencies + */ +import Editor from '../editor'; +import SidebarNavigationScreenTemplatesBrowse from '../sidebar-navigation-screen-templates-browse'; +import { unlock } from '../../lock-unlock'; +import PageTemplates from '../page-templates'; + +const { useLocation } = unlock( routerPrivateApis ); + +function MobileTemplatesView() { + const { query = {} } = useLocation(); + const { canvas = 'view' } = query; + + return canvas === 'edit' ? ( + + ) : ( + + ); +} + +export const templatesRoute = { + name: 'templates', + path: '/template', + areas: { + sidebar: , + content: , + preview( { query } ) { + const isListView = query.layout === 'list'; + return isListView ? : undefined; + }, + mobile: , + }, + widths: { + content( { query } ) { + const isListView = query.layout === 'list'; + return isListView ? 380 : undefined; + }, + }, +}; diff --git a/packages/edit-site/src/components/site-hub/index.js b/packages/edit-site/src/components/site-hub/index.js index 9e57034bfe73a..376b36ba2d431 100644 --- a/packages/edit-site/src/components/site-hub/index.js +++ b/packages/edit-site/src/components/site-hub/index.js @@ -170,7 +170,7 @@ export const SiteHubMobile = memo( } : { onClick: () => { - history.push( {} ); + history.navigate( '/' ); navigate( 'back' ); }, label: __( 'Go to Site Editor' ), diff --git a/packages/edit-site/src/hooks/commands/use-common-commands.js b/packages/edit-site/src/hooks/commands/use-common-commands.js index 3e87f8721e116..34ddae3e1af7a 100644 --- a/packages/edit-site/src/hooks/commands/use-common-commands.js +++ b/packages/edit-site/src/hooks/commands/use-common-commands.js @@ -49,27 +49,17 @@ const getGlobalStylesOpenStylesCommands = () => label: __( 'Open styles' ), callback: ( { close } ) => { close(); - if ( ! params.postId ) { - history.push( { - path: '/wp_global_styles', - canvas: 'edit', + if ( canvas !== 'edit' ) { + history.navigate( '/styles?canvas=edit', { + transition: 'canvas-mode-edit-transition', } ); } - if ( params.postId && canvas !== 'edit' ) { - history.push( - { ...params, canvas: 'edit' }, - undefined, - { - transition: 'canvas-mode-edit-transition', - } - ); - } openGeneralSidebar( 'edit-site/global-styles' ); }, icon: styles, }, ]; - }, [ history, openGeneralSidebar, params, canvas, isBlockBasedTheme ] ); + }, [ history, openGeneralSidebar, canvas, isBlockBasedTheme ] ); return { isLoading: false, @@ -100,24 +90,11 @@ const getGlobalStylesToggleWelcomeGuideCommands = () => label: __( 'Learn about styles' ), callback: ( { close } ) => { close(); - if ( ! params.postId ) { - history.push( { - path: '/wp_global_styles', - canvas: 'edit', + if ( canvas !== 'edit' ) { + history.navigate( '/styles?canvas=edit', { + transition: 'canvas-mode-edit-transition', } ); } - if ( params.postId && canvas !== 'edit' ) { - history.push( - { - ...params, - canvas: 'edit', - }, - undefined, - { - transition: 'canvas-mode-edit-transition', - } - ); - } openGeneralSidebar( 'edit-site/global-styles' ); set( 'core/edit-site', 'welcomeGuideStyles', true ); // sometimes there's a focus loss that happens after some time @@ -129,14 +106,7 @@ const getGlobalStylesToggleWelcomeGuideCommands = () => icon: help, }, ]; - }, [ - history, - openGeneralSidebar, - canvas, - isBlockBasedTheme, - set, - params, - ] ); + }, [ history, openGeneralSidebar, canvas, isBlockBasedTheme, set ] ); return { isLoading: false, @@ -205,24 +175,11 @@ const getGlobalStylesOpenCssCommands = () => icon: brush, callback: ( { close } ) => { close(); - if ( ! params.postId ) { - history.push( { - path: '/wp_global_styles', - canvas: 'edit', + if ( canvas !== 'edit' ) { + history.navigate( '/styles?canvas=edit', { + transition: 'canvas-mode-edit-transition', } ); } - if ( params.postId && canvas !== 'edit' ) { - history.push( - { - ...params, - canvas: 'edit', - }, - undefined, - { - transition: 'canvas-mode-edit-transition', - } - ); - } openGeneralSidebar( 'edit-site/global-styles' ); setEditorCanvasContainerView( 'global-styles-css' ); }, @@ -234,7 +191,6 @@ const getGlobalStylesOpenCssCommands = () => setEditorCanvasContainerView, canEditCSS, canvas, - params, ] ); return { isLoading: false, @@ -272,24 +228,11 @@ const getGlobalStylesOpenRevisionsCommands = () => icon: backup, callback: ( { close } ) => { close(); - if ( ! params.postId ) { - history.push( { - path: '/wp_global_styles', - canvas: 'edit', + if ( canvas !== 'edit' ) { + history.navigate( '/styles?canvas=edit', { + transition: 'canvas-mode-edit-transition', } ); } - if ( params.postId && canvas !== 'edit' ) { - history.push( - { - ...params, - canvas: 'edit', - }, - undefined, - { - transition: 'canvas-mode-edit-transition', - } - ); - } openGeneralSidebar( 'edit-site/global-styles' ); setEditorCanvasContainerView( 'global-styles-revisions' @@ -303,7 +246,6 @@ const getGlobalStylesOpenRevisionsCommands = () => openGeneralSidebar, setEditorCanvasContainerView, canvas, - params, ] ); return { diff --git a/packages/edit-site/src/hooks/commands/use-set-command-context.js b/packages/edit-site/src/hooks/commands/use-set-command-context.js index e27c4ca91582f..6ecdf04989609 100644 --- a/packages/edit-site/src/hooks/commands/use-set-command-context.js +++ b/packages/edit-site/src/hooks/commands/use-set-command-context.js @@ -19,8 +19,8 @@ const { useLocation } = unlock( routerPrivateApis ); * React hook used to set the correct command context based on the current state. */ export default function useSetCommandContext() { - const { params } = useLocation(); - const { canvas = 'view' } = params; + const { query = {} } = useLocation(); + const { canvas = 'view' } = query; const hasBlockSelected = useSelect( ( select ) => { return select( blockEditorStore ).getBlockSelectionStart(); }, [] ); diff --git a/packages/edit-site/src/store/private-actions.js b/packages/edit-site/src/store/private-actions.js index 1db3873acedda..9b16748049cd0 100644 --- a/packages/edit-site/src/store/private-actions.js +++ b/packages/edit-site/src/store/private-actions.js @@ -18,3 +18,10 @@ export function registerRoute( route ) { route, }; } + +export function unregisterRoute( name ) { + return { + type: 'UNREGISTER_ROUTE', + name, + }; +} diff --git a/packages/edit-site/src/store/reducer.js b/packages/edit-site/src/store/reducer.js index 3ce067c25c195..7ffb276a35da1 100644 --- a/packages/edit-site/src/store/reducer.js +++ b/packages/edit-site/src/store/reducer.js @@ -85,6 +85,8 @@ function routes( state = [], action ) { switch ( action.type ) { case 'REGISTER_ROUTE': return [ ...state, action.route ]; + case 'UNREGISTER_ROUTE': + return state.filter( ( route ) => route.name !== action.name ); } return state; diff --git a/packages/router/package.json b/packages/router/package.json index 26b4f29df04f6..9b86cbb7e8c41 100644 --- a/packages/router/package.json +++ b/packages/router/package.json @@ -32,7 +32,8 @@ "@wordpress/element": "*", "@wordpress/private-apis": "*", "@wordpress/url": "*", - "history": "^5.3.0" + "history": "^5.3.0", + "route-recognizer": "^0.3.4" }, "peerDependencies": { "react": "^18.0.0" diff --git a/packages/router/src/history.ts b/packages/router/src/history.ts deleted file mode 100644 index 6cbef108eec20..0000000000000 --- a/packages/router/src/history.ts +++ /dev/null @@ -1,99 +0,0 @@ -/** - * External dependencies - */ -import { createBrowserHistory, type BrowserHistory } from 'history'; - -/** - * WordPress dependencies - */ -import { buildQueryString } from '@wordpress/url'; - -export interface EnhancedHistory extends BrowserHistory { - getLocationWithParams: () => Location; -} - -interface PushOptions { - transition?: string; -} - -const history = createBrowserHistory(); - -const originalHistoryPush = history.push; -const originalHistoryReplace = history.replace; - -// Preserve the `wp_theme_preview` query parameter when navigating -// around the Site Editor. -// TODO: move this hack out of the router into Site Editor code. -function preserveThemePreview( params: Record< string, any > ) { - if ( params.hasOwnProperty( 'wp_theme_preview' ) ) { - return params; - } - const currentSearch = new URLSearchParams( history.location.search ); - const currentThemePreview = currentSearch.get( 'wp_theme_preview' ); - if ( currentThemePreview === null ) { - return params; - } - return { ...params, wp_theme_preview: currentThemePreview }; -} - -function push( - params: Record< string, any >, - state: Record< string, any >, - options: PushOptions = {} -) { - const performPush = () => { - const search = buildQueryString( preserveThemePreview( params ) ); - return originalHistoryPush.call( history, { search }, state ); - }; - - /* - * Skip transition in mobile, otherwise it crashes the browser. - * See: https://github.com/WordPress/gutenberg/pull/63002. - */ - const isMediumOrBigger = window.matchMedia( '(min-width: 782px)' ).matches; - if ( - ! isMediumOrBigger || - // @ts-expect-error - ! document.startViewTransition || - ! options.transition - ) { - return performPush(); - } - document.documentElement.classList.add( options.transition ); - // @ts-expect-error - const transition = document.startViewTransition( () => performPush() ); - transition.finished.finally( () => { - document.documentElement.classList.remove( options.transition ?? '' ); - } ); -} - -function replace( - params: Record< string, any >, - state: Record< string, any > -) { - const search = buildQueryString( preserveThemePreview( params ) ); - return originalHistoryReplace.call( history, { search }, state ); -} - -const locationMemo = new WeakMap(); -function getLocationWithParams() { - const location = history.location; - let locationWithParams = locationMemo.get( location ); - if ( ! locationWithParams ) { - locationWithParams = { - ...location, - params: Object.fromEntries( - new URLSearchParams( location.search ) - ), - }; - locationMemo.set( location, locationWithParams ); - } - return locationWithParams; -} - -export default { - ...history, - push, - replace, - getLocationWithParams, -}; diff --git a/packages/router/src/link.tsx b/packages/router/src/link.tsx new file mode 100644 index 0000000000000..1aa3c1a5ba479 --- /dev/null +++ b/packages/router/src/link.tsx @@ -0,0 +1,44 @@ +/** + * WordPress dependencies + */ +import { useContext } from '@wordpress/element'; + +/** + * Internal dependencies + */ +import { ConfigContext, type NavigationOptions, useHistory } from './router'; + +export function useLink( to: string, options: NavigationOptions = {} ) { + const history = useHistory(); + const { basePath } = useContext( ConfigContext ); + function onClick( event: React.SyntheticEvent< HTMLAnchorElement > ) { + event?.preventDefault(); + history.navigate( to, options ); + } + + const [ before ] = window.location.href.split( basePath ); + + return { + href: `${ before }${ basePath }${ to }`, + onClick, + }; +} + +export function Link( { + to, + options, + children, + ...props +}: { + to: string; + options?: NavigationOptions; + children: React.ReactNode; +} ) { + const { href, onClick } = useLink( to, options ); + + return ( + + { children } + + ); +} diff --git a/packages/router/src/private-apis.ts b/packages/router/src/private-apis.ts index 7b2945a24ab1a..9ef316ed716cf 100644 --- a/packages/router/src/private-apis.ts +++ b/packages/router/src/private-apis.ts @@ -2,6 +2,7 @@ * Internal dependencies */ import { useHistory, useLocation, RouterProvider } from './router'; +import { useLink, Link } from './link'; import { lock } from './lock-unlock'; export const privateApis = {}; @@ -9,4 +10,6 @@ lock( privateApis, { useHistory, useLocation, RouterProvider, + useLink, + Link, } ); diff --git a/packages/router/src/router.tsx b/packages/router/src/router.tsx index 9a1d01aa5f8d8..8e36a39f891cd 100644 --- a/packages/router/src/router.tsx +++ b/packages/router/src/router.tsx @@ -1,3 +1,9 @@ +/** + * External dependencies + */ +import RouteRecognizer from 'route-recognizer'; +import { createBrowserHistory } from 'history'; + /** * WordPress dependencies */ @@ -5,37 +11,184 @@ import { createContext, useContext, useSyncExternalStore, + useMemo, } from '@wordpress/element'; +import { addQueryArgs } from '@wordpress/url'; /** * Internal dependencies */ -import history from './history'; -import type { EnhancedHistory } from './history'; +import type { ReactNode } from 'react'; + +const history = createBrowserHistory(); +interface Route { + name: string; + path: string; + areas: Record< string, ReactNode >; + widths: Record< string, number >; +} + +type LocationWithQuery = Location & { + query?: Record< string, any >; +}; + +interface Match { + name: string; + path: string; + areas: Record< string, ReactNode >; + widths: Record< string, number >; + query?: Record< string, any >; + params?: Record< string, any >; +} + +interface Config { + basePath: string; +} -const RoutesContext = createContext< Location | null >( null ); -const HistoryContext = createContext< EnhancedHistory >( history ); +export interface NavigationOptions { + transition?: string; + state?: Record< string, any >; +} + +const RoutesContext = createContext< Match | null >( null ); +export const ConfigContext = createContext< Config >( { basePath: '/' } ); + +const locationMemo = new WeakMap(); +function getLocationWithQuery() { + const location = history.location; + let locationWithQuery = locationMemo.get( location ); + if ( ! locationWithQuery ) { + locationWithQuery = { + ...location, + query: Object.fromEntries( new URLSearchParams( location.search ) ), + }; + locationMemo.set( location, locationWithQuery ); + } + return locationWithQuery; +} export function useLocation() { return useContext( RoutesContext ); } export function useHistory() { - return useContext( HistoryContext ); + const { basePath } = useContext( ConfigContext ); + return useMemo( + () => ( { + navigate( path: string, options: NavigationOptions = {} ) { + const performPush = () => { + return history.push( + `${ basePath }${ path }`, + options.state + ); + }; + + /* + * Skip transition in mobile, otherwise it crashes the browser. + * See: https://github.com/WordPress/gutenberg/pull/63002. + */ + const isMediumOrBigger = + window.matchMedia( '(min-width: 782px)' ).matches; + if ( + ! isMediumOrBigger || + // @ts-expect-error + ! document.startViewTransition || + ! options.transition + ) { + return performPush(); + } + document.documentElement.classList.add( options.transition ); + // @ts-expect-error + const transition = document.startViewTransition( () => + performPush() + ); + transition.finished.finally( () => { + document.documentElement.classList.remove( + options.transition ?? '' + ); + } ); + }, + } ), + [ basePath ] + ); +} + +export default function useMatch( + location: LocationWithQuery, + routes: Route[], + basePath: string +): Match { + const { query = {}, pathname } = location; + + return useMemo( () => { + const matcher = new RouteRecognizer(); + routes.forEach( ( route ) => { + matcher.add( [ { path: route.path, handler: route } ], { + as: route.name, + } ); + } ); + const [ , path ] = basePath + ? pathname.split( basePath ) + : [ , pathname ]; + const result = matcher.recognize( path )?.[ 0 ]; + if ( ! result ) { + return { + name: '404', + path: addQueryArgs( path, query ), + areas: {}, + widths: {}, + query, + params: {}, + }; + } + + const matchedRoute = result.handler as Route; + const resolveFunctions = ( record: Record< string, any > = {} ) => { + return Object.fromEntries( + Object.entries( record ).map( ( [ key, value ] ) => { + if ( typeof value === 'function' ) { + return [ + key, + value( { query, params: result.params } ), + ]; + } + return [ key, value ]; + } ) + ); + }; + return { + name: matchedRoute.name, + areas: resolveFunctions( matchedRoute.areas ), + widths: resolveFunctions( matchedRoute.widths ), + params: result.params, + query, + path: addQueryArgs( path, query ), + }; + }, [ routes, query, basePath, pathname ] ); } -export function RouterProvider( { children }: { children: React.ReactNode } ) { +export function RouterProvider( { + routes, + basePath, + children, +}: { + routes: Route[]; + basePath: string; + children: React.ReactNode; +} ) { const location = useSyncExternalStore( history.listen, - history.getLocationWithParams, - history.getLocationWithParams + getLocationWithQuery, + getLocationWithQuery ); + const match = useMatch( location, routes, basePath ); + const config = useMemo( () => ( { basePath } ), [ basePath ] ); return ( - - + + { children } - + ); } From edd30757b54f373ee44c1056a40c252c9df8e6f9 Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Thu, 21 Nov 2024 13:28:52 +0100 Subject: [PATCH 02/26] Fix some bugs --- .../edit-site/src/components/editor/index.js | 29 ++++++++++++++----- .../sidebar-global-styles-wrapper/index.js | 2 +- .../site-editor-routes/navigation-item.js | 5 +--- 3 files changed, 24 insertions(+), 12 deletions(-) diff --git a/packages/edit-site/src/components/editor/index.js b/packages/edit-site/src/components/editor/index.js index 75d6c1d3cc486..102c5cd0df9f9 100644 --- a/packages/edit-site/src/components/editor/index.js +++ b/packages/edit-site/src/components/editor/index.js @@ -54,6 +54,7 @@ import { useResolveEditedEntity, useSyncDeprecatedEntityIntoState, } from './use-resolve-edited-entity'; +import { addQueryArgs } from '@wordpress/url'; const { Editor, BackButton } = unlock( editorPrivateApis ); const { useHistory, useLocation } = unlock( routerPrivateApis ); @@ -99,10 +100,25 @@ function getListPathForPostType( postType ) { throw 'Unknown post type'; } +function getNavigationPath( location, postType ) { + const { path, name } = location; + if ( + [ + 'pattern-item', + 'template-part-item', + 'page-item', + 'template-item', + ].includes( name ) + ) { + return getListPathForPostType( postType ); + } + return addQueryArgs( path, { canvas: undefined } ); +} + export default function EditSiteEditor( { isPostsList = false } ) { const disableMotion = useReducedMotion(); - const { query } = useLocation(); - const { canvas = 'view' } = query; + const location = useLocation(); + const { canvas = 'view' } = location.query; const isLoading = useIsSiteEditorLoading(); useAdaptEditorToCanvas( canvas ); const entity = useResolveEditedEntity(); @@ -290,7 +306,7 @@ export default function EditSiteEditor( { isPostsList = false } ) { // come here through `posts list` and are in focus mode editing a template, template part etc.. if ( isPostsList && - query?.focusMode + location.query?.focusMode ) { history.navigate( '/', { transition: @@ -298,10 +314,9 @@ export default function EditSiteEditor( { isPostsList = false } ) { } ); } else { history.navigate( - getListPathForPostType( - postWithTemplate - ? context.postType - : postType + getNavigationPath( + location, + postType ), { transition: diff --git a/packages/edit-site/src/components/sidebar-global-styles-wrapper/index.js b/packages/edit-site/src/components/sidebar-global-styles-wrapper/index.js index d868b5baba0c2..980f20c49821b 100644 --- a/packages/edit-site/src/components/sidebar-global-styles-wrapper/index.js +++ b/packages/edit-site/src/components/sidebar-global-styles-wrapper/index.js @@ -72,7 +72,7 @@ export default function GlobalStylesUIWrapper() { return [ query.section ?? '/', ( updatedSection ) => { - history.navigation( + history.navigate( addQueryArgs( path, { section: updatedSection, } ) diff --git a/packages/edit-site/src/components/site-editor-routes/navigation-item.js b/packages/edit-site/src/components/site-editor-routes/navigation-item.js index fbfec1ac3eefa..76983d8ff8daa 100644 --- a/packages/edit-site/src/components/site-editor-routes/navigation-item.js +++ b/packages/edit-site/src/components/site-editor-routes/navigation-item.js @@ -29,14 +29,11 @@ function MobileNavigationItemView() { export const navigationItemRoute = { name: 'navigation-item', path: '/wp_navigation/:postId', - match: ( params ) => { - return params.postType === NAVIGATION_POST_TYPE && !! params.postId; - }, areas: { sidebar: ( ), preview: , - mobile: MobileNavigationItemView, + mobile: , }, }; From 6a4cc0173c3373c2038adc171407b684293e268f Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Thu, 21 Nov 2024 13:33:41 +0100 Subject: [PATCH 03/26] Fix dashboard links --- lib/experimental/site-editor-permalinks.php | 24 ++++++++++++------- .../sidebar-navigation-screen/index.js | 2 +- .../src/components/site-hub/index.js | 7 ++---- 3 files changed, 19 insertions(+), 14 deletions(-) diff --git a/lib/experimental/site-editor-permalinks.php b/lib/experimental/site-editor-permalinks.php index c7950d2cbbf23..65841e295f73e 100644 --- a/lib/experimental/site-editor-permalinks.php +++ b/lib/experimental/site-editor-permalinks.php @@ -1,11 +1,19 @@ ) } Date: Thu, 21 Nov 2024 13:40:00 +0100 Subject: [PATCH 04/26] Add basic redirection --- lib/experimental/site-editor-permalinks.php | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/lib/experimental/site-editor-permalinks.php b/lib/experimental/site-editor-permalinks.php index 65841e295f73e..b2cfd978e38e2 100644 --- a/lib/experimental/site-editor-permalinks.php +++ b/lib/experimental/site-editor-permalinks.php @@ -17,3 +17,12 @@ function ( $settings ) { return $settings; } ); + +function gutenberg_redirect_site_editor_to_design() { + global $pagenow; + if ( 'site-editor.php' === $pagenow && strpos( $_SERVER['REQUEST_URI'], 'wp-admin/site-editor.php' ) ) { + wp_redirect( admin_url( '/design' ), 301 ); + exit; + } +} +add_action( 'admin_init', 'gutenberg_redirect_site_editor_to_design' ); From c3bff731d57d4913f2bb262e196ec649165f01e2 Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Thu, 21 Nov 2024 14:17:21 +0100 Subject: [PATCH 05/26] Add server side permanent redirects for the old urls --- lib/experimental/site-editor-permalinks.php | 97 ++++++++++++++++++- .../edit-site/src/components/editor/index.js | 4 +- .../edit-site/src/components/layout/router.js | 61 ------------ 3 files changed, 98 insertions(+), 64 deletions(-) delete mode 100644 packages/edit-site/src/components/layout/router.js diff --git a/lib/experimental/site-editor-permalinks.php b/lib/experimental/site-editor-permalinks.php index b2cfd978e38e2..d286cbccb64a1 100644 --- a/lib/experimental/site-editor-permalinks.php +++ b/lib/experimental/site-editor-permalinks.php @@ -18,11 +18,104 @@ function ( $settings ) { } ); +function gutenberg_remove_query_args( $args ) { + $query_string = $_SERVER['QUERY_STRING']; + $query = wp_parse_args( $query_string ); + foreach ( $args as $arg_name ) { + unset( $query[ $arg_name ] ); + } + return build_query( $query ); +} + function gutenberg_redirect_site_editor_to_design() { global $pagenow; - if ( 'site-editor.php' === $pagenow && strpos( $_SERVER['REQUEST_URI'], 'wp-admin/site-editor.php' ) ) { - wp_redirect( admin_url( '/design' ), 301 ); + if ( 'site-editor.php' !== $pagenow || ! strpos( $_SERVER['REQUEST_URI'], 'wp-admin/site-editor.php' ) ) { + return; + } + + // The following redirects are for the new permalinks in the site editor. + if ( isset( $_REQUEST['postType'] ) && 'wp_navigation' === $_REQUEST['postType'] && ! empty( $_REQUEST['postId'] ) ) { + wp_redirect( admin_url( '/design/wp_navigation/' . $_REQUEST['postId'] . '?' . gutenberg_remove_query_args( array( 'postType', 'postId' ) ) ), 301 ); + exit; + } + + if ( isset( $_REQUEST['postType'] ) && 'wp_navigation' === $_REQUEST['postType'] && empty( $_REQUEST['postId'] ) ) { + wp_redirect( admin_url( '/design/navigation?' . gutenberg_remove_query_args( array( 'postType' ) ) ), 301 ); + exit; + } + + if ( isset( $_REQUEST['path'] ) && '/wp_global_styles' === $_REQUEST['path'] ) { + wp_redirect( admin_url( '/design/styles?' . gutenberg_remove_query_args( array( 'path' ) ) ), 301 ); + exit; + } + + if ( isset( $_REQUEST['postType'] ) && 'page' === $_REQUEST['postType'] && ( empty( $_REQUEST['canvas'] ) || empty( $_REQUEST['postId'] ) ) ) { + wp_redirect( admin_url( '/design/page?' . gutenberg_remove_query_args( array( 'postType' ) ) ), 301 ); + exit; + } + + if ( isset( $_REQUEST['postType'] ) && 'page' === $_REQUEST['postType'] && ! empty( $_REQUEST['postId'] ) ) { + wp_redirect( admin_url( '/design/page/' . $_REQUEST['postId'] . '?' . gutenberg_remove_query_args( array( 'postType', 'postId' ) ) ), 301 ); + exit; + } + + if ( isset( $_REQUEST['postType'] ) && 'wp_template' === $_REQUEST['postType'] && ( empty( $_REQUEST['canvas'] ) || empty( $_REQUEST['postId'] ) ) ) { + wp_redirect( admin_url( '/design/template?' . gutenberg_remove_query_args( array( 'postType' ) ) ), 301 ); + exit; + } + + if ( isset( $_REQUEST['postType'] ) && 'wp_template' === $_REQUEST['postType'] && ! empty( $_REQUEST['postId'] ) ) { + wp_redirect( admin_url( '/design/wp_template/' . $_REQUEST['postId'] . '?' . gutenberg_remove_query_args( array( 'postType', 'postId' ) ) ), 301 ); + exit; + } + + if ( isset( $_REQUEST['postType'] ) && 'wp_block' === $_REQUEST['postType'] && ( empty( $_REQUEST['canvas'] ) || empty( $_REQUEST['postId'] ) ) ) { + wp_redirect( admin_url( '/design/pattern?' . gutenberg_remove_query_args( array( 'postType' ) ) ), 301 ); exit; } + + if ( isset( $_REQUEST['postType'] ) && 'wp_block' === $_REQUEST['postType'] && ! empty( $_REQUEST['postId'] ) ) { + wp_redirect( admin_url( '/design/wp_block/' . $_REQUEST['postId'] . '?' . gutenberg_remove_query_args( array( 'postType', 'postId' ) ) ), 301 ); + exit; + } + + if ( isset( $_REQUEST['postType'] ) && 'wp_template_part' === $_REQUEST['postType'] && ( empty( $_REQUEST['canvas'] ) || empty( $_REQUEST['postId'] ) ) ) { + wp_redirect( admin_url( '/design/pattern?' . $_SERVER['QUERY_STRING'] ), 301 ); + exit; + } + + if ( isset( $_REQUEST['postType'] ) && 'wp_template_part' === $_REQUEST['postType'] && ! empty( $_REQUEST['postId'] ) ) { + wp_redirect( admin_url( '/design/wp_template_part/' . $_REQUEST['postId'] . '?' . gutenberg_remove_query_args( array( 'postType', 'postId' ) ) ), 301 ); + exit; + } + + // The following redirects are for backward compatibility with the old site editor URLs. + if ( isset( $_REQUEST['path'] ) && '/wp_template_part/all' === $_REQUEST['path'] ) { + wp_redirect( admin_url( '/design/pattern?postType=wp_template_part' ), 301 ); + exit; + } + + if ( isset( $_REQUEST['path'] ) && '/page' === $_REQUEST['path'] ) { + wp_redirect( admin_url( '/design/page' ), 301 ); + exit; + } + + if ( isset( $_REQUEST['path'] ) && '/wp_template' === $_REQUEST['path'] ) { + wp_redirect( admin_url( '/design/template' ), 301 ); + exit; + } + + if ( isset( $_REQUEST['path'] ) && '/patterns' === $_REQUEST['path'] ) { + wp_redirect( admin_url( '/design/pattern' ), 301 ); + exit; + } + + if ( isset( $_REQUEST['path'] ) && '/navigation' === $_REQUEST['path'] ) { + wp_redirect( admin_url( '/design/navigation' ), 301 ); + exit; + } + + wp_redirect( admin_url( '/design' ), 301 ); + exit; } add_action( 'admin_init', 'gutenberg_redirect_site_editor_to_design' ); diff --git a/packages/edit-site/src/components/editor/index.js b/packages/edit-site/src/components/editor/index.js index 102c5cd0df9f9..7e3d4ab4fecc4 100644 --- a/packages/edit-site/src/components/editor/index.js +++ b/packages/edit-site/src/components/editor/index.js @@ -316,7 +316,9 @@ export default function EditSiteEditor( { isPostsList = false } ) { history.navigate( getNavigationPath( location, - postType + postWithTemplate + ? context.postType + : postType ), { transition: diff --git a/packages/edit-site/src/components/layout/router.js b/packages/edit-site/src/components/layout/router.js deleted file mode 100644 index f55ffdaffc04b..0000000000000 --- a/packages/edit-site/src/components/layout/router.js +++ /dev/null @@ -1,61 +0,0 @@ -/** - * WordPress dependencies - */ -import { privateApis as routerPrivateApis } from '@wordpress/router'; -import { useEffect } from '@wordpress/element'; - -/** - * Internal dependencies - */ -import { unlock } from '../../lock-unlock'; -import { - NAVIGATION_POST_TYPE, - PATTERN_TYPES, - TEMPLATE_PART_POST_TYPE, - TEMPLATE_POST_TYPE, -} from '../../utils/constants'; - -const { useLocation, useHistory } = unlock( routerPrivateApis ); - -export function useRedirectOldPaths() { - const history = useHistory(); - const { params } = useLocation(); - useEffect( () => { - const { postType, path, categoryType, ...rest } = params; - - if ( path === '/wp_template_part/all' ) { - history.replace( { postType: TEMPLATE_PART_POST_TYPE } ); - } - - if ( path === '/page' ) { - history.replace( { - postType: 'page', - ...rest, - } ); - } - - if ( path === '/wp_template' ) { - history.replace( { - postType: TEMPLATE_POST_TYPE, - ...rest, - } ); - } - - if ( path === '/patterns' ) { - history.replace( { - postType: - categoryType === TEMPLATE_PART_POST_TYPE - ? TEMPLATE_PART_POST_TYPE - : PATTERN_TYPES.user, - ...rest, - } ); - } - - if ( path === '/navigation' ) { - history.replace( { - postType: NAVIGATION_POST_TYPE, - ...rest, - } ); - } - }, [ history, params ] ); -} From 2c0b7f757035d627e8bda2b018ca28a3e7614857 Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Thu, 21 Nov 2024 16:25:02 +0100 Subject: [PATCH 06/26] Fix the posts dataviews --- lib/experimental/posts/load.php | 12 ---- lib/experimental/site-editor-permalinks.php | 26 +++++++- .../edit-site/src/components/editor/index.js | 3 + .../editor/use-resolve-edited-entity.js | 2 + .../src/components/posts-app-routes/home.js | 36 ---------- .../src/components/posts-app-routes/index.js | 17 +---- .../{posts-edit.js => post-item.js} | 14 ++-- .../posts-list-view-quick-edit.js | 52 --------------- .../posts-app-routes/posts-list-view.js | 40 ----------- .../posts-app-routes/posts-view-quick-edit.js | 49 -------------- .../components/posts-app-routes/posts-view.js | 35 ---------- .../src/components/posts-app-routes/posts.js | 66 +++++++++++++++++++ .../src/components/posts-app/index.js | 17 +++-- 13 files changed, 112 insertions(+), 257 deletions(-) delete mode 100644 packages/edit-site/src/components/posts-app-routes/home.js rename packages/edit-site/src/components/posts-app-routes/{posts-edit.js => post-item.js} (62%) delete mode 100644 packages/edit-site/src/components/posts-app-routes/posts-list-view-quick-edit.js delete mode 100644 packages/edit-site/src/components/posts-app-routes/posts-list-view.js delete mode 100644 packages/edit-site/src/components/posts-app-routes/posts-view-quick-edit.js delete mode 100644 packages/edit-site/src/components/posts-app-routes/posts-view.js create mode 100644 packages/edit-site/src/components/posts-app-routes/posts.js diff --git a/lib/experimental/posts/load.php b/lib/experimental/posts/load.php index 7321392b11a25..699534f1886f5 100644 --- a/lib/experimental/posts/load.php +++ b/lib/experimental/posts/load.php @@ -69,18 +69,6 @@ function gutenberg_posts_dashboard() { echo '
'; } -/** - * Redirects to the new posts dashboard page and adds the postType query arg. - */ -function gutenberg_add_post_type_arg() { - global $pagenow; - if ( 'admin.php' === $pagenow && isset( $_GET['page'] ) && 'gutenberg-posts-dashboard' === $_GET['page'] && empty( $_GET['postType'] ) ) { - wp_redirect( admin_url( '/admin.php?page=gutenberg-posts-dashboard&postType=post' ) ); - exit; - } -} -add_action( 'admin_init', 'gutenberg_add_post_type_arg' ); - /** * Replaces the default posts menu item with the new posts dashboard. */ diff --git a/lib/experimental/site-editor-permalinks.php b/lib/experimental/site-editor-permalinks.php index d286cbccb64a1..347488e6b9920 100644 --- a/lib/experimental/site-editor-permalinks.php +++ b/lib/experimental/site-editor-permalinks.php @@ -3,9 +3,16 @@ function gutenberg_rewrite_wp_admin_permalinks() { add_rewrite_rule( '^wp-admin/design/?(.*)?', - 'wp-admin/site-editor.php?path=$1', + 'wp-admin/site-editor.php?p=$1', 'top' ); + + add_rewrite_rule( + '^wp-admin/post/?(.*)?', + 'wp-admin/admin.php?page=gutenberg-posts-dashboard&p=$1', + 'top' + ); + flush_rewrite_rules(); } add_action( 'init', 'gutenberg_rewrite_wp_admin_permalinks' ); @@ -119,3 +126,20 @@ function gutenberg_redirect_site_editor_to_design() { exit; } add_action( 'admin_init', 'gutenberg_redirect_site_editor_to_design' ); + +function gutenberg_redirect_posts_dataviews_to_post() { + global $pagenow; + if ( + 'admin.php' !== $pagenow || + ! isset( $_REQUEST['page'] ) || + 'gutenberg-posts-dashboard' !== $_REQUEST['page'] || + ! strpos( $_SERVER['REQUEST_URI'], 'wp-admin/admin.php' ) + ) { + return; + } + + wp_redirect( admin_url( '/post' ), 301 ); + exit; +} + +add_action( 'admin_init', 'gutenberg_redirect_posts_dataviews_to_post' ); diff --git a/packages/edit-site/src/components/editor/index.js b/packages/edit-site/src/components/editor/index.js index 7e3d4ab4fecc4..c045bafd8a683 100644 --- a/packages/edit-site/src/components/editor/index.js +++ b/packages/edit-site/src/components/editor/index.js @@ -96,6 +96,8 @@ function getListPathForPostType( postType ) { return '/template'; case 'page': return '/page'; + case 'post': + return '/'; } throw 'Unknown post type'; } @@ -108,6 +110,7 @@ function getNavigationPath( location, postType ) { 'template-part-item', 'page-item', 'template-item', + 'post-item', ].includes( name ) ) { return getListPathForPostType( postType ); diff --git a/packages/edit-site/src/components/editor/use-resolve-edited-entity.js b/packages/edit-site/src/components/editor/use-resolve-edited-entity.js index 336a77f6ba88a..8da076f9f00b7 100644 --- a/packages/edit-site/src/components/editor/use-resolve-edited-entity.js +++ b/packages/edit-site/src/components/editor/use-resolve-edited-entity.js @@ -43,6 +43,8 @@ export function useResolveEditedEntity() { postType = TEMPLATE_POST_TYPE; } else if ( name === 'page-item' || name === 'pages' ) { postType = 'page'; + } else if ( name === 'post-item' || name === 'posts' ) { + postType = 'post'; } const homePage = useSelect( ( select ) => { diff --git a/packages/edit-site/src/components/posts-app-routes/home.js b/packages/edit-site/src/components/posts-app-routes/home.js deleted file mode 100644 index ec99cbd8899f1..0000000000000 --- a/packages/edit-site/src/components/posts-app-routes/home.js +++ /dev/null @@ -1,36 +0,0 @@ -/** - * WordPress dependencies - */ -import { privateApis as routerPrivateApis } from '@wordpress/router'; - -/** - * Internal dependencies - */ -import Editor from '../editor'; -import SidebarNavigationScreenMain from '../sidebar-navigation-screen-main'; -import { unlock } from '../../lock-unlock'; - -const { useLocation } = unlock( routerPrivateApis ); - -function HomeMobileView() { - const { params = {} } = useLocation(); - const { canvas = 'view' } = params; - - return canvas === 'edit' ? ( - - ) : ( - - ); -} - -export const homeRoute = { - name: 'home', - match: () => { - return true; - }, - areas: { - sidebar: , - preview: , - mobile: HomeMobileView, - }, -}; diff --git a/packages/edit-site/src/components/posts-app-routes/index.js b/packages/edit-site/src/components/posts-app-routes/index.js index e850bbd382200..3919ea3930d07 100644 --- a/packages/edit-site/src/components/posts-app-routes/index.js +++ b/packages/edit-site/src/components/posts-app-routes/index.js @@ -9,21 +9,10 @@ import { useEffect } from '@wordpress/element'; */ import { unlock } from '../../lock-unlock'; import { store as siteEditorStore } from '../../store'; -import { homeRoute } from './home'; -import { postsListViewQuickEditRoute } from './posts-list-view-quick-edit'; -import { postsListViewRoute } from './posts-list-view'; -import { postsViewQuickEditRoute } from './posts-view-quick-edit'; -import { postsViewRoute } from './posts-view'; -import { postsEditRoute } from './posts-edit'; +import { postsRoute } from './posts'; +import { postItemRoute } from './post-item'; -const routes = [ - postsListViewQuickEditRoute, - postsListViewRoute, - postsViewQuickEditRoute, - postsViewRoute, - postsEditRoute, - homeRoute, -]; +const routes = [ postItemRoute, postsRoute ]; export function useRegisterPostsAppRoutes() { const registry = useRegistry(); diff --git a/packages/edit-site/src/components/posts-app-routes/posts-edit.js b/packages/edit-site/src/components/posts-app-routes/post-item.js similarity index 62% rename from packages/edit-site/src/components/posts-app-routes/posts-edit.js rename to packages/edit-site/src/components/posts-app-routes/post-item.js index d395824559541..54131814f1ae2 100644 --- a/packages/edit-site/src/components/posts-app-routes/posts-edit.js +++ b/packages/edit-site/src/components/posts-app-routes/post-item.js @@ -6,25 +6,21 @@ import { __ } from '@wordpress/i18n'; /** * Internal dependencies */ -import PostList from '../post-list'; +import Editor from '../editor'; import DataViewsSidebarContent from '../sidebar-dataviews'; import SidebarNavigationScreen from '../sidebar-navigation-screen'; -import Editor from '../editor'; -export const postsEditRoute = { - name: 'posts-edit', - match: ( params ) => { - return params.postType === 'post' && params.canvas === 'edit'; - }, +export const postItemRoute = { + name: 'post-item', + path: '/post/:postId', areas: { sidebar: ( } + content={ } /> ), - content: , mobile: , preview: , }, diff --git a/packages/edit-site/src/components/posts-app-routes/posts-list-view-quick-edit.js b/packages/edit-site/src/components/posts-app-routes/posts-list-view-quick-edit.js deleted file mode 100644 index d2434b390ffd9..0000000000000 --- a/packages/edit-site/src/components/posts-app-routes/posts-list-view-quick-edit.js +++ /dev/null @@ -1,52 +0,0 @@ -/** - * WordPress dependencies - */ -import { __ } from '@wordpress/i18n'; -import { privateApis as routerPrivateApis } from '@wordpress/router'; - -/** - * Internal dependencies - */ -import PostList from '../post-list'; -import DataViewsSidebarContent from '../sidebar-dataviews'; -import SidebarNavigationScreen from '../sidebar-navigation-screen'; -import { unlock } from '../../lock-unlock'; -import { PostEdit } from '../post-edit'; -import Editor from '../editor'; - -const { useLocation } = unlock( routerPrivateApis ); - -function PostQuickEdit() { - const { params } = useLocation(); - return ; -} - -export const postsListViewQuickEditRoute = { - name: 'posts-list-view-quick-edit', - match: ( params ) => { - return ( - params.isCustom !== 'true' && - ( params.layout ?? 'list' ) === 'list' && - !! params.quickEdit && - params.postType === 'post' && - params.canvas !== 'edit' - ); - }, - areas: { - sidebar: ( - } - /> - ), - content: , - mobile: , - preview: , - edit: , - }, - widths: { - content: 380, - edit: 380, - }, -}; diff --git a/packages/edit-site/src/components/posts-app-routes/posts-list-view.js b/packages/edit-site/src/components/posts-app-routes/posts-list-view.js deleted file mode 100644 index 68aa86c7fb239..0000000000000 --- a/packages/edit-site/src/components/posts-app-routes/posts-list-view.js +++ /dev/null @@ -1,40 +0,0 @@ -/** - * WordPress dependencies - */ -import { __ } from '@wordpress/i18n'; - -/** - * Internal dependencies - */ -import PostList from '../post-list'; -import DataViewsSidebarContent from '../sidebar-dataviews'; -import SidebarNavigationScreen from '../sidebar-navigation-screen'; -import Editor from '../editor'; - -export const postsListViewRoute = { - name: 'posts-list-view', - match: ( params ) => { - return ( - params.isCustom !== 'true' && - ( params.layout ?? 'list' ) === 'list' && - ! params.quickEdit && - params.postType === 'post' && - params.canvas !== 'edit' - ); - }, - areas: { - sidebar: ( - } - /> - ), - content: , - preview: , - mobile: , - }, - widths: { - content: 380, - }, -}; diff --git a/packages/edit-site/src/components/posts-app-routes/posts-view-quick-edit.js b/packages/edit-site/src/components/posts-app-routes/posts-view-quick-edit.js deleted file mode 100644 index 52e6f9a2d26ef..0000000000000 --- a/packages/edit-site/src/components/posts-app-routes/posts-view-quick-edit.js +++ /dev/null @@ -1,49 +0,0 @@ -/** - * WordPress dependencies - */ -import { __ } from '@wordpress/i18n'; -import { privateApis as routerPrivateApis } from '@wordpress/router'; - -/** - * Internal dependencies - */ -import PostList from '../post-list'; -import DataViewsSidebarContent from '../sidebar-dataviews'; -import SidebarNavigationScreen from '../sidebar-navigation-screen'; -import { unlock } from '../../lock-unlock'; -import { PostEdit } from '../post-edit'; - -const { useLocation } = unlock( routerPrivateApis ); - -function PostQuickEdit() { - const { params } = useLocation(); - return ; -} - -export const postsViewQuickEditRoute = { - name: 'posts-view-quick-edit', - match: ( params ) => { - return ( - ( params.isCustom === 'true' || - ( params.layout ?? 'list' ) !== 'list' ) && - !! params.quickEdit && - params.postType === 'post' && - params.canvas !== 'edit' - ); - }, - areas: { - sidebar: ( - } - /> - ), - content: , - mobile: , - edit: , - }, - widths: { - edit: 380, - }, -}; diff --git a/packages/edit-site/src/components/posts-app-routes/posts-view.js b/packages/edit-site/src/components/posts-app-routes/posts-view.js deleted file mode 100644 index 6559991475d27..0000000000000 --- a/packages/edit-site/src/components/posts-app-routes/posts-view.js +++ /dev/null @@ -1,35 +0,0 @@ -/** - * WordPress dependencies - */ -import { __ } from '@wordpress/i18n'; - -/** - * Internal dependencies - */ -import PostList from '../post-list'; -import DataViewsSidebarContent from '../sidebar-dataviews'; -import SidebarNavigationScreen from '../sidebar-navigation-screen'; - -export const postsViewRoute = { - name: 'posts-view', - match: ( params ) => { - return ( - ( params.isCustom === 'true' || - ( params.layout ?? 'list' ) !== 'list' ) && - ! params.quickEdit && - params.postType === 'post' && - params.canvas !== 'edit' - ); - }, - areas: { - sidebar: ( - } - /> - ), - content: , - mobile: , - }, -}; diff --git a/packages/edit-site/src/components/posts-app-routes/posts.js b/packages/edit-site/src/components/posts-app-routes/posts.js new file mode 100644 index 0000000000000..80af8a75fbc80 --- /dev/null +++ b/packages/edit-site/src/components/posts-app-routes/posts.js @@ -0,0 +1,66 @@ +/** + * WordPress dependencies + */ +import { privateApis as routerPrivateApis } from '@wordpress/router'; +import { __ } from '@wordpress/i18n'; + +/** + * Internal dependencies + */ +import Editor from '../editor'; +import SidebarNavigationScreen from '../sidebar-navigation-screen'; +import DataViewsSidebarContent from '../sidebar-dataviews'; +import PostList from '../post-list'; +import { unlock } from '../../lock-unlock'; +import { PostEdit } from '../post-edit'; + +const { useLocation } = unlock( routerPrivateApis ); + +function MobilePostsView() { + const { query = {} } = useLocation(); + const { canvas = 'view' } = query; + + return canvas === 'edit' ? : ; +} + +export const postsRoute = { + name: 'posts', + path: '/', + areas: { + sidebar: ( + } + /> + ), + content: , + preview( { query } ) { + const isListView = + ( query.layout === 'list' || ! query.layout ) && + query.isCustom !== 'true'; + return isListView ? : undefined; + }, + mobile: , + edit( { query } ) { + const hasQuickEdit = + ( query.layout ?? 'list' ) === 'list' && !! query.quickEdit; + return hasQuickEdit ? ( + + ) : undefined; + }, + }, + widths: { + content( { query } ) { + const isListView = + ( query.layout === 'list' || ! query.layout ) && + query.isCustom !== 'true'; + return isListView ? 380 : undefined; + }, + edit( { query } ) { + const hasQuickEdit = + ( query.layout ?? 'list' ) === 'list' && !! query.quickEdit; + return hasQuickEdit ? 380 : undefined; + }, + }, +}; diff --git a/packages/edit-site/src/components/posts-app/index.js b/packages/edit-site/src/components/posts-app/index.js index e6eb90c168001..79cb5fb035d20 100644 --- a/packages/edit-site/src/components/posts-app/index.js +++ b/packages/edit-site/src/components/posts-app/index.js @@ -2,6 +2,7 @@ * WordPress dependencies */ import { privateApis as routerPrivateApis } from '@wordpress/router'; +import { useSelect } from '@wordpress/data'; /** * Internal dependencies @@ -9,20 +10,18 @@ import { privateApis as routerPrivateApis } from '@wordpress/router'; import Layout from '../layout'; import { useRegisterPostsAppRoutes } from '../posts-app-routes'; import { unlock } from '../../lock-unlock'; -import useActiveRoute from '../layout/router'; +import { store as editSiteStore } from '../../store'; const { RouterProvider } = unlock( routerPrivateApis ); -function PostsLayout() { - useRegisterPostsAppRoutes(); - const route = useActiveRoute(); - return ; -} - export default function PostsApp() { + useRegisterPostsAppRoutes(); + const routes = useSelect( ( select ) => { + return unlock( select( editSiteStore ) ).getRoutes(); + }, [] ); return ( - - + + ); } From 3c9a42ce89fc13f7c0e70a65ff1bb192b72d9045 Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Thu, 21 Nov 2024 18:18:10 +0100 Subject: [PATCH 07/26] Small fix --- lib/experimental/site-editor-permalinks.php | 4 ++-- packages/edit-site/src/components/posts-app/index.js | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/experimental/site-editor-permalinks.php b/lib/experimental/site-editor-permalinks.php index 347488e6b9920..babd3b8005caf 100644 --- a/lib/experimental/site-editor-permalinks.php +++ b/lib/experimental/site-editor-permalinks.php @@ -8,7 +8,7 @@ function gutenberg_rewrite_wp_admin_permalinks() { ); add_rewrite_rule( - '^wp-admin/post/?(.*)?', + '^wp-admin/posts/?(.*)?', 'wp-admin/admin.php?page=gutenberg-posts-dashboard&p=$1', 'top' ); @@ -138,7 +138,7 @@ function gutenberg_redirect_posts_dataviews_to_post() { return; } - wp_redirect( admin_url( '/post' ), 301 ); + wp_redirect( admin_url( '/posts' ), 301 ); exit; } diff --git a/packages/edit-site/src/components/posts-app/index.js b/packages/edit-site/src/components/posts-app/index.js index 79cb5fb035d20..c552a22aac33e 100644 --- a/packages/edit-site/src/components/posts-app/index.js +++ b/packages/edit-site/src/components/posts-app/index.js @@ -20,7 +20,7 @@ export default function PostsApp() { return unlock( select( editSiteStore ) ).getRoutes(); }, [] ); return ( - + ); From b811a485a183def6fb96b621a8f852d1644f545d Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Thu, 21 Nov 2024 19:50:59 +0100 Subject: [PATCH 08/26] Remove url rewrites --- lib/experimental/site-editor-permalinks.php | 79 ++++++++++--------- .../edit-site/src/components/app/index.js | 2 +- .../src/components/posts-app/index.js | 2 +- packages/router/src/link.tsx | 12 ++- packages/router/src/router.tsx | 44 +++++++---- 5 files changed, 79 insertions(+), 60 deletions(-) diff --git a/lib/experimental/site-editor-permalinks.php b/lib/experimental/site-editor-permalinks.php index babd3b8005caf..1f73043f96488 100644 --- a/lib/experimental/site-editor-permalinks.php +++ b/lib/experimental/site-editor-permalinks.php @@ -1,22 +1,5 @@ $path ) : array() ) ); + $base_url = admin_url( 'site-editor.php' ); + return $query_string ? $base_url . '?' . $query_string : $base_url; +} + +function gutenberg_get_posts_dataviews_url( $path = '', $query = array() ) { + $query_string = build_query( + array_merge( + $query, + $path ? array( + 'page' => 'gutenberg-posts-dashboard', + 'p' => $path, + ) : array( 'page' => 'gutenberg-posts-dashboard' ) + ) + ); + $base_url = admin_url( 'admin.php' ); + return $query_string ? $base_url . '?' . $query_string : $base_url; } function gutenberg_redirect_site_editor_to_design() { global $pagenow; - if ( 'site-editor.php' !== $pagenow || ! strpos( $_SERVER['REQUEST_URI'], 'wp-admin/site-editor.php' ) ) { + if ( 'site-editor.php' !== $pagenow || isset( $_REQUEST['p'] ) || ! isset( $_SERVER['querystring'] ) ) { return; } // The following redirects are for the new permalinks in the site editor. if ( isset( $_REQUEST['postType'] ) && 'wp_navigation' === $_REQUEST['postType'] && ! empty( $_REQUEST['postId'] ) ) { - wp_redirect( admin_url( '/design/wp_navigation/' . $_REQUEST['postId'] . '?' . gutenberg_remove_query_args( array( 'postType', 'postId' ) ) ), 301 ); + wp_redirect( gutenberg_get_site_editor_url( '/wp_navigation/' . $_REQUEST['postId'], gutenberg_remove_query_args( array( 'postType', 'postId' ) ) ), 301 ); exit; } if ( isset( $_REQUEST['postType'] ) && 'wp_navigation' === $_REQUEST['postType'] && empty( $_REQUEST['postId'] ) ) { - wp_redirect( admin_url( '/design/navigation?' . gutenberg_remove_query_args( array( 'postType' ) ) ), 301 ); + wp_redirect( gutenberg_get_site_editor_url( '/navigation', gutenberg_remove_query_args( array( 'postType' ) ) ), 301 ); exit; } if ( isset( $_REQUEST['path'] ) && '/wp_global_styles' === $_REQUEST['path'] ) { - wp_redirect( admin_url( '/design/styles?' . gutenberg_remove_query_args( array( 'path' ) ) ), 301 ); + wp_redirect( gutenberg_get_site_editor_url( '/styles', gutenberg_remove_query_args( array( 'path' ) ) ), 301 ); exit; } if ( isset( $_REQUEST['postType'] ) && 'page' === $_REQUEST['postType'] && ( empty( $_REQUEST['canvas'] ) || empty( $_REQUEST['postId'] ) ) ) { - wp_redirect( admin_url( '/design/page?' . gutenberg_remove_query_args( array( 'postType' ) ) ), 301 ); + wp_redirect( gutenberg_get_site_editor_url( '/page', gutenberg_remove_query_args( array( 'postType' ) ) ), 301 ); exit; } if ( isset( $_REQUEST['postType'] ) && 'page' === $_REQUEST['postType'] && ! empty( $_REQUEST['postId'] ) ) { - wp_redirect( admin_url( '/design/page/' . $_REQUEST['postId'] . '?' . gutenberg_remove_query_args( array( 'postType', 'postId' ) ) ), 301 ); + wp_redirect( gutenberg_get_site_editor_url( '/page/' . $_REQUEST['postId'], gutenberg_remove_query_args( array( 'postType', 'postId' ) ) ), 301 ); exit; } if ( isset( $_REQUEST['postType'] ) && 'wp_template' === $_REQUEST['postType'] && ( empty( $_REQUEST['canvas'] ) || empty( $_REQUEST['postId'] ) ) ) { - wp_redirect( admin_url( '/design/template?' . gutenberg_remove_query_args( array( 'postType' ) ) ), 301 ); + wp_redirect( gutenberg_get_site_editor_url( '/template', gutenberg_remove_query_args( array( 'postType' ) ) ), 301 ); exit; } if ( isset( $_REQUEST['postType'] ) && 'wp_template' === $_REQUEST['postType'] && ! empty( $_REQUEST['postId'] ) ) { - wp_redirect( admin_url( '/design/wp_template/' . $_REQUEST['postId'] . '?' . gutenberg_remove_query_args( array( 'postType', 'postId' ) ) ), 301 ); + wp_redirect( gutenberg_get_site_editor_url( '/wp_template/' . $_REQUEST['postId'], gutenberg_remove_query_args( array( 'postType', 'postId' ) ) ), 301 ); exit; } if ( isset( $_REQUEST['postType'] ) && 'wp_block' === $_REQUEST['postType'] && ( empty( $_REQUEST['canvas'] ) || empty( $_REQUEST['postId'] ) ) ) { - wp_redirect( admin_url( '/design/pattern?' . gutenberg_remove_query_args( array( 'postType' ) ) ), 301 ); + wp_redirect( gutenberg_get_site_editor_url( '/pattern', gutenberg_remove_query_args( array( 'postType' ) ) ), 301 ); exit; } if ( isset( $_REQUEST['postType'] ) && 'wp_block' === $_REQUEST['postType'] && ! empty( $_REQUEST['postId'] ) ) { - wp_redirect( admin_url( '/design/wp_block/' . $_REQUEST['postId'] . '?' . gutenberg_remove_query_args( array( 'postType', 'postId' ) ) ), 301 ); + wp_redirect( gutenberg_get_site_editor_url( '/wp_block/' . $_REQUEST['postId'], gutenberg_remove_query_args( array( 'postType', 'postId' ) ) ), 301 ); exit; } if ( isset( $_REQUEST['postType'] ) && 'wp_template_part' === $_REQUEST['postType'] && ( empty( $_REQUEST['canvas'] ) || empty( $_REQUEST['postId'] ) ) ) { - wp_redirect( admin_url( '/design/pattern?' . $_SERVER['QUERY_STRING'] ), 301 ); + wp_redirect( gutenberg_get_site_editor_url( '/pattern', gutenberg_remove_query_args() ), 301 ); exit; } if ( isset( $_REQUEST['postType'] ) && 'wp_template_part' === $_REQUEST['postType'] && ! empty( $_REQUEST['postId'] ) ) { - wp_redirect( admin_url( '/design/wp_template_part/' . $_REQUEST['postId'] . '?' . gutenberg_remove_query_args( array( 'postType', 'postId' ) ) ), 301 ); + wp_redirect( gutenberg_get_site_editor_url( '/wp_template_part/' . $_REQUEST['postId'], gutenberg_remove_query_args( array( 'postType', 'postId' ) ) ), 301 ); exit; } // The following redirects are for backward compatibility with the old site editor URLs. if ( isset( $_REQUEST['path'] ) && '/wp_template_part/all' === $_REQUEST['path'] ) { - wp_redirect( admin_url( '/design/pattern?postType=wp_template_part' ), 301 ); + wp_redirect( gutenberg_get_site_editor_url( '/pattern?postType=wp_template_part' ), 301 ); exit; } if ( isset( $_REQUEST['path'] ) && '/page' === $_REQUEST['path'] ) { - wp_redirect( admin_url( '/design/page' ), 301 ); + wp_redirect( gutenberg_get_site_editor_url( '/page' ), 301 ); exit; } if ( isset( $_REQUEST['path'] ) && '/wp_template' === $_REQUEST['path'] ) { - wp_redirect( admin_url( '/design/template' ), 301 ); + wp_redirect( gutenberg_get_site_editor_url( '/template' ), 301 ); exit; } if ( isset( $_REQUEST['path'] ) && '/patterns' === $_REQUEST['path'] ) { - wp_redirect( admin_url( '/design/pattern' ), 301 ); + wp_redirect( gutenberg_get_site_editor_url( '/pattern' ), 301 ); exit; } if ( isset( $_REQUEST['path'] ) && '/navigation' === $_REQUEST['path'] ) { - wp_redirect( admin_url( '/design/navigation' ), 301 ); + wp_redirect( gutenberg_get_site_editor_url( '/navigation' ), 301 ); exit; } - wp_redirect( admin_url( '/design' ), 301 ); + wp_redirect( gutenberg_get_site_editor_url(), 301 ); exit; } add_action( 'admin_init', 'gutenberg_redirect_site_editor_to_design' ); @@ -133,12 +136,12 @@ function gutenberg_redirect_posts_dataviews_to_post() { 'admin.php' !== $pagenow || ! isset( $_REQUEST['page'] ) || 'gutenberg-posts-dashboard' !== $_REQUEST['page'] || - ! strpos( $_SERVER['REQUEST_URI'], 'wp-admin/admin.php' ) + isset( $_REQUEST['p'] ) ) { return; } - wp_redirect( admin_url( '/posts' ), 301 ); + wp_redirect( gutenberg_get_posts_dataviews_url( '/' ), 301 ); exit; } diff --git a/packages/edit-site/src/components/app/index.js b/packages/edit-site/src/components/app/index.js index 464edea1615aa..d304666ceddfa 100644 --- a/packages/edit-site/src/components/app/index.js +++ b/packages/edit-site/src/components/app/index.js @@ -45,7 +45,7 @@ export default function App() { } return ( - + diff --git a/packages/edit-site/src/components/posts-app/index.js b/packages/edit-site/src/components/posts-app/index.js index c552a22aac33e..ab8cfab99f762 100644 --- a/packages/edit-site/src/components/posts-app/index.js +++ b/packages/edit-site/src/components/posts-app/index.js @@ -20,7 +20,7 @@ export default function PostsApp() { return unlock( select( editSiteStore ) ).getRoutes(); }, [] ); return ( - + ); diff --git a/packages/router/src/link.tsx b/packages/router/src/link.tsx index 1aa3c1a5ba479..96715720dc108 100644 --- a/packages/router/src/link.tsx +++ b/packages/router/src/link.tsx @@ -2,6 +2,7 @@ * WordPress dependencies */ import { useContext } from '@wordpress/element'; +import { getQueryArgs, getPath, buildQueryString } from '@wordpress/url'; /** * Internal dependencies @@ -10,16 +11,21 @@ import { ConfigContext, type NavigationOptions, useHistory } from './router'; export function useLink( to: string, options: NavigationOptions = {} ) { const history = useHistory(); - const { basePath } = useContext( ConfigContext ); + const { pathArg } = useContext( ConfigContext ); function onClick( event: React.SyntheticEvent< HTMLAnchorElement > ) { event?.preventDefault(); history.navigate( to, options ); } + const queryArgs = getQueryArgs( to ); + const path = getPath( 'http://domain.com/' + to ); - const [ before ] = window.location.href.split( basePath ); + const [ before ] = window.location.href.split( '?' ); return { - href: `${ before }${ basePath }${ to }`, + href: `${ before }?${ buildQueryString( { + [ pathArg ]: path, + ...queryArgs, + } ) }`, onClick, }; } diff --git a/packages/router/src/router.tsx b/packages/router/src/router.tsx index 8e36a39f891cd..9e203003fce7c 100644 --- a/packages/router/src/router.tsx +++ b/packages/router/src/router.tsx @@ -13,7 +13,12 @@ import { useSyncExternalStore, useMemo, } from '@wordpress/element'; -import { addQueryArgs } from '@wordpress/url'; +import { + addQueryArgs, + getQueryArgs, + getPath, + buildQueryString, +} from '@wordpress/url'; /** * Internal dependencies @@ -42,7 +47,7 @@ interface Match { } interface Config { - basePath: string; + pathArg: string; } export interface NavigationOptions { @@ -51,7 +56,7 @@ export interface NavigationOptions { } const RoutesContext = createContext< Match | null >( null ); -export const ConfigContext = createContext< Config >( { basePath: '/' } ); +export const ConfigContext = createContext< Config >( { pathArg: 'p' } ); const locationMemo = new WeakMap(); function getLocationWithQuery() { @@ -72,13 +77,20 @@ export function useLocation() { } export function useHistory() { - const { basePath } = useContext( ConfigContext ); + const { pathArg } = useContext( ConfigContext ); return useMemo( () => ( { - navigate( path: string, options: NavigationOptions = {} ) { + navigate( rawPath: string, options: NavigationOptions = {} ) { + const query = getQueryArgs( rawPath ); + const path = getPath( 'http://domain.com/' + rawPath ); const performPush = () => { return history.push( - `${ basePath }${ path }`, + { + search: buildQueryString( { + [ pathArg ]: path, + ...query, + } ), + }, options.state ); }; @@ -109,16 +121,16 @@ export function useHistory() { } ); }, } ), - [ basePath ] + [ pathArg ] ); } export default function useMatch( location: LocationWithQuery, routes: Route[], - basePath: string + pathArg: string ): Match { - const { query = {}, pathname } = location; + const { query: rawQuery = {} } = location; return useMemo( () => { const matcher = new RouteRecognizer(); @@ -127,9 +139,7 @@ export default function useMatch( as: route.name, } ); } ); - const [ , path ] = basePath - ? pathname.split( basePath ) - : [ , pathname ]; + const { [ pathArg ]: path = '/', ...query } = rawQuery; const result = matcher.recognize( path )?.[ 0 ]; if ( ! result ) { return { @@ -164,16 +174,16 @@ export default function useMatch( query, path: addQueryArgs( path, query ), }; - }, [ routes, query, basePath, pathname ] ); + }, [ routes, rawQuery, pathArg ] ); } export function RouterProvider( { routes, - basePath, + pathArg, children, }: { routes: Route[]; - basePath: string; + pathArg: string; children: React.ReactNode; } ) { const location = useSyncExternalStore( @@ -181,8 +191,8 @@ export function RouterProvider( { getLocationWithQuery, getLocationWithQuery ); - const match = useMatch( location, routes, basePath ); - const config = useMemo( () => ( { basePath } ), [ basePath ] ); + const match = useMatch( location, routes, pathArg ); + const config = useMemo( () => ( { pathArg } ), [ pathArg ] ); return ( From 515356762ed0f0381190d294979f03e93f445d86 Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Mon, 25 Nov 2024 12:11:32 +0100 Subject: [PATCH 09/26] Fix theme previewing --- package-lock.json | 1 + .../edit-site/src/components/app/index.js | 32 +++++++++++++++++- .../src/utils/is-previewing-theme.js | 4 +-- .../edit-site/src/utils/use-activate-theme.js | 7 ++-- packages/router/package.json | 1 + packages/router/src/link.tsx | 26 +++++++++++---- packages/router/src/router.tsx | 33 +++++++++++++++---- packages/router/tsconfig.json | 5 ++- 8 files changed, 86 insertions(+), 23 deletions(-) diff --git a/package-lock.json b/package-lock.json index ec7e6a89b2044..dc0c18f3b6ac5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -55569,6 +55569,7 @@ "license": "GPL-2.0-or-later", "dependencies": { "@babel/runtime": "7.25.7", + "@wordpress/compose": "*", "@wordpress/element": "*", "@wordpress/private-apis": "*", "@wordpress/url": "*", diff --git a/packages/edit-site/src/components/app/index.js b/packages/edit-site/src/components/app/index.js index d304666ceddfa..a589e2997cfce 100644 --- a/packages/edit-site/src/components/app/index.js +++ b/packages/edit-site/src/components/app/index.js @@ -6,6 +6,7 @@ import { useDispatch, useSelect } from '@wordpress/data'; import { __, sprintf } from '@wordpress/i18n'; import { PluginArea } from '@wordpress/plugins'; import { privateApis as routerPrivateApis } from '@wordpress/router'; +import { useMemo } from '@wordpress/element'; /** * Internal dependencies @@ -16,6 +17,10 @@ import { store as editSiteStore } from '../../store'; import { useCommonCommands } from '../../hooks/commands/use-common-commands'; import useSetCommandContext from '../../hooks/commands/use-set-command-context'; import { useRegisterSiteEditorRoutes } from '../site-editor-routes'; +import { + currentlyPreviewingTheme, + isPreviewingTheme, +} from '../../utils/is-previewing-theme'; const { RouterProvider } = unlock( routerPrivateApis ); @@ -43,9 +48,34 @@ export default function App() { ) ); } + const middlewares = useMemo( + () => [ + ( { path, query } ) => { + if ( ! isPreviewingTheme() ) { + return { path, query }; + } + + return { + path, + query: { + ...query, + wp_theme_preview: + 'wp_theme_preview' in query + ? query.wp_theme_preview + : currentlyPreviewingTheme(), + }, + }; + }, + ], + [] + ); return ( - + diff --git a/packages/edit-site/src/utils/is-previewing-theme.js b/packages/edit-site/src/utils/is-previewing-theme.js index 1a71c441f9925..a4c830b4b60ad 100644 --- a/packages/edit-site/src/utils/is-previewing-theme.js +++ b/packages/edit-site/src/utils/is-previewing-theme.js @@ -4,9 +4,7 @@ import { getQueryArg } from '@wordpress/url'; export function isPreviewingTheme() { - return ( - getQueryArg( window.location.href, 'wp_theme_preview' ) !== undefined - ); + return !! getQueryArg( window.location.href, 'wp_theme_preview' ); } export function currentlyPreviewingTheme() { diff --git a/packages/edit-site/src/utils/use-activate-theme.js b/packages/edit-site/src/utils/use-activate-theme.js index 0dafd88340ba7..447ea07305349 100644 --- a/packages/edit-site/src/utils/use-activate-theme.js +++ b/packages/edit-site/src/utils/use-activate-theme.js @@ -4,6 +4,7 @@ import { store as coreStore } from '@wordpress/core-data'; import { useDispatch } from '@wordpress/data'; import { privateApis as routerPrivateApis } from '@wordpress/router'; +import { addQueryArgs } from '@wordpress/url'; /** * Internal dependencies @@ -14,7 +15,7 @@ import { currentlyPreviewingTheme, } from './is-previewing-theme'; -const { useHistory } = unlock( routerPrivateApis ); +const { useHistory, useLocation } = unlock( routerPrivateApis ); /** * This should be refactored to use the REST API, once the REST API can activate themes. @@ -23,6 +24,7 @@ const { useHistory } = unlock( routerPrivateApis ); */ export function useActivateTheme() { const history = useHistory(); + const { path } = useLocation(); const { startResolution, finishResolution } = useDispatch( coreStore ); return async () => { @@ -37,8 +39,7 @@ export function useActivateTheme() { finishResolution( 'activateTheme' ); // Remove the wp_theme_preview query param: we've finished activating // the queue and are switching to normal Site Editor. - const { params } = history.getLocationWithParams(); - history.replace( { ...params, wp_theme_preview: undefined } ); + history.navigate( addQueryArgs( path, { wp_theme_preview: '' } ) ); } }; } diff --git a/packages/router/package.json b/packages/router/package.json index 9b86cbb7e8c41..66a64f4ddc5ba 100644 --- a/packages/router/package.json +++ b/packages/router/package.json @@ -29,6 +29,7 @@ "types": "build-types", "dependencies": { "@babel/runtime": "7.25.7", + "@wordpress/compose": "*", "@wordpress/element": "*", "@wordpress/private-apis": "*", "@wordpress/url": "*", diff --git a/packages/router/src/link.tsx b/packages/router/src/link.tsx index 96715720dc108..1864e5f9c6a28 100644 --- a/packages/router/src/link.tsx +++ b/packages/router/src/link.tsx @@ -1,30 +1,42 @@ /** * WordPress dependencies */ -import { useContext } from '@wordpress/element'; +import { useContext, useMemo } from '@wordpress/element'; import { getQueryArgs, getPath, buildQueryString } from '@wordpress/url'; +import { compose } from '@wordpress/compose'; /** * Internal dependencies */ -import { ConfigContext, type NavigationOptions, useHistory } from './router'; +import { + ConfigContext, + type Middleware, + type NavigationOptions, + useHistory, +} from './router'; export function useLink( to: string, options: NavigationOptions = {} ) { const history = useHistory(); - const { pathArg } = useContext( ConfigContext ); + const { pathArg, middlewares } = useContext( ConfigContext ); function onClick( event: React.SyntheticEvent< HTMLAnchorElement > ) { event?.preventDefault(); history.navigate( to, options ); } - const queryArgs = getQueryArgs( to ); - const path = getPath( 'http://domain.com/' + to ); + const query = getQueryArgs( to ); + const path = getPath( 'http://domain.com/' + to ) ?? ''; + const link = useMemo( () => { + const runMiddlewares = ( + middlewares ? compose( ...middlewares ) : ( i: unknown ) => i + ) as Middleware; + return runMiddlewares( { path, query } ); + }, [ path, query, middlewares ] ); const [ before ] = window.location.href.split( '?' ); return { href: `${ before }?${ buildQueryString( { - [ pathArg ]: path, - ...queryArgs, + [ pathArg ]: link.path, + ...link.query, } ) }`, onClick, }; diff --git a/packages/router/src/router.tsx b/packages/router/src/router.tsx index 9e203003fce7c..a199c7c49c612 100644 --- a/packages/router/src/router.tsx +++ b/packages/router/src/router.tsx @@ -19,6 +19,7 @@ import { getPath, buildQueryString, } from '@wordpress/url'; +import { compose } from '@wordpress/compose'; /** * Internal dependencies @@ -46,8 +47,17 @@ interface Match { params?: Record< string, any >; } +export type Middleware = ( arg: { + path: string; + query: Record< string, any >; +} ) => { + path: string; + query: Record< string, any >; +}; + interface Config { pathArg: string; + middlewares?: Middleware[]; } export interface NavigationOptions { @@ -77,18 +87,24 @@ export function useLocation() { } export function useHistory() { - const { pathArg } = useContext( ConfigContext ); + const { pathArg, middlewares } = useContext( ConfigContext ); return useMemo( () => ( { navigate( rawPath: string, options: NavigationOptions = {} ) { + const runMiddlewares = ( + middlewares + ? compose( ...middlewares ) + : ( i: unknown ) => i + ) as Middleware; const query = getQueryArgs( rawPath ); - const path = getPath( 'http://domain.com/' + rawPath ); + const path = getPath( 'http://domain.com/' + rawPath ) ?? ''; const performPush = () => { + const result = runMiddlewares( { path, query } ); return history.push( { search: buildQueryString( { - [ pathArg ]: path, - ...query, + [ pathArg ]: result.path, + ...result.query, } ), }, options.state @@ -121,7 +137,7 @@ export function useHistory() { } ); }, } ), - [ pathArg ] + [ pathArg, middlewares ] ); } @@ -180,10 +196,12 @@ export default function useMatch( export function RouterProvider( { routes, pathArg, + middlewares, children, }: { routes: Route[]; pathArg: string; + middlewares?: Middleware[]; children: React.ReactNode; } ) { const location = useSyncExternalStore( @@ -192,7 +210,10 @@ export function RouterProvider( { getLocationWithQuery ); const match = useMatch( location, routes, pathArg ); - const config = useMemo( () => ( { pathArg } ), [ pathArg ] ); + const config = useMemo( + () => ( { middlewares, pathArg } ), + [ middlewares, pathArg ] + ); return ( diff --git a/packages/router/tsconfig.json b/packages/router/tsconfig.json index e4945eef8bac0..8706b546ff304 100644 --- a/packages/router/tsconfig.json +++ b/packages/router/tsconfig.json @@ -4,11 +4,10 @@ "compilerOptions": { "rootDir": "src", "declarationDir": "build-types", - "types": [ "gutenberg-env" ], - "allowJs": false, - "checkJs": false + "types": [ "gutenberg-env" ] }, "references": [ + { "path": "../compose" }, { "path": "../element" }, { "path": "../private-apis" }, { "path": "../url" } From bc404a3654ce3cccedd074a9b84f2a2f6fc301a8 Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Mon, 25 Nov 2024 13:01:17 +0100 Subject: [PATCH 10/26] Fix query string argument --- lib/experimental/site-editor-permalinks.php | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/lib/experimental/site-editor-permalinks.php b/lib/experimental/site-editor-permalinks.php index 1f73043f96488..71b6fcaf016da 100644 --- a/lib/experimental/site-editor-permalinks.php +++ b/lib/experimental/site-editor-permalinks.php @@ -8,7 +8,7 @@ function ( $settings ) { } ); -function gutenberg_remove_query_args( $args ) { +function gutenberg_remove_query_args( $args = array() ) { $query_string = $_SERVER['QUERY_STRING']; $query = wp_parse_args( $query_string ); foreach ( $args as $arg_name ) { @@ -18,7 +18,7 @@ function gutenberg_remove_query_args( $args ) { } function gutenberg_get_site_editor_url( $path = '', $query = array() ) { - $query_string = build_query( array_merge( $query, $path ? array( 'p' => $path ) : array() ) ); + $query_string = build_query( array_merge( $query, array( 'p' => $path ) ) ); $base_url = admin_url( 'site-editor.php' ); return $query_string ? $base_url . '?' . $query_string : $base_url; } @@ -39,7 +39,7 @@ function gutenberg_get_posts_dataviews_url( $path = '', $query = array() ) { function gutenberg_redirect_site_editor_to_design() { global $pagenow; - if ( 'site-editor.php' !== $pagenow || isset( $_REQUEST['p'] ) || ! isset( $_SERVER['querystring'] ) ) { + if ( 'site-editor.php' !== $pagenow || isset( $_REQUEST['p'] ) || ! $_SERVER['QUERY_STRING'] ) { return; } @@ -101,31 +101,31 @@ function gutenberg_redirect_site_editor_to_design() { // The following redirects are for backward compatibility with the old site editor URLs. if ( isset( $_REQUEST['path'] ) && '/wp_template_part/all' === $_REQUEST['path'] ) { - wp_redirect( gutenberg_get_site_editor_url( '/pattern?postType=wp_template_part' ), 301 ); + wp_redirect( gutenberg_get_site_editor_url( '/pattern?postType=wp_template_part', gutenberg_remove_query_args( 'path' ) ), 301 ); exit; } if ( isset( $_REQUEST['path'] ) && '/page' === $_REQUEST['path'] ) { - wp_redirect( gutenberg_get_site_editor_url( '/page' ), 301 ); + wp_redirect( gutenberg_get_site_editor_url( '/page', gutenberg_remove_query_args( 'path' ) ), 301 ); exit; } if ( isset( $_REQUEST['path'] ) && '/wp_template' === $_REQUEST['path'] ) { - wp_redirect( gutenberg_get_site_editor_url( '/template' ), 301 ); + wp_redirect( gutenberg_get_site_editor_url( '/template', gutenberg_remove_query_args( 'path' ) ), 301 ); exit; } if ( isset( $_REQUEST['path'] ) && '/patterns' === $_REQUEST['path'] ) { - wp_redirect( gutenberg_get_site_editor_url( '/pattern' ), 301 ); + wp_redirect( gutenberg_get_site_editor_url( '/pattern', gutenberg_remove_query_args( 'path' ) ), 301 ); exit; } if ( isset( $_REQUEST['path'] ) && '/navigation' === $_REQUEST['path'] ) { - wp_redirect( gutenberg_get_site_editor_url( '/navigation' ), 301 ); + wp_redirect( gutenberg_get_site_editor_url( '/navigation', gutenberg_remove_query_args( 'path' ) ), 301 ); exit; } - wp_redirect( gutenberg_get_site_editor_url(), 301 ); + wp_redirect( gutenberg_get_site_editor_url( '', gutenberg_remove_query_args()), 301 ); exit; } add_action( 'admin_init', 'gutenberg_redirect_site_editor_to_design' ); From b4d15dce909b9bd6a64148d050a5e9bbf9453172 Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Mon, 25 Nov 2024 13:21:41 +0100 Subject: [PATCH 11/26] switch middleware to beforeNavigate --- package-lock.json | 1 - .../edit-site/src/components/app/index.js | 37 ++++++++----------- packages/router/package.json | 1 - packages/router/src/link.tsx | 19 +++------- packages/router/src/router.tsx | 26 ++++++------- packages/router/tsconfig.json | 1 - 6 files changed, 33 insertions(+), 52 deletions(-) diff --git a/package-lock.json b/package-lock.json index dc0c18f3b6ac5..ec7e6a89b2044 100644 --- a/package-lock.json +++ b/package-lock.json @@ -55569,7 +55569,6 @@ "license": "GPL-2.0-or-later", "dependencies": { "@babel/runtime": "7.25.7", - "@wordpress/compose": "*", "@wordpress/element": "*", "@wordpress/private-apis": "*", "@wordpress/url": "*", diff --git a/packages/edit-site/src/components/app/index.js b/packages/edit-site/src/components/app/index.js index a589e2997cfce..cf13e7baf1b73 100644 --- a/packages/edit-site/src/components/app/index.js +++ b/packages/edit-site/src/components/app/index.js @@ -6,7 +6,7 @@ import { useDispatch, useSelect } from '@wordpress/data'; import { __, sprintf } from '@wordpress/i18n'; import { PluginArea } from '@wordpress/plugins'; import { privateApis as routerPrivateApis } from '@wordpress/router'; -import { useMemo } from '@wordpress/element'; +import { useCallback } from '@wordpress/element'; /** * Internal dependencies @@ -48,33 +48,28 @@ export default function App() { ) ); } - const middlewares = useMemo( - () => [ - ( { path, query } ) => { - if ( ! isPreviewingTheme() ) { - return { path, query }; - } + const beforeNavigate = useCallback( ( { path, query } ) => { + if ( ! isPreviewingTheme() ) { + return { path, query }; + } - return { - path, - query: { - ...query, - wp_theme_preview: - 'wp_theme_preview' in query - ? query.wp_theme_preview - : currentlyPreviewingTheme(), - }, - }; + return { + path, + query: { + ...query, + wp_theme_preview: + 'wp_theme_preview' in query + ? query.wp_theme_preview + : currentlyPreviewingTheme(), }, - ], - [] - ); + }; + }, [] ); return ( diff --git a/packages/router/package.json b/packages/router/package.json index 66a64f4ddc5ba..9b86cbb7e8c41 100644 --- a/packages/router/package.json +++ b/packages/router/package.json @@ -29,7 +29,6 @@ "types": "build-types", "dependencies": { "@babel/runtime": "7.25.7", - "@wordpress/compose": "*", "@wordpress/element": "*", "@wordpress/private-apis": "*", "@wordpress/url": "*", diff --git a/packages/router/src/link.tsx b/packages/router/src/link.tsx index 1864e5f9c6a28..d312a9da14460 100644 --- a/packages/router/src/link.tsx +++ b/packages/router/src/link.tsx @@ -3,21 +3,15 @@ */ import { useContext, useMemo } from '@wordpress/element'; import { getQueryArgs, getPath, buildQueryString } from '@wordpress/url'; -import { compose } from '@wordpress/compose'; /** * Internal dependencies */ -import { - ConfigContext, - type Middleware, - type NavigationOptions, - useHistory, -} from './router'; +import { ConfigContext, type NavigationOptions, useHistory } from './router'; export function useLink( to: string, options: NavigationOptions = {} ) { const history = useHistory(); - const { pathArg, middlewares } = useContext( ConfigContext ); + const { pathArg, beforeNavigate } = useContext( ConfigContext ); function onClick( event: React.SyntheticEvent< HTMLAnchorElement > ) { event?.preventDefault(); history.navigate( to, options ); @@ -25,11 +19,10 @@ export function useLink( to: string, options: NavigationOptions = {} ) { const query = getQueryArgs( to ); const path = getPath( 'http://domain.com/' + to ) ?? ''; const link = useMemo( () => { - const runMiddlewares = ( - middlewares ? compose( ...middlewares ) : ( i: unknown ) => i - ) as Middleware; - return runMiddlewares( { path, query } ); - }, [ path, query, middlewares ] ); + return beforeNavigate + ? beforeNavigate( { path, query } ) + : { path, query }; + }, [ path, query, beforeNavigate ] ); const [ before ] = window.location.href.split( '?' ); diff --git a/packages/router/src/router.tsx b/packages/router/src/router.tsx index a199c7c49c612..9f8f704367584 100644 --- a/packages/router/src/router.tsx +++ b/packages/router/src/router.tsx @@ -19,7 +19,6 @@ import { getPath, buildQueryString, } from '@wordpress/url'; -import { compose } from '@wordpress/compose'; /** * Internal dependencies @@ -47,7 +46,7 @@ interface Match { params?: Record< string, any >; } -export type Middleware = ( arg: { +export type BeforeNavigate = ( arg: { path: string; query: Record< string, any >; } ) => { @@ -57,7 +56,7 @@ export type Middleware = ( arg: { interface Config { pathArg: string; - middlewares?: Middleware[]; + beforeNavigate?: BeforeNavigate; } export interface NavigationOptions { @@ -87,19 +86,16 @@ export function useLocation() { } export function useHistory() { - const { pathArg, middlewares } = useContext( ConfigContext ); + const { pathArg, beforeNavigate } = useContext( ConfigContext ); return useMemo( () => ( { navigate( rawPath: string, options: NavigationOptions = {} ) { - const runMiddlewares = ( - middlewares - ? compose( ...middlewares ) - : ( i: unknown ) => i - ) as Middleware; const query = getQueryArgs( rawPath ); const path = getPath( 'http://domain.com/' + rawPath ) ?? ''; const performPush = () => { - const result = runMiddlewares( { path, query } ); + const result = beforeNavigate + ? beforeNavigate( { path, query } ) + : { path, query }; return history.push( { search: buildQueryString( { @@ -137,7 +133,7 @@ export function useHistory() { } ); }, } ), - [ pathArg, middlewares ] + [ pathArg, beforeNavigate ] ); } @@ -196,12 +192,12 @@ export default function useMatch( export function RouterProvider( { routes, pathArg, - middlewares, + beforeNavigate, children, }: { routes: Route[]; pathArg: string; - middlewares?: Middleware[]; + beforeNavigate?: BeforeNavigate; children: React.ReactNode; } ) { const location = useSyncExternalStore( @@ -211,8 +207,8 @@ export function RouterProvider( { ); const match = useMatch( location, routes, pathArg ); const config = useMemo( - () => ( { middlewares, pathArg } ), - [ middlewares, pathArg ] + () => ( { beforeNavigate, pathArg } ), + [ beforeNavigate, pathArg ] ); return ( diff --git a/packages/router/tsconfig.json b/packages/router/tsconfig.json index 8706b546ff304..a9bd549048b24 100644 --- a/packages/router/tsconfig.json +++ b/packages/router/tsconfig.json @@ -7,7 +7,6 @@ "types": [ "gutenberg-env" ] }, "references": [ - { "path": "../compose" }, { "path": "../element" }, { "path": "../private-apis" }, { "path": "../url" } From e8ec07ac6ab6c5027be242253bd27b30e4ace949 Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Mon, 25 Nov 2024 13:27:08 +0100 Subject: [PATCH 12/26] Filter instead of action --- lib/experimental/site-editor-permalinks.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/experimental/site-editor-permalinks.php b/lib/experimental/site-editor-permalinks.php index 71b6fcaf016da..1321f9883baab 100644 --- a/lib/experimental/site-editor-permalinks.php +++ b/lib/experimental/site-editor-permalinks.php @@ -1,6 +1,6 @@ Date: Mon, 25 Nov 2024 13:42:30 +0100 Subject: [PATCH 13/26] Move the code to 6.8 folder --- .../wordpress-6.8/site-editor.php} | 9 ++++++++- lib/load.php | 2 +- 2 files changed, 9 insertions(+), 2 deletions(-) rename lib/{experimental/site-editor-permalinks.php => compat/wordpress-6.8/site-editor.php} (97%) diff --git a/lib/experimental/site-editor-permalinks.php b/lib/compat/wordpress-6.8/site-editor.php similarity index 97% rename from lib/experimental/site-editor-permalinks.php rename to lib/compat/wordpress-6.8/site-editor.php index 1321f9883baab..0b394c7f35959 100644 --- a/lib/experimental/site-editor-permalinks.php +++ b/lib/compat/wordpress-6.8/site-editor.php @@ -1,4 +1,11 @@ Date: Mon, 25 Nov 2024 14:15:06 +0100 Subject: [PATCH 14/26] Refactor deprecations --- lib/compat/wordpress-6.8/site-editor.php | 65 ++++++++++-------------- 1 file changed, 28 insertions(+), 37 deletions(-) diff --git a/lib/compat/wordpress-6.8/site-editor.php b/lib/compat/wordpress-6.8/site-editor.php index 0b394c7f35959..b34b0224aac3e 100644 --- a/lib/compat/wordpress-6.8/site-editor.php +++ b/lib/compat/wordpress-6.8/site-editor.php @@ -44,98 +44,89 @@ function gutenberg_get_posts_dataviews_url( $path = '', $query = array() ) { return $query_string ? $base_url . '?' . $query_string : $base_url; } -function gutenberg_redirect_site_editor_to_design() { +function gutenberg_get_site_editor_redirection() { global $pagenow; if ( 'site-editor.php' !== $pagenow || isset( $_REQUEST['p'] ) || ! $_SERVER['QUERY_STRING'] ) { - return; + return false; } // The following redirects are for the new permalinks in the site editor. if ( isset( $_REQUEST['postType'] ) && 'wp_navigation' === $_REQUEST['postType'] && ! empty( $_REQUEST['postId'] ) ) { - wp_redirect( gutenberg_get_site_editor_url( '/wp_navigation/' . $_REQUEST['postId'], gutenberg_remove_query_args( array( 'postType', 'postId' ) ) ), 301 ); - exit; + return gutenberg_get_site_editor_url( '/wp_navigation/' . $_REQUEST['postId'], gutenberg_remove_query_args( array( 'postType', 'postId' ) ) ); } if ( isset( $_REQUEST['postType'] ) && 'wp_navigation' === $_REQUEST['postType'] && empty( $_REQUEST['postId'] ) ) { - wp_redirect( gutenberg_get_site_editor_url( '/navigation', gutenberg_remove_query_args( array( 'postType' ) ) ), 301 ); - exit; + return gutenberg_get_site_editor_url( '/navigation', gutenberg_remove_query_args( array( 'postType' ) ) ); } if ( isset( $_REQUEST['path'] ) && '/wp_global_styles' === $_REQUEST['path'] ) { - wp_redirect( gutenberg_get_site_editor_url( '/styles', gutenberg_remove_query_args( array( 'path' ) ) ), 301 ); - exit; + return gutenberg_get_site_editor_url( '/styles', gutenberg_remove_query_args( array( 'path' ) ) ); } if ( isset( $_REQUEST['postType'] ) && 'page' === $_REQUEST['postType'] && ( empty( $_REQUEST['canvas'] ) || empty( $_REQUEST['postId'] ) ) ) { - wp_redirect( gutenberg_get_site_editor_url( '/page', gutenberg_remove_query_args( array( 'postType' ) ) ), 301 ); - exit; + return gutenberg_get_site_editor_url( '/page', gutenberg_remove_query_args( array( 'postType' ) ) ); } if ( isset( $_REQUEST['postType'] ) && 'page' === $_REQUEST['postType'] && ! empty( $_REQUEST['postId'] ) ) { - wp_redirect( gutenberg_get_site_editor_url( '/page/' . $_REQUEST['postId'], gutenberg_remove_query_args( array( 'postType', 'postId' ) ) ), 301 ); - exit; + return gutenberg_get_site_editor_url( '/page/' . $_REQUEST['postId'], gutenberg_remove_query_args( array( 'postType', 'postId' ) ) ); } if ( isset( $_REQUEST['postType'] ) && 'wp_template' === $_REQUEST['postType'] && ( empty( $_REQUEST['canvas'] ) || empty( $_REQUEST['postId'] ) ) ) { - wp_redirect( gutenberg_get_site_editor_url( '/template', gutenberg_remove_query_args( array( 'postType' ) ) ), 301 ); - exit; + return gutenberg_get_site_editor_url( '/template', gutenberg_remove_query_args( array( 'postType' ) ) ); } if ( isset( $_REQUEST['postType'] ) && 'wp_template' === $_REQUEST['postType'] && ! empty( $_REQUEST['postId'] ) ) { - wp_redirect( gutenberg_get_site_editor_url( '/wp_template/' . $_REQUEST['postId'], gutenberg_remove_query_args( array( 'postType', 'postId' ) ) ), 301 ); - exit; + return gutenberg_get_site_editor_url( '/wp_template/' . $_REQUEST['postId'], gutenberg_remove_query_args( array( 'postType', 'postId' ) ) ); } if ( isset( $_REQUEST['postType'] ) && 'wp_block' === $_REQUEST['postType'] && ( empty( $_REQUEST['canvas'] ) || empty( $_REQUEST['postId'] ) ) ) { - wp_redirect( gutenberg_get_site_editor_url( '/pattern', gutenberg_remove_query_args( array( 'postType' ) ) ), 301 ); - exit; + return gutenberg_get_site_editor_url( '/pattern', gutenberg_remove_query_args( array( 'postType' ) ) ); } if ( isset( $_REQUEST['postType'] ) && 'wp_block' === $_REQUEST['postType'] && ! empty( $_REQUEST['postId'] ) ) { - wp_redirect( gutenberg_get_site_editor_url( '/wp_block/' . $_REQUEST['postId'], gutenberg_remove_query_args( array( 'postType', 'postId' ) ) ), 301 ); - exit; + return gutenberg_get_site_editor_url( '/wp_block/' . $_REQUEST['postId'], gutenberg_remove_query_args( array( 'postType', 'postId' ) ) ); } if ( isset( $_REQUEST['postType'] ) && 'wp_template_part' === $_REQUEST['postType'] && ( empty( $_REQUEST['canvas'] ) || empty( $_REQUEST['postId'] ) ) ) { - wp_redirect( gutenberg_get_site_editor_url( '/pattern', gutenberg_remove_query_args() ), 301 ); - exit; + return gutenberg_get_site_editor_url( '/pattern', gutenberg_remove_query_args() ); } if ( isset( $_REQUEST['postType'] ) && 'wp_template_part' === $_REQUEST['postType'] && ! empty( $_REQUEST['postId'] ) ) { - wp_redirect( gutenberg_get_site_editor_url( '/wp_template_part/' . $_REQUEST['postId'], gutenberg_remove_query_args( array( 'postType', 'postId' ) ) ), 301 ); - exit; + return gutenberg_get_site_editor_url( '/wp_template_part/' . $_REQUEST['postId'], gutenberg_remove_query_args( array( 'postType', 'postId' ) ) ); } // The following redirects are for backward compatibility with the old site editor URLs. if ( isset( $_REQUEST['path'] ) && '/wp_template_part/all' === $_REQUEST['path'] ) { - wp_redirect( gutenberg_get_site_editor_url( '/pattern?postType=wp_template_part', gutenberg_remove_query_args( 'path' ) ), 301 ); - exit; + return gutenberg_get_site_editor_url( '/pattern?postType=wp_template_part', gutenberg_remove_query_args( 'path' ) ); } if ( isset( $_REQUEST['path'] ) && '/page' === $_REQUEST['path'] ) { - wp_redirect( gutenberg_get_site_editor_url( '/page', gutenberg_remove_query_args( 'path' ) ), 301 ); - exit; + return gutenberg_get_site_editor_url( '/page', gutenberg_remove_query_args( 'path' ) ); } if ( isset( $_REQUEST['path'] ) && '/wp_template' === $_REQUEST['path'] ) { - wp_redirect( gutenberg_get_site_editor_url( '/template', gutenberg_remove_query_args( 'path' ) ), 301 ); - exit; + return gutenberg_get_site_editor_url( '/template', gutenberg_remove_query_args( 'path' ) ); } if ( isset( $_REQUEST['path'] ) && '/patterns' === $_REQUEST['path'] ) { - wp_redirect( gutenberg_get_site_editor_url( '/pattern', gutenberg_remove_query_args( 'path' ) ), 301 ); - exit; + return gutenberg_get_site_editor_url( '/pattern', gutenberg_remove_query_args( 'path' ) ); } if ( isset( $_REQUEST['path'] ) && '/navigation' === $_REQUEST['path'] ) { - wp_redirect( gutenberg_get_site_editor_url( '/navigation', gutenberg_remove_query_args( 'path' ) ), 301 ); - exit; + return gutenberg_get_site_editor_url( '/navigation', gutenberg_remove_query_args( 'path' ) ); } - wp_redirect( gutenberg_get_site_editor_url( '', gutenberg_remove_query_args() ), 301 ); - exit; + return gutenberg_get_site_editor_url( '', gutenberg_remove_query_args() ); +} + +function gutenberg_redirect_site_editor_deprecated_urls() { + $redirection = gutenberg_get_site_editor_redirection(); + if ( false !== $redirection ) { + wp_redirect( $redirection, 301 ); + exit; + } } -add_action( 'admin_init', 'gutenberg_redirect_site_editor_to_design' ); +add_action( 'admin_init', 'gutenberg_redirect_site_editor_deprecated_urls' ); function gutenberg_redirect_posts_dataviews_to_post() { global $pagenow; From 5a51c5a545eb6177acfe9ab2e9eb67cbc909c495 Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Mon, 25 Nov 2024 14:15:32 +0100 Subject: [PATCH 15/26] Set the right path to avoid redirections --- lib/compat/wordpress-6.8/site-editor.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/compat/wordpress-6.8/site-editor.php b/lib/compat/wordpress-6.8/site-editor.php index b34b0224aac3e..e7f791d3ee7cf 100644 --- a/lib/compat/wordpress-6.8/site-editor.php +++ b/lib/compat/wordpress-6.8/site-editor.php @@ -10,7 +10,7 @@ add_filter( 'block_editor_settings_all', function ( $settings ) { - $settings['__experimentalDashboardLink'] = admin_url(); + $settings['__experimentalDashboardLink'] = admin_url( '/' ); return $settings; } ); From b03d30498bfd938c685e267374b7ceb64c7a5c27 Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Mon, 25 Nov 2024 15:16:12 +0100 Subject: [PATCH 16/26] Fix e2e tests --- lib/compat/wordpress-6.8/site-editor.php | 10 +- .../src/admin-navigation-commands.js | 6 +- .../src/site-editor-navigation-commands.js | 143 ++++++++---------- .../editor/various/pattern-overrides.spec.js | 12 +- .../specs/site-editor/browser-history.spec.js | 4 +- .../specs/site-editor/command-center.spec.js | 2 +- .../specs/site-editor/hybrid-theme.spec.js | 2 +- .../site-editor-url-navigation.spec.js | 4 +- 8 files changed, 88 insertions(+), 95 deletions(-) diff --git a/lib/compat/wordpress-6.8/site-editor.php b/lib/compat/wordpress-6.8/site-editor.php index e7f791d3ee7cf..8ea5fad2c0f7f 100644 --- a/lib/compat/wordpress-6.8/site-editor.php +++ b/lib/compat/wordpress-6.8/site-editor.php @@ -97,23 +97,23 @@ function gutenberg_get_site_editor_redirection() { // The following redirects are for backward compatibility with the old site editor URLs. if ( isset( $_REQUEST['path'] ) && '/wp_template_part/all' === $_REQUEST['path'] ) { - return gutenberg_get_site_editor_url( '/pattern?postType=wp_template_part', gutenberg_remove_query_args( 'path' ) ); + return gutenberg_get_site_editor_url( '/pattern', array_merge( array( 'postType' => 'wp_template_part' ), gutenberg_remove_query_args( array( 'path' ) ) ) ); } if ( isset( $_REQUEST['path'] ) && '/page' === $_REQUEST['path'] ) { - return gutenberg_get_site_editor_url( '/page', gutenberg_remove_query_args( 'path' ) ); + return gutenberg_get_site_editor_url( '/page', gutenberg_remove_query_args( array( 'path' ) ) ); } if ( isset( $_REQUEST['path'] ) && '/wp_template' === $_REQUEST['path'] ) { - return gutenberg_get_site_editor_url( '/template', gutenberg_remove_query_args( 'path' ) ); + return gutenberg_get_site_editor_url( '/template', gutenberg_remove_query_args( array( 'path' ) ) ); } if ( isset( $_REQUEST['path'] ) && '/patterns' === $_REQUEST['path'] ) { - return gutenberg_get_site_editor_url( '/pattern', gutenberg_remove_query_args( 'path' ) ); + return gutenberg_get_site_editor_url( '/pattern', gutenberg_remove_query_args( array( 'path' ) ) ); } if ( isset( $_REQUEST['path'] ) && '/navigation' === $_REQUEST['path'] ) { - return gutenberg_get_site_editor_url( '/navigation', gutenberg_remove_query_args( 'path' ) ); + return gutenberg_get_site_editor_url( '/navigation', gutenberg_remove_query_args( array( 'path' ) ) ); } return gutenberg_get_site_editor_url( '', gutenberg_remove_query_args() ); diff --git a/packages/core-commands/src/admin-navigation-commands.js b/packages/core-commands/src/admin-navigation-commands.js index 8a8167bb29b82..f82faa05baae4 100644 --- a/packages/core-commands/src/admin-navigation-commands.js +++ b/packages/core-commands/src/admin-navigation-commands.js @@ -44,11 +44,7 @@ const getAddNewPageCommand = () => } ); if ( page?.id ) { - history.push( { - postId: page.id, - postType: 'page', - canvas: 'edit', - } ); + history.navigate( `/page/${ page.id }?canvas=edit` ); } } catch ( error ) { const errorMessage = diff --git a/packages/core-commands/src/site-editor-navigation-commands.js b/packages/core-commands/src/site-editor-navigation-commands.js index 2785d809d41e0..c1b12a84d4d61 100644 --- a/packages/core-commands/src/site-editor-navigation-commands.js +++ b/packages/core-commands/src/site-editor-navigation-commands.js @@ -136,19 +136,18 @@ const getNavigationCommandLoaderPerPostType = ( postType ) => return { ...command, callback: ( { close } ) => { - const args = { - postType, - postId: record.id, - canvas: 'edit', - }; - const targetUrl = addQueryArgs( - 'site-editor.php', - args - ); if ( isSiteEditor ) { - history.push( args ); + history.navigate( + `/${ postType }/${ record.id }?canvas=edit` + ); } else { - document.location = targetUrl; + document.location = addQueryArgs( + 'site-editor.php', + { + p: `/${ postType }/${ record.id }`, + canvas: 'edit', + } + ); } close(); }, @@ -220,19 +219,18 @@ const getNavigationCommandLoaderPerTemplate = ( templateType ) => : __( '(no title)' ), icon: icons[ templateType ], callback: ( { close } ) => { - const args = { - postType: templateType, - postId: record.id, - canvas: 'edit', - }; - const targetUrl = addQueryArgs( - 'site-editor.php', - args - ); if ( isSiteEditor ) { - history.push( args ); + history.navigate( + `/${ templateType }/${ record.id }?canvas=edit` + ); } else { - document.location = targetUrl; + document.location = addQueryArgs( + 'site-editor.php', + { + p: `/${ templateType }/${ record.id }`, + canvas: 'edit', + } + ); } close(); }, @@ -249,18 +247,19 @@ const getNavigationCommandLoaderPerTemplate = ( templateType ) => label: __( 'Template parts' ), icon: symbolFilled, callback: ( { close } ) => { - const args = { - postType: 'wp_template_part', - categoryId: 'all-parts', - }; - const targetUrl = addQueryArgs( - 'site-editor.php', - args - ); if ( isSiteEditor ) { - history.push( args ); + history.navigate( + '/pattern?postType=wp_template_part&categoryId=all-parts' + ); } else { - document.location = targetUrl; + document.location = addQueryArgs( + 'site-editor.php', + { + p: '/pattern', + postType: 'wp_template_part', + categoryId: 'all-parts', + } + ); } close(); }, @@ -303,17 +302,15 @@ const getSiteEditorBasicNavigationCommands = () => label: __( 'Navigation' ), icon: navigation, callback: ( { close } ) => { - const args = { - postType: 'wp_navigation', - }; - const targetUrl = addQueryArgs( - 'site-editor.php', - args - ); if ( isSiteEditor ) { - history.push( args ); + history.navigate( '/navigation' ); } else { - document.location = targetUrl; + document.location = addQueryArgs( + 'site-editor.php', + { + p: '/navigation', + } + ); } close(); }, @@ -324,17 +321,15 @@ const getSiteEditorBasicNavigationCommands = () => label: __( 'Styles' ), icon: styles, callback: ( { close } ) => { - const args = { - path: '/wp_global_styles', - }; - const targetUrl = addQueryArgs( - 'site-editor.php', - args - ); if ( isSiteEditor ) { - history.push( args ); + history.navigate( '/styles' ); } else { - document.location = targetUrl; + document.location = addQueryArgs( + 'site-editor.php', + { + p: '/styles', + } + ); } close(); }, @@ -345,17 +340,15 @@ const getSiteEditorBasicNavigationCommands = () => label: __( 'Pages' ), icon: page, callback: ( { close } ) => { - const args = { - postType: 'page', - }; - const targetUrl = addQueryArgs( - 'site-editor.php', - args - ); if ( isSiteEditor ) { - history.push( args ); + history.navigate( '/page' ); } else { - document.location = targetUrl; + document.location = addQueryArgs( + 'site-editor.php', + { + p: '/page', + } + ); } close(); }, @@ -366,17 +359,15 @@ const getSiteEditorBasicNavigationCommands = () => label: __( 'Templates' ), icon: layout, callback: ( { close } ) => { - const args = { - postType: 'wp_template', - }; - const targetUrl = addQueryArgs( - 'site-editor.php', - args - ); if ( isSiteEditor ) { - history.push( args ); + history.navigate( '/template' ); } else { - document.location = targetUrl; + document.location = addQueryArgs( + 'site-editor.php', + { + p: '/template', + } + ); } close(); }, @@ -389,17 +380,15 @@ const getSiteEditorBasicNavigationCommands = () => icon: symbol, callback: ( { close } ) => { if ( canCreateTemplate ) { - const args = { - postType: 'wp_block', - }; - const targetUrl = addQueryArgs( - 'site-editor.php', - args - ); if ( isSiteEditor ) { - history.push( args ); + history.navigate( '/pattern' ); } else { - document.location = targetUrl; + document.location = addQueryArgs( + 'site-editor.php', + { + p: '/pattern', + } + ); } close(); } else { diff --git a/test/e2e/specs/editor/various/pattern-overrides.spec.js b/test/e2e/specs/editor/various/pattern-overrides.spec.js index 6f4a592930052..246048686d150 100644 --- a/test/e2e/specs/editor/various/pattern-overrides.spec.js +++ b/test/e2e/specs/editor/various/pattern-overrides.spec.js @@ -128,7 +128,11 @@ test.describe( 'Pattern Overrides', () => { page.getByRole( 'button', { name: 'Dismiss this notice' } ) ).toBeVisible(); - patternId = new URL( page.url() ).searchParams.get( 'postId' ); + patternId = await page.evaluate( () => { + return window.wp.data + .select( 'core/editor' ) + .getCurrentPostId(); + } ); } ); await test.step( 'Create a post and insert the pattern with overrides', async () => { @@ -993,7 +997,11 @@ test.describe( 'Pattern Overrides', () => { page.getByRole( 'button', { name: 'Dismiss this notice' } ) ).toBeVisible(); - patternId = new URL( page.url() ).searchParams.get( 'postId' ); + patternId = await page.evaluate( () => { + return window.wp.data + .select( 'core/editor' ) + .getCurrentPostId(); + } ); } ); await test.step( 'create a post and insert the pattern with synced values', async () => { diff --git a/test/e2e/specs/site-editor/browser-history.spec.js b/test/e2e/specs/site-editor/browser-history.spec.js index eaafb3aad1b3f..a2326d10e3cc5 100644 --- a/test/e2e/specs/site-editor/browser-history.spec.js +++ b/test/e2e/specs/site-editor/browser-history.spec.js @@ -21,13 +21,13 @@ test.describe( 'Site editor browser history', () => { await page.click( 'role=button[name="Templates"]' ); await page.getByRole( 'link', { name: 'Index' } ).click(); await expect( page ).toHaveURL( - '/wp-admin/site-editor.php?postId=emptytheme%2F%2Findex&postType=wp_template&canvas=edit' + '/wp-admin/site-editor.php?p=%2Fwp_template%2Femptytheme%2F%2Findex&canvas=edit' ); // Navigate back to the template list await page.goBack(); await expect( page ).toHaveURL( - '/wp-admin/site-editor.php?postType=wp_template' + '/wp-admin/site-editor.php?p=%2Ftemplate' ); // Navigate back to the dashboard diff --git a/test/e2e/specs/site-editor/command-center.spec.js b/test/e2e/specs/site-editor/command-center.spec.js index 19318081aa171..197a01c43c8b4 100644 --- a/test/e2e/specs/site-editor/command-center.spec.js +++ b/test/e2e/specs/site-editor/command-center.spec.js @@ -28,7 +28,7 @@ test.describe( 'Site editor command palette', () => { await page.keyboard.type( 'new page' ); await page.getByRole( 'option', { name: 'Add new page' } ).click(); await expect( page ).toHaveURL( - /\/wp-admin\/site-editor.php\?postId=(\d+)&postType=page&canvas=edit/ + /\/wp-admin\/site-editor.php\?p=%2Fpage%2F(\d+)&canvas=edit/ ); await expect( editor.canvas diff --git a/test/e2e/specs/site-editor/hybrid-theme.spec.js b/test/e2e/specs/site-editor/hybrid-theme.spec.js index b568aaf4445b5..58dcceb5b3600 100644 --- a/test/e2e/specs/site-editor/hybrid-theme.spec.js +++ b/test/e2e/specs/site-editor/hybrid-theme.spec.js @@ -33,7 +33,7 @@ test.describe( 'Hybrid theme', () => { ); await expect( page ).toHaveURL( - '/wp-admin/site-editor.php?postType=wp_template_part' + '/wp-admin/site-editor.php?postType=wp_template_part&p=/pattern' ); await expect( diff --git a/test/e2e/specs/site-editor/site-editor-url-navigation.spec.js b/test/e2e/specs/site-editor/site-editor-url-navigation.spec.js index f26fb8e13b8c3..a0cc0af5463ae 100644 --- a/test/e2e/specs/site-editor/site-editor-url-navigation.spec.js +++ b/test/e2e/specs/site-editor/site-editor-url-navigation.spec.js @@ -44,7 +44,7 @@ test.describe( 'Site editor url navigation', () => { .click(); await page.getByRole( 'option', { name: 'Demo' } ).click(); await expect( page ).toHaveURL( - '/wp-admin/site-editor.php?postId=emptytheme%2F%2Fsingle-post-demo&postType=wp_template&canvas=edit' + '/wp-admin/site-editor.php?p=%2Fwp_template%2Femptytheme%2F%2Fsingle-post-demo&canvas=edit' ); } ); @@ -63,7 +63,7 @@ test.describe( 'Site editor url navigation', () => { await page.type( 'role=dialog >> role=textbox[name="Name"i]', 'Demo' ); await page.keyboard.press( 'Enter' ); await expect( page ).toHaveURL( - '/wp-admin/site-editor.php?postId=emptytheme%2F%2Fdemo&postType=wp_template_part&canvas=edit' + '/wp-admin/site-editor.php?p=%2Fwp_template_part%2Femptytheme%2F%2Fdemo&canvas=edit' ); } ); From 551674f28a2e3d6e8b75ec43ebd8266a7163423a Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Mon, 25 Nov 2024 17:31:00 +0100 Subject: [PATCH 17/26] Fix hybrid themes --- lib/compat/wordpress-6.8/site-editor.php | 16 ++++++++++++++++ test/e2e/specs/site-editor/hybrid-theme.spec.js | 2 +- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/lib/compat/wordpress-6.8/site-editor.php b/lib/compat/wordpress-6.8/site-editor.php index 8ea5fad2c0f7f..3ae5dbf0d418d 100644 --- a/lib/compat/wordpress-6.8/site-editor.php +++ b/lib/compat/wordpress-6.8/site-editor.php @@ -144,3 +144,19 @@ function gutenberg_redirect_posts_dataviews_to_post() { } add_action( 'admin_init', 'gutenberg_redirect_posts_dataviews_to_post' ); + + +/** + * Filter the `wp_die_handler` to allow access to the Site Editor's new pages page + * for Classic themes. + * + * @param callable $default_handler The default handler. + * @return callable The default handler or a custom handler. + */ +function gutenberg_styles_wp_die_handler( $default_handler ) { + if ( ! wp_is_block_theme() && str_contains( $_SERVER['REQUEST_URI'], 'site-editor.php' ) && isset( $_GET['p'] ) ) { + return '__return_false'; + } + return $default_handler; +} +add_filter( 'wp_die_handler', 'gutenberg_styles_wp_die_handler' ); diff --git a/test/e2e/specs/site-editor/hybrid-theme.spec.js b/test/e2e/specs/site-editor/hybrid-theme.spec.js index 58dcceb5b3600..d763c8f0640d9 100644 --- a/test/e2e/specs/site-editor/hybrid-theme.spec.js +++ b/test/e2e/specs/site-editor/hybrid-theme.spec.js @@ -33,7 +33,7 @@ test.describe( 'Hybrid theme', () => { ); await expect( page ).toHaveURL( - '/wp-admin/site-editor.php?postType=wp_template_part&p=/pattern' + '/wp-admin/site-editor.php?postType=wp_template_part&p=%2Fpattern' ); await expect( From 0bce3bac1b58ad78f87c0385a8f7b61129f62660 Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Tue, 26 Nov 2024 11:20:00 +0100 Subject: [PATCH 18/26] Simplify redirects --- lib/compat/wordpress-6.8/site-editor.php | 55 ++++++++++-------------- 1 file changed, 23 insertions(+), 32 deletions(-) diff --git a/lib/compat/wordpress-6.8/site-editor.php b/lib/compat/wordpress-6.8/site-editor.php index 3ae5dbf0d418d..305f4000005f9 100644 --- a/lib/compat/wordpress-6.8/site-editor.php +++ b/lib/compat/wordpress-6.8/site-editor.php @@ -15,21 +15,6 @@ function ( $settings ) { } ); -function gutenberg_remove_query_args( $args = array() ) { - $query_string = $_SERVER['QUERY_STRING']; - $query = wp_parse_args( $query_string ); - foreach ( $args as $arg_name ) { - unset( $query[ $arg_name ] ); - } - return $query; -} - -function gutenberg_get_site_editor_url( $path = '', $query = array() ) { - $query_string = build_query( array_merge( $query, array( 'p' => $path ) ) ); - $base_url = admin_url( 'site-editor.php' ); - return $query_string ? $base_url . '?' . $query_string : $base_url; -} - function gutenberg_get_posts_dataviews_url( $path = '', $query = array() ) { $query_string = build_query( array_merge( @@ -52,71 +37,77 @@ function gutenberg_get_site_editor_redirection() { // The following redirects are for the new permalinks in the site editor. if ( isset( $_REQUEST['postType'] ) && 'wp_navigation' === $_REQUEST['postType'] && ! empty( $_REQUEST['postId'] ) ) { - return gutenberg_get_site_editor_url( '/wp_navigation/' . $_REQUEST['postId'], gutenberg_remove_query_args( array( 'postType', 'postId' ) ) ); + return add_query_arg( array( 'p' => '/wp_navigation/' . $_REQUEST['postId'] ), remove_query_arg( array( 'postType', 'postId' ) ) ); } if ( isset( $_REQUEST['postType'] ) && 'wp_navigation' === $_REQUEST['postType'] && empty( $_REQUEST['postId'] ) ) { - return gutenberg_get_site_editor_url( '/navigation', gutenberg_remove_query_args( array( 'postType' ) ) ); + return add_query_arg( array( 'p' => '/navigation' ), remove_query_arg( 'postType' ) ); } if ( isset( $_REQUEST['path'] ) && '/wp_global_styles' === $_REQUEST['path'] ) { - return gutenberg_get_site_editor_url( '/styles', gutenberg_remove_query_args( array( 'path' ) ) ); + return add_query_arg( array( 'p' => '/styles' ), remove_query_arg( 'path' ) ); } if ( isset( $_REQUEST['postType'] ) && 'page' === $_REQUEST['postType'] && ( empty( $_REQUEST['canvas'] ) || empty( $_REQUEST['postId'] ) ) ) { - return gutenberg_get_site_editor_url( '/page', gutenberg_remove_query_args( array( 'postType' ) ) ); + return add_query_arg( array( 'p' => '/page' ), remove_query_arg( 'postType' ) ); } if ( isset( $_REQUEST['postType'] ) && 'page' === $_REQUEST['postType'] && ! empty( $_REQUEST['postId'] ) ) { - return gutenberg_get_site_editor_url( '/page/' . $_REQUEST['postId'], gutenberg_remove_query_args( array( 'postType', 'postId' ) ) ); + return add_query_arg( array( 'p' => '/page/' . $_REQUEST['postId'] ), remove_query_arg( array( 'postType', 'postId' ) ) ); } if ( isset( $_REQUEST['postType'] ) && 'wp_template' === $_REQUEST['postType'] && ( empty( $_REQUEST['canvas'] ) || empty( $_REQUEST['postId'] ) ) ) { - return gutenberg_get_site_editor_url( '/template', gutenberg_remove_query_args( array( 'postType' ) ) ); + return add_query_arg( array( 'p' => '/template' ), remove_query_arg( 'postType' ) ); } if ( isset( $_REQUEST['postType'] ) && 'wp_template' === $_REQUEST['postType'] && ! empty( $_REQUEST['postId'] ) ) { - return gutenberg_get_site_editor_url( '/wp_template/' . $_REQUEST['postId'], gutenberg_remove_query_args( array( 'postType', 'postId' ) ) ); + return add_query_arg( array( 'p' => '/wp_template/' . $_REQUEST['postId'] ), remove_query_arg( array( 'postType', 'postId' ) ) ); } if ( isset( $_REQUEST['postType'] ) && 'wp_block' === $_REQUEST['postType'] && ( empty( $_REQUEST['canvas'] ) || empty( $_REQUEST['postId'] ) ) ) { - return gutenberg_get_site_editor_url( '/pattern', gutenberg_remove_query_args( array( 'postType' ) ) ); + return add_query_arg( array( 'p' => '/pattern' ), remove_query_arg( 'postType' ) ); } if ( isset( $_REQUEST['postType'] ) && 'wp_block' === $_REQUEST['postType'] && ! empty( $_REQUEST['postId'] ) ) { - return gutenberg_get_site_editor_url( '/wp_block/' . $_REQUEST['postId'], gutenberg_remove_query_args( array( 'postType', 'postId' ) ) ); + return add_query_arg( array( 'p' => '/wp_block/' . $_REQUEST['postId'] ), remove_query_arg( array( 'postType', 'postId' ) ) ); } if ( isset( $_REQUEST['postType'] ) && 'wp_template_part' === $_REQUEST['postType'] && ( empty( $_REQUEST['canvas'] ) || empty( $_REQUEST['postId'] ) ) ) { - return gutenberg_get_site_editor_url( '/pattern', gutenberg_remove_query_args() ); + return add_query_arg( array( 'p' => '/pattern' ) ); } if ( isset( $_REQUEST['postType'] ) && 'wp_template_part' === $_REQUEST['postType'] && ! empty( $_REQUEST['postId'] ) ) { - return gutenberg_get_site_editor_url( '/wp_template_part/' . $_REQUEST['postId'], gutenberg_remove_query_args( array( 'postType', 'postId' ) ) ); + return add_query_arg( array( 'p' => '/wp_template_part/' . $_REQUEST['postId'] ), remove_query_arg( array( 'postType', 'postId' ) ) ); } // The following redirects are for backward compatibility with the old site editor URLs. if ( isset( $_REQUEST['path'] ) && '/wp_template_part/all' === $_REQUEST['path'] ) { - return gutenberg_get_site_editor_url( '/pattern', array_merge( array( 'postType' => 'wp_template_part' ), gutenberg_remove_query_args( array( 'path' ) ) ) ); + return add_query_arg( + array( + 'p' => '/pattern', + 'postType' => 'wp_template_part', + ), + remove_query_arg( 'path' ) + ); } if ( isset( $_REQUEST['path'] ) && '/page' === $_REQUEST['path'] ) { - return gutenberg_get_site_editor_url( '/page', gutenberg_remove_query_args( array( 'path' ) ) ); + return add_query_arg( array( 'p' => '/page' ), remove_query_arg( 'path' ) ); } if ( isset( $_REQUEST['path'] ) && '/wp_template' === $_REQUEST['path'] ) { - return gutenberg_get_site_editor_url( '/template', gutenberg_remove_query_args( array( 'path' ) ) ); + return add_query_arg( array( 'p' => '/template' ), remove_query_arg( 'path' ) ); } if ( isset( $_REQUEST['path'] ) && '/patterns' === $_REQUEST['path'] ) { - return gutenberg_get_site_editor_url( '/pattern', gutenberg_remove_query_args( array( 'path' ) ) ); + return add_query_arg( array( 'p' => '/pattern' ), remove_query_arg( 'path' ) ); } if ( isset( $_REQUEST['path'] ) && '/navigation' === $_REQUEST['path'] ) { - return gutenberg_get_site_editor_url( '/navigation', gutenberg_remove_query_args( array( 'path' ) ) ); + return add_query_arg( array( 'p' => '/navigation' ), remove_query_arg( 'path' ) ); } - return gutenberg_get_site_editor_url( '', gutenberg_remove_query_args() ); + return add_query_arg( array( 'p' => '/' ) ); } function gutenberg_redirect_site_editor_deprecated_urls() { From 29eb79899a98fc3426e984956e6b12368ef321e1 Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Tue, 26 Nov 2024 11:23:12 +0100 Subject: [PATCH 19/26] Add useLocation check --- packages/router/src/router.tsx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/router/src/router.tsx b/packages/router/src/router.tsx index 9f8f704367584..19703fe06e7d2 100644 --- a/packages/router/src/router.tsx +++ b/packages/router/src/router.tsx @@ -82,7 +82,11 @@ function getLocationWithQuery() { } export function useLocation() { - return useContext( RoutesContext ); + const context = useContext( RoutesContext ); + if ( ! context ) { + throw new Error( 'useLocation must be used within a RouterProvider' ); + } + return context; } export function useHistory() { From ff1411c3c534988d2124a18e24de1f0e2463e924 Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Tue, 26 Nov 2024 11:30:17 +0100 Subject: [PATCH 20/26] useEvent to avoid memoization --- package-lock.json | 1 + packages/router/package.json | 1 + packages/router/src/router.tsx | 94 ++++++++++++++++++---------------- packages/router/tsconfig.json | 1 + 4 files changed, 53 insertions(+), 44 deletions(-) diff --git a/package-lock.json b/package-lock.json index ec7e6a89b2044..dc0c18f3b6ac5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -55569,6 +55569,7 @@ "license": "GPL-2.0-or-later", "dependencies": { "@babel/runtime": "7.25.7", + "@wordpress/compose": "*", "@wordpress/element": "*", "@wordpress/private-apis": "*", "@wordpress/url": "*", diff --git a/packages/router/package.json b/packages/router/package.json index 9b86cbb7e8c41..66a64f4ddc5ba 100644 --- a/packages/router/package.json +++ b/packages/router/package.json @@ -29,6 +29,7 @@ "types": "build-types", "dependencies": { "@babel/runtime": "7.25.7", + "@wordpress/compose": "*", "@wordpress/element": "*", "@wordpress/private-apis": "*", "@wordpress/url": "*", diff --git a/packages/router/src/router.tsx b/packages/router/src/router.tsx index 19703fe06e7d2..cca74b207ae0a 100644 --- a/packages/router/src/router.tsx +++ b/packages/router/src/router.tsx @@ -19,6 +19,7 @@ import { getPath, buildQueryString, } from '@wordpress/url'; +import { useEvent } from '@wordpress/compose'; /** * Internal dependencies @@ -91,53 +92,58 @@ export function useLocation() { export function useHistory() { const { pathArg, beforeNavigate } = useContext( ConfigContext ); - return useMemo( - () => ( { - navigate( rawPath: string, options: NavigationOptions = {} ) { - const query = getQueryArgs( rawPath ); - const path = getPath( 'http://domain.com/' + rawPath ) ?? ''; - const performPush = () => { - const result = beforeNavigate - ? beforeNavigate( { path, query } ) - : { path, query }; - return history.push( - { - search: buildQueryString( { - [ pathArg ]: result.path, - ...result.query, - } ), - }, - options.state - ); - }; - - /* - * Skip transition in mobile, otherwise it crashes the browser. - * See: https://github.com/WordPress/gutenberg/pull/63002. - */ - const isMediumOrBigger = - window.matchMedia( '(min-width: 782px)' ).matches; - if ( - ! isMediumOrBigger || - // @ts-expect-error - ! document.startViewTransition || - ! options.transition - ) { - return performPush(); - } - document.documentElement.classList.add( options.transition ); + + const navigate = useEvent( + ( rawPath: string, options: NavigationOptions = {} ) => { + const query = getQueryArgs( rawPath ); + const path = getPath( 'http://domain.com/' + rawPath ) ?? ''; + const performPush = () => { + const result = beforeNavigate + ? beforeNavigate( { path, query } ) + : { path, query }; + return history.push( + { + search: buildQueryString( { + [ pathArg ]: result.path, + ...result.query, + } ), + }, + options.state + ); + }; + + /* + * Skip transition in mobile, otherwise it crashes the browser. + * See: https://github.com/WordPress/gutenberg/pull/63002. + */ + const isMediumOrBigger = + window.matchMedia( '(min-width: 782px)' ).matches; + if ( + ! isMediumOrBigger || // @ts-expect-error - const transition = document.startViewTransition( () => - performPush() + ! document.startViewTransition || + ! options.transition + ) { + return performPush(); + } + document.documentElement.classList.add( options.transition ); + // @ts-expect-error + const transition = document.startViewTransition( () => + performPush() + ); + transition.finished.finally( () => { + document.documentElement.classList.remove( + options.transition ?? '' ); - transition.finished.finally( () => { - document.documentElement.classList.remove( - options.transition ?? '' - ); - } ); - }, + } ); + } + ); + + return useMemo( + () => ( { + navigate, } ), - [ pathArg, beforeNavigate ] + [ navigate ] ); } diff --git a/packages/router/tsconfig.json b/packages/router/tsconfig.json index a9bd549048b24..8706b546ff304 100644 --- a/packages/router/tsconfig.json +++ b/packages/router/tsconfig.json @@ -7,6 +7,7 @@ "types": [ "gutenberg-env" ] }, "references": [ + { "path": "../compose" }, { "path": "../element" }, { "path": "../private-apis" }, { "path": "../url" } From e46b7ef62500b4d04b8a53ed8f1c80df855550eb Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Wed, 27 Nov 2024 10:30:21 +0100 Subject: [PATCH 21/26] Return a promise from navigate --- packages/router/src/router.tsx | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/packages/router/src/router.tsx b/packages/router/src/router.tsx index cca74b207ae0a..ff2400baf8f92 100644 --- a/packages/router/src/router.tsx +++ b/packages/router/src/router.tsx @@ -94,7 +94,7 @@ export function useHistory() { const { pathArg, beforeNavigate } = useContext( ConfigContext ); const navigate = useEvent( - ( rawPath: string, options: NavigationOptions = {} ) => { + async ( rawPath: string, options: NavigationOptions = {} ) => { const query = getQueryArgs( rawPath ); const path = getPath( 'http://domain.com/' + rawPath ) ?? ''; const performPush = () => { @@ -124,17 +124,20 @@ export function useHistory() { ! document.startViewTransition || ! options.transition ) { - return performPush(); + performPush(); } - document.documentElement.classList.add( options.transition ); - // @ts-expect-error - const transition = document.startViewTransition( () => - performPush() - ); - transition.finished.finally( () => { - document.documentElement.classList.remove( - options.transition ?? '' + + await new Promise< void >( ( resolve ) => { + const classname = options.transition ?? ''; + document.documentElement.classList.add( classname ); + // @ts-expect-error + const transition = document.startViewTransition( () => + performPush() ); + transition.finished.finally( () => { + document.documentElement.classList.remove( classname ); + resolve(); + } ); } ); } ); From 544fe66860232c18872b01afcf92f509b8c09a16 Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Wed, 27 Nov 2024 10:33:52 +0100 Subject: [PATCH 22/26] Memoize route recognizer --- packages/router/src/router.tsx | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/packages/router/src/router.tsx b/packages/router/src/router.tsx index ff2400baf8f92..ea0b218fa6a40 100644 --- a/packages/router/src/router.tsx +++ b/packages/router/src/router.tsx @@ -152,18 +152,12 @@ export function useHistory() { export default function useMatch( location: LocationWithQuery, - routes: Route[], + matcher: RouteRecognizer, pathArg: string ): Match { const { query: rawQuery = {} } = location; return useMemo( () => { - const matcher = new RouteRecognizer(); - routes.forEach( ( route ) => { - matcher.add( [ { path: route.path, handler: route } ], { - as: route.name, - } ); - } ); const { [ pathArg ]: path = '/', ...query } = rawQuery; const result = matcher.recognize( path )?.[ 0 ]; if ( ! result ) { @@ -199,7 +193,7 @@ export default function useMatch( query, path: addQueryArgs( path, query ), }; - }, [ routes, rawQuery, pathArg ] ); + }, [ matcher, rawQuery, pathArg ] ); } export function RouterProvider( { @@ -218,7 +212,16 @@ export function RouterProvider( { getLocationWithQuery, getLocationWithQuery ); - const match = useMatch( location, routes, pathArg ); + const matcher = useMemo( () => { + const ret = new RouteRecognizer(); + routes.forEach( ( route ) => { + ret.add( [ { path: route.path, handler: route } ], { + as: route.name, + } ); + } ); + return ret; + }, [ routes ] ); + const match = useMatch( location, matcher, pathArg ); const config = useMemo( () => ( { beforeNavigate, pathArg } ), [ beforeNavigate, pathArg ] From 97a7ee7fe71e6f7696d080542c06489351b04a05 Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Wed, 27 Nov 2024 11:21:03 +0100 Subject: [PATCH 23/26] Add a comment --- lib/compat/wordpress-6.8/site-editor.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/compat/wordpress-6.8/site-editor.php b/lib/compat/wordpress-6.8/site-editor.php index 305f4000005f9..7ad0c89456c4c 100644 --- a/lib/compat/wordpress-6.8/site-editor.php +++ b/lib/compat/wordpress-6.8/site-editor.php @@ -141,6 +141,9 @@ function gutenberg_redirect_posts_dataviews_to_post() { * Filter the `wp_die_handler` to allow access to the Site Editor's new pages page * for Classic themes. * + * site-editor.php's access is forbidden for hybrid/classic themes and only allowed with some very special query args (some very special pages like template parts...). + * The only way to disable this protection since we're changing the urls in Gutenberg is to override the wp_die_handler. + * * @param callable $default_handler The default handler. * @return callable The default handler or a custom handler. */ From 233fa6b9f549ae1a247796eacb868cfef9c568df Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Wed, 27 Nov 2024 11:44:40 +0100 Subject: [PATCH 24/26] Fix e2e test --- test/e2e/specs/site-editor/hybrid-theme.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/e2e/specs/site-editor/hybrid-theme.spec.js b/test/e2e/specs/site-editor/hybrid-theme.spec.js index d763c8f0640d9..042cb1042cac2 100644 --- a/test/e2e/specs/site-editor/hybrid-theme.spec.js +++ b/test/e2e/specs/site-editor/hybrid-theme.spec.js @@ -33,7 +33,7 @@ test.describe( 'Hybrid theme', () => { ); await expect( page ).toHaveURL( - '/wp-admin/site-editor.php?postType=wp_template_part&p=%2Fpattern' + '/wp-admin/site-editor.php?p=%2Fpattern&postType=wp_template_part' ); await expect( From 7fb975ed9b1eecf2028c3000dde01586f4d276b6 Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Wed, 27 Nov 2024 13:37:05 +0100 Subject: [PATCH 25/26] Add backport PR --- backport-changelog/6.8/7903.md | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 backport-changelog/6.8/7903.md diff --git a/backport-changelog/6.8/7903.md b/backport-changelog/6.8/7903.md new file mode 100644 index 0000000000000..cb20d8d2dd2b1 --- /dev/null +++ b/backport-changelog/6.8/7903.md @@ -0,0 +1,3 @@ +https://github.com/WordPress/wordpress-develop/pull/7903 + +* https://github.com/WordPress/gutenberg/pull/67199 From 2e4c03da18b95730a771263ed8dd26c00eade983 Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Wed, 27 Nov 2024 13:38:10 +0100 Subject: [PATCH 26/26] Remove posts redirectins --- lib/compat/wordpress-6.8/site-editor.php | 32 ------------------------ 1 file changed, 32 deletions(-) diff --git a/lib/compat/wordpress-6.8/site-editor.php b/lib/compat/wordpress-6.8/site-editor.php index 7ad0c89456c4c..cde108830b1d2 100644 --- a/lib/compat/wordpress-6.8/site-editor.php +++ b/lib/compat/wordpress-6.8/site-editor.php @@ -15,20 +15,6 @@ function ( $settings ) { } ); -function gutenberg_get_posts_dataviews_url( $path = '', $query = array() ) { - $query_string = build_query( - array_merge( - $query, - $path ? array( - 'page' => 'gutenberg-posts-dashboard', - 'p' => $path, - ) : array( 'page' => 'gutenberg-posts-dashboard' ) - ) - ); - $base_url = admin_url( 'admin.php' ); - return $query_string ? $base_url . '?' . $query_string : $base_url; -} - function gutenberg_get_site_editor_redirection() { global $pagenow; if ( 'site-editor.php' !== $pagenow || isset( $_REQUEST['p'] ) || ! $_SERVER['QUERY_STRING'] ) { @@ -119,24 +105,6 @@ function gutenberg_redirect_site_editor_deprecated_urls() { } add_action( 'admin_init', 'gutenberg_redirect_site_editor_deprecated_urls' ); -function gutenberg_redirect_posts_dataviews_to_post() { - global $pagenow; - if ( - 'admin.php' !== $pagenow || - ! isset( $_REQUEST['page'] ) || - 'gutenberg-posts-dashboard' !== $_REQUEST['page'] || - isset( $_REQUEST['p'] ) - ) { - return; - } - - wp_redirect( gutenberg_get_posts_dataviews_url( '/' ), 301 ); - exit; -} - -add_action( 'admin_init', 'gutenberg_redirect_posts_dataviews_to_post' ); - - /** * Filter the `wp_die_handler` to allow access to the Site Editor's new pages page * for Classic themes.