Jump to content

selector sort=path returns sorted by id


MarkE
 Share

Recommended Posts

I have a selector, e.g. "has_parent=/property/bawd-hall/bookings/, sort=path"

The results (in this case several hundred) are not sorted by path, they are sorted by id. Changing 'path' to 'name' or any other property/field works fine. It makes no difference what the first part of the selector is (I've tried several) - the sort=path always returns a sort order of id. No doubt I am being dim, but any ideas?

Link to comment
Share on other sites

I think that sorting by path simply isn't available using selectors.

What are you trying to achieve?

If it's to get the results into the same order as in the admin (which of course it may not be!), you probably want "sort=sort" (see "How to force pages to sort by their admin order with $pages->find()" on https://processwire.com/docs/selectors/).

Link to comment
Share on other sites

12 minutes ago, BillH said:

What are you trying to achieve?

I'm trying to get them in parent-child order. There are two levels below the 'has_parent' and I wanted to get each parent followed by its children. I thought that sorting by path would achieve that but, as you say, maybe its not available in a selector. Strange, because the docs say "This behavior can be overridden by specifying your own sort=property (where property is any property or field name)" (my emphasis). sort=sort doesn't work for 2 levels like this.

Link to comment
Share on other sites

@MarkE Correct me if I am wrong, but is the "path" a field name, or you are just needing the sorting to go by URL?

If the path is a field that you would like to use as a selector argument, maybe you should check its values and make sure the name is correct or there are any values for the parents/children needed to be sorted.

As to my humble experience, I've not seen any trick to use PATH as a selector.

On another note, you might borrow the sitemap function from the default profile which already lists pages in the needed way as you've mentioned. Of course, you might need to adjust the styling and other extra functionalities needed, but you get the idea...

Link to comment
Share on other sites

28 minutes ago, MilenKo said:

the "path" a field name, or you are just needing the sorting to go by URL

I mean path as in url (which doesn't work either). path is a property of page so, per the docs, should be available in sort=, but doesn't seem to be. Looks like I'll need to do the sorting after the selection 😔 Thanks for the comments.

Link to comment
Share on other sites

1 hour ago, MilenKo said:

I've not seen any trick to use PATH as a selector.

This seems to work (N.B. this is with a php array not a PageArray)

                    $pages = $this->wire()->pages->find($selector);
                    $pages = $pages->getArray(); // want them as a php array not an object
                    if (strpos($selector, 'sort=path')) {
                        usort($pages,function ($a, $b) {
                            return ($a->path >= $b->path) ? 1 : -1;
                        });
                    }

 

  • Like 1
Link to comment
Share on other sites

@MarkE, if you are sorting when getting pages from the database (as opposed to sorting a PageArray in memory) you can only sort by properties that have a corresponding column in the database. By default PW doesn't store paths for each page in the database, which is why you can't sort by path. But if you install the core PagePaths module then PW will store paths in the database and so I think you should then be able to sort by path.

8 hours ago, MarkE said:

I'm trying to get them in parent-child order. There are two levels below the 'has_parent' and I wanted to get each parent followed by its children.

Another way to do this when you have two levels of pages in your results is to do "sort=parent.sort, sort=sort".

  • Like 2
Link to comment
Share on other sites

Thanks @Robin S. I installed PagePaths, but sort=path still didn't seem to work.

By way of context, I was testing out my new DbMigrate module. I realised that if a page selector was used which resulted in multiple levels then the pages would need to be sorted in parent-child order before exporting to the json file, so that the subsequent import didn't try and load parents before their children. While my test may only have had 2 levels, in theory there could be any number of levels. "sort=parent.sort, sort=sort" didn't seem to do the business either.

I notice that in @adrian's ProcessMigrator module, he just counts the number of path segments and then sorts by that, so that all parents are loaded first and then all children, then all grandchildren etc. I wanted the children to follow on immediately from their parents in the json which makes for a more human-readable output. (Why bother? My plan was to use the DbMigrate module as a way of exporting pages such that they could in theory be loaded in a different environment, possibly not even PW 🤨. In doing this, I find being able to visually review the data is helpful. Also, it seems more logical and more likely to fit a subsequent import process).

I'm puzzled as to why PagePaths doesn't work, but my snippet seems to do the business - although it is a bit of a hack, it may be the best way to go as I would ideally like to refine the sorting so that numeric elements of strings are fully respected - eg. /bkg20/ should be before /bkg101/.

Link to comment
Share on other sites

53 minutes ago, MarkE said:

I would ideally like to refine the sorting so that numeric elements of strings are fully respected

Quite easy, actually - just replace the return statement in the snippet with

return strnatcmp($a->path, $b->path);

 

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...