Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
15f1913
Site Editor: Use permalinks instead of query args and site-editor.php…
youknowriad Nov 21, 2024
edd3075
Fix some bugs
youknowriad Nov 21, 2024
6a4cc01
Fix dashboard links
youknowriad Nov 21, 2024
937ebf0
Add basic redirection
youknowriad Nov 21, 2024
c3bff73
Add server side permanent redirects for the old urls
youknowriad Nov 21, 2024
2c0b7f7
Fix the posts dataviews
youknowriad Nov 21, 2024
3c9a42c
Small fix
youknowriad Nov 21, 2024
b811a48
Remove url rewrites
youknowriad Nov 21, 2024
5153567
Fix theme previewing
youknowriad Nov 25, 2024
bc404a3
Fix query string argument
youknowriad Nov 25, 2024
b4d15dc
switch middleware to beforeNavigate
youknowriad Nov 25, 2024
e8ec07a
Filter instead of action
youknowriad Nov 25, 2024
a3324ac
Move the code to 6.8 folder
youknowriad Nov 25, 2024
2b9d0bd
Refactor deprecations
youknowriad Nov 25, 2024
5a51c5a
Set the right path to avoid redirections
youknowriad Nov 25, 2024
b03d304
Fix e2e tests
youknowriad Nov 25, 2024
551674f
Fix hybrid themes
youknowriad Nov 25, 2024
0bce3ba
Simplify redirects
youknowriad Nov 26, 2024
29eb798
Add useLocation check
youknowriad Nov 26, 2024
ff1411c
useEvent to avoid memoization
youknowriad Nov 26, 2024
e46b7ef
Return a promise from navigate
youknowriad Nov 27, 2024
544fe66
Memoize route recognizer
youknowriad Nov 27, 2024
97a7ee7
Add a comment
youknowriad Nov 27, 2024
233fa6b
Fix e2e test
youknowriad Nov 27, 2024
7fb975e
Add backport PR
youknowriad Nov 27, 2024
2e4c03d
Remove posts redirectins
youknowriad Nov 27, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Remove url rewrites
  • Loading branch information
youknowriad committed Nov 27, 2024
commit b811a485a183def6fb96b621a8f852d1644f545d
79 changes: 41 additions & 38 deletions lib/experimental/site-editor-permalinks.php
Original file line number Diff line number Diff line change
@@ -1,22 +1,5 @@
<?php

function gutenberg_rewrite_wp_admin_permalinks() {
add_rewrite_rule(
'^wp-admin/design/?(.*)?',
'wp-admin/site-editor.php?p=$1',
'top'
);

add_rewrite_rule(
'^wp-admin/posts/?(.*)?',
'wp-admin/admin.php?page=gutenberg-posts-dashboard&p=$1',
'top'
);

flush_rewrite_rules();
}
add_action( 'init', 'gutenberg_rewrite_wp_admin_permalinks' );

add_action(
'block_editor_settings_all',
function ( $settings ) {
Expand All @@ -31,98 +14,118 @@ function gutenberg_remove_query_args( $args ) {
foreach ( $args as $arg_name ) {
unset( $query[ $arg_name ] );
}
return build_query( $query );
return $query;
}

function gutenberg_get_site_editor_url( $path = '', $query = array() ) {
$query_string = build_query( array_merge( $query, $path ? array( 'p' => $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' );
Expand All @@ -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;
}

Expand Down
2 changes: 1 addition & 1 deletion packages/edit-site/src/components/app/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ export default function App() {
}

return (
<RouterProvider routes={ routes } basePath="/wp-admin/design">
<RouterProvider routes={ routes } pathArg="p">
<AppLayout />
<PluginArea onError={ onPluginAreaError } />
</RouterProvider>
Expand Down
2 changes: 1 addition & 1 deletion packages/edit-site/src/components/posts-app/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export default function PostsApp() {
return unlock( select( editSiteStore ) ).getRoutes();
}, [] );
return (
<RouterProvider routes={ routes } basePath="/wp-admin/posts">
<RouterProvider routes={ routes } pathArg="p">
<Layout />
</RouterProvider>
);
Expand Down
12 changes: 9 additions & 3 deletions packages/router/src/link.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
* WordPress dependencies
*/
import { useContext } from '@wordpress/element';
import { getQueryArgs, getPath, buildQueryString } from '@wordpress/url';

/**
* Internal dependencies
Expand All @@ -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,
};
}
Expand Down
44 changes: 27 additions & 17 deletions packages/router/src/router.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -42,7 +47,7 @@ interface Match {
}

interface Config {
basePath: string;
pathArg: string;
}

export interface NavigationOptions {
Expand All @@ -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() {
Expand All @@ -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
);
};
Expand Down Expand Up @@ -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();
Expand All @@ -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 {
Expand Down Expand Up @@ -164,25 +174,25 @@ 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(
history.listen,
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 (
<ConfigContext.Provider value={ config }>
Expand Down