Make WordPress Core


Ignore:
Timestamp:
10/10/2023 02:03:03 PM (21 months ago)
Author:
spacedmonkey
Message:

REST API: Fix issue with Template and Template Part Revision/Autosave REST API controllers.

The Template and Template Part REST API controllers have unique characteristics compared to other post type REST API controllers. They do not rely on integer IDs to reference objects; instead, they use a combination of the theme name and slug of the template, like 'twentytwentyfourhome.' Consequently, when the post types template and template part were introduced in [52062], it led to the registration of REST API endpoints for autosaves and revisions with invalid URL structures.

In this commit, we introduce new functionality to enable custom autosave and revisions endpoints to be registered at the post type level. Similar to the 'rest_controller_class' parameter, developers can now define 'revisions_rest_controller' and 'autosave_rest_controller.' This empowers developers to create custom controllers for these functionalities. Additionally, we introduce a 'late_route_registration' parameter, which proves helpful when dealing with custom URL patterns and regex pattern matching issues.
This commit registers new classes for template and template part autosave and revisions controllers, differentiating them from standard controllers in the following ways:

  • The response shape now matches that of the template controller.
  • Permission checks align with the template controller.
  • A custom URL pattern is introduced to support slug-based identification of templates.

Furthermore, we've updated the utility function '_build_block_template_result_from_post' to support passing revision post objects. This enhancement ensures compatibility with the custom revisions controller.

Props spacedmonkey, revgeorge, andraganescu, hellofromTonya, antonvlasenko, kadamwhite, ironprogrammer, costdev, mukesh27, timothyblynjacobs, adamsilverstein.
Fixes 56922.

File:
1 edited

