Jump to content

How to group filtered grandchild pages by parent title?


101Bram
 Share

Recommended Posts

I have a simple hierarchy in my pages:

  • parent 1
    • child 1
      • subchild 1
      • subchild 2
    • child 2
      • subchild 1
  • parent 2
    • child1
      • subchild 1
      • subchild 2
  • parent 3
    • ....

I want to display all the subschilds that are satisfying some conditions, and I can do it with a really efficient selector.

e.g (pseudocode)

sub_childs = page.find(template='subchild', parent.title='child1', parent.parent.location='US', ...)

I want to format these results with their parents, e.g. if the highlighted childs are selected in the query, I want to output:

  • parent 1
    • child 1
      • subchild 2
  • parent 2
    • child 1
      • subchild 1
      • subchild 2

Is there a simple way to achieve this with only using the 1 selector?

 

Link to comment
Share on other sites

I suggest taking a look at the sections 'Finding pages that have specific parents or ancestors' and 'Sub-selectors: selectors within selectors' of the 'Using Selectors' page at https://processwire.com/docs/selectors/.

You might end up with something a little like this, here finding all grandchildren with a name beginning with 'a' that have a grandparent with location = 'US':

$grandchildren = $pages->find("has_parent=[template=grandparent, location=US], name^=a");

 

Link to comment
Share on other sites

Maybe my question was not completely clear, but I have a selector to find all the grandchildren.

The question is how I can output the structure  

  • parent 1
    • child 1
      • subchild 2
  • parent 2
    • child 1
      • subchild 1
      • subchild 2

when these highlighted pages are the result of my selector.

Link to comment
Share on other sites

So assuming you selected the subchildren using “->find()”, to render the structure you want you have to iterate the result of the “subchildren” selection and use “subchild->parents()”. Check the docs here: https://processwire.com/api/ref/page/parents/

though to make sure that parent 2’s subchildren will be under the same node I don’t think there’s a straight answer to it and you may have to build the logic for that.

Link to comment
Share on other sites

This is how I would do it. Example in Twig, but you can see the logic in it.

<ul>
    {% for child in pages.get(1).children() %}
        <li>
            <a href="{{ child.url }}">
                {{ child.title }}
            </a>
            {% if child.numChildren(true) %}
                <ul>
                    {% for gchild in child.children('YOUR CUSTOM SELECTOR HERE') %}
                        <li>
                            <a href="{{ gchild.url }}">
                                {{ gchild.title }}
                            </a>
                        </li>
                    {% endfor %}
                </ul>
            {% endif %}
        </li>
    {% endfor %}
</ul>

 

Link to comment
Share on other sites

Another possible approach, given $subchildren as the result of your find:

$parent = null;
$grandparent = null;
foreach($subchildren as $subchild) {
    $scParent = $subchild->parent;
    $scGrandparent = $scParent->parent; // Or $subchild->parent->parent
	if($grandparent != $scGrandparent) {
		$grandparent = $scGrandparent;
		echo $grandparent->name . '<br/>';
	}
	if($parent != $scParent) {
		$parent = $scParent;
		echo '&emsp;' . $parent->name . '<br/>';
	}
	echo '&emsp;&emsp;' . $subchild->name . '<br/>';
}

Obviously, this'll produce simple indented text, but you could adapt to generate a list or whatever you need.

Link to comment
Share on other sites

7 hours ago, BillH said:

Another possible approach, given $subchildren as the result of your find:


$parent = null;
$grandparent = null;
foreach($subchildren as $subchild) {
    $scParent = $subchild->parent;
    $scGrandparent = $scParent->parent; // Or $subchild->parent->parent
	if($grandparent != $scGrandparent) {
		$grandparent = $scGrandparent;
		echo $grandparent->name . '<br/>';
	}
	if($parent != $scParent) {
		$parent = $scParent;
		echo '&emsp;' . $parent->name . '<br/>';
	}
	echo '&emsp;&emsp;' . $subchild->name . '<br/>';
}

Obviously, this'll produce simple indented text, but you could adapt to generate a list or whatever you need.

If I can force the subchildren to be ordered by parent / grandparent, I really like this idea!

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...