REST API: Allow passing existing template value for posts even when template no longer exists.

Also remove `enum` for validating allowed templates to allow plugins to dynamically supply their own templates for specific posts, even when they are not in the theme.

Props TimothyBlynJacobs, jnylen0, swissspidy.
Fixes #39996.

Built from https://develop.svn.wordpress.org/trunk@41979


git-svn-id: http://core.svn.wordpress.org/trunk@41813 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This commit is contained in:
Weston Ruter 2017-10-23 22:11:46 +00:00
parent b8fc8cb59c
commit 29d213cfbd
2 changed files with 55 additions and 8 deletions

View File

@ -574,7 +574,7 @@ class WP_REST_Posts_Controller extends WP_REST_Controller {
}
if ( ! empty( $schema['properties']['template'] ) && isset( $request['template'] ) ) {
$this->handle_template( $request['template'], $post_id );
$this->handle_template( $request['template'], $post_id, true );
}
$terms_update = $this->handle_terms( $post_id, $request );
@ -1071,6 +1071,11 @@ class WP_REST_Posts_Controller extends WP_REST_Controller {
$prepared_post->ping_status = $request['ping_status'];
}
if ( ! empty( $schema['properties']['template'] ) ) {
// Force template to null so that it can be handled exclusively by the REST controller.
$prepared_post->page_template = null;
}
/**
* Filters a post before it is inserted via the REST API.
*
@ -1147,20 +1152,60 @@ class WP_REST_Posts_Controller extends WP_REST_Controller {
}
/**
* Check whether the template is valid for the given post.
*
* @since 4.9.0
*
* @param string $template Page template filename.
* @param WP_REST_Request $request Request.
* @return bool|WP_Error True if template is still valid or if the same as existing value, or false if template not supported.
*/
public function check_template( $template, $request ) {
if ( ! $template ) {
return true;
}
if ( $request['id'] ) {
$current_template = get_page_template_slug( $request['id'] );
} else {
$current_template = '';
}
// Always allow for updating a post to the same template, even if that template is no longer supported.
if ( $template === $current_template ) {
return true;
}
// If this is a create request, get_post() will return null and wp theme will fallback to the passed post type.
$allowed_templates = wp_get_theme()->get_page_templates( get_post( $request['id'] ), $this->post_type );
if ( isset( $allowed_templates[ $template ] ) ) {
return true;
}
/* translators: 1: parameter, 2: list of valid values */
return new WP_Error( 'rest_invalid_param', sprintf( __( '%1$s is not one of %2$s.' ), 'template', implode( ', ', array_keys( $allowed_templates ) ) ) );
}
/**
* Sets the template for a post.
*
* @since 4.7.0
* @since 4.9.0 Introduced the $validate parameter.
*
* @param string $template Page template filename.
* @param integer $post_id Post ID.
* @param bool $validate Whether to validate that the template selected is valid.
*/
public function handle_template( $template, $post_id ) {
if ( in_array( $template, array_keys( wp_get_theme()->get_page_templates( get_post( $post_id ) ) ), true ) ) {
update_post_meta( $post_id, '_wp_page_template', $template );
} else {
update_post_meta( $post_id, '_wp_page_template', '' );
public function handle_template( $template, $post_id, $validate = false ) {
if ( $validate && ! array_key_exists( $template, wp_get_theme()->get_page_templates( get_post( $post_id ) ) ) ) {
$template = '';
}
update_post_meta( $post_id, '_wp_page_template', $template );
}
/**
@ -1996,8 +2041,10 @@ class WP_REST_Posts_Controller extends WP_REST_Controller {
$schema['properties']['template'] = array(
'description' => __( 'The theme file to use to display the object.' ),
'type' => 'string',
'enum' => array_merge( array_keys( wp_get_theme()->get_page_templates( null, $this->post_type ) ), array( '' ) ),
'context' => array( 'view', 'edit' ),
'arg_options' => array(
'validate_callback' => array( $this, 'check_template' ),
),
);
$taxonomies = wp_list_filter( get_object_taxonomies( $this->post_type, 'objects' ), array( 'show_in_rest' => true ) );

View File

@ -4,7 +4,7 @@
*
* @global string $wp_version
*/
$wp_version = '4.9-beta3-41978';
$wp_version = '4.9-beta3-41979';
/**
* Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.