REST API: Support custom namespaces for custom post types.

While a custom post type can define a custom route by using the `rest_base` argument, a namespace of `wp/v2` was assumed. This commit introduces support for a `rest_namespace` argument. 

A new `rest_get_route_for_post_type_items` function has been introduced and the `rest_get_route_for_post` function updated to facilitate getting the correct route for custom post types.

While the WordPress Core Block Editor bootstrap code has been updated to use these API functions, for maximum compatibility sticking with the default `wp/v2` namespace is recommended until the API functions see wider use.

Props spacedmonkey, swissspidy.
Fixes #53656.

Built from https://develop.svn.wordpress.org/trunk@51962


git-svn-id: http://core.svn.wordpress.org/trunk@51551 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This commit is contained in:
TimothyBlynJacobs
2021-10-31 23:16:58 +00:00
parent c60a9d92e2
commit bac6e41c85
14 changed files with 95 additions and 48 deletions

View File

@@ -3049,24 +3049,12 @@ function rest_get_route_for_post( $post ) {
return '';
}
$post_type = get_post_type_object( $post->post_type );
if ( ! $post_type ) {
$post_type_route = rest_get_route_for_post_type_items( $post->post_type );
if ( ! $post_type_route ) {
return '';
}
$controller = $post_type->get_rest_controller();
if ( ! $controller ) {
return '';
}
$route = '';
// The only two controllers that we can detect are the Attachments and Posts controllers.
if ( in_array( get_class( $controller ), array( 'WP_REST_Attachments_Controller', 'WP_REST_Posts_Controller' ), true ) ) {
$namespace = 'wp/v2';
$rest_base = ! empty( $post_type->rest_base ) ? $post_type->rest_base : $post_type->name;
$route = sprintf( '/%s/%s/%d', $namespace, $rest_base, $post->ID );
}
$route = sprintf( '%s/%d', $post_type_route, $post->ID );
/**
* Filters the REST API route for a post.
@@ -3079,6 +3067,39 @@ function rest_get_route_for_post( $post ) {
return apply_filters( 'rest_route_for_post', $route, $post );
}
/**
* Gets the REST API route for a post type.
*
* @since 5.9.0
*
* @param string $post_type The name of a registered post type.
* @return string The route path with a leading slash for the given post type, or an empty string if there is not a route.
*/
function rest_get_route_for_post_type_items( $post_type ) {
$post_type = get_post_type_object( $post_type );
if ( ! $post_type ) {
return '';
}
if ( ! $post_type->show_in_rest ) {
return '';
}
$namespace = ! empty( $post_type->rest_namespace ) ? $post_type->rest_namespace : 'wp/v2';
$rest_base = ! empty( $post_type->rest_base ) ? $post_type->rest_base : $post_type->name;
$route = sprintf( '/%s/%s', $namespace, $rest_base );
/**
* Filters the REST API route for a post type.
*
* @since 5.9.0
*
* @param string $route The route path.
* @param WP_Post_Type $post_type The post type object.
*/
return apply_filters( 'rest_route_for_post_type_items', $route, $post_type );
}
/**
* Gets the REST API route for a term.
*