diff --git a/src/wp-includes/post.php b/src/wp-includes/post.php index 993056ff2c032..ce820e6188117 100644 --- a/src/wp-includes/post.php +++ b/src/wp-includes/post.php @@ -26,46 +26,48 @@ function create_initial_post_types() { 'labels' => array( 'name_admin_bar' => _x( 'Post', 'add new from admin bar' ), ), - 'public' => true, - '_builtin' => true, /* internal use only. don't use this when registering your own post type. */ - '_edit_link' => 'post.php?post=%d', /* internal use only. don't use this when registering your own post type. */ - 'capability_type' => 'post', - 'map_meta_cap' => true, - 'menu_position' => 5, - 'menu_icon' => 'dashicons-admin-post', - 'hierarchical' => false, - 'rewrite' => false, - 'query_var' => false, - 'delete_with_user' => true, - 'supports' => array( 'title', 'editor', 'author', 'thumbnail', 'excerpt', 'trackbacks', 'custom-fields', 'comments', 'revisions', 'post-formats' ), - 'show_in_rest' => true, - 'rest_base' => 'posts', - 'rest_controller_class' => 'WP_REST_Posts_Controller', + 'public' => true, + '_builtin' => true, /* internal use only. don't use this when registering your own post type. */ + '_edit_link' => 'post.php?post=%d', /* internal use only. don't use this when registering your own post type. */ + 'capability_type' => 'post', + 'map_meta_cap' => true, + 'menu_position' => 5, + 'menu_icon' => 'dashicons-admin-post', + 'hierarchical' => false, + 'rewrite' => false, + 'query_var' => false, + 'delete_with_user' => true, + 'supports' => array( 'title', 'editor', 'author', 'thumbnail', 'excerpt', 'trackbacks', 'custom-fields', 'comments', 'revisions', 'post-formats' ), + 'show_in_rest' => true, + 'rest_base' => 'posts', + 'rest_controller_class' => 'WP_REST_Posts_Controller', + 'default_rendering_mode' => 'post-only', ) ); register_post_type( 'page', array( - 'labels' => array( + 'labels' => array( 'name_admin_bar' => _x( 'Page', 'add new from admin bar' ), ), - 'public' => true, - 'publicly_queryable' => false, - '_builtin' => true, /* internal use only. don't use this when registering your own post type. */ - '_edit_link' => 'post.php?post=%d', /* internal use only. don't use this when registering your own post type. */ - 'capability_type' => 'page', - 'map_meta_cap' => true, - 'menu_position' => 20, - 'menu_icon' => 'dashicons-admin-page', - 'hierarchical' => true, - 'rewrite' => false, - 'query_var' => false, - 'delete_with_user' => true, - 'supports' => array( 'title', 'editor', 'author', 'thumbnail', 'page-attributes', 'custom-fields', 'comments', 'revisions' ), - 'show_in_rest' => true, - 'rest_base' => 'pages', - 'rest_controller_class' => 'WP_REST_Posts_Controller', + 'public' => true, + 'publicly_queryable' => false, + '_builtin' => true, /* internal use only. don't use this when registering your own post type. */ + '_edit_link' => 'post.php?post=%d', /* internal use only. don't use this when registering your own post type. */ + 'capability_type' => 'page', + 'map_meta_cap' => true, + 'menu_position' => 20, + 'menu_icon' => 'dashicons-admin-page', + 'hierarchical' => true, + 'rewrite' => false, + 'query_var' => false, + 'delete_with_user' => true, + 'supports' => array( 'title', 'editor', 'author', 'thumbnail', 'page-attributes', 'custom-fields', 'comments', 'revisions' ), + 'show_in_rest' => true, + 'rest_base' => 'pages', + 'rest_controller_class' => 'WP_REST_Posts_Controller', + 'default_rendering_mode' => 'template-lock', ) ); @@ -2326,6 +2328,25 @@ function get_post_types_by_support( $feature, $operator = 'and' ) { return array_keys( wp_filter_object_list( $_wp_post_type_features, $features, $operator ) ); } +/** + * Get the available rendering modes for the Block Editor. + * + * post-only: This mode extracts the post blocks from the template and renders only those. + * The idea is to allow the user to edit the post/page in isolation without the wrapping template. + * + * template-locked: This mode renders both the template and the post blocks + * but the template blocks are locked and can't be edited. The post blocks are editable. + * + * @return array Array of available rendering modes. + */ +function get_post_type_rendering_modes() { + return array( + 'post-only', + 'template-lock', + 'template-locked', + ); +} + /** * Updates the post type for the post ID. * diff --git a/src/wp-includes/rest-api/endpoints/class-wp-rest-post-types-controller.php b/src/wp-includes/rest-api/endpoints/class-wp-rest-post-types-controller.php index d766d5c61ddf8..a660e2f2dd301 100644 --- a/src/wp-includes/rest-api/endpoints/class-wp-rest-post-types-controller.php +++ b/src/wp-includes/rest-api/endpoints/class-wp-rest-post-types-controller.php @@ -255,8 +255,42 @@ public function prepare_item_for_response( $item, $request ) { } $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; - $data = $this->add_additional_fields_to_object( $data, $request ); - $data = $this->filter_response_by_context( $data, $context ); + + // Editor rendering mode. + if ( wp_is_block_theme() && 'edit' === $context && property_exists( $post_type, 'default_rendering_mode' ) ) { + /** + * Filters the block editor rendering mode for a post type. + * + * @since 6.7.0 + * @param string $default_rendering_mode Default rendering mode for the post type. + * @param WP_Post_Type $post_type Post type name. + * @return string Default rendering mode for the post type. + */ + $rendering_mode = apply_filters( 'post_type_default_rendering_mode', $post_type->default_rendering_mode, $post_type ); + + /** + * Filters the block editor rendering mode for a specific post type. + * Applied after the `post_type_default_rendering_mode` filter. + * + * The dynamic portion of the hook name, `$item->name`, refers to the post type slug. + * + * @since 6.7.0 + * @param string $default_rendering_mode Default rendering mode for the post type. + * @param WP_Post_Type $post_type Post type object. + * @return string Default rendering mode for the post type. + */ + $rendering_mode = apply_filters( "post_type_{$post_type->name}_default_rendering_mode", $rendering_mode, $post_type ); + + // Validate the filtered rendering mode. + if ( ! in_array( $rendering_mode, get_post_type_rendering_modes(), true ) ) { + $rendering_mode = 'post-only'; + } + + $data['default_rendering_mode'] = $rendering_mode; + } + + $data = $this->add_additional_fields_to_object( $data, $request ); + $data = $this->filter_response_by_context( $data, $context ); // Wrap the data in a response object. $response = rest_ensure_response( $data );