-
Notifications
You must be signed in to change notification settings - Fork 4.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement forward-compatible REST API search controller #7894
Implement forward-compatible REST API search controller #7894
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. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a reason we default to ID
and then switch to relevance?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When
search
is 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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Core doesn't typically type cast.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Makes sense to me!
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. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's party! 🎉
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wait, I got ahead of myself.
@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. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🎉
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/v1
as its namespace at the moment. This should change when it gets merged into core.This addresses #2084.
Types of changes
WP_REST_Search_Controller
is a read-only controller that contains a single route which is a collection of arbitrary search results.id
title
url
type
(i.e. 'post', 'term', 'comment', 'user', etc.)subtype
(i.e. a post type, a taxonomy, a comment type, etc.)search
is most important here. However, the controller also works without it, simply listing all content that is available.page
andper_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 viatype
are 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_Handler
is part of the PR.Checklist: