Skip to content

Commit

Permalink
Editor: Adds template types, is_wp_suggestion, and fallback templat…
Browse files Browse the repository at this point in the history
…e content.

This commit improves site editor templates by:

* Adds a post meta `is_wp_suggestion` to templates created from the site editor.

Why? To differentiate the templates created from the post editor in the Template panel in inspector controls and the templates suggested in site editor.

See [WordPress/gutenberg#41387 Gutenberg PR 41387] for more details.

* Expands the template types that can be added to the site editor to include single custom post type and specific posts templates.

See [WordPress/gutenberg#41189 Gutenberg PR 41189] for more details.

* Adds fallback template content on creation in site editor:
   * Introduces `get_template_hierarchy()` to get the template hierarchy for a given template slug to be created.
   * Adds a `lookup` route to `WP_REST_Templates_Controller` to get the fallback template content.

See [WordPress/gutenberg#42520 Gutenberg PR 42520] for more details.

* Fixes a typo in default category template's description within `get_default_block_template_types()`.

See [WordPress/gutenberg#42586 Gutenberg PR 42586] for more details.

* Changes field checks from `in_array()` to `rest_is_field_included()` in `WP_REST_Post_Types_Controller`.
* Adds an `icon` field to `WP_REST_Post_Types_Controller`

Follow-up to [53129], [52331], [52275], [52062], [51962], [43087].

Props ntsekouras, spacedmonkey, mamaduka, mburridge, jameskoster, bernhard-reiter, mcsf, hellofromTonya.
See #56467.
Built from https://develop.svn.wordpress.org/trunk@54269


git-svn-id: http://core.svn.wordpress.org/trunk@53828 1a063a9b-81f0-0310-95a4-ce76da25c4cd
  • Loading branch information
hellofromtonya committed Sep 20, 2022
1 parent f2b9a6c commit 3b68d37
Show file tree
Hide file tree
Showing 4 changed files with 157 additions and 19 deletions.
86 changes: 80 additions & 6 deletions wp-includes/block-template-utils.php
Expand Up @@ -147,7 +147,7 @@ function get_default_block_template_types() {
),
'category' => array(
'title' => _x( 'Category', 'Template name' ),
'description' => __( 'Displays latest posts in single post category.' ),
'description' => __( 'Displays latest posts from a single post category.' ),
),
'taxonomy' => array(
'title' => _x( 'Taxonomy', 'Template name' ),
Expand Down Expand Up @@ -555,7 +555,8 @@ function _build_block_template_result_from_post( $post ) {
$template_file = _get_block_template_file( $post->post_type, $post->post_name );
$has_theme_file = wp_get_theme()->get_stylesheet() === $theme && null !== $template_file;

$origin = get_post_meta( $post->ID, 'origin', true );
$origin = get_post_meta( $post->ID, 'origin', true );
$is_wp_suggestion = get_post_meta( $post->ID, 'is_wp_suggestion', true );

$template = new WP_Block_Template();
$template->wp_id = $post->ID;
Expand All @@ -570,7 +571,7 @@ function _build_block_template_result_from_post( $post ) {
$template->title = $post->post_title;
$template->status = $post->post_status;
$template->has_theme_file = $has_theme_file;
$template->is_custom = true;
$template->is_custom = empty( $is_wp_suggestion );
$template->author = $post->post_author;

if ( 'wp_template' === $post->post_type && $has_theme_file && isset( $template_file['postTypes'] ) ) {
Expand Down Expand Up @@ -679,7 +680,8 @@ function get_block_templates( $query = array(), $template_type = 'wp_template' )
continue;
}

if ( $post_type &&
if (
$post_type &&
isset( $template->post_types ) &&
! in_array( $post_type, $template->post_types, true )
) {
Expand Down Expand Up @@ -912,9 +914,10 @@ function block_footer_area() {
* @return Bool Whether this file is in an ignored directory.
*/
function wp_is_theme_directory_ignored( $path ) {
$directories_to_ignore = array( '.svn', '.git', '.hg', '.bzr', 'node_modules', 'vendor' );
$directories_to_ignore = array( '.DS_Store', '.svn', '.git', '.hg', '.bzr', 'node_modules', 'vendor' );

foreach ( $directories_to_ignore as $directory ) {
if ( strpos( $path, $directory ) === 0 ) {
if ( str_starts_with( $path, $directory ) ) {
return true;
}
}
Expand Down Expand Up @@ -1023,3 +1026,74 @@ function wp_generate_block_templates_export_file() {

return $filename;
}

/**
* Gets the template hierarchy for the given template slug to be created.
*
*
* Note: Always add `index` as the last fallback template.
*
* @since 6.1.0
*
* @param string $slug The template slug to be created.
* @param boolean $is_custom Optional. Indicates if a template is custom or
* part of the template hierarchy. Default false.
* @param string $template_prefix Optional. The template prefix for the created template.
* Used to extract the main template type, e.g.
* in `taxonomy-books` the `taxonomy` is extracted.
* Default empty string.
* @return string[] The template hierarchy.
*/
function get_template_hierarchy( $slug, $is_custom = false, $template_prefix = '' ) {
if ( 'index' === $slug ) {
return array( 'index' );
}
if ( $is_custom ) {
return array( 'page', 'singular', 'index' );
}
if ( 'front-page' === $slug ) {
return array( 'front-page', 'home', 'index' );
}

$template_hierarchy = array( $slug );

// Most default templates don't have `$template_prefix` assigned.
if ( $template_prefix ) {
list( $type ) = explode( '-', $template_prefix );
// These checks are needed because the `$slug` above is always added.
if ( ! in_array( $template_prefix, array( $slug, $type ), true ) ) {
$template_hierarchy[] = $template_prefix;
}
if ( $slug !== $type ) {
$template_hierarchy[] = $type;
}
}

// Handle `archive` template.
if (
str_starts_with( $slug, 'author' ) ||
str_starts_with( $slug, 'taxonomy' ) ||
str_starts_with( $slug, 'category' ) ||
str_starts_with( $slug, 'tag' ) ||
'date' === $slug
) {
$template_hierarchy[] = 'archive';
}
// Handle `single` template.
if ( 'attachment' === $slug ) {
$template_hierarchy[] = 'single';
}

// Handle `singular` template.
if (
str_starts_with( $slug, 'single' ) ||
str_starts_with( $slug, 'page' ) ||
'attachment' === $slug
) {
$template_hierarchy[] = 'singular';
}

$template_hierarchy[] = 'index';

return $template_hierarchy;
};
Expand Up @@ -186,54 +186,58 @@ public function prepare_item_for_response( $item, $request ) {
$fields = $this->get_fields_for_response( $request );
$data = array();

if ( in_array( 'capabilities', $fields, true ) ) {
if ( rest_is_field_included( 'capabilities', $fields ) ) {
$data['capabilities'] = $post_type->cap;
}

if ( in_array( 'description', $fields, true ) ) {
if ( rest_is_field_included( 'description', $fields ) ) {
$data['description'] = $post_type->description;
}

if ( in_array( 'hierarchical', $fields, true ) ) {
if ( rest_is_field_included( 'hierarchical', $fields ) ) {
$data['hierarchical'] = $post_type->hierarchical;
}

if ( in_array( 'visibility', $fields, true ) ) {
if ( rest_is_field_included( 'visibility', $fields ) ) {
$data['visibility'] = array(
'show_in_nav_menus' => (bool) $post_type->show_in_nav_menus,
'show_ui' => (bool) $post_type->show_ui,
);
}

if ( in_array( 'viewable', $fields, true ) ) {
if ( rest_is_field_included( 'viewable', $fields ) ) {
$data['viewable'] = is_post_type_viewable( $post_type );
}

if ( in_array( 'labels', $fields, true ) ) {
if ( rest_is_field_included( 'labels', $fields ) ) {
$data['labels'] = $post_type->labels;
}

if ( in_array( 'name', $fields, true ) ) {
if ( rest_is_field_included( 'name', $fields ) ) {
$data['name'] = $post_type->label;
}

if ( in_array( 'slug', $fields, true ) ) {
if ( rest_is_field_included( 'slug', $fields ) ) {
$data['slug'] = $post_type->name;
}

if ( in_array( 'supports', $fields, true ) ) {
if ( rest_is_field_included( 'icon', $fields ) ) {
$data['icon'] = $post_type->menu_icon;
}

if ( rest_is_field_included( 'supports', $fields ) ) {
$data['supports'] = $supports;
}

if ( in_array( 'taxonomies', $fields, true ) ) {
if ( rest_is_field_included( 'taxonomies', $fields ) ) {
$data['taxonomies'] = array_values( $taxonomies );
}

if ( in_array( 'rest_base', $fields, true ) ) {
if ( rest_is_field_included( 'rest_base', $fields ) ) {
$data['rest_base'] = $base;
}

if ( in_array( 'rest_namespace', $fields, true ) ) {
if ( rest_is_field_included( 'rest_namespace', $fields ) ) {
$data['rest_namespace'] = $namespace;
}

Expand Down Expand Up @@ -287,6 +291,7 @@ protected function prepare_links( $post_type ) {
* @since 4.7.0
* @since 4.8.0 The `supports` property was added.
* @since 5.9.0 The `visibility` and `rest_namespace` properties were added.
* @since 6.1.0 The `icon` property was added.
*
* @return array Item schema data.
*/
Expand Down Expand Up @@ -385,6 +390,12 @@ public function get_item_schema() {
),
),
),
'icon' => array(
'description' => __( 'The icon for the post type.' ),
'type' => array( 'string', 'null' ),
'context' => array( 'view', 'edit', 'embed' ),
'readonly' => true,
),
),
);

Expand Down
Expand Up @@ -42,6 +42,7 @@ public function __construct( $post_type ) {
* Registers the controllers routes.
*
* @since 5.8.0
* @since 6.1.0 Endpoint for fallback template content.
*/
public function register_routes() {
// Lists all templates.
Expand All @@ -65,6 +66,34 @@ public function register_routes() {
)
);

// Get fallback template content.
register_rest_route(
$this->namespace,
'/' . $this->rest_base . '/lookup',
array(
array(
'methods' => WP_REST_Server::READABLE,
'callback' => array( $this, 'get_template_fallback' ),
'permission_callback' => array( $this, 'get_item_permissions_check' ),
'args' => array(
'slug' => array(
'description' => __( 'The slug of the template to get the fallback for' ),
'type' => 'string',
'required' => true,
),
'is_custom' => array(
'description' => __( ' Indicates if a template is custom or part of the template hierarchy' ),
'type' => 'boolean',
),
'template_prefix' => array(
'description' => __( 'The template prefix for the created template. This is used to extract the main template type, e.g. in `taxonomy-books` extracts the `taxonomy`' ),
'type' => 'string',
),
),
),
)
);

// Lists/updates a single template based on the given id.
register_rest_route(
$this->namespace,
Expand Down Expand Up @@ -117,6 +146,21 @@ public function register_routes() {
);
}

/**
* Returns the fallback template for the given slug.
*
* @since 6.1.0
*
* @param WP_REST_Request $request The request instance.
* @return WP_REST_Response|WP_Error
*/
public function get_template_fallback( $request ) {
$hierarchy = get_template_hierarchy( $request['slug'], $request['is_custom'], $request['template_prefix'] );
$fallback_template = resolve_block_template( $request['slug'], $hierarchy, '' );
$response = $this->prepare_item_for_response( $fallback_template, $request );
return rest_ensure_response( $response );
}

/**
* Checks if the user has permissions to make the request.
*
Expand Down Expand Up @@ -525,6 +569,15 @@ protected function prepare_item_for_database( $request ) {
$changes->post_excerpt = $template->description;
}

if ( 'wp_template' === $this->post_type && isset( $request['is_wp_suggestion'] ) ) {
$changes->meta_input = wp_parse_args(
array(
'is_wp_suggestion' => $request['is_wp_suggestion'],
),
$changes->meta_input = array()
);
}

if ( 'wp_template_part' === $this->post_type ) {
if ( isset( $request['area'] ) ) {
$changes->tax_input['wp_template_part_area'] = _filter_block_template_part_area( $request['area'] );
Expand Down
2 changes: 1 addition & 1 deletion wp-includes/version.php
Expand Up @@ -16,7 +16,7 @@
*
* @global string $wp_version
*/
$wp_version = '6.1-alpha-54268';
$wp_version = '6.1-alpha-54269';

/**
* Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.
Expand Down

0 comments on commit 3b68d37

Please sign in to comment.