diff --git a/lib/experimental/site-editor-permalinks.php b/lib/experimental/site-editor-permalinks.php index babd3b8005caf9..fa14b681df75fe 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 fde4d312ebe848..715326c3018c21 100644 --- a/packages/edit-site/src/components/app/index.js +++ b/packages/edit-site/src/components/app/index.js @@ -54,7 +54,7 @@ export default function App() { - + diff --git a/packages/edit-site/src/components/posts-app/index.js b/packages/edit-site/src/components/posts-app/index.js index 491cfa5f88d370..714c1da2a614a1 100644 --- a/packages/edit-site/src/components/posts-app/index.js +++ b/packages/edit-site/src/components/posts-app/index.js @@ -27,7 +27,7 @@ export default function PostsApp() { return ( - + diff --git a/packages/router/src/link.tsx b/packages/router/src/link.tsx index 1aa3c1a5ba479c..96715720dc1087 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 8e36a39f891cd6..9e203003fce7cf 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 (