Implement forward-compatible REST API search controller#7894
Implement forward-compatible REST API search controller#7894pento merged 11 commits intoWordPress:masterfrom
Conversation
…ress content, only supporting posts for now.
|
I've tested the controller manually by making some requests and it appears to work well. I'll work on unit tests after an initial review to ensure it's on the right track. |
danielbachhuber
left a comment
There was a problem hiding this comment.
Looks like a good start. Left a couple of comments with the time I have to look now.
I'm not overly enthusiastic about the abstraction, but I'm not opposed either. What would make it much more compelling is a (plugin?) implementation of the abstraction, to prove that it's useful.
| } | ||
|
|
||
| // Get the public post statuses as only those should be searched. | ||
| $post_statuses = array_values( get_post_stati( array( |
There was a problem hiding this comment.
For parity with core, we should simply use post_status=>publish. We can discuss custom statuses at greater depth with #3144
There was a problem hiding this comment.
I'm still not fully convinced why as the REST API handles post statuses like that in core already, but I'm okay simplifying it.
There was a problem hiding this comment.
I'm still not fully convinced why as the REST API handles post statuses like that in core already, but I'm okay simplifying it.
Oh. If that's the case, I'm fine with it as-is.
There was a problem hiding this comment.
For now, I decided to follow your suggestion and only use publish for now. The only problem that brings is that the controller won't be able to search attachments at this point because they typically use inherit. Is it acceptable not having that in the first iteration? Pinging @pento for an opinion on this too.
There was a problem hiding this comment.
Because searching for attachments will always return an empty array for now (which is unexpected), I explicitly removed support for type=>post and subtype=attachment. Once we add support, we can allow that again.
| 'fields' => 'ids', | ||
| ); | ||
|
|
||
| // If a search term is given, add it and order by relevance. |
There was a problem hiding this comment.
Is there a reason we default to ID and then switch to relevance?
There was a problem hiding this comment.
When search is not given, it is impossible to sort by relevance, so we need to have some default.
There was a problem hiding this comment.
When
searchis not given, it is impossible to sort by relevance, so we need to have some default.
Makes sense. It'd be great to have this clarified in the comment.
| * an array of found IDs and `WP_REST_Object_Search_Handler::RESULT_TOTAL` containing the | ||
| * total count for the matching search results. | ||
| */ | ||
| public function search_items( WP_REST_Request $request ) { |
There was a problem hiding this comment.
Core doesn't typically type cast.
There was a problem hiding this comment.
True, but I don't see why this cannot change. To be fair, there are a few areas in core where type hints are present, and them being available (where possible in PHP 5.2) ensures that the parameter is valid.
I'm not strongly opposed to changing it, but only if there's other arguments/opinions against it.
There was a problem hiding this comment.
There are a handful of uses in Core, I have no problem with adding this one.
(Run ack --php 'ack --php '(?:^|\s)function [^(]+\([^)]*?(\S+[^(,] \$[^ ),]+)'' on Core for examples.)
Are you saying you would like to see a demo plugin where that abstraction is leveraged? I could do that, but in that case I think it would make more sense to implement a search handler for terms as a proof-of-concept because that is something we could actually use in core at some point. Well, I could still implement that as a plugin. |
Yep. |
|
@felixarntz Let's go ahead and get tests + Gutenberg integration in place for this. |
|
@danielbachhuber I'll implement the feedback and work on tests + integration on Friday. |
pento
left a comment
There was a problem hiding this comment.
Thanks for tackling this, @felixarntz.
I have similar feelings as @danielbachhuber about the abstraction. I see how it will be potentially valuable in the future, as more search handlers are implemented, but it does feel a little premature.
I would certainly want to see several other search handlers implemented before it could be merged into Core. If you're okay with ensuring that happens, I'm fine with leaving it.
| * an array of found IDs and `WP_REST_Object_Search_Handler::RESULT_TOTAL` containing the | ||
| * total count for the matching search results. | ||
| */ | ||
| public function search_items( WP_REST_Request $request ) { |
There was a problem hiding this comment.
There are a handful of uses in Core, I have no problem with adding this one.
(Run ack --php 'ack --php '(?:^|\s)function [^(]+\([^)]*?(\S+[^(,] \$[^ ),]+)'' on Core for examples.)
| * | ||
| * @since 3.3.0 | ||
| */ | ||
| abstract class WP_REST_Object_Search_Handler { |
There was a problem hiding this comment.
To match the naming scheme of other abstract classes in the REST API WP_REST_Meta_Fields, WP_REST_Controller, the class name should just be WP_REST_Search_Handler, the implementing classes would follow the naming scheme you uses for WP_REST_Post_Search_Handler.
I will ensure that then. :) Originally my thought was it would be fine to add them later, but I agree implementing them before merge ensures the abstraction is solid enough. I'll implement the terms integration as a plugin for now, but once we get to a core merge, I can move that over into the actual patch for the whole thing. |
…rch term is given.
…ject search handlers into search controller, including a filter hook.
…or now because they are not support at this point.
|
I have added tests for the search controller now, including a very simple I've also adjusted the An additional plugin adding term support to the REST search controller is available at https://github.com/felixarntz/gutenberg-rest-term-search-handler. Simply download and activate it together with this Gutenberg PR to see it in action. |
|
From my POV this now has everything we discussed so far. I have two open questions we need to answer before merge though:
|
All of the In the case of In the case of
I don't think that's necessary for now. If we decide to do it later, I suspect it will take two forms:
I don't think it's worth the effort of planning for and adding either of these until we have an actual use case in Core for them. |
|
Agreed. Will update the PR accordingly. |
|
@karmatosed, could you please provide design feedback on this? Classic shows a bit more information in the search results than Gutenberg does, do you think Gutenberg needs to show more information? Classic Editor Gutenberg |
|
I don't mind adding that in if there is a use case for knowing that information. I do wonder how useful a date is though. I can see the use of seeing if something is a page. |
|
It seems like the use case is being able to differentiate results. For posts, it shows the post date, for all other post types, it shows the post type. The date is probably useful for sites that do regular posts on a particular topic, but they keep the same title every time. (Eg, "Monthly Review Roundup", or something like that.) Being able to link to the post that happened most recently would be useful. |
|
@pento If we need the date here (which I agree would be useful), that would be a very specific thing because not all content types in WordPress have dates (for example terms). In that case I would suggest querying the REST API search controller with |
|
Yah, let's do that in a follow up, so we can get this shipped. |


Description
This PR is a new take on what was previously worked on in #6489. It was decided to go with a completely different approach (particularly explained in #6489 (comment)), and it didn't make sense to adjust that PR for that. The new implementation is a fully forward-compatible approach that theoretically allows for searching any WordPress content and is not tied to only posts like the original PR was. However, since only post search is a priority for Gutenberg, that object type (
post) is the only one we need.The REST controller uses
gutenberg/v1as its namespace at the moment. This should change when it gets merged into core.This addresses #2084.
Types of changes
WP_REST_Search_Controlleris a read-only controller that contains a single route which is a collection of arbitrary search results.idtitleurltype(i.e. 'post', 'term', 'comment', 'user', etc.)subtype(i.e. a post type, a taxonomy, a comment type, etc.)searchis most important here. However, the controller also works without it, simply listing all content that is available.pageandper_page, as used by almost all core REST controllerstype: A single string identifying whether to search posts, terms, comments, ... The default value is 'post' since that is the most likely type people want to search and the only one this PR adds support for. Other types like 'term' and 'comment' could be implemented after the initial core merge. In some point far away in the future, it may be possible to search cross-content, which is also considered here. The parameter only supports a string now, but it can easily be adjusted to support an array if that becomes possible.subtype: One or more strings (i.e. an array) identifying the subtypes (post types, taxonomies, ...) to search. The default value is set to 'any', which essentially ensures that all subtypes of the type specified viatypeare searched.WP_REST_Object_Search_Handler, which makes sense because all types work very differently in terms of querying and preparing the output in a uniform format that matches the above search result properties. It also allows for the logic in the search controller itself to be very straightforward.WP_REST_Post_Search_Handleris part of the PR.Checklist: