[wp-trac] [WordPress Trac] #15667: wp_list_pages, if it finds no pages to display, shows random child pages instead because of a bug in get_pages()
WordPress Trac
noreply at wordpress.org
Sun Mar 2 16:46:51 UTC 2014
#15667: wp_list_pages, if it finds no pages to display, shows random child pages
instead because of a bug in get_pages()
-------------------------------------------------+-------------------------
Reporter: bobsoap | Owner:
Type: defect (bug) | jackreichert
Priority: normal | Status: assigned
Component: Query | Milestone: 3.9
Severity: minor | Version: 3.0.2
Keywords: good-first-bug needs-unit-tests | Resolution:
has-patch 2nd-opinion | Focuses:
-------------------------------------------------+-------------------------
Changes (by willmot):
* keywords: good-first-bug needs-unit-tests has-patch => good-first-bug
needs-unit-tests has-patch 2nd-opinion
Comment:
Been digging into this, it's not as simple as it first seems. First order
of business,
[https://core.trac.wordpress.org/attachment/ticket/15667/15667
.wp_list_pages-unit-tests.diff 15667.wp_list_pages-unit-tests.diff]
includes a couple of unit tests to prove this issue.
> The root of the problem is get_pages(), since the Walker's behavior when
fed bad data like this should probably be left undefined.
I actually don't think that's the case, `get_pages()` will return the
children of any excluded parent pages as long as `hierarchical` is set to
`false` (as it is in `wp_list_pages`),
[https://core.trac.wordpress.org/attachment/ticket/15667/15667.get_pages-
unit-tests.diff 15667.get_pages-unit-tests.diff] adds some unit tests to
prove that. I think that behaviour makes sense and isn't something that
should be changed.
> What's causing this is a condition in the walk method in class-wp-
walker.php.
I'm also not convinced we need to fix this in the Walker, although I do
think that separate issue merits some thought.
Currently the `Walker` attempts to handle the situation where it has been
passed a list of elements with no top level elements by just taking the
first element and treating that as root. This seems like a pretty strange
assumption. It would seem more logical to either always omit elements
which have a missing parent or to treat all elements with missing parents
as being top level. Obviously doing the former would resolve this issue
for `wp_list_pages` but might not actually be the desired behaviour for
the `Walkers`. Currently if there is both a valid top-level element and an
orphaned child then that is treated as top level when `depth=0` but is
omitted when `depth=1`.
> This assumption should fine, except when the depth is limited to 1
I don't necessarily agree, `depth=1` should probably mean the first level
of the elements that are passed in, not just elements which have parent
set to `0`.
I've added some unit tests for the base Walker class in
[https://core.trac.wordpress.org/attachment/ticket/15667/15667.walker-
unit-tests.diff 15667.walker-unit-tests.diff] which assert the current
functionality.
> Now we now add the "exclude_tree" attr just for fun:
> 2) wp_list_pages('title_li=&depth=1&exclude=3,5,7&exclude_tree=3,5,7');
> => should again return nothing, but instead, it displays the first-ever
published child page globally (here: a child page of 5).
Actually, `exclude_tree` works as expected, it's just that it only accepts
a single `(int)` not a comma separated list so in your example above you
were only actually excluding children of`3`.
> adds condition to walker class to prevent random child
[https://core.trac.wordpress.org/attachment/ticket/15667/class-wp-
walker.php.diff class-wp-walker.php.diff] breaks both `depth=-1` and
`depth=0`. [https://core.trac.wordpress.org/attachment/ticket/15667/class-
wp-walker.php.1.diff class-wp-walker.php.1.diff] changes the `>` to a
`!==` so we only trigger the behaviour when `depth=1`.
Phew!
There's a couple of ways to approach fixing this:
1. In `wp_list_pages` stop passing the orphaned children that we receive
from `get_pages` to the `Page_Walker`.
2. Change the behaviour of the `Walker` so that it skips orphaned child
elements, either always or when `depth=1`.
3. Allow a comma separated list of id's to be passed to `exclude_tree` in
`get_pages` and then either recommend that over `exclude` or even
specifically map `exclude` to `exclude_tree` in `wp_list_pages`.
4. Use a Nav Menu ;-)
Would be good to get a second opinion on the above, happy to add more unit
tests and / or produce a patch for any of the above.
--
Ticket URL: <https://core.trac.wordpress.org/ticket/15667#comment:8>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform
More information about the wp-trac
mailing list