WordPress.org

Make WordPress Core

Opened 7 months ago

Closed 7 months ago

#38877 closed defect (bug) (fixed)

REST API - Unable to update page when default template used.

Reported by: lucasstark Owned by: rmccue
Milestone: 4.7 Priority: normal
Severity: normal Version: 4.7
Component: REST API Keywords: has-patch has-unit-tests
Focuses: rest-api Cc:

Description

Sending a request to update a page with the template property set to an empty string results in an Invalid Rest Request Parameter.

The reason this occurs is because the schema property for template is configured as an enum of the theme page templates.

<?php
$schema['properties']['template'] = array(
                        'description' => __( 'The theme file to use to display the object.' ),
                        'type'        => 'string',
                        'enum'        => array_keys( wp_get_theme()->get_page_templates( null, $this->post_type ) ),
                        'context'     => array( 'view', 'edit' ),
                );

When validation occurs against the template property it will fail if the template is the default, which is an empty string.

An example to reproduce, use the Javascript Client Library and do something like the following. This assumes the page you fetch is using the default template, which will be an empty string.

var page = new wp.api.models.Page( { id : 1 } );
page.fetch().done(function() {
      page.set('title', 'Testing');
      page.save();
});

This fails since the template property on the model is empty, therefore schema param validation fails when the template property is compared against the enumerated values for the themes page templates.

Attachments (3)

38877.diff (2.9 KB) - added by swissspidy 7 months ago.
38877.2.diff (4.4 KB) - added by joehoyle 7 months ago.
38877.3.diff (7.3 KB) - added by joehoyle 7 months ago.

Download all attachments as: .zip

Change History (15)

@swissspidy
7 months ago

#1 @swissspidy
7 months ago

  • Keywords has-patch has-unit-tests added
  • Milestone changed from Awaiting Review to 4.7

wp_insert_post() checks if the page template is valid (i.e. exists) or equals 'default'. It seems sensible to do the same for the REST API. See 38877.diff.

#2 @lucasstark
7 months ago

@swissspidy The page template can also be empty, so it needs to account for that as well.

To reproduce create a new page from the dashboard and then look at the result from the API for that new page.

http://example.com/wp-json/wp/v2/pages/<PAGE-ID>

You'll see that the template is an empty string.

#3 @joehoyle
7 months ago

  • Owner set to joehoyle
  • Status changed from new to assigned

I think we should support '' as a value value, however I don't think default is a good idea. Elsewhere in the API we use null / empty strings to set things back to their default, also setting to default I believe actually set's it to an empty string anyway.

In trying to fix this, I'm having some issues with our unit tests which is holding this up. We have an issue with the global state in the tests where the route is registered with the enum, so filtering the templates doesn't affect the enum - as all the endpoints are registered on rest_api_init before the tests have run, this is proving to be quite tricky.

#4 @rmccue
7 months ago

  • Owner changed from joehoyle to rmccue
  • Status changed from assigned to reviewing

#5 follow-up: @rmccue
7 months ago

I agree with @joehoyle on '' vs 'default', I'd rather avoid the magic string if we can here.

#6 in reply to: ↑ 5 @rachelbaker
7 months ago

Replying to rmccue:

I agree with @joehoyle on '' vs 'default', I'd rather avoid the magic string if we can here.


This is the opposite of how we handle type in the Comments Controller, where we change '' to comment. If we were to change '' -> default here, we would be consistent.

@joehoyle
7 months ago

#7 @joehoyle
7 months ago

This is the opposite of how we handle type in the Comments Controller, where we change to comment. If we were to change -> default here, we would be consistent.

I don't agree with this - the value is actually "comment", the value of "template" is never "default". The template field is somethat can have an relation set to a page-template, comment type is not the same in this regard.

Also, I added patch with passing tests, because of how the available templates affect the route's enum I had to provide a way to register the route.

This ticket was mentioned in Slack in #core-restapi by joehoyle. View the logs.


7 months ago

#9 @rachelbaker
7 months ago

@joehoyle In 38877.2.diff we still need a test for updating a template to the default '' in WP_Test_REST_Pages_Controller since that was how this issue was discovered.

Also, why did you chose to puttest_create_item_with_template_none() in WP_Test_REST_Posts_Controller instead of the pages controller tests?

#10 @swissspidy
7 months ago

@rachelbaker Since #18375 the post type doesn't really matter anymore. This bug isn't specific to pages, but affects all post types.

This ticket was mentioned in Slack in #core-restapi by joehoyle. View the logs.


7 months ago

@joehoyle
7 months ago

#12 @joehoyle
7 months ago

  • Resolution set to fixed
  • Status changed from reviewing to closed

In 39343:

REST API: Allow unsetting of page templates in update requests.

Sending a request to update a page with the template property set to an empty string resulted in an error because “” was not a valid value in the enum.

Props lucasstark, swissspidy.
Fixes #38877.

Note: See TracTickets for help on using tickets.