Jump to content

Limit selector in foreach not working properly


RyanJ
 Share

Recommended Posts

I am using the below to go several levels deep, but when using a select of "limit" or "sort" I am getting strange results. For example, if limit=2 I get five results. If limit=3 I get six results. I am sure I have messed up something.

Maybe there is a better way?

$cats = $pages->get("/mypage/")->children;
// get children of the parent
       foreach ($cats as $cat) {
        $menu .= "<div>";
        $menu .= "<h2 class='titlebg'>$cat->title</h2>";
         if($cat->children) {
// if they have children
           $menu .= "<ul>";
            foreach($cat->children as $subchild) {
             foreach ($subchild->children("limit=2, sort=-date,   
       sort=title") as $child) {
           $menu .= "<li><a href='{$child->url}'>$child->title</a></li>";
         }
        }
         $menu .= "</ul>";
     }
         $menu .= "<span><a href='{$cat->url}'>See More</a></span>";
        $menu .= "</div>";
Link to comment
Share on other sites

I'm sure there's a better way - if only I knew what you're trying to achieve exactly ;).

Here's an example of a page structure to demonstrate what's happening:

post-481-0-96494100-1384969656_thumb.png

With "limit=2" your code prints out:

cat1
cat2
  child2.1.1
  child2.1.2
  child2.2.1
  child2.2.2
cat3

And with "limit=3":

cat1
cat2
  child2.1.1
  child2.1.2
  child2.1.3
  child2.2.1
  child2.2.2
cat3

Reading the code, it's pretty much expected output to me, but obviously not the one you're after :). You're printing first two (or three) "child" pages under each "subchild" page found under children of "/mypage/" ("cat" pages). (Edit: and leaving all divs open.)

So, what is the output you'd like to see with the page structure outlined above?

(Edit 2: Fixed my examples...)

(Edit 3: Really fixed my examples... It's not my day.)

Edited by nik
  • Like 2
Link to comment
Share on other sites

Hi Nik,

I am pulling in multiple content areas on one page. I was trying in minimize my code. My goal based off your diagram is to get the grandchildren of cat1, cat2 and cat3 and limit them to 3.

Print Cat1 Title

 Loop through 3 grandchilden of Cat1 and print them

Print Cat2 Title
Loop through 3 grandchilden of Cat2 and print them

Print Cat3 Title
Loop through 3 grandchilden of Cat3 and print them

 I am getting the correct grandchildren for each cat, but the limit part is confusing me. Clear as mud? :).. I also updated my original snippet of code to include the closing div, just forgot to add it when I posted it.

Link to comment
Share on other sites

First of all, my examples were not right - not at all, sorry. Now they're fixed.

The problem is that you're limiting pages under each "subchild" separately, not all grandchildren at once. Here's one way to get there:

$limit = 4;

$cats = $pages->get("/mypage/")->children;
foreach ($cats as $cat) {
    $menu .= "<div>";
    $menu .= "<h2 class='titlebg'>$cat->title</h2>";
    $grandchildren = $pages->find("parent={$cat->children}, limit=$limit, sort=-date, sort=title");
    if($grandchildren) {
        // if they have GRANDchildren
        $menu .= "<ul>";
        foreach($grandchildren as $child) {
            $menu .= "<li><a href='{$child->url}'>$child->title</a></li>";
        }
        $menu .= "</ul>";
        if($grandchildren->getTotal() > $limit) $menu .= "<span><a href='{$cat->url}'>See More</a></span>";
    }
    $menu .= "</div>";
}

This would give (with the example structure again):

cat1

cat2
  child2.1.1
  child2.1.2
  child2.1.3
  child2.2.1

  See More

cat3
  child3.1.1

This trick to get grandchildren ("parent={$cat->children}") would not be the way to go if there were a lot of "subchild" pages under any "cat" page. This is because the selector expands to something like "parent=1234|1235|1236|1237|...|1507|1508" giving a too long selector string at one point. But assuming there aren't more than a couple of dozen of them, this would work just fine.

I also added a little condition to show "See more" only if there are more grandchildren to see - just as an example.

  • Like 6
Link to comment
Share on other sites

That is great! You always go the extra mile to explain things in full detail and even with extra details. Makes sense about what was happening. Thanks so much! In time there maybe a lot of sub children, but not for now. May I ask what your approach would be then just for learning purpose?

Link to comment
Share on other sites

Well, another way would be using a different template for the child pages ("child-template" in the following example). Then you'd be able to fetch the grandchildren like this:

$grandchildren = $pages->find("has_parent=$cat, template=child-template, limit=$limit, sort=-date, sort=title");

This scales really well and has no issues with the length of the selector string. And who knows, maybe you already have things set up in a compatible way. :)

Of course with "has_parent=$cat" you could also filter by some other property that gives you child pages only: "property_abc=only-child-pages-have-this-value". Or filter out the subchildren level with "template!=subchild-template" or "property_xyz!=only-subchild-pages-have-this-value". Those properties and values are naturally only placeholders to demonstrate possible solutions.

The possibilities are more or less endless. Some options, like using different templates, are pretty general but often there are ways specific to the situation available as well.

  • Like 3
Link to comment
Share on other sites

I had actually added the template=child-template part but was unsure of its effectiveness. template!=a-template even sounds better. It is great to have someone giving you new perspectives and options on how to do/see things differently. It is all too often the brain gets tunnel vision and cannot think of a different solution. I am glad you took the time to make it clear and give a different perspective. Once again, I thank you.

Link to comment
Share on other sites

  • 3 years later...

@nik, that is exactly what I was looking for because I got stuck with the child of the child of the child pulling and I either need some coffee to wake up or some good sleep and no distraction from the family. You have made my day, man!

 

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

×
×
  • Create New...