REST API: Add additional fields to the themes controller.
When the themes controller was introduced it only returned a theme's supported features. This adds the majority of a theme's header information to the response. Props ockham, spacedmonkey. Fixes #49906. git-svn-id: https://develop.svn.wordpress.org/trunk@47921 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
parent
602faebb0d
commit
4fb1e58c50
@ -115,10 +115,65 @@ class WP_REST_Themes_Controller extends WP_REST_Controller {
|
||||
$data = array();
|
||||
$fields = $this->get_fields_for_response( $request );
|
||||
|
||||
if ( in_array( 'theme_supports', $fields, true ) ) {
|
||||
if ( rest_is_field_included( 'stylesheet', $fields ) ) {
|
||||
$data['stylesheet'] = $theme->get_stylesheet();
|
||||
}
|
||||
|
||||
if ( rest_is_field_included( 'template', $fields ) ) {
|
||||
/**
|
||||
* Use the get_template() method, not the 'Template' header, for finding the template.
|
||||
* The 'Template' header is only good for what was written in the style.css, while
|
||||
* get_template() takes into account where WordPress actually located the theme and
|
||||
* whether it is actually valid.
|
||||
*/
|
||||
$data['template'] = $theme->get_template();
|
||||
}
|
||||
|
||||
$plain_field_mappings = array(
|
||||
'requires_php' => 'RequiresPHP',
|
||||
'requires_wp' => 'RequiresWP',
|
||||
'textdomain' => 'TextDomain',
|
||||
'version' => 'Version',
|
||||
);
|
||||
|
||||
foreach ( $plain_field_mappings as $field => $header ) {
|
||||
if ( rest_is_field_included( $field, $fields ) ) {
|
||||
$data[ $field ] = $theme->get( $header );
|
||||
}
|
||||
}
|
||||
|
||||
if ( rest_is_field_included( 'screenshot', $fields ) ) {
|
||||
// Using $theme->get_screenshot() with no args to get absolute URL.
|
||||
$data['screenshot'] = $theme->get_screenshot() ?: '';
|
||||
}
|
||||
|
||||
$rich_field_mappings = array(
|
||||
'author' => 'Author',
|
||||
'author_uri' => 'AuthorURI',
|
||||
'description' => 'Description',
|
||||
'name' => 'Name',
|
||||
'tags' => 'Tags',
|
||||
'theme_uri' => 'ThemeURI',
|
||||
);
|
||||
|
||||
foreach ( $rich_field_mappings as $field => $header ) {
|
||||
if ( rest_is_field_included( "{$field}.raw", $fields ) ) {
|
||||
$data[ $field ]['raw'] = $theme->display( $header, false, true );
|
||||
}
|
||||
|
||||
if ( rest_is_field_included( "{$field}.rendered", $fields ) ) {
|
||||
$data[ $field ]['rendered'] = $theme->display( $header );
|
||||
}
|
||||
}
|
||||
|
||||
if ( rest_is_field_included( 'theme_supports', $fields ) ) {
|
||||
$item_schemas = $this->get_item_schema();
|
||||
$theme_supports = $item_schemas['properties']['theme_supports']['properties'];
|
||||
foreach ( $theme_supports as $name => $schema ) {
|
||||
if ( ! rest_is_field_included( "theme_supports.{$name}", $fields ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( 'formats' === $name ) {
|
||||
continue;
|
||||
}
|
||||
@ -192,6 +247,117 @@ class WP_REST_Themes_Controller extends WP_REST_Controller {
|
||||
'title' => 'theme',
|
||||
'type' => 'object',
|
||||
'properties' => array(
|
||||
'stylesheet' => array(
|
||||
'description' => __( 'The theme\'s stylesheet. This uniquely identifies the theme.' ),
|
||||
'type' => 'string',
|
||||
'readonly' => true,
|
||||
),
|
||||
'template' => array(
|
||||
'description' => __( 'The theme\'s template. If this is a child theme, this refers to the parent theme, otherwise this is the same as the theme\'s stylesheet.' ),
|
||||
'type' => 'string',
|
||||
'readonly' => true,
|
||||
),
|
||||
'author' => array(
|
||||
'description' => __( 'The theme author.' ),
|
||||
'type' => 'object',
|
||||
'readonly' => true,
|
||||
'properties' => array(
|
||||
'raw' => array(
|
||||
'description' => __( 'The theme author\'s name, as found in the theme header.' ),
|
||||
'type' => 'string',
|
||||
),
|
||||
'rendered' => array(
|
||||
'description' => __( 'HTML for the theme author, transformed for display.' ),
|
||||
'type' => 'string',
|
||||
),
|
||||
),
|
||||
),
|
||||
'author_uri' => array(
|
||||
'description' => __( 'The website of the theme author.' ),
|
||||
'type' => 'object',
|
||||
'readonly' => true,
|
||||
'properties' => array(
|
||||
'raw' => array(
|
||||
'description' => __( 'The website of the theme author, as found in the theme header.' ),
|
||||
'type' => 'string',
|
||||
'format' => 'uri',
|
||||
),
|
||||
'rendered' => array(
|
||||
'description' => __( 'The website of the theme author, transformed for display.' ),
|
||||
'type' => 'string',
|
||||
'format' => 'uri',
|
||||
),
|
||||
),
|
||||
),
|
||||
'description' => array(
|
||||
'description' => __( 'A description of the theme.' ),
|
||||
'type' => 'object',
|
||||
'readonly' => true,
|
||||
'properties' => array(
|
||||
'raw' => array(
|
||||
'description' => __( 'The theme description, as found in the theme header.' ),
|
||||
'type' => 'string',
|
||||
),
|
||||
'rendered' => array(
|
||||
'description' => __( 'The theme description, transformed for display.' ),
|
||||
'type' => 'string',
|
||||
),
|
||||
),
|
||||
),
|
||||
'name' => array(
|
||||
'description' => __( 'The name of the theme.' ),
|
||||
'type' => 'object',
|
||||
'readonly' => true,
|
||||
'properties' => array(
|
||||
'raw' => array(
|
||||
'description' => __( 'The theme name, as found in the theme header.' ),
|
||||
'type' => 'string',
|
||||
),
|
||||
'rendered' => array(
|
||||
'description' => __( 'The theme name, transformed for display.' ),
|
||||
'type' => 'string',
|
||||
),
|
||||
),
|
||||
),
|
||||
'requires_php' => array(
|
||||
'description' => __( 'The minimum PHP version required for the theme to work.' ),
|
||||
'type' => 'string',
|
||||
'readonly' => true,
|
||||
),
|
||||
'requires_wp' => array(
|
||||
'description' => __( 'The minimum WordPress version required for the theme to work.' ),
|
||||
'type' => 'string',
|
||||
'readonly' => true,
|
||||
),
|
||||
'screenshot' => array(
|
||||
'description' => __( 'The theme\'s screenshot URL.' ),
|
||||
'type' => 'string',
|
||||
'format' => 'uri',
|
||||
'readonly' => true,
|
||||
),
|
||||
'tags' => array(
|
||||
'description' => __( 'Tags indicating styles and features of the theme.' ),
|
||||
'type' => 'object',
|
||||
'readonly' => true,
|
||||
'properties' => array(
|
||||
'raw' => array(
|
||||
'description' => __( 'The theme tags, as found in the theme header.' ),
|
||||
'type' => 'array',
|
||||
'items' => array(
|
||||
'type' => 'string',
|
||||
),
|
||||
),
|
||||
'rendered' => array(
|
||||
'description' => __( 'The theme tags, transformed for display.' ),
|
||||
'type' => 'string',
|
||||
),
|
||||
),
|
||||
),
|
||||
'textdomain' => array(
|
||||
'description' => __( 'The theme\'s textdomain.' ),
|
||||
'type' => 'string',
|
||||
'readonly' => true,
|
||||
),
|
||||
'theme_supports' => array(
|
||||
'description' => __( 'Features supported by this theme.' ),
|
||||
'type' => 'object',
|
||||
@ -458,6 +624,28 @@ class WP_REST_Themes_Controller extends WP_REST_Controller {
|
||||
),
|
||||
),
|
||||
),
|
||||
'theme_uri' => array(
|
||||
'description' => __( 'The URI of the theme\'s webpage.' ),
|
||||
'type' => 'object',
|
||||
'readonly' => true,
|
||||
'properties' => array(
|
||||
'raw' => array(
|
||||
'description' => __( 'The URI of the theme\'s webpage, as found in the theme header.' ),
|
||||
'type' => 'string',
|
||||
'format' => 'uri',
|
||||
),
|
||||
'rendered' => array(
|
||||
'description' => __( 'The URI of the theme\'s webpage, transformed for display.' ),
|
||||
'type' => 'string',
|
||||
'format' => 'uri',
|
||||
),
|
||||
),
|
||||
),
|
||||
'version' => array(
|
||||
'description' => __( 'The theme\'s current version.' ),
|
||||
'type' => 'string',
|
||||
'readonly' => true,
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
|
15
tests/phpunit/data/themedir1/rest-api/style.css
Normal file
15
tests/phpunit/data/themedir1/rest-api/style.css
Normal file
@ -0,0 +1,15 @@
|
||||
/*
|
||||
Theme Name: REST Theme
|
||||
Theme URI: http://wordpress.org/?search=1&term=2
|
||||
Description: The 9' foot tall theme.
|
||||
Version: 1.6
|
||||
Author: Michael Heilemann
|
||||
Author URI: http://binarybonsai.com/?search=1&term=2
|
||||
Tags: holiday, custom-menu
|
||||
Template: default
|
||||
Requires at least: 5.3
|
||||
Requires PHP: 5.6
|
||||
Text Domain: rest-api
|
||||
*/
|
||||
|
||||
|
@ -125,6 +125,7 @@ class WP_Test_REST_Themes_Controller extends WP_Test_REST_Controller_Testcase {
|
||||
parent::setUp();
|
||||
|
||||
wp_set_current_user( self::$contributor_id );
|
||||
switch_theme( 'rest-api' );
|
||||
}
|
||||
|
||||
/**
|
||||
@ -150,7 +151,20 @@ class WP_Test_REST_Themes_Controller extends WP_Test_REST_Controller_Testcase {
|
||||
|
||||
$this->check_get_theme_response( $response );
|
||||
$fields = array(
|
||||
'author',
|
||||
'author_uri',
|
||||
'description',
|
||||
'name',
|
||||
'requires_php',
|
||||
'requires_wp',
|
||||
'screenshot',
|
||||
'stylesheet',
|
||||
'tags',
|
||||
'template',
|
||||
'textdomain',
|
||||
'theme_supports',
|
||||
'theme_uri',
|
||||
'version',
|
||||
);
|
||||
$this->assertEqualSets( $fields, array_keys( $data[0] ) );
|
||||
}
|
||||
@ -207,8 +221,44 @@ class WP_Test_REST_Themes_Controller extends WP_Test_REST_Controller_Testcase {
|
||||
$response = self::perform_active_theme_request( 'OPTIONS' );
|
||||
$data = $response->get_data();
|
||||
$properties = $data['schema']['properties'];
|
||||
$this->assertEquals( 1, count( $properties ) );
|
||||
$this->assertEquals( 14, count( $properties ) );
|
||||
|
||||
$this->assertArrayHasKey( 'author', $properties );
|
||||
$this->assertArrayHasKey( 'raw', $properties['author']['properties'] );
|
||||
$this->assertArrayHasKey( 'rendered', $properties['author']['properties'] );
|
||||
|
||||
$this->assertArrayHasKey( 'author_uri', $properties );
|
||||
$this->assertArrayHasKey( 'raw', $properties['author_uri']['properties'] );
|
||||
$this->assertArrayHasKey( 'rendered', $properties['author_uri']['properties'] );
|
||||
|
||||
$this->assertArrayHasKey( 'description', $properties );
|
||||
$this->assertArrayHasKey( 'raw', $properties['description']['properties'] );
|
||||
$this->assertArrayHasKey( 'rendered', $properties['description']['properties'] );
|
||||
|
||||
$this->assertArrayHasKey( 'name', $properties );
|
||||
$this->assertArrayHasKey( 'raw', $properties['name']['properties'] );
|
||||
$this->assertArrayHasKey( 'rendered', $properties['name']['properties'] );
|
||||
|
||||
$this->assertArrayHasKey( 'requires_php', $properties );
|
||||
$this->assertArrayHasKey( 'requires_wp', $properties );
|
||||
$this->assertArrayHasKey( 'screenshot', $properties );
|
||||
$this->assertArrayHasKey( 'stylesheet', $properties );
|
||||
|
||||
$this->assertArrayHasKey( 'tags', $properties );
|
||||
$this->assertArrayHasKey( 'raw', $properties['tags']['properties'] );
|
||||
$this->assertArrayHasKey( 'items', $properties['tags']['properties']['raw'] );
|
||||
$this->assertArrayHasKey( 'rendered', $properties['tags']['properties'] );
|
||||
|
||||
$this->assertArrayHasKey( 'template', $properties );
|
||||
$this->assertArrayHasKey( 'textdomain', $properties );
|
||||
$this->assertArrayHasKey( 'theme_supports', $properties );
|
||||
|
||||
$this->assertArrayHasKey( 'theme_uri', $properties );
|
||||
$this->assertArrayHasKey( 'raw', $properties['theme_uri']['properties'] );
|
||||
$this->assertArrayHasKey( 'rendered', $properties['theme_uri']['properties'] );
|
||||
|
||||
$this->assertArrayHasKey( 'version', $properties );
|
||||
|
||||
$theme_supports = $properties['theme_supports']['properties'];
|
||||
$this->assertEquals( 20, count( $theme_supports ) );
|
||||
$this->assertArrayHasKey( 'align-wide', $theme_supports );
|
||||
@ -233,6 +283,148 @@ class WP_Test_REST_Themes_Controller extends WP_Test_REST_Controller_Testcase {
|
||||
$this->assertArrayHasKey( 'wp-block-styles', $theme_supports );
|
||||
}
|
||||
|
||||
/**
|
||||
* @ticket 49906
|
||||
*/
|
||||
public function test_theme_author() {
|
||||
$response = self::perform_active_theme_request();
|
||||
$result = $response->get_data();
|
||||
$this->assertArrayHasKey( 'author', $result[0] );
|
||||
$this->assertSame( 'Michael Heilemann', $result[0]['author']['raw'] );
|
||||
$this->assertSame(
|
||||
'<a href="http://binarybonsai.com/?search=1&term=2">Michael Heilemann</a>',
|
||||
$result[0]['author']['rendered']
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @ticket 49906
|
||||
*/
|
||||
public function test_theme_author_uri() {
|
||||
$response = self::perform_active_theme_request();
|
||||
$result = $response->get_data();
|
||||
$this->assertArrayHasKey( 'author_uri', $result[0] );
|
||||
$this->assertSame( 'http://binarybonsai.com/?search=1&term=2', $result[0]['author_uri']['raw'] );
|
||||
$this->assertSame( 'http://binarybonsai.com/?search=1&term=2', $result[0]['author_uri']['rendered'] );
|
||||
}
|
||||
|
||||
/**
|
||||
* @ticket 49906
|
||||
*/
|
||||
public function test_theme_description() {
|
||||
$response = self::perform_active_theme_request();
|
||||
$result = $response->get_data();
|
||||
$this->assertArrayHasKey( 'description', $result[0] );
|
||||
$this->assertSame(
|
||||
'The 9\' foot tall theme.',
|
||||
$result[0]['description']['raw']
|
||||
);
|
||||
$this->assertSame(
|
||||
'The 9′ foot tall theme.',
|
||||
$result[0]['description']['rendered']
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @ticket 49906
|
||||
*/
|
||||
public function test_theme_requires_php() {
|
||||
$response = self::perform_active_theme_request();
|
||||
$result = $response->get_data();
|
||||
$this->assertArrayHasKey( 'requires_php', $result[0] );
|
||||
$this->assertSame( '5.6', $result[0]['requires_php'] );
|
||||
}
|
||||
|
||||
/**
|
||||
* @ticket 49906
|
||||
*/
|
||||
public function test_theme_requires_wp() {
|
||||
$response = self::perform_active_theme_request();
|
||||
$result = $response->get_data();
|
||||
$this->assertArrayHasKey( 'requires_wp', $result[0] );
|
||||
$this->assertSame( '5.3', $result[0]['requires_wp'] );
|
||||
}
|
||||
|
||||
/**
|
||||
* @ticket 49906
|
||||
*/
|
||||
public function test_theme_name() {
|
||||
$response = self::perform_active_theme_request();
|
||||
$result = $response->get_data();
|
||||
$this->assertArrayHasKey( 'name', $result[0] );
|
||||
$this->assertSame( 'REST Theme', $result[0]['name']['raw'] );
|
||||
$this->assertSame( 'REST Theme', $result[0]['name']['rendered'] );
|
||||
}
|
||||
|
||||
/**
|
||||
* @ticket 49906
|
||||
*/
|
||||
public function test_theme_screenshot() {
|
||||
$response = self::perform_active_theme_request();
|
||||
$result = $response->get_data();
|
||||
$this->assertArrayHasKey( 'screenshot', $result[0] );
|
||||
$this->assertSame( '', $result[0]['screenshot'] ); // No screenshot for default theme
|
||||
}
|
||||
|
||||
/**
|
||||
* @ticket 49906
|
||||
*/
|
||||
public function test_theme_stylesheet() {
|
||||
$response = self::perform_active_theme_request();
|
||||
$result = $response->get_data();
|
||||
$this->assertArrayHasKey( 'stylesheet', $result[0] );
|
||||
$this->assertSame( 'rest-api', $result[0]['stylesheet'] );
|
||||
}
|
||||
|
||||
/**
|
||||
* @ticket 49906
|
||||
*/
|
||||
public function test_theme_tags() {
|
||||
$response = self::perform_active_theme_request();
|
||||
$result = $response->get_data();
|
||||
$this->assertArrayHasKey( 'tags', $result[0] );
|
||||
$this->assertSame( array( 'holiday', 'custom-menu' ), $result[0]['tags']['raw'] );
|
||||
$this->assertSame( 'holiday, custom-menu', $result[0]['tags']['rendered'] );
|
||||
}
|
||||
|
||||
/**
|
||||
* @ticket 49906
|
||||
*/
|
||||
public function test_theme_template() {
|
||||
$response = self::perform_active_theme_request();
|
||||
$result = $response->get_data();
|
||||
$this->assertArrayHasKey( 'template', $result[0] );
|
||||
$this->assertSame( 'default', $result[0]['template'] );
|
||||
}
|
||||
|
||||
/**
|
||||
* @ticket 49906
|
||||
*/
|
||||
public function test_theme_textdomain() {
|
||||
$response = self::perform_active_theme_request();
|
||||
$result = $response->get_data();
|
||||
$this->assertArrayHasKey( 'textdomain', $result[0] );
|
||||
$this->assertSame( 'rest-api', $result[0]['textdomain'] );
|
||||
}
|
||||
|
||||
public function test_theme_theme_uri() {
|
||||
$response = self::perform_active_theme_request();
|
||||
$result = $response->get_data();
|
||||
$this->assertArrayHasKey( 'theme_uri', $result[0] );
|
||||
$this->assertSame( 'http://wordpress.org/?search=1&term=2', $result[0]['theme_uri']['raw'] );
|
||||
$this->assertSame( 'http://wordpress.org/?search=1&term=2', $result[0]['theme_uri']['rendered'] );
|
||||
}
|
||||
|
||||
/**
|
||||
* @ticket 49906
|
||||
*/
|
||||
public function test_theme_version() {
|
||||
$response = self::perform_active_theme_request();
|
||||
$result = $response->get_data();
|
||||
$this->assertArrayHasKey( 'version', $result[0] );
|
||||
$this->assertSame( '1.6', $result[0]['version'] );
|
||||
}
|
||||
|
||||
/**
|
||||
* @ticket 49037
|
||||
*/
|
||||
|
@ -163,6 +163,7 @@ class Tests_Theme_ThemeDir extends WP_UnitTestCase {
|
||||
'Theme with Spaces in the Directory',
|
||||
'Internationalized Theme',
|
||||
'camelCase',
|
||||
'REST Theme',
|
||||
);
|
||||
|
||||
sort( $theme_names );
|
||||
|
Loading…
Reference in New Issue
Block a user