This can be done in a single query:
$parent_only = new WP_Query( array(
'post_parent' => 0,
) );
If you want to have all children of a specific page (for e.g.) in the loop (or on a request that returns TRUE
for is_singular()
), use get_the_ID()
as argument for post_parent
.
Edit (after seeing the full loop in the updated question)
The get_page_template()
function should be used in the template_include
filter callback. When you look at ~/wp-includes/template-loader.php
and its internals, then you will see the following:
is_page() && $template = get_page_template()
This function is not meant to be used inside templates. When you want to include template parts, then stick with get_template_part()
instead.
I assume you want to build a list of pages where each child page is listed below the parent page – and each child-child page is listed below the parent page. This can be done with wp_list_pages()
Source:
<ul>
?>
wp_list_pages( array(
'title_li' => sprintf(
'<h2>%s</h2>'
__( 'Pages sorted by parent', 'your-textdomain' )
),
) );
<?php
</ul>
Now this will just output a list of pages. When you look closer at the list of arguments, then you can use: child_of
and echo
as well:
// Get all parent pages:
$pages = get_pages( array(
'number' => 0, // get *all* pages
) );
// Container:
$output = array();
// Loop and fetch
foreach ( $pages as $page )
{
$output[] = wp_list_pages( array(
'title_li' => '...',
'echo' => false,
'child_of' => $page->ID,
) );
}
// Build the output:
foreach ( $output as $p )
// etc.
Above example is just meant to clarify internals. Of course you can simply adjust the depth
argument, so wp_list_pages()
fetches parents and their children to build an unordered HTML list.
So the correct approach would be to pass in the needed depth
and if you need custom ordering, then go with a custom walker assigned to the walker
-key.