Skip to content

Commit

Permalink
Add an 'area' term for Template Parts. (#28410)
Browse files Browse the repository at this point in the history
* register term

* update rest controller and build result functions

* dont add term to regular template posts

* only prepare term for database if template part

* rename 'section'

* add query support

* refactor json attribute injection, use for both plural and singular file getters

* only allow for supported section types

* remove unnecessary newlines

* help function for ensuring supported section type

* fix php lint error

* rename function

* only decode json once per request

* update 'from post' test

* rename term 'wp_template_section'

* update rest tests for template parts

* update block templates tests

* add TODOs to follow up on after updating themes

* rename register function

* remove unnecessary else

* fix renamed function in tests

* make should_include logic more readable

* update format, function name, and check terms error

* define constants

* trigger warning when unsupported type is used

* use WP_Theme_JSON_Resolver

* just some spacing

* use new methods after rebase updates

* use 'uncategorized' for both unspecified and unsupported

* remove unnecessarily added newlines

* add test for new theme json getter

* Update lib/class-wp-theme-json.php

Co-authored-by: André <nosolosw@users.noreply.github.com>

* Update phpunit/class-wp-theme-json-test.php

Co-authored-by: André <nosolosw@users.noreply.github.com>

* update method name calls

* rename section to area

* fix typo

Co-authored-by: André <nosolosw@users.noreply.github.com>
  • Loading branch information
Addison-Stavlo and nosolosw authored Feb 11, 2021
1 parent beb765c commit 1a29dbd
Show file tree
Hide file tree
Showing 7 changed files with 392 additions and 6 deletions.
13 changes: 13 additions & 0 deletions lib/class-wp-theme-json.php
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ class WP_Theme_JSON {
*/
const SCHEMA = array(
'customTemplates' => null,
'templateParts' => null,
'styles' => array(
'border' => array(
'radius' => null,
Expand Down Expand Up @@ -1068,6 +1069,18 @@ public function get_custom_templates() {
}
}

/**
* Returns the template part data of current theme.
*
* @return array
*/
public function get_template_parts() {
if ( ! isset( $this->theme_json['templateParts'] ) ) {
return array();
}
return $this->theme_json['templateParts'];
}

/**
* Returns the stylesheet that results of processing
* the theme.json structure this object represents.
Expand Down
66 changes: 60 additions & 6 deletions lib/full-site-editing/block-templates.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,17 @@ function _gutenberg_get_template_file( $template_type, $slug ) {
foreach ( $themes as $theme_slug => $theme_dir ) {
$file_path = $theme_dir . '/' . $template_base_paths[ $template_type ] . '/' . $slug . '.html';
if ( file_exists( $file_path ) ) {
return array(
$new_template_item = array(
'slug' => $slug,
'path' => $file_path,
'theme' => $theme_slug,
'type' => $template_type,
);

if ( 'wp_template_part' === $template_type ) {
return _gutenberg_add_template_part_area_info( $new_template_item );
}
return $new_template_item;
}
}

Expand Down Expand Up @@ -93,18 +98,45 @@ function _gutenberg_get_template_files( $template_type ) {
// Subtract ending '.html'.
-5
);
$template_files[] = array(
$new_template_item = array(
'slug' => $template_slug,
'path' => $template_file,
'theme' => $theme_slug,
'type' => $template_type,
);

if ( 'wp_template_part' === $template_type ) {
$template_files[] = _gutenberg_add_template_part_area_info( $new_template_item );
} else {
$template_files[] = $new_template_item;
}
}
}

return $template_files;
}

/**
* Attempts to add the template part's area information to the input template.
*
* @param array $template_info Template to add information to (requires 'type' and 'slug' fields).
*
* @return array Template.
*/
function _gutenberg_add_template_part_area_info( $template_info ) {
if ( WP_Theme_JSON_Resolver::theme_has_support() ) {
$theme_data = WP_Theme_JSON_Resolver::get_theme_data()->get_template_parts();
}

if ( isset( $theme_data[ $template_info['slug'] ]['area'] ) ) {
$template_info['area'] = gutenberg_filter_template_part_area_type( $theme_data[ $template_info['slug'] ]['area'] );
} else {
$template_info['area'] = WP_TEMPLATE_PART_AREA_UNCATEGORIZED;
}

return $template_info;
}

/**
* Parses wp_template content and injects the current theme's
* stylesheet as a theme attribute into each wp_template_part
Expand Down Expand Up @@ -171,6 +203,10 @@ function _gutenberg_build_template_result_from_file( $template_file, $template_t
$template->title = $default_template_types[ $template_file['slug'] ]['title'];
}

if ( 'wp_template_part' === $template_type && isset( $template_file['area'] ) ) {
$template->area = $template_file['area'];
}

return $template;
}

Expand Down Expand Up @@ -206,6 +242,13 @@ function _gutenberg_build_template_result_from_post( $post ) {
$template->title = $post->post_title;
$template->status = $post->post_status;

if ( 'wp_template_part' === $post->post_type ) {
$type_terms = get_the_terms( $post, 'wp_template_part_area' );
if ( ! is_wp_error( $type_terms ) && false !== $type_terms ) {
$template->area = $type_terms[0]->name;
}
}

return $template;
}

Expand Down Expand Up @@ -237,6 +280,15 @@ function gutenberg_get_block_templates( $query = array(), $template_type = 'wp_t
),
);

if ( 'wp_template_part' === $template_type && isset( $query['area'] ) ) {
$wp_query_args['tax_query'][] = array(
'taxonomy' => 'wp_template_part_area',
'field' => 'name',
'terms' => $query['area'],
);
$wp_query_args['tax_query']['relation'] = 'AND';
}

if ( isset( $query['slug__in'] ) ) {
$wp_query_args['post_name__in'] = $query['slug__in'];
}
Expand All @@ -261,14 +313,16 @@ function gutenberg_get_block_templates( $query = array(), $template_type = 'wp_t
if ( ! isset( $query['wp_id'] ) ) {
$template_files = _gutenberg_get_template_files( $template_type );
foreach ( $template_files as $template_file ) {
$is_custom = array_search(
$is_not_custom = false === array_search(
wp_get_theme()->get_stylesheet() . '//' . $template_file['slug'],
array_column( $query_result, 'id' ),
true
);
$should_include = false === $is_custom && (
! isset( $query['slug__in'] ) || in_array( $template_file['slug'], $query['slug__in'], true )
);
$fits_slug_query =
! isset( $query['slug__in'] ) || in_array( $template_file['slug'], $query['slug__in'], true );
$fits_area_query =
! isset( $query['area'] ) || $template_file['area'] === $query['area'];
$should_include = $is_not_custom && $fits_slug_query && $fits_area_query;
if ( $should_include ) {
$query_result[] = _gutenberg_build_template_result_from_file( $template_file, $template_type );
}
Expand Down
25 changes: 25 additions & 0 deletions lib/full-site-editing/class-wp-rest-templates-controller.php
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,9 @@ public function get_items( $request ) {
if ( isset( $request['wp_id'] ) ) {
$query['wp_id'] = $request['wp_id'];
}
if ( isset( $request['area'] ) ) {
$query['area'] = $request['area'];
}
$templates = array();
foreach ( gutenberg_get_block_templates( $query, $this->post_type ) as $template ) {
$data = $this->prepare_item_for_response( $template, $request );
Expand Down Expand Up @@ -358,6 +361,16 @@ protected function prepare_item_for_database( $request ) {
$changes->post_excerpt = $template->description;
}

if ( 'wp_template_part' === $this->post_type ) {
if ( isset( $request['area'] ) ) {
$changes->tax_input['wp_template_part_area'] = gutenberg_filter_template_part_area_type( $request['area'] );
} elseif ( null !== $template && ! $template->is_custom && $template->area ) {
$changes->tax_input['wp_template_part_area'] = gutenberg_filter_template_part_area_type( $template->area );
} elseif ( ! $template->area ) {
$changes->tax_input['wp_template_part_area'] = WP_TEMPLATE_PART_AREA_UNCATEGORIZED;
}
}

return $changes;
}

Expand Down Expand Up @@ -386,6 +399,10 @@ public function prepare_item_for_response( $template, $request ) { // phpcs:igno
'wp_id' => $template->wp_id,
);

if ( 'wp_template_part' === $template->type ) {
$result['area'] = $template->area;
}

$result = $this->add_additional_fields_to_object( $result, $request );

$response = rest_ensure_response( $result );
Expand Down Expand Up @@ -536,6 +553,14 @@ public function get_item_schema() {
),
);

if ( 'wp_template_part' === $this->post_type ) {
$schema['properties']['area'] = array(
'description' => __( 'Where the template part is intended for use (header, footer, etc.)', 'gutenberg' ),
'type' => 'string',
'context' => array( 'embed', 'view', 'edit' ),
);
}

$this->schema = $schema;

return $this->add_additional_fields_schema( $this->schema );
Expand Down
83 changes: 83 additions & 0 deletions lib/full-site-editing/template-parts.php
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,49 @@ function gutenberg_register_template_part_post_type() {
}
add_action( 'init', 'gutenberg_register_template_part_post_type' );

/**
* Registers the 'wp_template_part_area' taxonomy.
*/
function gutenberg_register_wp_template_part_area_taxonomy() {
if ( ! gutenberg_is_fse_theme() ) {
return;
}

register_taxonomy(
'wp_template_part_area',
array( 'wp_template_part' ),
array(
'public' => false,
'hierarchical' => false,
'labels' => array(
'name' => __( 'Template Part Areas', 'gutenberg' ),
'singular_name' => __( 'Template Part Area', 'gutenberg' ),
),
'query_var' => false,
'rewrite' => false,
'show_ui' => false,
'_builtin' => true,
'show_in_nav_menus' => false,
'show_in_rest' => false,
)
);
}
add_action( 'init', 'gutenberg_register_wp_template_part_area_taxonomy' );

// Definte constants for supported wp_template_part_area taxonomy.
if ( ! defined( 'WP_TEMPLATE_PART_AREA_HEADER' ) ) {
define( 'WP_TEMPLATE_PART_AREA_HEADER', 'header' );
}
if ( ! defined( 'WP_TEMPLATE_PART_AREA_FOOTER' ) ) {
define( 'WP_TEMPLATE_PART_AREA_FOOTER', 'footer' );
}
if ( ! defined( 'WP_TEMPLATE_PART_AREA_SIDEBAR' ) ) {
define( 'WP_TEMPLATE_PART_AREA_SIDEBAR', 'sidebar' );
}
if ( ! defined( 'WP_TEMPLATE_PART_AREA_UNCATEGORIZED' ) ) {
define( 'WP_TEMPLATE_PART_AREA_UNCATEGORIZED', 'uncategorized' );
}

/**
* Fixes the label of the 'wp_template_part' admin menu entry.
*/
Expand Down Expand Up @@ -118,3 +161,43 @@ function set_unique_slug_on_create_template_part( $post_id ) {
}
}
add_action( 'save_post_wp_template_part', 'set_unique_slug_on_create_template_part' );

/**
* Returns a filtered list of allowed area types for template parts.
*
* @return array The supported template part area types.
*/
function gutenberg_get_allowed_template_part_area_types() {
$default_area_types = array(
WP_TEMPLATE_PART_AREA_HEADER,
WP_TEMPLATE_PART_AREA_FOOTER,
WP_TEMPLATE_PART_AREA_SIDEBAR,
WP_TEMPLATE_PART_AREA_UNCATEGORIZED,
);

/**
* Filters the list of allowed template part area types.
*
* @param array $default_area_types An array of supported area types.
*/
return apply_filters( 'default_wp_template_part_area_types', $default_area_types );
}

/**
* Checks whether the input 'type' is a supported area type.
* Returns the input if supported, otherwise returns the 'other' type.
*
* @param string $type Template part area name.
*
* @return string Input if supported, else 'other'.
*/
function gutenberg_filter_template_part_area_type( $type ) {
if ( in_array( $type, gutenberg_get_allowed_template_part_area_types(), true ) ) {
return $type;
}
$warning_message = '"' . $type . '"';
$warning_message .= __( ' is not a supported wp_template_part_area type and has been added as ', 'gutenberg' );
$warning_message .= '"' . WP_TEMPLATE_PART_AREA_UNCATEGORIZED . '".';
trigger_error( $warning_message, E_USER_NOTICE );
return WP_TEMPLATE_PART_AREA_UNCATEGORIZED;
}
Loading

0 comments on commit 1a29dbd

Please sign in to comment.