In the Bricks Facebook group, a user asked:
Looking for a custom query to output a list of posts in the same hierarchy that the posts use. For example, the posts are like:
Parent 1
– child A
– child B
Parent 2
– child C
– child D
That’s the way I need to build an unordered list. If you just query posts you get them all without hierarchy, for example (if sorted by name) child A, child B, child C, child D, Parent 1, Parent 2.
Anyone have a code snippet that will accomplish this?
WordPress has a wp_list_pages() function for showing a list of all Pages, but it outputs all Pages, and there’s no direct way to specify that only the top-level Pages and their children are to be included.
This Pro tutorial provides the steps to output top-level parent posts (can be Pages or any hierarchical post type) and their child posts using nested query loops in Bricks.
Given this Page structure:

this will be the output after implementing the tutorial:

Step 1
Edit the Page where you’d like to show the top-level parent Pages and their children with Bricks.

Section JSON is provided near the end.
Add a Section and inside its Container, a Container (UL).
Add a Block (LI) inside the Container.
Enable query loop on the Block.
Post type: Pages
Enable PHP query editor.
$top_level_posts = get_posts( [
'post_type' => 'page',
'post_parent' => 0,
'nopaging' => true,
'fields' => 'ids'
] );
$top_level_posts_with_children = array_filter( $top_level_posts, function ( $id ) {
$has_children = get_posts( [
'post_type' => 'page',
'post_parent' => $id,
'fields' => 'ids'
] );
return $has_children;
});
return [
'post__in' => $top_level_posts_with_children,
'orderby' => 'title',
'order' => 'ASC',
];
Note: For most sites, the above code with two loops (calls to get_posts()) should be fine. But if you want more performant code that uses a single SQL query (thanks ChatGPT), replace that with:
global $wpdb;
// SQL query to select all top-level pages that have at least one child
$sql = "SELECT ID FROM {$wpdb->posts} p1
WHERE p1.post_type = 'page'
AND p1.post_parent = 0
AND EXISTS (
SELECT 1 FROM {$wpdb->posts} p2
WHERE p2.post_type = 'page'
AND p2.post_parent = p1.ID
)";
$top_level_posts_with_children = $wpdb->get_col($sql);
return [
'orderby' => 'title',
'order' => 'ASC',
'post__in' => $top_level_posts_with_children,
];
Add a Basic Text element inside the Block having:
{post_title:link}
Add a Container (UL) (this will be at the same level as the outer query loop block).
Add a Block (LI) inside the Container.
Enable query loop and change settings to:

Add a Basic Text element inside the Block having:
{post_title:link}
Check on the front end.