-
Notifications
You must be signed in to change notification settings - Fork 4.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Templates: allow templates to be activated and deactivated
- Loading branch information
Showing
58 changed files
with
1,004 additions
and
558 deletions.
There are no files selected for viewing
125 changes: 125 additions & 0 deletions
125
lib/compat/wordpress-6.8/class-gutenberg-rest-static-templates-controller.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,125 @@ | ||
<?php | ||
|
||
class Gutenberg_REST_Static_Templates_Controller extends Gutenberg_REST_Templates_Controller_6_7 { | ||
public function register_routes() { | ||
// Lists all templates. | ||
register_rest_route( | ||
$this->namespace, | ||
'/' . $this->rest_base, | ||
array( | ||
array( | ||
'methods' => WP_REST_Server::READABLE, | ||
'callback' => array( $this, 'get_items' ), | ||
'permission_callback' => array( $this, 'get_items_permissions_check' ), | ||
'args' => $this->get_collection_params(), | ||
), | ||
'schema' => array( $this, 'get_public_item_schema' ), | ||
) | ||
); | ||
|
||
// Lists/updates a single template based on the given id. | ||
register_rest_route( | ||
$this->namespace, | ||
// The route. | ||
sprintf( | ||
'/%s/(?P<id>%s%s)', | ||
$this->rest_base, | ||
/* | ||
* Matches theme's directory: `/themes/<subdirectory>/<theme>/` or `/themes/<theme>/`. | ||
* Excludes invalid directory name characters: `/:<>*?"|`. | ||
*/ | ||
'([^\/:<>\*\?"\|]+(?:\/[^\/:<>\*\?"\|]+)?)', | ||
// Matches the template name. | ||
'[\/\w%-]+' | ||
), | ||
array( | ||
'args' => array( | ||
'id' => array( | ||
'description' => __( 'The id of a template' ), | ||
'type' => 'string', | ||
'sanitize_callback' => array( $this, '_sanitize_template_id' ), | ||
), | ||
), | ||
array( | ||
'methods' => WP_REST_Server::READABLE, | ||
'callback' => array( $this, 'get_item' ), | ||
'permission_callback' => array( $this, 'get_item_permissions_check' ), | ||
'args' => array( | ||
'context' => $this->get_context_param( array( 'default' => 'view' ) ), | ||
), | ||
), | ||
'schema' => array( $this, 'get_public_item_schema' ), | ||
) | ||
); | ||
} | ||
|
||
public function get_item_schema() { | ||
$schema = parent::get_item_schema(); | ||
$schema['properties']['is_custom'] = array( | ||
'description' => __( 'Whether a template is a custom template.' ), | ||
'type' => 'bool', | ||
'context' => array( 'embed', 'view', 'edit' ), | ||
'readonly' => true, | ||
); | ||
$schema['properties']['plugin'] = array( | ||
'type' => 'string', | ||
'description' => __( 'Plugin that registered the template.' ), | ||
'readonly' => true, | ||
'context' => array( 'view', 'edit', 'embed' ), | ||
); | ||
return $schema; | ||
} | ||
|
||
public function get_items( $request ) { | ||
$query = array(); | ||
if ( isset( $request['area'] ) ) { | ||
$query['area'] = $request['area']; | ||
} | ||
if ( isset( $request['post_type'] ) ) { | ||
$query['post_type'] = $request['post_type']; | ||
} | ||
$template_files = _get_block_templates_files( 'wp_template', $query ); | ||
$query_result = array(); | ||
foreach ( $template_files as $template_file ) { | ||
$query_result[] = _build_block_template_result_from_file( $template_file, 'wp_template' ); | ||
} | ||
|
||
// Add templates registered in the template registry. Filtering out the ones which have a theme file. | ||
$registered_templates = WP_Block_Templates_Registry::get_instance()->get_by_query( $query ); | ||
$matching_registered_templates = array_filter( | ||
$registered_templates, | ||
function ( $registered_template ) use ( $template_files ) { | ||
foreach ( $template_files as $template_file ) { | ||
if ( $template_file['slug'] === $registered_template->slug ) { | ||
return false; | ||
} | ||
} | ||
return true; | ||
} | ||
); | ||
|
||
$query_result = array_merge( $query_result, $matching_registered_templates ); | ||
|
||
$templates = array(); | ||
foreach ( $query_result as $template ) { | ||
$item = $this->prepare_item_for_response( $template, $request ); | ||
$item->data['type'] = '_wp_static_template'; | ||
$templates[] = $this->prepare_response_for_collection( $item ); | ||
} | ||
|
||
return rest_ensure_response( $templates ); | ||
} | ||
|
||
public function get_item( $request ) { | ||
$template = get_block_file_template( $request['id'], 'wp_template' ); | ||
|
||
if ( ! $template ) { | ||
return new WP_Error( 'rest_template_not_found', __( 'No templates exist with that id.' ), array( 'status' => 404 ) ); | ||
} | ||
|
||
$item = $this->prepare_item_for_response( $template, $request ); | ||
// adjust the template type here instead | ||
$item->data['type'] = '_wp_static_template'; | ||
return rest_ensure_response( $item ); | ||
} | ||
} |
16 changes: 16 additions & 0 deletions
16
lib/compat/wordpress-6.8/class-gutenberg-rest-templates-controller.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
<?php | ||
|
||
class Gutenberg_REST_Templates_Controller extends WP_REST_Posts_Controller { | ||
protected function handle_status_param( $status, $request ) { | ||
if ( 'auto-draft' === $status ) { | ||
return $status; | ||
} | ||
return parent::handle_status_param( $status, $request ); | ||
} | ||
protected function add_additional_fields_schema( $schema ) { | ||
$schema = parent::add_additional_fields_schema( $schema ); | ||
|
||
$schema['properties']['status']['enum'][] = 'auto-draft'; | ||
return $schema; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,130 @@ | ||
<?php | ||
|
||
// How does this work? | ||
// 1. For wp_template, we remove the custom templates controller, so it becomes | ||
// a normal posts endpoint, modified slightly to allow auto-drafts. | ||
add_filter( 'register_post_type_args', 'gutenberg_modify_wp_template_post_type_args', 10, 2 ); | ||
function gutenberg_modify_wp_template_post_type_args( $args, $post_type ) { | ||
if ( 'wp_template' === $post_type ) { | ||
$args['rest_base'] = 'wp_template'; | ||
$args['rest_controller_class'] = 'Gutenberg_REST_Templates_Controller'; | ||
$args['autosave_rest_controller_class'] = null; | ||
$args['revisions_rest_controller_class'] = null; | ||
} | ||
return $args; | ||
} | ||
|
||
// 2. We maintain the routes for /templates and /templates/lookup. I think we'll | ||
// need to deprecate /templates eventually, but we'll still want to be able | ||
// to lookup the active template for a specific slug, and probably get a list | ||
// of all _active_ templates. For that we can keep /lookup. | ||
add_action( 'rest_api_init', 'gutenberg_maintain_templates_routes' ); | ||
function gutenberg_maintain_templates_routes() { | ||
// This should later be changed in core so we don't need initialise | ||
// WP_REST_Templates_Controller with a post type. | ||
global $wp_post_types; | ||
$wp_post_types['wp_template']->rest_base = 'templates'; | ||
$controller = new Gutenberg_REST_Templates_Controller_6_7( 'wp_template' ); | ||
$wp_post_types['wp_template']->rest_base = 'wp_template'; | ||
$controller->register_routes(); | ||
} | ||
|
||
// 3. We need a route to get that raw static templates from themes and plugins. | ||
// I registered this as a post type route because right now the | ||
// EditorProvider assumes templates are posts. | ||
add_action( 'init', 'gutenberg_setup_static_template' ); | ||
function gutenberg_setup_static_template() { | ||
global $wp_post_types; | ||
$wp_post_types['_wp_static_template'] = clone $wp_post_types['wp_template']; | ||
$wp_post_types['_wp_static_template']->name = '_wp_static_template'; | ||
$wp_post_types['_wp_static_template']->rest_base = '_wp_static_template'; | ||
$wp_post_types['_wp_static_template']->rest_controller_class = 'Gutenberg_REST_Static_Templates_Controller'; | ||
|
||
register_setting( | ||
'reading', | ||
'active_templates', | ||
array( | ||
'type' => 'object', | ||
'show_in_rest' => array( | ||
'schema' => array( | ||
'type' => 'object', | ||
'additionalProperties' => true, | ||
), | ||
), | ||
'default' => array(), | ||
'label' => 'Active Templates', | ||
) | ||
); | ||
} | ||
|
||
add_filter( 'pre_wp_unique_post_slug', 'gutenberg_allow_template_slugs_to_be_duplicated', 10, 5 ); | ||
function gutenberg_allow_template_slugs_to_be_duplicated( $override, $slug, $post_id, $post_status, $post_type ) { | ||
return 'wp_template' === $post_type ? $slug : $override; | ||
} | ||
|
||
add_filter( 'pre_get_block_templates', 'gutenberg_pre_get_block_templates', 10, 3 ); | ||
function gutenberg_pre_get_block_templates( $output, $query, $template_type ) { | ||
if ( 'wp_template' === $template_type && ! empty( $query['slug__in'] ) ) { | ||
$active_templates = get_option( 'active_templates', array() ); | ||
$slugs = $query['slug__in']; | ||
$output = array(); | ||
foreach ( $slugs as $slug ) { | ||
if ( isset( $active_templates[ $slug ] ) ) { | ||
if ( false !== $active_templates[ $slug ] ) { | ||
$post = get_post( $active_templates[ $slug ] ); | ||
if ( $post && 'publish' === $post->post_status ) { | ||
$output[] = _build_block_template_result_from_post( $post ); | ||
} | ||
} else { | ||
// Deactivated template, fall back to next slug. | ||
$output[] = array(); | ||
} | ||
} | ||
} | ||
if ( empty( $output ) ) { | ||
$output = null; | ||
} | ||
} | ||
return $output; | ||
} | ||
|
||
// Whenever templates are queried by slug, never return any user templates. | ||
// We are handling that in gutenberg_pre_get_block_templates. | ||
function gutenberg_remove_tax_query_for_templates( $query ) { | ||
if ( isset( $query->query['post_type'] ) && 'wp_template' === $query->query['post_type'] ) { | ||
// We don't have templates with this status, that's the point. We want | ||
// this query to not return any user templates. | ||
$query->set( 'post_status', array( 'pending' ) ); | ||
} | ||
} | ||
|
||
add_filter( 'pre_get_block_templates', 'gutenberg_tax_pre_get_block_templates', 10, 3 ); | ||
function gutenberg_tax_pre_get_block_templates( $output, $query, $template_type ) { | ||
// Do not remove the tax query when querying for a specific slug. | ||
if ( 'wp_template' === $template_type && ! empty( $query['slug__in'] ) ) { | ||
add_action( 'pre_get_posts', 'gutenberg_remove_tax_query_for_templates' ); | ||
} | ||
return $output; | ||
} | ||
|
||
add_filter( 'get_block_templates', 'gutenberg_tax_get_block_templates', 10, 3 ); | ||
function gutenberg_tax_get_block_templates( $output, $query, $template_type ) { | ||
if ( 'wp_template' === $template_type && ! empty( $query['slug__in'] ) ) { | ||
remove_action( 'pre_get_posts', 'gutenberg_remove_tax_query_for_templates' ); | ||
} | ||
return $output; | ||
} | ||
|
||
// We need to set the theme for the template when it's created. See: | ||
// https://github.com/WordPress/wordpress-develop/blob/b2c8d8d2c8754cab5286b06efb4c11e2b6aa92d5/src/wp-includes/rest-api/endpoints/class-wp-rest-templates-controller.php#L571-L578 | ||
add_action( 'rest_pre_insert_wp_template', 'gutenberg_set_active_template_theme', 10, 2 ); | ||
function gutenberg_set_active_template_theme( $changes, $request ) { | ||
$template = $request['id'] ? get_block_template( $request['id'], 'wp_template' ) : null; | ||
if ( $template ) { | ||
return $changes; | ||
} | ||
$changes->tax_input = array( | ||
'wp_theme' => isset( $request['theme'] ) ? $request['theme'] : get_stylesheet(), | ||
); | ||
return $changes; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.