Skip to content
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

Query and Search blocks: support for Instant Search #63053

Open
luisherranz opened this issue Jul 2, 2024 · 13 comments
Open

Query and Search blocks: support for Instant Search #63053

luisherranz opened this issue Jul 2, 2024 · 13 comments
Assignees
Labels
[Block] Query Loop Affects the Query Loop Block [Block] Search Affects the Search Block - used to display a search field [Feature] Interactivity API API to add frontend interactivity to blocks. [Type] Enhancement A suggestion for improvement.

Comments

@luisherranz
Copy link
Member

What problem does this address?

Now that we have the Interactivity API in Core, it's time to start experimenting with enhanced user experiences. One of these would be the ability to refresh the content of a Query block without refreshing the page while the user is typing a search.

What is your proposed solution?

I believe the simplest way to start with the Instant Search would be to convert the search into an instant search when the Search block is inside a Query block that has the Forge Page Reload option disabled.

When the Force Page Reload option is disabled, the enhancedPagination attribute is true and is passed via block context. Therefore, the Search block can subscribe to the enhancedPagination context. If it is true, it can add the necessary directives using the HTML_Tag_Processor and enqueue de view file.

@luisherranz luisherranz added [Type] Enhancement A suggestion for improvement. [Block] Search Affects the Search Block - used to display a search field [Block] Query Loop Affects the Query Loop Block [Feature] Interactivity API API to add frontend interactivity to blocks. labels Jul 2, 2024
@r-chrzan
Copy link

r-chrzan commented Jul 2, 2024

I will prepare the initial implementation.

@luisherranz
Copy link
Member Author

luisherranz commented Jul 2, 2024

Another thing that we need to do, but doesn't need to be in the initial implementation is to always add the "No results" block to the page even if it's initially hidden, so all the necessary CSS/JS is properly loaded.

@ktmn
Copy link

ktmn commented Jul 2, 2024

it's time to start experimenting

When using enhancedPagination the Pagination block could have a child block called "Load more button" which you could use instead of the "Previous Page", "Page Numbers" and "Next Page" blocks. Instead of going to the next page it could pick the items from the response and append them to the <ul>.

Just throwing this in here for consideration, because when implementing search, the query would be changing and pagination would therefore also be changing and if there was different methods of pagination, they would all need to be accounted for as well, which might get complex or maybe not.

Also with search, a "Result count" block or something like that could potentially be needed.

@r-chrzan
Copy link

r-chrzan commented Jul 2, 2024

@ktmn Thanks for your suggestions! It will be very similar to this solution that I posted some times ago as a plugin. You can check by download my repo if you want. You may notice that the pagination behaves dynamically, disappearing if there are less than a given number of posts.

@luisherranz
Copy link
Member Author

Yeah, thanks for the insight @ktmn, although I'm not too worried about those kinds of details right now. Let's see if we can get an initial version and then we'll look at the UX and see what we need to improve 🙂

@michalczaplinski
Copy link
Contributor

michalczaplinski commented Nov 25, 2024

I made decent progress on the implementation of the Instant Search: #63147 (please note the updated PR description 🙂)

I've also created 2 PRs with an alternative implementation using filters:

#63147

  • 👍 It will be easier to port it to Core because it does NOT use a filter to add the functionality.
  • 👎 This implementation touches more files and is more complex than #67013 & #67181

#67013 & #67181

  • 👍 Fewer lines of code
  • 👎 Porting to Core will be harder because we can't use filters in Core.

@michalczaplinski
Copy link
Contributor

👎 Porting to Core will be harder because we can't use filters in Core.

I think I was mistaken here. For example, for the implementation using query_loop_block_query_vars (#67181) we can probably copy-paste the contents of the filter around this line in Core.

@luisherranz
Copy link
Member Author

As we need to modify the query for both the default and custom cases, I'd rather go with something like this instead (kudos to @roborourke).

@michalczaplinski
Copy link
Contributor

As we need to modify the query for both the default and custom cases, I'd rather go with something like this instead (kudos to @roborourke).

That makes sense. The approach you shared is almost the same as what I've explored in:

https://github.com/humanmade/query-filter uses the same two filters to add the functionality. The main difference is that they are using query_loop_block_query_vars ONLY to inject the queryId into the block context. Then, all of the work is done in the pre_get_posts which fires for ALL queries (both Default and Custom).

I'd have to study their implementation some more to understand if there's a significant advantage to one or the approach.

In any case, using those two filters is the best approach, in my opinion. So, given what you mentioned, can we close #63147 & #67013 and continue with #67181 & #67289 ?

@roborourke
Copy link
Contributor

@michalczaplinski the reason I did it that way iirc is because if the query loop block is set to inherit the global query you don’t get the query_loop_block_query_vars filter. For that plugin I needed to support both possibilities.

@luisherranz
Copy link
Member Author

In any case, using those two filters is the best approach, in my opinion. So, given what you mentioned, can we close #63147 & #67013 and continue with #67181 & #67289 ?

I think so, yes 🙂

@michalczaplinski
Copy link
Contributor

michalczaplinski commented Dec 5, 2024

@michalczaplinski the reason I did it that way iirc is because if the query loop block is set to inherit the global query you don’t get the query_loop_block_query_vars filter. For that plugin I needed to support both possibilities.

Hi Rob! 👋 Thanks for chiming in! You're right, that's exactly what we also figured out: query_loop_block_query_vars doesn't run for inherited queries.

What I was wondering about is your specific use of query_loop_block_query_vars: You only use it to pass the queryId into the block context and then you filter both custom and inherited queries in the pre_get_posts.

Have you considered using query_loop_block_query_vars to only filter the custom queries and pre_get_posts to only filter the inherited queries?

@roborourke
Copy link
Contributor

@michalczaplinski yeah I guess that could work too, I think I just wanted to use the same single function for the filtering, so it was easier to act on the WP_Query object rather than the object in the pre_get_posts case, and an array of query vars in the filter.

Your approach sounds like it might be more performant than mine, but you might need to replicate the logic a bit, unless there's a way to update a WP_Query object from a query vars array I missed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Block] Query Loop Affects the Query Loop Block [Block] Search Affects the Search Block - used to display a search field [Feature] Interactivity API API to add frontend interactivity to blocks. [Type] Enhancement A suggestion for improvement.
Projects
None yet
5 participants