Make WordPress Core


Ignore:
Timestamp:
06/25/2020 10:11:09 PM (6 years ago)
Author:
TimothyBlynJacobs
Message:

Themes: Introduce register_theme_feature API.

Currently themes can declare support for a given feature by using add_theme_support(). This commit adds a register_theme_feature() API that allows plugins and WordPress Core to declare a list of available features that themes can support.

The REST API uses this to expose a theme's supported features if the feature has been registered with "show_in_rest" set to true.

Props kadamwhite, spacedmonkey, williampatton, desrosj, TimothyBlynJacobs.
Fixes #49406.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/tests/phpunit/tests/theme.php

    r47122 r48171  
    416416                $this->assertEquals( 'private', get_post_status( $nav_created_post_ids[1] ) );
    417417        }
     418
     419        /**
     420         * @ticket 49406
     421         */
     422        public function test_register_theme_support_defaults() {
     423                $registered = register_theme_feature( 'test-feature' );
     424                $this->assertTrue( $registered );
     425
     426                $expected = array(
     427                        'type'         => 'boolean',
     428                        'variadic'     => false,
     429                        'description'  => '',
     430                        'show_in_rest' => false,
     431                );
     432                $this->assertEqualSets( $expected, get_registered_theme_feature( 'test-feature' ) );
     433        }
     434
     435        /**
     436         * @ticket 49406
     437         */
     438        public function test_register_theme_support_explicit() {
     439                $args = array(
     440                        'type'         => 'array',
     441                        'variadic'     => true,
     442                        'description'  => 'My Feature',
     443                        'show_in_rest' => array(
     444                                'schema' => array(
     445                                        'items' => array(
     446                                                'type' => 'string',
     447                                        ),
     448                                ),
     449                        ),
     450                );
     451
     452                register_theme_feature( 'test-feature', $args );
     453                $actual = get_registered_theme_feature( 'test-feature' );
     454
     455                $this->assertEquals( 'array', $actual['type'] );
     456                $this->assertTrue( $actual['variadic'] );
     457                $this->assertEquals( 'My Feature', $actual['description'] );
     458                $this->assertEquals( array( 'type' => 'string' ), $actual['show_in_rest']['schema']['items'] );
     459        }
     460
     461        /**
     462         * @ticket 49406
     463         */
     464        public function test_register_theme_support_upgrades_show_in_rest() {
     465                register_theme_feature( 'test-feature', array( 'show_in_rest' => true ) );
     466
     467                $expected = array(
     468                        'schema'           => array(
     469                                'type'        => 'boolean',
     470                                'description' => '',
     471                                'default'     => false,
     472                        ),
     473                        'name'             => 'test-feature',
     474                        'prepare_callback' => null,
     475                );
     476                $actual   = get_registered_theme_feature( 'test-feature' )['show_in_rest'];
     477
     478                $this->assertEqualSets( $expected, $actual );
     479        }
     480
     481        /**
     482         * @ticket 49406
     483         */
     484        public function test_register_theme_support_fills_schema() {
     485                register_theme_feature(
     486                        'test-feature',
     487                        array(
     488                                'type'         => 'array',
     489                                'description'  => 'Cool Feature',
     490                                'show_in_rest' => array(
     491                                        'schema' => array(
     492                                                'items'    => array(
     493                                                        'type' => 'string',
     494                                                ),
     495                                                'minItems' => 1,
     496                                        ),
     497                                ),
     498                        )
     499                );
     500
     501                $expected = array(
     502                        'description' => 'Cool Feature',
     503                        'type'        => array( 'boolean', 'array' ),
     504                        'items'       => array(
     505                                'type' => 'string',
     506                        ),
     507                        'minItems'    => 1,
     508                        'default'     => false,
     509                );
     510                $actual   = get_registered_theme_feature( 'test-feature' )['show_in_rest']['schema'];
     511
     512                $this->assertEqualSets( $expected, $actual );
     513        }
     514
     515        /**
     516         * @ticket 49406
     517         */
     518        public function test_register_theme_support_does_not_add_boolean_type_if_non_bool_default() {
     519                register_theme_feature(
     520                        'test-feature',
     521                        array(
     522                                'type'         => 'array',
     523                                'show_in_rest' => array(
     524                                        'schema' => array(
     525                                                'items'   => array(
     526                                                        'type' => 'string',
     527                                                ),
     528                                                'default' => array( 'standard' ),
     529                                        ),
     530                                ),
     531                        )
     532                );
     533
     534                $actual = get_registered_theme_feature( 'test-feature' )['show_in_rest']['schema']['type'];
     535                $this->assertEquals( 'array', $actual );
     536        }
     537
     538        /**
     539         * @ticket 49406
     540         */
     541        public function test_register_theme_support_defaults_additional_properties_to_false() {
     542                register_theme_feature(
     543                        'test-feature',
     544                        array(
     545                                'type'         => 'object',
     546                                'description'  => 'Cool Feature',
     547                                'show_in_rest' => array(
     548                                        'schema' => array(
     549                                                'properties' => array(
     550                                                        'a' => array(
     551                                                                'type' => 'string',
     552                                                        ),
     553                                                ),
     554                                        ),
     555                                ),
     556                        )
     557                );
     558
     559                $actual = get_registered_theme_feature( 'test-feature' )['show_in_rest']['schema'];
     560
     561                $this->assertArrayHasKey( 'additionalProperties', $actual );
     562                $this->assertFalse( $actual['additionalProperties'] );
     563        }
     564
     565        /**
     566         * @ticket 49406
     567         */
     568        public function test_register_theme_support_with_additional_properties() {
     569                register_theme_feature(
     570                        'test-feature',
     571                        array(
     572                                'type'         => 'object',
     573                                'description'  => 'Cool Feature',
     574                                'show_in_rest' => array(
     575                                        'schema' => array(
     576                                                'properties'           => array(),
     577                                                'additionalProperties' => array(
     578                                                        'type' => 'string',
     579                                                ),
     580                                        ),
     581                                ),
     582                        )
     583                );
     584
     585                $expected = array(
     586                        'type' => 'string',
     587                );
     588                $actual   = get_registered_theme_feature( 'test-feature' )['show_in_rest']['schema']['additionalProperties'];
     589
     590                $this->assertEqualSets( $expected, $actual );
     591        }
     592
     593        /**
     594         * @ticket 49406
     595         */
     596        public function test_register_theme_support_defaults_additional_properties_to_false_in_array() {
     597                register_theme_feature(
     598                        'test-feature',
     599                        array(
     600                                'type'         => 'array',
     601                                'description'  => 'Cool Feature',
     602                                'show_in_rest' => array(
     603                                        'schema' => array(
     604                                                'items' => array(
     605                                                        'type'       => 'object',
     606                                                        'properties' => array(
     607                                                                'a' => array(
     608                                                                        'type' => 'string',
     609                                                                ),
     610                                                        ),
     611                                                ),
     612                                        ),
     613                                ),
     614                        )
     615                );
     616
     617                $actual = get_registered_theme_feature( 'test-feature' )['show_in_rest']['schema']['items'];
     618
     619                $this->assertArrayHasKey( 'additionalProperties', $actual );
     620                $this->assertFalse( $actual['additionalProperties'] );
     621        }
     622
     623        /**
     624         * @ticket       49406
     625         * @dataProvider _dp_register_theme_support_validation
     626         * @param string $error_code The error code expected.
     627         * @param array  $args       The args to register.
     628         */
     629        public function test_register_theme_support_validation( $error_code, $args ) {
     630                $registered = register_theme_feature( 'test-feature', $args );
     631
     632                $this->assertWPError( $registered );
     633                $this->assertEquals( $error_code, $registered->get_error_code() );
     634        }
     635
     636        public function _dp_register_theme_support_validation() {
     637                return array(
     638                        array(
     639                                'invalid_type',
     640                                array(
     641                                        'type' => 'float',
     642                                ),
     643                        ),
     644                        array(
     645                                'invalid_type',
     646                                array(
     647                                        'type' => array( 'string' ),
     648                                ),
     649                        ),
     650                        array(
     651                                'variadic_must_be_array',
     652                                array(
     653                                        'variadic' => true,
     654                                ),
     655                        ),
     656                        array(
     657                                'missing_schema',
     658                                array(
     659                                        'type'         => 'object',
     660                                        'show_in_rest' => true,
     661                                ),
     662                        ),
     663                        array(
     664                                'missing_schema',
     665                                array(
     666                                        'type'         => 'array',
     667                                        'show_in_rest' => true,
     668                                ),
     669                        ),
     670                        array(
     671                                'missing_schema_items',
     672                                array(
     673                                        'type'         => 'array',
     674                                        'show_in_rest' => array(
     675                                                'schema' => array(
     676                                                        'type' => 'array',
     677                                                ),
     678                                        ),
     679                                ),
     680                        ),
     681                        array(
     682                                'missing_schema_properties',
     683                                array(
     684                                        'type'         => 'object',
     685                                        'show_in_rest' => array(
     686                                                'schema' => array(
     687                                                        'type' => 'object',
     688                                                ),
     689                                        ),
     690                                ),
     691                        ),
     692                        array(
     693                                'invalid_rest_prepare_callback',
     694                                array(
     695                                        'show_in_rest' => array(
     696                                                'prepare_callback' => 'this is not a valid function',
     697                                        ),
     698                                ),
     699                        ),
     700                );
     701        }
    418702}
Note: See TracChangeset for help on using the changeset viewer.