Repository navigation
Query Loop: Fix sticky posts repeated on every page - #83604
Vrishabhsk wants to merge 1 commit into
Conversation
`build_query_vars_from_query_block()` paginates custom queries with `offset` alone and never sets `paged`. `WP_Query` relocates sticky posts to the top based on `paged`, so when it is unset every page is treated as the first one and the sticky posts are prepended again on pages 2 and up. Set `paged` for paginated queries so sticky posts are placed on the first page only. `offset` still drives the LIMIT, so the posts returned for each page are unchanged. Closes WordPress#80624.
🤖 PR meta 🤖🎉 PropsUnlinked AccountsThe following contributors have not linked their GitHub and WordPress.org accounts: @Vrishabhsk, @iritfab. Contributors, please read how to link your accounts to ensure your work is properly credited in WordPress releases. If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message. To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook. Updated as activity occurs, without notifying anyone named here. Add the |
|
Thanks for this. I am currently on holiday but will test it next week. Not sure if I understood everything, I am no developer. But there is still a second issue: given again a loop with 12 posts. If the sticky post is older (let's say no. 15) there will be on the first page 13 posts! I never worked with github, not sure how to address this correctly |
Test ReportPatch tested: #83604 Environment
Steps
Results
Expected resultThe sticky post appears at the top of page 1 only and is not prepended again on page 2. Additional notes
Screenshots |
|
Tested this on WP 7.1.3 + Gutenberg 24.2.0 (Twenty Twenty-Five, headless Chrome on Linux), using the same setup as my report on #80624: Query Loop not inheriting, 4 per page, newest first, sticky posts included, one older post marked sticky, 17 posts total.
Both of those last two match how the main blog query behaves, so they may be expected. Page count and the last page look right. |


What?
Closes #80624
Limit sticky posts to the first page of a Query Loop, so they are no longer repeated on every paginated page.
Why?
A Query Loop that includes sticky posts repeats the sticky posts at the top of every paginated page. On page 1 the sticky posts are moved to the top as expected; on pages 2 and beyond the same sticky posts are prepended again, so they appear more than once and the page renders more items than "Items per page".
The cause is that
build_query_vars_from_query_block()paginates custom queries with theoffsetquery var alone and never setspaged.WP_Querydecides whether to relocate sticky posts frompaged, notoffset:When
pagedis unset,$pageis0, so$page <= 1is true on every request and the sticky posts are prepended each time.Related: #69867, #71088, https://core.trac.wordpress.org/ticket/63365.
How?
Adds a
query_loop_block_query_varsfilter in the WordPress 7.2 compat layer (lib/compat/wordpress-7.2/query-block.php) that setspagedto the current page for paginated queries, matching the main query and the REST API.The filter only runs when the block has a numeric
perPage, which is the same condition under whichbuild_query_vars_from_query_block()paginates.offsetis still set by core and still drives theLIMIT, so the posts returned for each page are unchanged; the only difference is thatWP_Querynow relocates sticky posts on the first page only.This is intentionally the narrow fix: page 1 keeps its existing behavior (sticky posts at the top), and no query attribute, block attribute, REST argument, or default changes, so there is no backwards-compatibility impact.
Testing Instructions
Run the unit tests:
Use of AI Tools
Core backport
The change lives in the
lib/compat/layer and needs a Core backport. It is covered by the existing Core PR WordPress/wordpress-develop#8750 (Trac https://core.trac.wordpress.org/ticket/63365), which adds the samepagedquery var.