Jump to content
Vigilante

How do I find pages under a parent when using another pagearray as the selector?

Recommended Posts

I have a pagearray that contains all the pages I need to work with. Just call it $everything.

I have another pagearray that contains a set of parent pages I need to work with. $parents.

What I need to do is loop through the parents and get just the children which exist in $everything.

```

foreach ($parents as $p) {

$childlist = $p->find($everything);

}

```

 

This doesn't work though as I can't do find($everything) like this. So how can I take some page, and then get all the children which happen to exist in another pagearray? Is it filter()? has()?

Share this post


Link to post
Share on other sites

did you try has_parent and do it the other way around?

foreach($everything as $e) {
	foreach($parent as $p) {
		if($e->has_parent($p) {
			// do something
		}
	}
}

Without knowing what you actually do with $childlist, it's hard to suggest maybe a more efficient way to do this...

Share this post


Link to post
Share on other sites

I need to loop through the parents first as this creates the outer html portion of the output. Then loop through those child pages for the inner html for each parent. I just only want to include children which exist in the $everything array.

If it helps. The $everything query is finding stuff from all across the site. I will need to put these into a ul->li list but organized by their parents

```

<!-- loop each parent -->

<section>
<h2>Parent stuff</h2>
<ul>
<!-- loop child stuff under each parent -->
</ul>
</section>

```

So I have my $everything query, but I need it filtered, sorted, parsed out, whatever, by the parents so I can create each parent section such as in the above.

My original logic was to create an array with the everything query, then loop through that to create another array that holds just the parents. Both of these arrays only contain unique pages. But now I need them cross referenced, looping the parents and only getting children that exist in the everything array.

Share this post


Link to post
Share on other sites

@Vigilante, please use code blocks for your code examples.

2017-12-27_101449.png.978607ed22e1914b7988fc652335722e.png

 

On 24/12/2017 at 7:30 AM, Vigilante said:

What I need to do is loop through the parents and get just the children which exist in $everything.

If you really need to do it this way then you could do...

<?php foreach($parents as $parent): ?>
    <?php $children = $parent->children("id=$everything"); // PageArray dereferenced as string of pipe-separated IDs ?>
    <?php if(count($children)): ?>
        <section>
            <h2><?= $parent->title ?></h2>
            <ul>
                <?php foreach($children as $child): ?>
                    <li><?= $child->title ?></li>
                <?php endforeach; ?>
            </ul>
        </section>
    <?php endif; ?>
<?php endforeach; ?>

...but it's not very efficient.

 

Instead, I suggest you don't need the $parents PageArray and should just work on sorting the $everything PageArray. For example:

// Sort by parent in the selector for $everything
$everything = $pages->find("template=basic-page, sort=parent");

// Initialise $parent_title
$parent_title = '';
foreach($everything as $one) {
    // By default, this is not a new section
    $new_section = false;
    if($one->parent->title !== $parent_title) {
        // If the parent title of $one is different to the existing $parent_title
        // then this is a new section
        $new_section = true;
        // Set $parent_title
        $parent_title = $one->parent->title;
    }
    // If this is a new section and $one is not the first item in $everything
    // close ul and section from previous section
    if($new_section && $one !== $everything->first) echo "</ul></section>";
    // If this is a new section, add the open section, heading and open ul
    if($new_section) echo "<section><h2>$parent_title</h2><ul>";
    // Output the li
    echo "<li>$one->title</li>";
    // If $one is the last item in $everything then close the ul and section
    if($one === $everything->last) echo "</ul></section>";
}

If you need some custom sort of the parents then you could loop through $everything and add a custom sort property to each item, then sort $everything by the custom property. Not exactly the same, but this post shows the general idea:

 

 

  • Like 1

Share this post


Link to post
Share on other sites

The first method might not be super efficient, but when would that efficiency be realized? I probably have an $everything with maybe 50 to 100 pages which separate into around 10 or 15 parents lets say. Is that efficiency causing me 3 seconds or a blink of the eye?

The second method makes sense but isn't as easy to follow. If the speed difference is 5ms then at the end of the day doesn't really matter so much.

Share this post


Link to post
Share on other sites

You can also use wirecache or markupcache to remedy possible performance issues. 

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...