WordPress.org

Make WordPress Core

Changeset 50527


Ignore:
Timestamp:
03/12/2021 01:33:21 PM (8 months ago)
Author:
gziolo
Message:

Editor: Make block type aware of variations

Currently block variations are only defined on the client. In some cases, creating block variations on the server can be very useful, especially when needed data is not exposed in the REST APIs.

Related to https://github.com/WordPress/gutenberg/pull/29095.

Props: gwwar, timothyblynjacobs.
Fixes: #52688.

Location:
trunk
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-admin/includes/post.php

    r50505 r50527  
    22582258        'keywords'         => 'keywords',
    22592259        'example'          => 'example',
     2260        'variations'       => 'variations',
    22602261    );
    22612262
  • trunk/src/wp-includes/class-wp-block-type.php

    r50419 r50527  
    9999     */
    100100    public $styles = array();
     101
     102    /**
     103     * Block variations.
     104     * @since 5.8.0
     105     * @var array
     106     */
     107    public $variations = array();
    101108
    102109    /**
  • trunk/src/wp-includes/post.php

    r50505 r50527  
    17041704 *                    'Page scheduled.'
    17051705 * - `item_updated` - Label used when an item is updated. Default is 'Post updated.' / 'Page updated.'
     1706 * - `item_link` - Title for a navigation link block variation. Default is 'Post Link' / 'Page Link'.
     1707 * - `item_link_description` - Description for a navigation link block variation. Default is 'A link to a post.' /
     1708 *                             'A link to a page.'
    17061709 *
    17071710 * Above, the first default value is for non-hierarchical post types (like posts)
     
    17271730 */
    17281731function get_post_type_labels( $post_type_object ) {
    1729     $nohier_vs_hier_defaults              = array(
     1732    $nohier_vs_hier_defaults                  = array(
    17301733        'name'                     => array( _x( 'Posts', 'post type general name' ), _x( 'Pages', 'post type general name' ) ),
    17311734        'singular_name'            => array( _x( 'Post', 'post type singular name' ), _x( 'Page', 'post type singular name' ) ),
     
    17581761        'item_scheduled'           => array( __( 'Post scheduled.' ), __( 'Page scheduled.' ) ),
    17591762        'item_updated'             => array( __( 'Post updated.' ), __( 'Page updated.' ) ),
     1763        'item_link'                => array(
     1764            _x( 'Post Link', 'navigation link block title' ),
     1765            _x( 'Page Link', 'navigation link block title' ),
     1766        ),
     1767        'item_link_description'    => array(
     1768            _x( 'A link to a post.', 'navigation link block description' ),
     1769            _x( 'A link to a page.', 'navigation link block description' ),
     1770        ),
    17601771    );
    17611772    $nohier_vs_hier_defaults['menu_name'] = $nohier_vs_hier_defaults['name'];
  • trunk/src/wp-includes/rest-api/endpoints/class-wp-rest-block-types-controller.php

    r49929 r50527  
    275275            'editor_style',
    276276            'style',
     277            'variations',
    277278        );
    278279        foreach ( $extra_fields as $extra_field ) {
     
    362363        }
    363364
     365        //rest_validate_value_from_schema doesn't understand $refs, pull out reused definitions for readability.
     366        $inner_blocks_definition = array(
     367            'description' => __( 'The list of inner blocks used in the example.' ),
     368            'type'        => 'array',
     369            'items'       => array(
     370                'type'       => 'object',
     371                'properties' => array(
     372                    'name'        => array(
     373                        'description' => __( 'The name of the inner block.' ),
     374                        'type'        => 'string',
     375                    ),
     376                    'attributes'  => array(
     377                        'description' => __( 'The attributes of the inner block.' ),
     378                        'type'        => 'object',
     379                    ),
     380                    'innerBlocks' => array(
     381                        'description' => __( "A list of the inner block's own inner blocks. This is a recursive definition following the parent innerBlocks schema." ),
     382                        'type'        => 'array',
     383                    ),
     384                ),
     385            ),
     386        );
     387
     388        $example_definition      = array(
     389            'description' => __( 'Block example.' ),
     390            'type'        => array( 'object', 'null' ),
     391            'default'     => null,
     392            'properties'  => array(
     393                'attributes'  => array(
     394                    'description' => __( 'The attributes used in the example.' ),
     395                    'type'        => 'object',
     396                ),
     397                'innerBlocks' => $inner_blocks_definition,
     398            ),
     399            'context'     => array( 'embed', 'view', 'edit' ),
     400            'readonly'    => true,
     401        );
     402
     403        $keywords_definition = array(
     404            'description' => __( 'Block keywords.' ),
     405            'type'        => 'array',
     406            'items'       => array(
     407                'type' => 'string',
     408            ),
     409            'default'     => array(),
     410            'context'     => array( 'embed', 'view', 'edit' ),
     411            'readonly'    => true,
     412        );
     413
     414        $icon_definition = array(
     415            'description' => __( 'Icon of block type.' ),
     416            'type'        => array( 'string', 'null' ),
     417            'default'     => null,
     418            'context'     => array( 'embed', 'view', 'edit' ),
     419            'readonly'    => true,
     420        );
     421
     422        $category_definition = array(
     423            'description' => __( 'Block category.' ),
     424            'type'        => array( 'string', 'null' ),
     425            'default'     => null,
     426            'context'     => array( 'embed', 'view', 'edit' ),
     427            'readonly'    => true,
     428        );
     429
    364430        $schema = array(
    365431            '$schema'    => 'http://json-schema.org/draft-04/schema#',
     
    395461                    'readonly'    => true,
    396462                ),
    397                 'icon'             => array(
    398                     'description' => __( 'Icon of block type.' ),
    399                     'type'        => array( 'string', 'null' ),
    400                     'default'     => null,
    401                     'context'     => array( 'embed', 'view', 'edit' ),
    402                     'readonly'    => true,
    403                 ),
     463                'icon'             => $icon_definition,
    404464                'attributes'       => array(
    405465                    'description'          => __( 'Block attributes.' ),
     
    442502                    'readonly'    => true,
    443503                ),
    444                 'category'         => array(
    445                     'description' => __( 'Block category.' ),
    446                     'type'        => array( 'string', 'null' ),
    447                     'default'     => null,
    448                     'context'     => array( 'embed', 'view', 'edit' ),
    449                     'readonly'    => true,
    450                 ),
     504                'category'         => $category_definition,
    451505                'is_dynamic'       => array(
    452506                    'description' => __( 'Is the block dynamically rendered.' ),
     
    513567                    'readonly'    => true,
    514568                ),
     569                'variations'       => array(
     570                    'description' => __( 'Block variations.' ),
     571                    'type'        => 'array',
     572                    'items'       => array(
     573                        'type'       => 'object',
     574                        'properties' => array(
     575                            'name'        => array(
     576                                'description' => __( 'The unique and machine-readable name.' ),
     577                                'type'        => 'string',
     578                                'required'    => true,
     579                            ),
     580                            'title'       => array(
     581                                'description' => __( 'A human-readable variation title.' ),
     582                                'type'        => 'string',
     583                                'required'    => true,
     584                            ),
     585                            'description' => array(
     586                                'description' => __( 'A detailed variation description.' ),
     587                                'type'        => 'string',
     588                                'required'    => false,
     589                            ),
     590                            'category'    => $category_definition,
     591                            'icon'        => $icon_definition,
     592                            'isDefault'   => array(
     593                                'description' => __( 'Indicates whether the current variation is the default one.' ),
     594                                'type'        => 'boolean',
     595                                'required'    => false,
     596                                'default'     => false,
     597                            ),
     598                            'attributes'  => array(
     599                                'description' => __( 'The initial values for attributes.' ),
     600                                'type'        => 'object',
     601                            ),
     602                            'innerBlocks' => $inner_blocks_definition,
     603                            'example'     => $example_definition,
     604                            'scope'       => array(
     605                                'description' => __( 'The list of scopes where the variation is applicable. When not provided, it assumes all available scopes.' ),
     606                                'type'        => array( 'array', 'null' ),
     607                                'default'     => null,
     608                                'items'       => array(
     609                                    'type' => 'string',
     610                                    'enum' => array( 'block', 'inserter', 'transform' ),
     611                                ),
     612                                'readonly'    => true,
     613                            ),
     614                            'keywords'    => $keywords_definition,
     615                        ),
     616                    ),
     617                    'readonly'    => true,
     618                    'context'     => array( 'embed', 'view', 'edit' ),
     619                    'default'     => null,
     620                ),
    515621                'textdomain'       => array(
    516622                    'description' => __( 'Public text domain.' ),
     
    530636                    'readonly'    => true,
    531637                ),
    532                 'keywords'         => array(
    533                     'description' => __( 'Block keywords.' ),
    534                     'type'        => 'array',
    535                     'items'       => array(
    536                         'type' => 'string',
    537                     ),
    538                     'default'     => array(),
    539                     'context'     => array( 'embed', 'view', 'edit' ),
    540                     'readonly'    => true,
    541                 ),
    542                 'example'          => array(
    543                     'description' => __( 'Block example.' ),
    544                     'type'        => array( 'object', 'null' ),
    545                     'default'     => null,
    546                     'properties'  => array(
    547                         'attributes'  => array(
    548                             'description' => __( 'The attributes used in the example.' ),
    549                             'type'        => 'object',
    550                         ),
    551                         'innerBlocks' => array(
    552                             'description' => __( 'The list of inner blocks used in the example.' ),
    553                             'type'        => 'array',
    554                             'items'       => array(
    555                                 'type'       => 'object',
    556                                 'properties' => array(
    557                                     'name'        => array(
    558                                         'description' => __( 'The name of the inner block.' ),
    559                                         'type'        => 'string',
    560                                     ),
    561                                     'attributes'  => array(
    562                                         'description' => __( 'The attributes of the inner block.' ),
    563                                         'type'        => 'object',
    564                                     ),
    565                                     'innerBlocks' => array(
    566                                         'description' => __( "A list of the inner block's own inner blocks. This is a recursive definition following the parent innerBlocks schema." ),
    567                                         'type'        => 'array',
    568                                     ),
    569                                 ),
    570                             ),
    571                         ),
    572                     ),
    573                     'context'     => array( 'embed', 'view', 'edit' ),
    574                     'readonly'    => true,
    575                 ),
     638                'keywords'         => $keywords_definition,
     639                'example'          => $example_definition,
    576640            ),
    577641        );
  • trunk/src/wp-includes/taxonomy.php

    r50505 r50527  
    577577 *     @type string $most_used                  Title for the Most Used tab. Default 'Most Used'.
    578578 *     @type string $back_to_items              Label displayed after a term has been updated.
     579 *     @type string $item_link                  Used in the block editor. Title for a navigation link block variation.
     580 *                                              Default 'Tag Link'/'Category Link'.
     581 *     @type string $item_link_description      Used in the block editor. Description for a navigation link block
     582 *                                              variation. Default 'A link to a tag.'/'A link to a category'.
    579583 * }
    580584 */
     
    614618        'most_used'                  => array( _x( 'Most Used', 'tags' ), _x( 'Most Used', 'categories' ) ),
    615619        'back_to_items'              => array( __( '← Go to Tags' ), __( '← Go to Categories' ) ),
     620        'item_link'                  => array(
     621            _x( 'Tag Link', 'navigation link block title' ),
     622            _x( 'Category Link', 'navigation link block description' ),
     623        ),
     624        'item_link_description'      => array(
     625            _x( 'A link to a tag.', 'navigation link block description' ),
     626            _x( 'A link to a category.', 'navigation link block description' ),
     627        ),
    616628    );
    617629    $nohier_vs_hier_defaults['menu_name'] = $nohier_vs_hier_defaults['name'];
  • trunk/tests/phpunit/tests/admin/includesPost.php

    r50300 r50527  
    848848                'styles'      => array(),
    849849                'keywords'    => array(),
     850                'variations'  => array(),
    850851            ),
    851852            $blocks[ $name ]
  • trunk/tests/phpunit/tests/rest-api/rest-block-type-controller.php

    r49603 r50527  
    225225            'render_callback'  => 'invalid_callback',
    226226            'textdomain'       => true,
     227            'variations'       => 'invalid_variations',
    227228        );
    228229        register_block_type( $block_type, $settings );
     
    250251        $this->assertNull( $data['textdomain'] );
    251252        $this->assertFalse( $data['is_dynamic'] );
     253        $this->assertSameSets( array( array() ), $data['variations'] );
    252254    }
    253255
     
    276278            'textdomain'       => false,
    277279            'example'          => false,
     280            'variations'       => false,
    278281        );
    279282        register_block_type( $block_type, $settings );
     
    302305        $this->assertNull( $data['textdomain'] );
    303306        $this->assertFalse( $data['is_dynamic'] );
     307        $this->assertSameSets( array(), $data['variations'] );
     308    }
     309
     310    public function test_get_variation() {
     311        $block_type = 'fake/variations';
     312        $settings   = array(
     313            'title'       => 'variations block test',
     314            'description' => 'a variations block test',
     315            'attributes'  => array( 'kind' => array( 'type' => 'string' ) ),
     316            'variations'  => array(
     317                array(
     318                    'name'        => 'variation',
     319                    'title'       => 'variation title',
     320                    'description' => 'variation description',
     321                    'category'    => 'media',
     322                    'icon'        => 'checkmark',
     323                    'attributes'  => array( 'kind' => 'foo' ),
     324                    'isDefault'   => true,
     325                    'example'     => array( 'attributes' => array( 'kind' => 'example' ) ),
     326                    'scope'       => array( 'inserter', 'block' ),
     327                    'keywords'    => array( 'dogs', 'cats', 'mice' ),
     328                    'innerBlocks' => array(
     329                        array(
     330                            'name'       => 'fake/bar',
     331                            'attributes' => array( 'label' => 'hi' ),
     332                        ),
     333                    ),
     334                ),
     335            ),
     336        );
     337        register_block_type( $block_type, $settings );
     338        wp_set_current_user( self::$admin_id );
     339        $request  = new WP_REST_Request( 'GET', '/wp/v2/block-types/' . $block_type );
     340        $response = rest_get_server()->dispatch( $request );
     341        $data     = $response->get_data();
     342        $this->assertSame( $block_type, $data['name'] );
     343        $this->assertArrayHasKey( 'variations', $data );
     344        $this->assertSame( 1, count( $data['variations'] ) );
     345        $variation = $data['variations'][0];
     346        $this->assertSame( 'variation title', $variation['title'] );
     347        $this->assertSame( 'variation description', $variation['description'] );
     348        $this->assertSame( 'media', $variation['category'] );
     349        $this->assertSame( 'checkmark', $variation['icon'] );
     350        $this->assertSameSets( array( 'inserter', 'block' ), $variation['scope'] );
     351        $this->assertSameSets( array( 'dogs', 'cats', 'mice' ), $variation['keywords'] );
     352        $this->assertSameSets( array( 'attributes' => array( 'kind' => 'example' ) ), $variation['example'] );
     353        $this->assertSameSets(
     354            array(
     355                array(
     356                    'name'       => 'fake/bar',
     357                    'attributes' => array( 'label' => 'hi' ),
     358                ),
     359            ),
     360            $variation['innerBlocks']
     361        );
     362        $this->assertSameSets(
     363            array( 'kind' => 'foo' ),
     364            $variation['attributes']
     365        );
    304366    }
    305367
     
    313375        $data       = $response->get_data();
    314376        $properties = $data['schema']['properties'];
    315         $this->assertCount( 20, $properties );
     377        $this->assertCount( 21, $properties );
    316378        $this->assertArrayHasKey( 'api_version', $properties );
    317379        $this->assertArrayHasKey( 'title', $properties );
     
    334396        $this->assertArrayHasKey( 'uses_context', $properties );
    335397        $this->assertArrayHasKey( 'provides_context', $properties );
     398        $this->assertArrayHasKey( 'variations', $properties );
    336399    }
    337400
Note: See TracChangeset for help on using the changeset viewer.