WordPress.org

Make WordPress Core

Changeset 47921


Ignore:
Timestamp:
06/07/2020 06:44:08 AM (3 months ago)
Author:
TimothyBlynJacobs
Message:

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.

Location:
trunk
Files:
2 added
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/rest-api/endpoints/class-wp-rest-themes-controller.php

    r47432 r47921  
    116116        $fields = $this->get_fields_for_response( $request );
    117117
    118         if ( in_array( 'theme_supports', $fields, true ) ) {
     118        if ( rest_is_field_included( 'stylesheet', $fields ) ) {
     119            $data['stylesheet'] = $theme->get_stylesheet();
     120        }
     121
     122        if ( rest_is_field_included( 'template', $fields ) ) {
     123            /**
     124             * Use the get_template() method, not the 'Template' header, for finding the template.
     125             * The 'Template' header is only good for what was written in the style.css, while
     126             * get_template() takes into account where WordPress actually located the theme and
     127             * whether it is actually valid.
     128             */
     129            $data['template'] = $theme->get_template();
     130        }
     131
     132        $plain_field_mappings = array(
     133            'requires_php' => 'RequiresPHP',
     134            'requires_wp'  => 'RequiresWP',
     135            'textdomain'   => 'TextDomain',
     136            'version'      => 'Version',
     137        );
     138
     139        foreach ( $plain_field_mappings as $field => $header ) {
     140            if ( rest_is_field_included( $field, $fields ) ) {
     141                $data[ $field ] = $theme->get( $header );
     142            }
     143        }
     144
     145        if ( rest_is_field_included( 'screenshot', $fields ) ) {
     146            // Using $theme->get_screenshot() with no args to get absolute URL.
     147            $data['screenshot'] = $theme->get_screenshot() ?: '';
     148        }
     149
     150        $rich_field_mappings = array(
     151            'author'      => 'Author',
     152            'author_uri'  => 'AuthorURI',
     153            'description' => 'Description',
     154            'name'        => 'Name',
     155            'tags'        => 'Tags',
     156            'theme_uri'   => 'ThemeURI',
     157        );
     158
     159        foreach ( $rich_field_mappings as $field => $header ) {
     160            if ( rest_is_field_included( "{$field}.raw", $fields ) ) {
     161                $data[ $field ]['raw'] = $theme->display( $header, false, true );
     162            }
     163
     164            if ( rest_is_field_included( "{$field}.rendered", $fields ) ) {
     165                $data[ $field ]['rendered'] = $theme->display( $header );
     166            }
     167        }
     168
     169        if ( rest_is_field_included( 'theme_supports', $fields ) ) {
    119170            $item_schemas   = $this->get_item_schema();
    120171            $theme_supports = $item_schemas['properties']['theme_supports']['properties'];
    121172            foreach ( $theme_supports as $name => $schema ) {
     173                if ( ! rest_is_field_included( "theme_supports.{$name}", $fields ) ) {
     174                    continue;
     175                }
     176
    122177                if ( 'formats' === $name ) {
    123178                    continue;
     
    193248            'type'       => 'object',
    194249            'properties' => array(
     250                'stylesheet'     => array(
     251                    'description' => __( 'The theme\'s stylesheet. This uniquely identifies the theme.' ),
     252                    'type'        => 'string',
     253                    'readonly'    => true,
     254                ),
     255                'template'       => array(
     256                    '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.' ),
     257                    'type'        => 'string',
     258                    'readonly'    => true,
     259                ),
     260                'author'         => array(
     261                    'description' => __( 'The theme author.' ),
     262                    'type'        => 'object',
     263                    'readonly'    => true,
     264                    'properties'  => array(
     265                        'raw'      => array(
     266                            'description' => __( 'The theme author\'s name, as found in the theme header.' ),
     267                            'type'        => 'string',
     268                        ),
     269                        'rendered' => array(
     270                            'description' => __( 'HTML for the theme author, transformed for display.' ),
     271                            'type'        => 'string',
     272                        ),
     273                    ),
     274                ),
     275                'author_uri'     => array(
     276                    'description' => __( 'The website of the theme author.' ),
     277                    'type'        => 'object',
     278                    'readonly'    => true,
     279                    'properties'  => array(
     280                        'raw'      => array(
     281                            'description' => __( 'The website of the theme author, as found in the theme header.' ),
     282                            'type'        => 'string',
     283                            'format'      => 'uri',
     284                        ),
     285                        'rendered' => array(
     286                            'description' => __( 'The website of the theme author, transformed for display.' ),
     287                            'type'        => 'string',
     288                            'format'      => 'uri',
     289                        ),
     290                    ),
     291                ),
     292                'description'    => array(
     293                    'description' => __( 'A description of the theme.' ),
     294                    'type'        => 'object',
     295                    'readonly'    => true,
     296                    'properties'  => array(
     297                        'raw'      => array(
     298                            'description' => __( 'The theme description, as found in the theme header.' ),
     299                            'type'        => 'string',
     300                        ),
     301                        'rendered' => array(
     302                            'description' => __( 'The theme description, transformed for display.' ),
     303                            'type'        => 'string',
     304                        ),
     305                    ),
     306                ),
     307                'name'           => array(
     308                    'description' => __( 'The name of the theme.' ),
     309                    'type'        => 'object',
     310                    'readonly'    => true,
     311                    'properties'  => array(
     312                        'raw'      => array(
     313                            'description' => __( 'The theme name, as found in the theme header.' ),
     314                            'type'        => 'string',
     315                        ),
     316                        'rendered' => array(
     317                            'description' => __( 'The theme name, transformed for display.' ),
     318                            'type'        => 'string',
     319                        ),
     320                    ),
     321                ),
     322                'requires_php'   => array(
     323                    'description' => __( 'The minimum PHP version required for the theme to work.' ),
     324                    'type'        => 'string',
     325                    'readonly'    => true,
     326                ),
     327                'requires_wp'    => array(
     328                    'description' => __( 'The minimum WordPress version required for the theme to work.' ),
     329                    'type'        => 'string',
     330                    'readonly'    => true,
     331                ),
     332                'screenshot'     => array(
     333                    'description' => __( 'The theme\'s screenshot URL.' ),
     334                    'type'        => 'string',
     335                    'format'      => 'uri',
     336                    'readonly'    => true,
     337                ),
     338                'tags'           => array(
     339                    'description' => __( 'Tags indicating styles and features of the theme.' ),
     340                    'type'        => 'object',
     341                    'readonly'    => true,
     342                    'properties'  => array(
     343                        'raw'      => array(
     344                            'description' => __( 'The theme tags, as found in the theme header.' ),
     345                            'type'        => 'array',
     346                            'items'       => array(
     347                                'type' => 'string',
     348                            ),
     349                        ),
     350                        'rendered' => array(
     351                            'description' => __( 'The theme tags, transformed for display.' ),
     352                            'type'        => 'string',
     353                        ),
     354                    ),
     355                ),
     356                'textdomain'     => array(
     357                    'description' => __( 'The theme\'s textdomain.' ),
     358                    'type'        => 'string',
     359                    'readonly'    => true,
     360                ),
    195361                'theme_supports' => array(
    196362                    'description' => __( 'Features supported by this theme.' ),
     
    459625                    ),
    460626                ),
     627                'theme_uri'      => array(
     628                    'description' => __( 'The URI of the theme\'s webpage.' ),
     629                    'type'        => 'object',
     630                    'readonly'    => true,
     631                    'properties'  => array(
     632                        'raw'      => array(
     633                            'description' => __( 'The URI of the theme\'s webpage, as found in the theme header.' ),
     634                            'type'        => 'string',
     635                            'format'      => 'uri',
     636                        ),
     637                        'rendered' => array(
     638                            'description' => __( 'The URI of the theme\'s webpage, transformed for display.' ),
     639                            'type'        => 'string',
     640                            'format'      => 'uri',
     641                        ),
     642                    ),
     643                ),
     644                'version'        => array(
     645                    'description' => __( 'The theme\'s current version.' ),
     646                    'type'        => 'string',
     647                    'readonly'    => true,
     648                ),
    461649            ),
    462650        );
  • trunk/tests/phpunit/tests/rest-api/rest-themes-controller.php

    r47361 r47921  
    126126
    127127        wp_set_current_user( self::$contributor_id );
     128        switch_theme( 'rest-api' );
    128129    }
    129130
     
    151152        $this->check_get_theme_response( $response );
    152153        $fields = array(
     154            'author',
     155            'author_uri',
     156            'description',
     157            'name',
     158            'requires_php',
     159            'requires_wp',
     160            'screenshot',
     161            'stylesheet',
     162            'tags',
     163            'template',
     164            'textdomain',
    153165            'theme_supports',
     166            'theme_uri',
     167            'version',
    154168        );
    155169        $this->assertEqualSets( $fields, array_keys( $data[0] ) );
     
    208222        $data       = $response->get_data();
    209223        $properties = $data['schema']['properties'];
    210         $this->assertEquals( 1, count( $properties ) );
     224        $this->assertEquals( 14, count( $properties ) );
     225
     226        $this->assertArrayHasKey( 'author', $properties );
     227        $this->assertArrayHasKey( 'raw', $properties['author']['properties'] );
     228        $this->assertArrayHasKey( 'rendered', $properties['author']['properties'] );
     229
     230        $this->assertArrayHasKey( 'author_uri', $properties );
     231        $this->assertArrayHasKey( 'raw', $properties['author_uri']['properties'] );
     232        $this->assertArrayHasKey( 'rendered', $properties['author_uri']['properties'] );
     233
     234        $this->assertArrayHasKey( 'description', $properties );
     235        $this->assertArrayHasKey( 'raw', $properties['description']['properties'] );
     236        $this->assertArrayHasKey( 'rendered', $properties['description']['properties'] );
     237
     238        $this->assertArrayHasKey( 'name', $properties );
     239        $this->assertArrayHasKey( 'raw', $properties['name']['properties'] );
     240        $this->assertArrayHasKey( 'rendered', $properties['name']['properties'] );
     241
     242        $this->assertArrayHasKey( 'requires_php', $properties );
     243        $this->assertArrayHasKey( 'requires_wp', $properties );
     244        $this->assertArrayHasKey( 'screenshot', $properties );
     245        $this->assertArrayHasKey( 'stylesheet', $properties );
     246
     247        $this->assertArrayHasKey( 'tags', $properties );
     248        $this->assertArrayHasKey( 'raw', $properties['tags']['properties'] );
     249        $this->assertArrayHasKey( 'items', $properties['tags']['properties']['raw'] );
     250        $this->assertArrayHasKey( 'rendered', $properties['tags']['properties'] );
     251
     252        $this->assertArrayHasKey( 'template', $properties );
     253        $this->assertArrayHasKey( 'textdomain', $properties );
    211254        $this->assertArrayHasKey( 'theme_supports', $properties );
     255
     256        $this->assertArrayHasKey( 'theme_uri', $properties );
     257        $this->assertArrayHasKey( 'raw', $properties['theme_uri']['properties'] );
     258        $this->assertArrayHasKey( 'rendered', $properties['theme_uri']['properties'] );
     259
     260        $this->assertArrayHasKey( 'version', $properties );
     261
    212262        $theme_supports = $properties['theme_supports']['properties'];
    213263        $this->assertEquals( 20, count( $theme_supports ) );
     
    235285
    236286    /**
     287     * @ticket 49906
     288     */
     289    public function test_theme_author() {
     290        $response = self::perform_active_theme_request();
     291        $result   = $response->get_data();
     292        $this->assertArrayHasKey( 'author', $result[0] );
     293        $this->assertSame( 'Michael Heilemann', $result[0]['author']['raw'] );
     294        $this->assertSame(
     295            '<a href="http://binarybonsai.com/?search=1&#038;term=2">Michael Heilemann</a>',
     296            $result[0]['author']['rendered']
     297        );
     298    }
     299
     300    /**
     301     * @ticket 49906
     302     */
     303    public function test_theme_author_uri() {
     304        $response = self::perform_active_theme_request();
     305        $result   = $response->get_data();
     306        $this->assertArrayHasKey( 'author_uri', $result[0] );
     307        $this->assertSame( 'http://binarybonsai.com/?search=1&term=2', $result[0]['author_uri']['raw'] );
     308        $this->assertSame( 'http://binarybonsai.com/?search=1&#038;term=2', $result[0]['author_uri']['rendered'] );
     309    }
     310
     311    /**
     312     * @ticket 49906
     313     */
     314    public function test_theme_description() {
     315        $response = self::perform_active_theme_request();
     316        $result   = $response->get_data();
     317        $this->assertArrayHasKey( 'description', $result[0] );
     318        $this->assertSame(
     319            'The 9\' foot tall theme.',
     320            $result[0]['description']['raw']
     321        );
     322        $this->assertSame(
     323            'The 9&#8242; foot tall theme.',
     324            $result[0]['description']['rendered']
     325        );
     326    }
     327
     328    /**
     329     * @ticket 49906
     330     */
     331    public function test_theme_requires_php() {
     332        $response = self::perform_active_theme_request();
     333        $result   = $response->get_data();
     334        $this->assertArrayHasKey( 'requires_php', $result[0] );
     335        $this->assertSame( '5.6', $result[0]['requires_php'] );
     336    }
     337
     338    /**
     339     * @ticket 49906
     340     */
     341    public function test_theme_requires_wp() {
     342        $response = self::perform_active_theme_request();
     343        $result   = $response->get_data();
     344        $this->assertArrayHasKey( 'requires_wp', $result[0] );
     345        $this->assertSame( '5.3', $result[0]['requires_wp'] );
     346    }
     347
     348    /**
     349     * @ticket 49906
     350     */
     351    public function test_theme_name() {
     352        $response = self::perform_active_theme_request();
     353        $result   = $response->get_data();
     354        $this->assertArrayHasKey( 'name', $result[0] );
     355        $this->assertSame( 'REST Theme', $result[0]['name']['raw'] );
     356        $this->assertSame( 'REST Theme', $result[0]['name']['rendered'] );
     357    }
     358
     359    /**
     360     * @ticket 49906
     361     */
     362    public function test_theme_screenshot() {
     363        $response = self::perform_active_theme_request();
     364        $result   = $response->get_data();
     365        $this->assertArrayHasKey( 'screenshot', $result[0] );
     366        $this->assertSame( '', $result[0]['screenshot'] ); // No screenshot for default theme
     367    }
     368
     369    /**
     370     * @ticket 49906
     371     */
     372    public function test_theme_stylesheet() {
     373        $response = self::perform_active_theme_request();
     374        $result   = $response->get_data();
     375        $this->assertArrayHasKey( 'stylesheet', $result[0] );
     376        $this->assertSame( 'rest-api', $result[0]['stylesheet'] );
     377    }
     378
     379    /**
     380     * @ticket 49906
     381     */
     382    public function test_theme_tags() {
     383        $response = self::perform_active_theme_request();
     384        $result   = $response->get_data();
     385        $this->assertArrayHasKey( 'tags', $result[0] );
     386        $this->assertSame( array( 'holiday', 'custom-menu' ), $result[0]['tags']['raw'] );
     387        $this->assertSame( 'holiday, custom-menu', $result[0]['tags']['rendered'] );
     388    }
     389
     390    /**
     391     * @ticket 49906
     392     */
     393    public function test_theme_template() {
     394        $response = self::perform_active_theme_request();
     395        $result   = $response->get_data();
     396        $this->assertArrayHasKey( 'template', $result[0] );
     397        $this->assertSame( 'default', $result[0]['template'] );
     398    }
     399
     400    /**
     401     * @ticket 49906
     402     */
     403    public function test_theme_textdomain() {
     404        $response = self::perform_active_theme_request();
     405        $result   = $response->get_data();
     406        $this->assertArrayHasKey( 'textdomain', $result[0] );
     407        $this->assertSame( 'rest-api', $result[0]['textdomain'] );
     408    }
     409
     410    public function test_theme_theme_uri() {
     411        $response = self::perform_active_theme_request();
     412        $result   = $response->get_data();
     413        $this->assertArrayHasKey( 'theme_uri', $result[0] );
     414        $this->assertSame( 'http://wordpress.org/?search=1&term=2', $result[0]['theme_uri']['raw'] );
     415        $this->assertSame( 'http://wordpress.org/?search=1&#038;term=2', $result[0]['theme_uri']['rendered'] );
     416    }
     417
     418    /**
     419     * @ticket 49906
     420     */
     421    public function test_theme_version() {
     422        $response = self::perform_active_theme_request();
     423        $result   = $response->get_data();
     424        $this->assertArrayHasKey( 'version', $result[0] );
     425        $this->assertSame( '1.6', $result[0]['version'] );
     426    }
     427
     428    /**
    237429     * @ticket 49037
    238430     */
  • trunk/tests/phpunit/tests/theme/themeDir.php

    r47122 r47921  
    164164            'Internationalized Theme',
    165165            'camelCase',
     166            'REST Theme',
    166167        );
    167168
Note: See TracChangeset for help on using the changeset viewer.