Skip to content

Fix ExcludePostsControl fetching all posts#160

Open
PatelUtkarsh wants to merge 20 commits into
ryanwelcher:trunkfrom
PatelUtkarsh:fix/exclude-posts-fetch-all
Open

Fix ExcludePostsControl fetching all posts#160
PatelUtkarsh wants to merge 20 commits into
ryanwelcher:trunkfrom
PatelUtkarsh:fix/exclude-posts-fetch-all

Conversation

@PatelUtkarsh
Copy link
Copy Markdown

@PatelUtkarsh PatelUtkarsh commented Apr 22, 2026

Fixes #157
Fixes #142

Props to @trevormills-xwp for the PostPickerControl refactor, debounce, loading states, and backwards compat migration.

Problem

ExcludePostsControl calls getEntityRecords with per_page: -1. The REST API middleware splits this into paginated requests of 100. On sites with thousands of posts, these requests pile up, hang the block editor, and block post saving and autosaves.

Fix

Refactors both ExcludePostsControl and PostIncludeControls into a shared PostPickerControl component that:

  • Replaces per_page: -1 with per_page: 10 with debounced search-as-you-type (500ms)
  • Adds search_columns: post_title so REST results match what FormTokenField filters client-side
  • Adds _fields: id,title to keep responses lightweight
  • Skips search fetch when input is empty
  • Shows loading state ("Searching...") and idle hint ("Type to search by title")
  • Deduplicates suggestions via Set to prevent FormTokenField issues
  • Resets search term on token selection

Backwards compatibility:

  • exclude_posts attribute format changed from [id, id] to [{id, title}, ...] to match include_posts
  • Auto-migration: old format is detected and converted on load via useSelect + useEffect
  • PHP Exclude_Posts trait updated to handle numeric, {id, title}, and plain array formats
  • Unit tests added for both legacy and new formats

Other changes:

  • defined('ABSPATH') || exit changed to if block in PHP files for phpunit compatibility

Testing

  1. Create a Post on a site with thousands of posts
  2. Insert an AQL block, click "Start blank", pick a variation
  3. Switch Query Type to Custom
  4. Editor should stay responsive. Save draft should complete.
  5. In "Posts to Exclude", search by title. Suggestions should appear with debounce.
  6. Add a post, save, reload - confirm it persists.
  7. Search and add a second post - confirm both remain after save.
  8. Test with a post that has old-format exclude_posts (array of IDs) - confirm auto-migration to {id, title} format.
  9. Test "Posts to Include" - same search behavior should work.
  10. Network tab should show single wp/v2/posts requests with per_page=10, not paginated chains.

Replace per_page: -1 with per_page: 25 and add search support
in ExcludePostsControl, matching the existing IncludePostsControl
pattern. This prevents endless paginated REST API calls that hang
the editor on sites with many posts.

Fixes: ryanwelcher#157
@PatelUtkarsh PatelUtkarsh marked this pull request as draft April 22, 2026 09:26
- Fetch saved exclude IDs separately via include param so saved
  selections are never dropped from the token field
- Cache resolved posts in a ref so title lookups survive search
  input resets
- Add search_columns: post_title so REST results match what
  FormTokenField filters client-side
- Add _fields: id,title to keep responses lightweight
- Set per_page: 10 to match IncludePostsControl
@PatelUtkarsh PatelUtkarsh marked this pull request as ready for review April 22, 2026 10:48
TrevorMills and others added 18 commits April 22, 2026 19:13
  - debounce the search input
  - only call server when we have a search argument
  - limit search_column to title, and only return id and title
  - user friendly messages when searching instead of No items found with no spinner
 - port UX improvements from PostIncludeControls
- both now use a common PostPickerControl
- legacy support for ExcludePostsControl where the block attribute is an array of IDs
…y-title

Fix/include posts search by title
…alues when called with the same state and parameters." warning
…y-title

Refactor ExcludePostsControl and PostIncludesControl
Comment thread src/components/post-picker-control.js
Copy link
Copy Markdown
Owner

@ryanwelcher ryanwelcher left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall, this looks great. I need to test it to make sure it compatible with the old way of storing posts. I just have one real note to address. I am at WCEU right now so I won't be able to release this until I get back.

Comment thread src/components/post-picker-control.js
@ryanwelcher
Copy link
Copy Markdown
Owner

ryanwelcher commented Jun 5, 2026

I was able to test the back compat and it seems to work fine. I'd love another set of eyes on this if possible @TrevorMills have you been able to test this on a site with a large data set?

I think this is ready to go once the helper is moved out into a new file as per my comment - great work!

@trevormills-xwp
Copy link
Copy Markdown

I was able to test the back compat and it seems to work fine. I'd love another set of eyes on this if possible @TrevorMills have you been able to test this on a site with a large data set?

I think this is ready to go once the helper is moved out into a new file as per my comment - great work!

@ryanwelcher Yes, we tested this with a data set of around 10K posts and it worked well!

Your feedback is addressed in a PR on the downstream fork of this.

@ryanwelcher
Copy link
Copy Markdown
Owner

@ryanwelcher Yes, we tested this with a data set of around 10K posts and it worked well!

Your feedback is addressed in a PR on the downstream fork of this.

Amazing! Once that's merged, I'll merge this and get it released once I am back from WCEU. Thanks for the great work here!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Unable to save post with AQL on site with many posts Only most recent published post available to select in excluded posts field

4 participants