Opened 5 years ago
Closed 5 years ago
#47779 closed enhancement (fixed)
Add a filter to `get_item_schema()` to be able to extend the schema of existing properties
Reported by: | luisherranz | Owned by: | kadamwhite |
---|---|---|---|
Milestone: | 5.4 | Priority: | normal |
Severity: | trivial | Version: | 4.7 |
Component: | REST API | Keywords: | has-patch dev-feedback has-unit-tests needs-refresh |
Focuses: | rest-api | Cc: |
Description
Right now there's no way to properly extend the schema of existing fields with additional properties. For example, the content
field could be extended with new properties (in addition to content.rendered and content.raw).
Adding a filter to WP_REST_Posts_Controller::get_item_schema()
would help solve this problem.
Attachments (9)
Change History (26)
This ticket was mentioned in Slack in #core-restapi by luisherranz. View the logs.
5 years ago
#2
@
5 years ago
For more context about why this filter is needed, please take a look at this slack conversation:
https://wordpress.slack.com/archives/C02RQC26G/p1563397511313900
Pascal's question appeared because of this new feature of the AMP plugin:
https://github.com/ampproject/amp-wp/issues/1014
https://github.com/ampproject/amp-wp/pull/2827
#3
@
5 years ago
I think we should consider not allowing people to add properties to the main object via this filter and enforce people to use the additional fields API for that case.
Something like comparing the keys of $schema['properties']
before and after the filter call and issuing a _doing_it_wrong
.
@
5 years ago
Emit a _doing_it_wrong warning if user tries to add new properties with this filter instead of register_rest_field.
@
5 years ago
I've added the first test, but it's not working yet. Somehow the same code works perfectly fine in the regular site.
@
5 years ago
I've added the first test, but it's not working yet. Somehow the same code works perfectly fine in the regular site.
#5
@
5 years ago
This filter works fine in the regular site:
function filter_post_item_schema( $schema ) {
$schema['properties']['content']['properties']['new_prop'] = array(
'description' => __( 'A new prop added with a the rest_post_item_schema filter.' ),
'type' => 'string',
'context' => array( 'view', 'edit' ),
);
return $schema;
}
add_filter( 'rest_post_item_schema', 'filter_post_item_schema' );
However, in the testing environment, the filter doesn't seem to work:
public function test_rest_post_type_item_schema_filter_change_property() {
add_filter( 'rest_post_item_schema', array( $this, 'filter_post_item_schema' ) );
$request = new WP_REST_Request( 'OPTIONS', '/wp/v2/posts' );
$response = rest_get_server()->dispatch( $request );
$data = $response->get_data();
$properties = $data['schema']['properties']['content']['properties'];
remove_filter( 'rest_post_item_schema', array( $this, 'filter_post_item_schema' ) );
$this->assertArrayHasKey( 'new_prop', $properties );
}
...
public function filter_post_item_schema( $schema ) {
$schema['properties']['content']['properties']['new_prop'] = array(
'description' => __( 'A new prop added with a the rest_post_item_schema filter.' ),
'type' => 'string',
'context' => array( 'view', 'edit' ),
);
return $schema;
}
Any help is appreciated.
Once this is solved I'll add more use cases to the test.
This ticket was mentioned in Slack in #core-restapi by luisherranz. View the logs.
5 years ago
#7
@
5 years ago
Ok, I had some more time today to look into this and I found the problem.
Looking at the stack, it looks like get_item_schema
is called on the rest_api_init
hook, which is called on the WP_Test_REST_Posts_Controller->setUp
method.
That means we would need to add the filter before the setUp
, or do the setUp
or the rest_api_init
again. I don't like either of those.
I've tested adding the filter in the setUp
just to check if the test is passing and the test is working:
public function setUp() {
add_filter( 'rest_post_item_schema', array( $this, 'filter_post_item_schema' ) );
parent::setUp(); // <- this is where the do_action( 'rest_api_ini' ) happens.
// the rest of the setUp...
Where should I add the filter? Any idea?
#8
@
5 years ago
Such a filter seems very crucial for enabling other contexts beyond view
, edit
, and embed
, so +1 on adding one.
I might wanna add a new field for post objects using register_rest_field
that only works in context foo
, and at the same time also want to use some of the existing fields like id
in that context.
This doesn't seem to be doable without this proposed filter, as id
in the schema is hardcoded to the view
, edit
, and embed
contexts and not available otherwise.
@kadamwhite Since you chimed in on https://github.com/ampproject/amp-wp/issues/1014 originally - do you perhaps have any insights here regarding adding and testing such a filter?
#9
@
5 years ago
- Milestone changed from Awaiting Review to 5.4
- Owner set to kadamwhite
- Status changed from new to accepted
I'd be in favor of this, I'd seen this ticket when it was filed but it dropped off my radar; milestoning for 5.4 to make sure we get to it!
#10
@
5 years ago
Awesome :)
Do you have any idea about how to solve the test problem with rest_api_init
?
I don't like neither of these solutions:
- Add the filter before
parent::setUp()
. - Do the
setUp
again in the test. - Do the
rest_api_init
again in the test. - Don't do
setUp
at initialization and move it inside each individual test. - Create a new file for filters that depend on
rest_api_init
.
This ticket was mentioned in Slack in #core-restapi by luisherranz. View the logs.
5 years ago
This ticket was mentioned in Slack in #core-restapi by luisherranz. View the logs.
5 years ago
This ticket was mentioned in Slack in #core-restapi by luisherranz. View the logs.
5 years ago
This ticket was mentioned in Slack in #core-restapi by timothybjacobs. View the logs.
5 years ago
#15
@
5 years ago
- Keywords has-unit-tests needs-refresh added; needs-unit-tests removed
@kadamwhite The most recent patch fails against trunk
, so this needs a refresh. Is this still in the cards for 5.4 with Beta 1 approaching in a few days?
Added filter
rest_{$this->post_type}_item_schema
in class-wp-rest-posts-controller.php