Opened 4 years ago
Last modified 3 months ago
#52626 new defect (bug)
Block editor doesn't paginate parent page results
Reported by: | hobzhobz | Owned by: | |
---|---|---|---|
Milestone: | Awaiting Review | Priority: | normal |
Severity: | major | Version: | 5.6.2 |
Component: | Editor | Keywords: | |
Focuses: | rest-api | Cc: |
Description
Conditions:
More than 100 pages.
Use gutenberg editor.
Edit a page.
Result:
Parent page dropdown is broken / does not contain all pages.
Expected result:
Should be able to see all the 100+ pages in the parent page dropdown.
Reason:
rest api ajax request only fetches the first 100 pages. The response headers does contain the corrent headers:
X-WP-Total: 1040 (i have 1040 pages)
X-WP-TotalPages: 11 (yes it's 11 x 100 pages)
I see only one ajax request for the first 100 pages.
After that i would see 10 more requests in older versions of wordpress.
Now it's only one.
I have tried reading the javascript but it's not easy to read.
This breaks my companies internal website. Would be nice to have a fix. We can't switch away from gutenberg.
This is also related to an older unfixed bug: https://core.trac.wordpress.org/ticket/46294
Attachments (2)
Change History (17)
@
4 years ago
Screenshot showing parent page dropdown with only 3 pages (should contain 1040 pages) (sorry, swedish)
#2
@
4 years ago
- Summary changed from wp rest api fails to paginate page requests correctly for parent page dropdown on edit post page when using gutenberg to Block editor doesn't paginate parent page results
#3
@
4 years ago
I want to add a detail to anyone trying to reproduce this bug.
Your pages needs to be in a somewhat complex tree.
If your pages are perfectly flat, then the dropdown will at least show the first 100 pages. But if they are in a tree, the javascript (i assume) will not be able to build the page tree correctly with only a fraction of the pages, so it will produce seemingly random results.
#4
@
4 years ago
WORKAROUND (VERY UGLY/HACKY) (UPDATED: 2024-07-17 for wp 6.6) (I cant believe I'm still patching this three years after finding the bug)
WARNING: You need to do this after every time you upgrade wordpress.
- Copy the contents of wp-includes/js/dist/editor.js to wp-includes/js/dist/editor.min.js (because the minified version is annoying to edit)
- Edit wp-includes/js/dist/editor.min.js line 9917, Change per_page: 100 to per_page: 10000 (or whatever you need for your site)
- Edit wp-includes/rest-api/endpoints/class-wp-rest-controller.php line 357, change 'maximum' => 100 to 'maximum' => 10000 (or whatever you set in step 2)
With this hack you no longer need the menu_order fix, because now they all come in the same response without pagination so the ordering doesnt matter.
#6
follow-up:
↓ 8
@
2 years ago
Too many records in the drop-down list will make it impossible to use it.
No need to solve this problem by outputing the headings of all pages.
Perhaps someone can solve it using the menu-order field.
#7
in reply to:
↑ 5
@
2 years ago
Replying to SergeyBiryukov:
#55609 was marked as a duplicate.
This is not a duplicate. This is another side of the problem that needs to be solved from different sides.
#8
in reply to:
↑ 6
;
follow-up:
↓ 9
@
2 years ago
Replying to axdr:
Too many records in the drop-down list will make it impossible to use it.
No need to solve this problem by outputing the headings of all pages.
Perhaps someone can solve it using the menu-order field.
It's already sorted by menu_order.
You know what happens if menu_order is 0 on all pages? Undefined behavior. You know what that means? It means that they come in seemingly random order. Do you know what that means when doing pagination? It means that page 1 has 100 random pages. Page 2 has 100 random pages. Did you know that this means that the same page can come on page 1 and page 2? Yes it can.
You need to sort on menu_order AND a secondary parameter. Something like ID perhaps.
BAD: order by menu_order limit 0,100
GOOD: order by meny_order, ID limit 0,100
#9
in reply to:
↑ 8
;
follow-up:
↓ 10
@
2 years ago
Replying to hobzhobz:
Replying to axdr:
Too many records in the drop-down list will make it impossible to use it.
No need to solve this problem by outputing the headings of all pages.
Perhaps someone can solve it using the menu-order field.
Warning: might sound condescending. But i'm trying to be extra clear here because this seems so hard for people to understand...
It's already sorted by menu_order.
You know what happens if menu_order is 0 on all pages? Undefined behavior. You know what that means? It means that they come in seemingly random order. Do you know what that means when doing pagination? It means that page 1 has 100 random pages. Page 2 has 100 random pages. Did you know that this means that the same page can come on page 1 and page 2? Yes it can.
You need to sort on menu_order AND a secondary parameter. Something like ID perhaps.
BAD: order by menu_order limit 0,100
GOOD: order by menu_order, ID limit 0,100
BAD: ORDER BY menu_order LIMIT 0,100
GOOD: WHERE menu_order<>0 ORDER BY menu_order, post_title
The problem is that it is GOOD only when the number of pages is more than critical
#10
in reply to:
↑ 9
@
2 years ago
Replying to axdr:
Replying to hobzhobz:
Replying to axdr:
Too many records in the drop-down list will make it impossible to use it.
No need to solve this problem by outputing the headings of all pages.
Perhaps someone can solve it using the menu-order field.
Warning: might sound condescending. But i'm trying to be extra clear here because this seems so hard for people to understand...
It's already sorted by menu_order.
You know what happens if menu_order is 0 on all pages? Undefined behavior. You know what that means? It means that they come in seemingly random order. Do you know what that means when doing pagination? It means that page 1 has 100 random pages. Page 2 has 100 random pages. Did you know that this means that the same page can come on page 1 and page 2? Yes it can.
You need to sort on menu_order AND a secondary parameter. Something like ID perhaps.
BAD: order by menu_order limit 0,100
GOOD: order by menu_order, ID limit 0,100
BAD: ORDER BY menu_order LIMIT 0,100
GOOD: WHERE menu_order<>0 ORDER BY menu_order, post_title
The problem is that it is GOOD only when the number of pages is more than critical
You can't add a where statement to exclude all pages that has menu_order 0. They need to be included.
post_title is not safe also. Two pages can have the same title. they will be sorted in undefined behavior/random. If they happen to be just around the cut-off it's gonna be problem. You need to always have a unique field in the sorting when doing pagination with SQL database.
BAD: ORDER BY menu_order, page_title
GOOD: ORDER BY menu_order, page_title, ID
#11
follow-up:
↓ 12
@
2 years ago
All pages are definitely unnecessary to fill this list when there are too many pages.
And there is no point in the pagination.
#12
in reply to:
↑ 11
@
2 years ago
Replying to axdr:
All pages are definitely unnecessary to fill this list when there are too many pages.
And there is no point in the pagination.
How to build a page tree without all the pages?
What exactly are you proposing?
#13
follow-up:
↓ 14
@
2 years ago
Do not forget that one of the conditions of the problem is too large number of pages. When there are few of them, this problem does not exist.
There is no task to build a tree of all pages. Not all pages can be a parent. And the box is too small to put all pages there.
I already wrote what I propose as an option #55609
"choose pages that have parent=0, then pages that have parent among first group of pages."
#14
in reply to:
↑ 13
@
2 years ago
Replying to axdr:
Do not forget that one of the conditions of the problem is too large number of pages. When there are few of them, this problem does not exist.
There is no task to build a tree of all pages. Not all pages can be a parent. And the box is too small to put all pages there.
I already wrote what I propose as an option #55609
"choose pages that have parent=0, then pages that have parent among first group of pages."
Any page can be a parent.
More than 100 pages can have parent = 0.
Screenshot showing that the headers for the first ajax request is correct and that there's no more requests after that.