Legend:

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

    r56811 r56819  
    347347        'wp_template',
    348348        array(
    349             'labels'                => array(
     349            'labels'                          => array(
    350350                'name'                  => _x( 'Templates', 'post type general name' ),
    351351                'singular_name'         => _x( 'Template', 'post type singular name' ),
     
    367367                'items_list'            => __( 'Templates list' ),
    368368            ),
    369             'description'           => __( 'Templates to include in your theme.' ),
    370             'public'                => false,
    371             '_builtin'              => true, /* internal use only. don't use this when registering your own post type. */
    372             '_edit_link'            => $template_edit_link, /* internal use only. don't use this when registering your own post type. */
    373             'has_archive'           => false,
    374             'show_ui'               => false,
    375             'show_in_menu'          => false,
    376             'show_in_rest'          => true,
    377             'rewrite'               => false,
    378             'rest_base'             => 'templates',
    379             'rest_controller_class' => 'WP_REST_Templates_Controller',
    380             'capability_type'       => array( 'template', 'templates' ),
    381             'capabilities'          => array(
     369            'description'                     => __( 'Templates to include in your theme.' ),
     370            'public'                          => false,
     371            '_builtin'                        => true, /* internal use only. don't use this when registering your own post type. */
     372            '_edit_link'                      => $template_edit_link, /* internal use only. don't use this when registering your own post type. */
     373            'has_archive'                     => false,
     374            'show_ui'                         => false,
     375            'show_in_menu'                    => false,
     376            'show_in_rest'                    => true,
     377            'rewrite'                         => false,
     378            'rest_base'                       => 'templates',
     379            'rest_controller_class'           => 'WP_REST_Templates_Controller',
     380            'autosave_rest_controller_class'  => 'WP_REST_Template_Autosaves_Controller',
     381            'revisions_rest_controller_class' => 'WP_REST_Template_Revisions_Controller',
     382            'late_route_registration'         => true,
     383            'capability_type'                 => array( 'template', 'templates' ),
     384            'capabilities'                    => array(
    382385                'create_posts'           => 'edit_theme_options',
    383386                'delete_posts'           => 'edit_theme_options',
     
    393396                'read_private_posts'     => 'edit_theme_options',
    394397            ),
    395             'map_meta_cap'          => true,
    396             'supports'              => array(
     398            'map_meta_cap'                    => true,
     399            'supports'                        => array(
    397400                'title',
    398401                'slug',
     
    408411        'wp_template_part',
    409412        array(
    410             'labels'                => array(
     413            'labels'                          => array(
    411414                'name'                  => _x( 'Template Parts', 'post type general name' ),
    412415                'singular_name'         => _x( 'Template Part', 'post type singular name' ),
     
    428431                'items_list'            => __( 'Template parts list' ),
    429432            ),
    430             'description'           => __( 'Template parts to include in your templates.' ),
    431             'public'                => false,
    432             '_builtin'              => true, /* internal use only. don't use this when registering your own post type. */
    433             '_edit_link'            => $template_edit_link, /* internal use only. don't use this when registering your own post type. */
    434             'has_archive'           => false,
    435             'show_ui'               => false,
    436             'show_in_menu'          => false,
    437             'show_in_rest'          => true,
    438             'rewrite'               => false,
    439             'rest_base'             => 'template-parts',
    440             'rest_controller_class' => 'WP_REST_Templates_Controller',
    441             'map_meta_cap'          => true,
    442             'capabilities'          => array(
     433            'description'                     => __( 'Template parts to include in your templates.' ),
     434            'public'                          => false,
     435            '_builtin'                        => true, /* internal use only. don't use this when registering your own post type. */
     436            '_edit_link'                      => $template_edit_link, /* internal use only. don't use this when registering your own post type. */
     437            'has_archive'                     => false,
     438            'show_ui'                         => false,
     439            'show_in_menu'                    => false,
     440            'show_in_rest'                    => true,
     441            'rewrite'                         => false,
     442            'rest_base'                       => 'template-parts',
     443            'rest_controller_class'           => 'WP_REST_Templates_Controller',
     444            'autosave_rest_controller_class'  => 'WP_REST_Template_Autosaves_Controller',
     445            'revisions_rest_controller_class' => 'WP_REST_Template_Revisions_Controller',
     446            'late_route_registration'         => true,
     447            'map_meta_cap'                    => true,
     448            'capabilities'                    => array(
    443449                'create_posts'           => 'edit_theme_options',
    444450                'delete_posts'           => 'edit_theme_options',
     
    454460                'read_private_posts'     => 'edit_theme_options',
    455461            ),
    456             'supports'              => array(
     462            'supports'                        => array(
    457463                'title',
    458464                'slug',
     
    15761582 *     Array or string of arguments for registering a post type.
    15771583 *
    1578  *     @type string       $label                 Name of the post type shown in the menu. Usually plural.
    1579  *                                               Default is value of $labels['name'].
    1580  *     @type string[]     $labels                An array of labels for this post type. If not set, post
    1581  *                                               labels are inherited for non-hierarchical types and page
    1582  *                                               labels for hierarchical ones. See get_post_type_labels() for a full
    1583  *                                               list of supported labels.
    1584  *     @type string       $description           A short descriptive summary of what the post type is.
    1585  *                                               Default empty.
    1586  *     @type bool         $public                Whether a post type is intended for use publicly either via
    1587  *                                               the admin interface or by front-end users. While the default
    1588  *                                               settings of $exclude_from_search, $publicly_queryable, $show_ui,
    1589  *                                               and $show_in_nav_menus are inherited from $public, each does not
    1590  *                                               rely on this relationship and controls a very specific intention.
    1591  *                                               Default false.
    1592  *     @type bool         $hierarchical          Whether the post type is hierarchical (e.g. page). Default false.
    1593  *     @type bool         $exclude_from_search   Whether to exclude posts with this post type from front end search
    1594  *                                               results. Default is the opposite value of $public.
    1595  *     @type bool         $publicly_queryable    Whether queries can be performed on the front end for the post type
    1596  *                                               as part of parse_request(). Endpoints would include:
    1597  *                                               * ?post_type={post_type_key}
    1598  *                                               * ?{post_type_key}={single_post_slug}
    1599  *                                               * ?{post_type_query_var}={single_post_slug}
    1600  *                                               If not set, the default is inherited from $public.
    1601  *     @type bool         $show_ui               Whether to generate and allow a UI for managing this post type in the
    1602  *                                               admin. Default is value of $public.
    1603  *     @type bool|string  $show_in_menu          Where to show the post type in the admin menu. To work, $show_ui
    1604  *                                               must be true. If true, the post type is shown in its own top level
    1605  *                                               menu. If false, no menu is shown. If a string of an existing top
    1606  *                                               level menu ('tools.php' or 'edit.php?post_type=page', for example), the
    1607  *                                               post type will be placed as a sub-menu of that.
    1608  *                                               Default is value of $show_ui.
    1609  *     @type bool         $show_in_nav_menus     Makes this post type available for selection in navigation menus.
    1610  *                                               Default is value of $public.
    1611  *     @type bool         $show_in_admin_bar     Makes this post type available via the admin bar. Default is value
    1612  *                                               of $show_in_menu.
    1613  *     @type bool         $show_in_rest          Whether to include the post type in the REST API. Set this to true
    1614  *                                               for the post type to be available in the block editor.
    1615  *     @type string       $rest_base             To change the base URL of REST API route. Default is $post_type.
    1616  *     @type string       $rest_namespace        To change the namespace URL of REST API route. Default is wp/v2.
    1617  *     @type string       $rest_controller_class REST API controller class name. Default is 'WP_REST_Posts_Controller'.
    1618  *     @type int          $menu_position         The position in the menu order the post type should appear. To work,
    1619  *                                               $show_in_menu must be true. Default null (at the bottom).
    1620  *     @type string       $menu_icon             The URL to the icon to be used for this menu. Pass a base64-encoded
    1621  *                                               SVG using a data URI, which will be colored to match the color scheme
    1622  *                                               -- this should begin with 'data:image/svg+xml;base64,'. Pass the name
    1623  *                                               of a Dashicons helper class to use a font icon, e.g.
    1624  *                                               'dashicons-chart-pie'. Pass 'none' to leave div.wp-menu-image empty
    1625  *                                               so an icon can be added via CSS. Defaults to use the posts icon.
    1626  *     @type string|array $capability_type       The string to use to build the read, edit, and delete capabilities.
    1627  *                                               May be passed as an array to allow for alternative plurals when using
    1628  *                                               this argument as a base to construct the capabilities, e.g.
    1629  *                                               array('story', 'stories'). Default 'post'.
    1630  *     @type string[]     $capabilities          Array of capabilities for this post type. $capability_type is used
    1631  *                                               as a base to construct capabilities by default.
    1632  *                                               See get_post_type_capabilities().
    1633  *     @type bool         $map_meta_cap          Whether to use the internal default meta capability handling.
    1634  *                                               Default false.
    1635  *     @type array        $supports              Core feature(s) the post type supports. Serves as an alias for calling
    1636  *                                               add_post_type_support() directly. Core features include 'title',
    1637  *                                               'editor', 'comments', 'revisions', 'trackbacks', 'author', 'excerpt',
    1638  *                                               'page-attributes', 'thumbnail', 'custom-fields', and 'post-formats'.
    1639  *                                               Additionally, the 'revisions' feature dictates whether the post type
    1640  *                                               will store revisions, and the 'comments' feature dictates whether the
    1641  *                                               comments count will show on the edit screen. A feature can also be
    1642  *                                               specified as an array of arguments to provide additional information
    1643  *                                               about supporting that feature.
    1644  *                                               Example: `array( 'my_feature', array( 'field' => 'value' ) )`.
    1645  *                                               Default is an array containing 'title' and 'editor'.
    1646  *     @type callable     $register_meta_box_cb  Provide a callback function that sets up the meta boxes for the
    1647  *                                               edit form. Do remove_meta_box() and add_meta_box() calls in the
    1648  *                                               callback. Default null.
    1649  *     @type string[]     $taxonomies            An array of taxonomy identifiers that will be registered for the
    1650  *                                               post type. Taxonomies can be registered later with register_taxonomy()
    1651  *                                               or register_taxonomy_for_object_type().
    1652  *                                               Default empty array.
    1653  *     @type bool|string  $has_archive           Whether there should be post type archives, or if a string, the
    1654  *                                               archive slug to use. Will generate the proper rewrite rules if
    1655  *                                               $rewrite is enabled. Default false.
    1656  *     @type bool|array   $rewrite               {
     1584 *     @type string       $label                           Name of the post type shown in the menu. Usually plural.
     1585 *                                                         Default is value of $labels['name'].
     1586 *     @type string[]     $labels                          An array of labels for this post type. If not set, post
     1587 *                                                         labels are inherited for non-hierarchical types and page
     1588 *                                                         labels for hierarchical ones. See get_post_type_labels() for a full
     1589 *                                                         list of supported labels.
     1590 *     @type string       $description                     A short descriptive summary of what the post type is.
     1591 *                                                         Default empty.
     1592 *     @type bool         $public                          Whether a post type is intended for use publicly either via
     1593 *                                                         the admin interface or by front-end users. While the default
     1594 *                                                         settings of $exclude_from_search, $publicly_queryable, $show_ui,
     1595 *                                                         and $show_in_nav_menus are inherited from $public, each does not
     1596 *                                                         rely on this relationship and controls a very specific intention.
     1597 *                                                         Default false.
     1598 *     @type bool         $hierarchical                    Whether the post type is hierarchical (e.g. page). Default false.
     1599 *     @type bool         $exclude_from_search             Whether to exclude posts with this post type from front end search
     1600 *                                                         results. Default is the opposite value of $public.
     1601 *     @type bool         $publicly_queryable              Whether queries can be performed on the front end for the post type
     1602 *                                                         as part of parse_request(). Endpoints would include:
     1603 *                                                          * ?post_type={post_type_key}
     1604 *                                                          * ?{post_type_key}={single_post_slug}
     1605 *                                                          * ?{post_type_query_var}={single_post_slug}
     1606 *                                                         If not set, the default is inherited from $public.
     1607 *     @type bool         $show_ui                         Whether to generate and allow a UI for managing this post type in the
     1608 *                                                         admin. Default is value of $public.
     1609 *     @type bool|string  $show_in_menu                    Where to show the post type in the admin menu. To work, $show_ui
     1610 *                                                         must be true. If true, the post type is shown in its own top level
     1611 *                                                         menu. If false, no menu is shown. If a string of an existing top
     1612 *                                                         level menu ('tools.php' or 'edit.php?post_type=page', for example), the
     1613 *                                                         post type will be placed as a sub-menu of that.
     1614 *                                                         Default is value of $show_ui.
     1615 *     @type bool         $show_in_nav_menus               Makes this post type available for selection in navigation menus.
     1616 *                                                         Default is value of $public.
     1617 *     @type bool         $show_in_admin_bar               Makes this post type available via the admin bar. Default is value
     1618 *                                                         of $show_in_menu.
     1619 *     @type bool         $show_in_rest                    Whether to include the post type in the REST API. Set this to true
     1620 *                                                         for the post type to be available in the block editor.
     1621 *     @type string       $rest_base                       To change the base URL of REST API route. Default is $post_type.
     1622 *     @type string       $rest_namespace                  To change the namespace URL of REST API route. Default is wp/v2.
     1623 *     @type string       $rest_controller_class           REST API controller class name. Default is 'WP_REST_Posts_Controller'.
     1624 *     @type string|bool  $autosave_rest_controller_class  REST API controller class name. Default is 'WP_REST_Autosaves_Controller'.
     1625 *     @type string|bool  $revisions_rest_controller_class REST API controller class name. Default is 'WP_REST_Revisions_Controller'.
     1626 *     @type bool         $late_route_registration         A flag to direct the REST API controllers for autosave / revisions should be registered before/after the post type controller.
     1627 *     @type int          $menu_position                   The position in the menu order the post type should appear. To work,
     1628 *                                                         $show_in_menu must be true. Default null (at the bottom).
     1629 *     @type string       $menu_icon                       The URL to the icon to be used for this menu. Pass a base64-encoded
     1630 *                                                         SVG using a data URI, which will be colored to match the color scheme
     1631 *                                                         -- this should begin with 'data:image/svg+xml;base64,'. Pass the name
     1632 *                                                         of a Dashicons helper class to use a font icon, e.g.
     1633 *                                                        'dashicons-chart-pie'. Pass 'none' to leave div.wp-menu-image empty
     1634 *                                                         so an icon can be added via CSS. Defaults to use the posts icon.
     1635 *     @type string|array $capability_type                 The string to use to build the read, edit, and delete capabilities.
     1636 *                                                         May be passed as an array to allow for alternative plurals when using
     1637 *                                                         this argument as a base to construct the capabilities, e.g.
     1638 *                                                         array('story', 'stories'). Default 'post'.
     1639 *     @type string[]     $capabilities                    Array of capabilities for this post type. $capability_type is used
     1640 *                                                         as a base to construct capabilities by default.
     1641 *                                                         See get_post_type_capabilities().
     1642 *     @type bool         $map_meta_cap                    Whether to use the internal default meta capability handling.
     1643 *                                                         Default false.
     1644 *     @type array        $supports                        Core feature(s) the post type supports. Serves as an alias for calling
     1645 *                                                         add_post_type_support() directly. Core features include 'title',
     1646 *                                                         'editor', 'comments', 'revisions', 'trackbacks', 'author', 'excerpt',
     1647 *                                                         'page-attributes', 'thumbnail', 'custom-fields', and 'post-formats'.
     1648 *                                                         Additionally, the 'revisions' feature dictates whether the post type
     1649 *                                                         will store revisions, and the 'comments' feature dictates whether the
     1650 *                                                         comments count will show on the edit screen. A feature can also be
     1651 *                                                         specified as an array of arguments to provide additional information
     1652 *                                                         about supporting that feature.
     1653 *                                                         Example: `array( 'my_feature', array( 'field' => 'value' ) )`.
     1654 *                                                         Default is an array containing 'title' and 'editor'.
     1655 *     @type callable     $register_meta_box_cb            Provide a callback function that sets up the meta boxes for the
     1656 *                                                         edit form. Do remove_meta_box() and add_meta_box() calls in the
     1657 *                                                         callback. Default null.
     1658 *     @type string[]     $taxonomies                      An array of taxonomy identifiers that will be registered for the
     1659 *                                                         post type. Taxonomies can be registered later with register_taxonomy()
     1660 *                                                         or register_taxonomy_for_object_type().
     1661 *                                                         Default empty array.
     1662 *     @type bool|string  $has_archive                     Whether there should be post type archives, or if a string, the
     1663 *                                                         archive slug to use. Will generate the proper rewrite rules if
     1664 *                                                         $rewrite is enabled. Default false.
     1665 *     @type bool|array   $rewrite                         {
    16571666 *         Triggers the handling of rewrites for this post type. To prevent rewrite, set to false.
    16581667 *         Defaults to true, using $post_type as slug. To specify rewrite rules, an array can be
     
    16691678 *                                  is not set, defaults to EP_PERMALINK.
    16701679 *     }
    1671  *     @type string|bool  $query_var             Sets the query_var key for this post type. Defaults to $post_type
    1672  *                                               key. If false, a post type cannot be loaded at
    1673  *                                               ?{query_var}={post_slug}. If specified as a string, the query
    1674  *                                               ?{query_var_string}={post_slug} will be valid.
    1675  *     @type bool         $can_export            Whether to allow this post type to be exported. Default true.
    1676  *     @type bool         $delete_with_user      Whether to delete posts of this type when deleting a user.
    1677  *                                               * If true, posts of this type belonging to the user will be moved
    1678  *                                                 to Trash when the user is deleted.
    1679  *                                               * If false, posts of this type belonging to the user will *not*
    1680  *                                                 be trashed or deleted.
    1681  *                                               * If not set (the default), posts are trashed if post type supports
    1682  *                                                 the 'author' feature. Otherwise posts are not trashed or deleted.
    1683  *                                               Default null.
    1684  *     @type array        $template              Array of blocks to use as the default initial state for an editor
    1685  *                                               session. Each item should be an array containing block name and
    1686  *                                               optional attributes. Default empty array.
    1687  *     @type string|false $template_lock         Whether the block template should be locked if $template is set.
    1688  *                                               * If set to 'all', the user is unable to insert new blocks,
    1689  *                                                 move existing blocks and delete blocks.
    1690  *                                               * If set to 'insert', the user is able to move existing blocks
    1691  *                                                 but is unable to insert new blocks and delete blocks.
    1692  *                                               Default false.
    1693  *     @type bool         $_builtin              FOR INTERNAL USE ONLY! True if this post type is a native or
    1694  *                                               "built-in" post_type. Default false.
    1695  *     @type string       $_edit_link            FOR INTERNAL USE ONLY! URL segment to use for edit link of
    1696  *                                               this post type. Default 'post.php?post=%d'.
     1680 *     @type string|bool  $query_var                      Sets the query_var key for this post type. Defaults to $post_type
     1681 *                                                        key. If false, a post type cannot be loaded at
     1682 *                                                        ?{query_var}={post_slug}. If specified as a string, the query
     1683 *                                                        ?{query_var_string}={post_slug} will be valid.
     1684 *     @type bool         $can_export                     Whether to allow this post type to be exported. Default true.
     1685 *     @type bool         $delete_with_user               Whether to delete posts of this type when deleting a user.
     1686 *                                                          * If true, posts of this type belonging to the user will be moved
     1687 *                                                            to Trash when the user is deleted.
     1688 *                                                          * If false, posts of this type belonging to the user will *not*
     1689 *                                                            be trashed or deleted.
     1690 *                                                          * If not set (the default), posts are trashed if post type supports
     1691 *                                                            the 'author' feature. Otherwise posts are not trashed or deleted.
     1692 *                                                        Default null.
     1693 *     @type array        $template                       Array of blocks to use as the default initial state for an editor
     1694 *                                                        session. Each item should be an array containing block name and
     1695 *                                                        optional attributes. Default empty array.
     1696 *     @type string|false $template_lock                  Whether the block template should be locked if $template is set.
     1697 *                                                        * If set to 'all', the user is unable to insert new blocks,
     1698 *                                                          move existing blocks and delete blocks.
     1699 *                                                       * If set to 'insert', the user is able to move existing blocks
     1700 *                                                         but is unable to insert new blocks and delete blocks.
     1701 *                                                         Default false.
     1702 *     @type bool         $_builtin                     FOR INTERNAL USE ONLY! True if this post type is a native or
     1703 *                                                      "built-in" post_type. Default false.
     1704 *     @type string       $_edit_link                   FOR INTERNAL USE ONLY! URL segment to use for edit link of
     1705 *                                                      this post type. Default 'post.php?post=%d'.
    16971706 * }
    16981707 * @return WP_Post_Type|WP_Error The registered post type object on success,
Note: See TracChangeset for help on using the changeset viewer.