diff --git a/src/wp-includes/rest-api/endpoints/class-wp-rest-post-types-controller.php b/src/wp-includes/rest-api/endpoints/class-wp-rest-post-types-controller.php index 0d3d0e1279146..d766d5c61ddf8 100644 --- a/src/wp-includes/rest-api/endpoints/class-wp-rest-post-types-controller.php +++ b/src/wp-includes/rest-api/endpoints/class-wp-rest-post-types-controller.php @@ -246,6 +246,14 @@ public function prepare_item_for_response( $item, $request ) { $data['rest_namespace'] = $namespace; } + if ( rest_is_field_included( 'template', $fields ) ) { + $data['template'] = $post_type->template ?? array(); + } + + if ( rest_is_field_included( 'template_lock', $fields ) ) { + $data['template_lock'] = ! empty( $post_type->template_lock ) ? $post_type->template_lock : false; + } + $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; $data = $this->add_additional_fields_to_object( $data, $request ); $data = $this->filter_response_by_context( $data, $context ); @@ -407,6 +415,19 @@ public function get_item_schema() { 'context' => array( 'view', 'edit', 'embed' ), 'readonly' => true, ), + 'template' => array( + 'type' => array( 'array' ), + 'description' => __( 'The block template associated with the post type.' ), + 'readonly' => true, + 'context' => array( 'view', 'edit', 'embed' ), + ), + 'template_lock' => array( + 'type' => array( 'string', 'boolean' ), + 'enum' => array( 'all', 'insert', 'contentOnly', false ), + 'description' => __( 'The template_lock associated with the post type, or false if none.' ), + 'readonly' => true, + 'context' => array( 'view', 'edit', 'embed' ), + ), ), ); diff --git a/tests/phpunit/tests/rest-api/rest-post-types-controller.php b/tests/phpunit/tests/rest-api/rest-post-types-controller.php index c902aefbd375d..8967a507063a1 100644 --- a/tests/phpunit/tests/rest-api/rest-post-types-controller.php +++ b/tests/phpunit/tests/rest-api/rest-post-types-controller.php @@ -77,6 +77,27 @@ public function test_get_item_cpt() { $this->check_post_type_object_response( 'view', $response, 'cpt' ); } + /** + * @ticket 61477 + */ + public function test_get_item_template_cpt() { + register_post_type( + 'cpt_template', + array( + 'show_in_rest' => true, + 'rest_base' => 'cpt_template', + 'rest_namespace' => 'wordpress/v1', + 'template' => array( + array( 'core/paragraph', array( 'placeholder' => 'Content' ) ), + ), + 'template_lock' => 'all', + ) + ); + $request = new WP_REST_Request( 'GET', '/wp/v2/types/cpt_template' ); + $response = rest_get_server()->dispatch( $request ); + $this->check_post_type_object_response( 'view', $response, 'cpt_template' ); + } + public function test_get_item_page() { $request = new WP_REST_Request( 'GET', '/wp/v2/types/page' ); $response = rest_get_server()->dispatch( $request ); @@ -165,7 +186,7 @@ public function test_get_item_schema() { $data = $response->get_data(); $properties = $data['schema']['properties']; - $this->assertCount( 14, $properties, 'Schema should have 14 properties' ); + $this->assertCount( 16, $properties, 'Schema should have 16 properties' ); $this->assertArrayHasKey( 'capabilities', $properties, '`capabilities` should be included in the schema' ); $this->assertArrayHasKey( 'description', $properties, '`description` should be included in the schema' ); $this->assertArrayHasKey( 'hierarchical', $properties, '`hierarchical` should be included in the schema' ); @@ -180,6 +201,8 @@ public function test_get_item_schema() { $this->assertArrayHasKey( 'rest_namespace', $properties, '`rest_namespace` should be included in the schema' ); $this->assertArrayHasKey( 'visibility', $properties, '`visibility` should be included in the schema' ); $this->assertArrayHasKey( 'icon', $properties, '`icon` should be included in the schema' ); + $this->assertArrayHasKey( 'template', $properties, '`template` should be included in the schema' ); + $this->assertArrayHasKey( 'template_lock', $properties, '`template_lock` should be included in the schema' ); } public function test_get_additional_field_registration() { @@ -230,6 +253,8 @@ protected function check_post_type_obj( $context, $post_type_obj, $data, $links $this->assertSame( $post_type_obj->rest_base, $data['rest_base'] ); $this->assertSame( $post_type_obj->rest_namespace, $data['rest_namespace'] ); $this->assertSame( $post_type_obj->has_archive, $data['has_archive'] ); + $this->assertSame( $post_type_obj->template ?? array(), $data['template'] ); + $this->assertSame( ! empty( $post_type_obj->template_lock ) ? $post_type_obj->template_lock : false, $data['template_lock'] ); $links = test_rest_expand_compact_links( $links ); $this->assertSame( rest_url( 'wp/v2/types' ), $links['collection'][0]['href'] ); diff --git a/tests/qunit/fixtures/wp-api-generated.js b/tests/qunit/fixtures/wp-api-generated.js index 017a18ecaeb93..a5a2d3622eb0f 100644 --- a/tests/qunit/fixtures/wp-api-generated.js +++ b/tests/qunit/fixtures/wp-api-generated.js @@ -13014,6 +13014,8 @@ mockedApiResponse.TypesCollection = { ], "rest_base": "posts", "rest_namespace": "wp/v2", + "template": [], + "template_lock": false, "_links": { "collection": [ { @@ -13044,6 +13046,8 @@ mockedApiResponse.TypesCollection = { "taxonomies": [], "rest_base": "pages", "rest_namespace": "wp/v2", + "template": [], + "template_lock": false, "_links": { "collection": [ { @@ -13074,6 +13078,8 @@ mockedApiResponse.TypesCollection = { "taxonomies": [], "rest_base": "media", "rest_namespace": "wp/v2", + "template": [], + "template_lock": false, "_links": { "collection": [ { @@ -13106,6 +13112,8 @@ mockedApiResponse.TypesCollection = { ], "rest_base": "menu-items", "rest_namespace": "wp/v2", + "template": [], + "template_lock": false, "_links": { "collection": [ { @@ -13138,6 +13146,8 @@ mockedApiResponse.TypesCollection = { ], "rest_base": "blocks", "rest_namespace": "wp/v2", + "template": [], + "template_lock": false, "_links": { "collection": [ { @@ -13168,6 +13178,8 @@ mockedApiResponse.TypesCollection = { "taxonomies": [], "rest_base": "templates", "rest_namespace": "wp/v2", + "template": [], + "template_lock": false, "_links": { "collection": [ { @@ -13198,6 +13210,8 @@ mockedApiResponse.TypesCollection = { "taxonomies": [], "rest_base": "template-parts", "rest_namespace": "wp/v2", + "template": [], + "template_lock": false, "_links": { "collection": [ { @@ -13228,6 +13242,8 @@ mockedApiResponse.TypesCollection = { "taxonomies": [], "rest_base": "global-styles", "rest_namespace": "wp/v2", + "template": [], + "template_lock": false, "_links": { "collection": [ { @@ -13258,6 +13274,8 @@ mockedApiResponse.TypesCollection = { "taxonomies": [], "rest_base": "navigation", "rest_namespace": "wp/v2", + "template": [], + "template_lock": false, "_links": { "collection": [ { @@ -13288,6 +13306,8 @@ mockedApiResponse.TypesCollection = { "taxonomies": [], "rest_base": "font-families", "rest_namespace": "wp/v2", + "template": [], + "template_lock": false, "_links": { "collection": [ { @@ -13318,6 +13338,8 @@ mockedApiResponse.TypesCollection = { "taxonomies": [], "rest_base": "font-families/(?P[\\d]+)/font-faces", "rest_namespace": "wp/v2", + "template": [], + "template_lock": false, "_links": { "collection": [ { @@ -13352,7 +13374,9 @@ mockedApiResponse.TypeModel = { "post_tag" ], "rest_base": "posts", - "rest_namespace": "wp/v2" + "rest_namespace": "wp/v2", + "template": [], + "template_lock": false }; mockedApiResponse.StatusesCollection = {