Jump to content

Does $p->children()->eq() first return all child pages?


Matte85
 Share

Recommended Posts

Hi,

In the $page documentation we can read:

Quote

The children property may not be efficient to use when the page has a lot of children. Care should be taken on large sites in consideration of the fact that this property will load all child pages.

Would the following then retrieve the full children array and only then pick the desired page:

$p->children()->eq($i)

My concern is using the above in conjunction with "while", like below:

 while( $i++ < $limit){
        $child = $parent->children()->eq($i);
   ...

 

Thanks!

Link to comment
Share on other sites

3 hours ago, Matte85 said:

Would the following then retrieve the full children array and only then pick the desired page

It does return all children if you use the children() method without a selector, or use children as a property.

 

3 hours ago, Matte85 said:

My concern is using the above in conjunction with "while", like below:


 while( $i++ < $limit){
        $child = $parent->children()->eq($i);
   ...

You could do that more efficiently as:

foreach($parent->children("limit=$limit") as $child) {
    //...
}

 

Link to comment
Share on other sites

Thanks Robin, but the issue with the solution you are suggesting wouldn't work if there is a variable number of children. This can be the case when using multi-language sites where e.g. a blog post might or might not have a translation. If you then wish to return a set number of blog posts, you would end up short for the ones that lack translations.

The only solutions I have come up with for this issue is to either first retrieve all children and then iterate through them, like so:

$allChildren = $parent->children();
foreach( $allChildren as $child...

...which has the drawback that it first retrieves all children which might be a heavy process if there are many pages. The other option is indeed the one presented in my first post, which I have my doubts about too.

Thanks!

Link to comment
Share on other sites

6 minutes ago, Matte85 said:

the issue with the solution you are suggesting wouldn't work if there is a variable number of children. This can be the case when using multi-language sites where e.g. a blog post might or might not have a translation. If you then wish to return a set number of blog posts, you would end up short for the ones that lack translations.

Could you explain more about this? I haven't built multi-language sites myself, but I'm not seeing how translations would have an affect on applying the limit within the selector as opposed to getting individual children with $parent->children()->eq($i).

If your limit is 5, but there are only 3 children under a particular parent, then of course you will only get 3 children returned. But that is the same with eq() also.

Note that if you want to return only pages with some particular template, property, field value, etc then you can specify that in the selector for children(), e.g.

// Return children up to $limit where my_field is not empty
$items = $parent->children("my_field!='', limit=$limit");

 

Link to comment
Share on other sites

This probably depends on how you set up the multi language site, but I set it up so that you have pages with duplicates of each field for each available language. For example, a page could normally have one title field and one text area, which in a multi language site with 3 languages would mean you have three fields for title and three text areas for the page, that is one for each language.

It might be that some pages lack a translation in a certain language. That is, the page would exist, but for the particular language the fields would be empty. If you want to iterate through these pages you need to set up a loop that checks if a translation exists for each page, and if it doesn't exist, skip to the next page amongst its siblings.

Now, the complexity comes of the fact that there might be a variable amount of siblings (they might be blog posts for example) where it is not known which texts have translations in which languages. So, if you want to display e.g. the 5 most recent posts in any given language, "limit=5" wouldn't cut it, since it would fetch the 5 first pages, regardless if they have translations or not.

Therefore ->eq($i) is a better solution seeing how this one handles only one page at a time. As such a loop can be constructed that would include e.g. the 5 latest blog posts that indeed have been translated. However, since ->eq() relies on ->children(), it means the backend process needs to first include all siblings in the array (unlike when using "limit=$limit"), which wouldn't be optimal, especially if there are a lot of siblings.

In practical terms, I'm not sure if this actually can cause issues even with moderate traffic. But, it would be interesting to see if there is an optimal way to do this that I haven't thought of.

 

Link to comment
Share on other sites

Oh actually! Just saw your last comment there:

Quote

// Return children up to $limit where my_field is not empty
$items = $parent->children("my_field!='', limit=$limit");

That could work for this case! I did not realise you could use conditional statements like that for the selector. Will update once I get a chance to try that out!

Thanks in advance Robin, I think this might cut it!

 

Link to comment
Share on other sites

3 hours ago, Matte85 said:

I did not realise you could use conditional statements like that for the selector.

In the selector that you use with the children() method, you can do anything that you can do in a $pages->find() selector. Because behind the scenes...

$page->children($selector)

...is essentially...

$pages->find("parent=$page, $selector")

 

3 hours ago, Matte85 said:

I set it up so that you have pages with duplicates of each field for each available language. For example, a page could normally have one title field and one text area, which in a multi language site with 3 languages would mean you have three fields for title and three text areas for the page, that is one for each language.

Like I said, I'm no expert on multi-language, but I think PW has tools that let you handle multi-language smarter than this. Have a read here about multi-language fields and here about language support in general.

  • Thanks 1
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...