REST API: Include permalink_template/generated_slug for Posts
In order for clients to present permalink previews, the REST API must share the computed results of get_sample_permalink(). These two values are now exposed as permalink_template and generated_slug for public, viewable post types, but only for context=edit. Merges [43720] to trunk. Props danielbachhuber, rahulsprajapati. Fixes #45017. git-svn-id: https://develop.svn.wordpress.org/trunk@43980 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
parent
c0e80b028a
commit
894a8e02d2
@ -1587,6 +1587,23 @@ class WP_REST_Posts_Controller extends WP_REST_Controller {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$post_type_obj = get_post_type_object( $post->post_type );
|
||||||
|
if ( is_post_type_viewable( $post_type_obj ) && $post_type_obj->public ) {
|
||||||
|
|
||||||
|
if ( ! function_exists( 'get_sample_permalink' ) ) {
|
||||||
|
require_once ABSPATH . '/wp-admin/includes/post.php';
|
||||||
|
}
|
||||||
|
|
||||||
|
$sample_permalink = get_sample_permalink( $post->ID, $post->post_title, '' );
|
||||||
|
|
||||||
|
if ( in_array( 'permalink_template', $fields, true ) ) {
|
||||||
|
$data['permalink_template'] = $sample_permalink[0];
|
||||||
|
}
|
||||||
|
if ( in_array( 'generated_slug', $fields, true ) ) {
|
||||||
|
$data['generated_slug'] = $sample_permalink[1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$context = ! empty( $request['context'] ) ? $request['context'] : 'view';
|
$context = ! empty( $request['context'] ) ? $request['context'] : 'view';
|
||||||
$data = $this->add_additional_fields_to_object( $data, $request );
|
$data = $this->add_additional_fields_to_object( $data, $request );
|
||||||
$data = $this->filter_response_by_context( $data, $context );
|
$data = $this->filter_response_by_context( $data, $context );
|
||||||
@ -1918,6 +1935,21 @@ class WP_REST_Posts_Controller extends WP_REST_Controller {
|
|||||||
);
|
);
|
||||||
|
|
||||||
$post_type_obj = get_post_type_object( $this->post_type );
|
$post_type_obj = get_post_type_object( $this->post_type );
|
||||||
|
if ( is_post_type_viewable( $post_type_obj ) && $post_type_obj->public ) {
|
||||||
|
$schema['properties']['permalink_template'] = array(
|
||||||
|
'description' => __( 'Permalink template for the object.' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'context' => array( 'edit' ),
|
||||||
|
'readonly' => true,
|
||||||
|
);
|
||||||
|
|
||||||
|
$schema['properties']['generated_slug'] = array(
|
||||||
|
'description' => __( 'Slug automatically generated from the object title.' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'context' => array( 'edit' ),
|
||||||
|
'readonly' => true,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
if ( $post_type_obj->hierarchical ) {
|
if ( $post_type_obj->hierarchical ) {
|
||||||
$schema['properties']['parent'] = array(
|
$schema['properties']['parent'] = array(
|
||||||
|
@ -40,7 +40,7 @@ abstract class WP_Test_REST_Controller_Testcase extends WP_Test_REST_TestCase {
|
|||||||
abstract public function test_get_item_schema();
|
abstract public function test_get_item_schema();
|
||||||
|
|
||||||
public function filter_rest_url_for_leading_slash( $url, $path ) {
|
public function filter_rest_url_for_leading_slash( $url, $path ) {
|
||||||
if ( is_multisite() ) {
|
if ( is_multisite() || get_option( 'permalink_structure' ) ) {
|
||||||
return $url;
|
return $url;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1295,7 +1295,7 @@ class WP_Test_REST_Attachments_Controller extends WP_Test_REST_Post_Type_Control
|
|||||||
$response = rest_get_server()->dispatch( $request );
|
$response = rest_get_server()->dispatch( $request );
|
||||||
$data = $response->get_data();
|
$data = $response->get_data();
|
||||||
$properties = $data['schema']['properties'];
|
$properties = $data['schema']['properties'];
|
||||||
$this->assertEquals( 24, count( $properties ) );
|
$this->assertEquals( 26, count( $properties ) );
|
||||||
$this->assertArrayHasKey( 'author', $properties );
|
$this->assertArrayHasKey( 'author', $properties );
|
||||||
$this->assertArrayHasKey( 'alt_text', $properties );
|
$this->assertArrayHasKey( 'alt_text', $properties );
|
||||||
$this->assertArrayHasKey( 'caption', $properties );
|
$this->assertArrayHasKey( 'caption', $properties );
|
||||||
@ -1307,6 +1307,7 @@ class WP_Test_REST_Attachments_Controller extends WP_Test_REST_Post_Type_Control
|
|||||||
$this->assertArrayHasKey( 'comment_status', $properties );
|
$this->assertArrayHasKey( 'comment_status', $properties );
|
||||||
$this->assertArrayHasKey( 'date', $properties );
|
$this->assertArrayHasKey( 'date', $properties );
|
||||||
$this->assertArrayHasKey( 'date_gmt', $properties );
|
$this->assertArrayHasKey( 'date_gmt', $properties );
|
||||||
|
$this->assertArrayHasKey( 'generated_slug', $properties );
|
||||||
$this->assertArrayHasKey( 'guid', $properties );
|
$this->assertArrayHasKey( 'guid', $properties );
|
||||||
$this->assertArrayHasKey( 'id', $properties );
|
$this->assertArrayHasKey( 'id', $properties );
|
||||||
$this->assertArrayHasKey( 'link', $properties );
|
$this->assertArrayHasKey( 'link', $properties );
|
||||||
@ -1318,6 +1319,7 @@ class WP_Test_REST_Attachments_Controller extends WP_Test_REST_Post_Type_Control
|
|||||||
$this->assertArrayHasKey( 'modified_gmt', $properties );
|
$this->assertArrayHasKey( 'modified_gmt', $properties );
|
||||||
$this->assertArrayHasKey( 'post', $properties );
|
$this->assertArrayHasKey( 'post', $properties );
|
||||||
$this->assertArrayHasKey( 'ping_status', $properties );
|
$this->assertArrayHasKey( 'ping_status', $properties );
|
||||||
|
$this->assertArrayHasKey( 'permalink_template', $properties );
|
||||||
$this->assertArrayHasKey( 'status', $properties );
|
$this->assertArrayHasKey( 'status', $properties );
|
||||||
$this->assertArrayHasKey( 'slug', $properties );
|
$this->assertArrayHasKey( 'slug', $properties );
|
||||||
$this->assertArrayHasKey( 'source_url', $properties );
|
$this->assertArrayHasKey( 'source_url', $properties );
|
||||||
|
@ -678,12 +678,13 @@ class WP_Test_REST_Pages_Controller extends WP_Test_REST_Post_Type_Controller_Te
|
|||||||
$response = rest_get_server()->dispatch( $request );
|
$response = rest_get_server()->dispatch( $request );
|
||||||
$data = $response->get_data();
|
$data = $response->get_data();
|
||||||
$properties = $data['schema']['properties'];
|
$properties = $data['schema']['properties'];
|
||||||
$this->assertEquals( 22, count( $properties ) );
|
$this->assertEquals( 24, count( $properties ) );
|
||||||
$this->assertArrayHasKey( 'author', $properties );
|
$this->assertArrayHasKey( 'author', $properties );
|
||||||
$this->assertArrayHasKey( 'comment_status', $properties );
|
$this->assertArrayHasKey( 'comment_status', $properties );
|
||||||
$this->assertArrayHasKey( 'content', $properties );
|
$this->assertArrayHasKey( 'content', $properties );
|
||||||
$this->assertArrayHasKey( 'date', $properties );
|
$this->assertArrayHasKey( 'date', $properties );
|
||||||
$this->assertArrayHasKey( 'date_gmt', $properties );
|
$this->assertArrayHasKey( 'date_gmt', $properties );
|
||||||
|
$this->assertArrayHasKey( 'generated_slug', $properties );
|
||||||
$this->assertArrayHasKey( 'guid', $properties );
|
$this->assertArrayHasKey( 'guid', $properties );
|
||||||
$this->assertArrayHasKey( 'excerpt', $properties );
|
$this->assertArrayHasKey( 'excerpt', $properties );
|
||||||
$this->assertArrayHasKey( 'featured_media', $properties );
|
$this->assertArrayHasKey( 'featured_media', $properties );
|
||||||
@ -695,6 +696,7 @@ class WP_Test_REST_Pages_Controller extends WP_Test_REST_Post_Type_Controller_Te
|
|||||||
$this->assertArrayHasKey( 'modified_gmt', $properties );
|
$this->assertArrayHasKey( 'modified_gmt', $properties );
|
||||||
$this->assertArrayHasKey( 'parent', $properties );
|
$this->assertArrayHasKey( 'parent', $properties );
|
||||||
$this->assertArrayHasKey( 'password', $properties );
|
$this->assertArrayHasKey( 'password', $properties );
|
||||||
|
$this->assertArrayHasKey( 'permalink_template', $properties );
|
||||||
$this->assertArrayHasKey( 'ping_status', $properties );
|
$this->assertArrayHasKey( 'ping_status', $properties );
|
||||||
$this->assertArrayHasKey( 'slug', $properties );
|
$this->assertArrayHasKey( 'slug', $properties );
|
||||||
$this->assertArrayHasKey( 'status', $properties );
|
$this->assertArrayHasKey( 'status', $properties );
|
||||||
|
@ -3479,7 +3479,7 @@ class WP_Test_REST_Posts_Controller extends WP_Test_REST_Post_Type_Controller_Te
|
|||||||
$response = rest_get_server()->dispatch( $request );
|
$response = rest_get_server()->dispatch( $request );
|
||||||
$data = $response->get_data();
|
$data = $response->get_data();
|
||||||
$properties = $data['schema']['properties'];
|
$properties = $data['schema']['properties'];
|
||||||
$this->assertEquals( 24, count( $properties ) );
|
$this->assertEquals( 26, count( $properties ) );
|
||||||
$this->assertArrayHasKey( 'author', $properties );
|
$this->assertArrayHasKey( 'author', $properties );
|
||||||
$this->assertArrayHasKey( 'comment_status', $properties );
|
$this->assertArrayHasKey( 'comment_status', $properties );
|
||||||
$this->assertArrayHasKey( 'content', $properties );
|
$this->assertArrayHasKey( 'content', $properties );
|
||||||
@ -3487,6 +3487,7 @@ class WP_Test_REST_Posts_Controller extends WP_Test_REST_Post_Type_Controller_Te
|
|||||||
$this->assertArrayHasKey( 'date_gmt', $properties );
|
$this->assertArrayHasKey( 'date_gmt', $properties );
|
||||||
$this->assertArrayHasKey( 'excerpt', $properties );
|
$this->assertArrayHasKey( 'excerpt', $properties );
|
||||||
$this->assertArrayHasKey( 'featured_media', $properties );
|
$this->assertArrayHasKey( 'featured_media', $properties );
|
||||||
|
$this->assertArrayHasKey( 'generated_slug', $properties );
|
||||||
$this->assertArrayHasKey( 'guid', $properties );
|
$this->assertArrayHasKey( 'guid', $properties );
|
||||||
$this->assertArrayHasKey( 'format', $properties );
|
$this->assertArrayHasKey( 'format', $properties );
|
||||||
$this->assertArrayHasKey( 'id', $properties );
|
$this->assertArrayHasKey( 'id', $properties );
|
||||||
@ -3495,6 +3496,7 @@ class WP_Test_REST_Posts_Controller extends WP_Test_REST_Post_Type_Controller_Te
|
|||||||
$this->assertArrayHasKey( 'modified', $properties );
|
$this->assertArrayHasKey( 'modified', $properties );
|
||||||
$this->assertArrayHasKey( 'modified_gmt', $properties );
|
$this->assertArrayHasKey( 'modified_gmt', $properties );
|
||||||
$this->assertArrayHasKey( 'password', $properties );
|
$this->assertArrayHasKey( 'password', $properties );
|
||||||
|
$this->assertArrayHasKey( 'permalink_template', $properties );
|
||||||
$this->assertArrayHasKey( 'ping_status', $properties );
|
$this->assertArrayHasKey( 'ping_status', $properties );
|
||||||
$this->assertArrayHasKey( 'slug', $properties );
|
$this->assertArrayHasKey( 'slug', $properties );
|
||||||
$this->assertArrayHasKey( 'status', $properties );
|
$this->assertArrayHasKey( 'status', $properties );
|
||||||
@ -3564,6 +3566,7 @@ class WP_Test_REST_Posts_Controller extends WP_Test_REST_Post_Type_Controller_Te
|
|||||||
'excerpt',
|
'excerpt',
|
||||||
'featured_media',
|
'featured_media',
|
||||||
'format',
|
'format',
|
||||||
|
'generated_slug',
|
||||||
'guid',
|
'guid',
|
||||||
'id',
|
'id',
|
||||||
'link',
|
'link',
|
||||||
@ -3571,6 +3574,7 @@ class WP_Test_REST_Posts_Controller extends WP_Test_REST_Post_Type_Controller_Te
|
|||||||
'modified',
|
'modified',
|
||||||
'modified_gmt',
|
'modified_gmt',
|
||||||
'password',
|
'password',
|
||||||
|
'permalink_template',
|
||||||
'ping_status',
|
'ping_status',
|
||||||
'slug',
|
'slug',
|
||||||
'status',
|
'status',
|
||||||
@ -4086,7 +4090,76 @@ class WP_Test_REST_Posts_Controller extends WP_Test_REST_Post_Type_Controller_Te
|
|||||||
$this->assertArrayNotHasKey( 'https://api.w.org/action-unfiltered-html', $links );
|
$this->assertArrayNotHasKey( 'https://api.w.org/action-unfiltered-html', $links );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function test_generated_permalink_template_generated_slug_for_non_viewable_posts() {
|
||||||
|
register_post_type(
|
||||||
|
'private-post',
|
||||||
|
array(
|
||||||
|
'label' => 'Private Posts',
|
||||||
|
'supports' => array( 'title', 'editor', 'author' ),
|
||||||
|
'show_in_rest' => true,
|
||||||
|
'publicly_queryable' => false,
|
||||||
|
'public' => true,
|
||||||
|
'rest_base' => 'private-post',
|
||||||
|
)
|
||||||
|
);
|
||||||
|
create_initial_rest_routes();
|
||||||
|
|
||||||
|
wp_set_current_user( self::$editor_id );
|
||||||
|
|
||||||
|
$post_id = $this->factory->post->create(
|
||||||
|
array(
|
||||||
|
'post_title' => 'Permalink Template',
|
||||||
|
'post_type' => 'private-post',
|
||||||
|
'post_status' => 'draft',
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
// Neither 'permalink_template' and 'generated_slug' are expected for this post type.
|
||||||
|
$request = new WP_REST_Request( 'GET', '/wp/v2/private-post/' . $post_id );
|
||||||
|
$request->set_param( 'context', 'edit' );
|
||||||
|
$response = rest_get_server()->dispatch( $request );
|
||||||
|
$data = $response->get_data();
|
||||||
|
$this->assertEquals( 200, $response->get_status() );
|
||||||
|
$this->assertArrayNotHasKey( 'permalink_template', $data );
|
||||||
|
$this->assertArrayNotHasKey( 'generated_slug', $data );
|
||||||
|
}
|
||||||
|
|
||||||
|
public function test_generated_permalink_template_generated_slug_for_posts() {
|
||||||
|
$this->set_permalink_structure( '/%postname%/' );
|
||||||
|
$expected_permalink_template = trailingslashit( home_url( '/%postname%/' ) );
|
||||||
|
|
||||||
|
wp_set_current_user( self::$editor_id );
|
||||||
|
|
||||||
|
$post_id = $this->factory->post->create(
|
||||||
|
array(
|
||||||
|
'post_title' => 'Permalink Template',
|
||||||
|
'post_type' => 'post',
|
||||||
|
'post_status' => 'draft',
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
// Both 'permalink_template' and 'generated_slug' are expected for context=edit.
|
||||||
|
$request = new WP_REST_Request( 'GET', '/wp/v2/posts/' . $post_id );
|
||||||
|
$request->set_param( 'context', 'edit' );
|
||||||
|
$response = rest_get_server()->dispatch( $request );
|
||||||
|
$data = $response->get_data();
|
||||||
|
$this->assertEquals( 200, $response->get_status() );
|
||||||
|
$this->assertEquals( $expected_permalink_template, $data['permalink_template'] );
|
||||||
|
$this->assertEquals( 'permalink-template', $data['generated_slug'] );
|
||||||
|
|
||||||
|
// Neither 'permalink_template' and 'generated_slug' are expected for context=view.
|
||||||
|
$request = new WP_REST_Request( 'GET', '/wp/v2/posts/' . $post_id );
|
||||||
|
$request->set_param( 'context', 'view' );
|
||||||
|
$response = rest_get_server()->dispatch( $request );
|
||||||
|
$data = $response->get_data();
|
||||||
|
$this->assertEquals( 200, $response->get_status() );
|
||||||
|
$this->assertArrayNotHasKey( 'permalink_template', $data );
|
||||||
|
$this->assertArrayNotHasKey( 'generated_slug', $data );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public function tearDown() {
|
public function tearDown() {
|
||||||
|
_unregister_post_type( 'private-post' );
|
||||||
_unregister_post_type( 'youseeeme' );
|
_unregister_post_type( 'youseeeme' );
|
||||||
if ( isset( $this->attachment_id ) ) {
|
if ( isset( $this->attachment_id ) ) {
|
||||||
$this->remove_added_uploads();
|
$this->remove_added_uploads();
|
||||||
|
Loading…
Reference in New Issue
Block a user