Display Child Pages by Parent ID

Advertisement

Problem Problem

I have categorize the articles in parent and child relationship.

Below is the real time example of my current blog.

Webpack Webpack

Here, My parent page is Webpack and Its child pages are Blog and How to respectively.

The Blog and How to pages also have their own child pages.

So, I want to show all the child pages in nth depth.

Top ↑

Solution Solution

WordPress provides us the function get_pages() which return all the child pages of the parent page.

Top ↑

Get All Childs Get All Childs

<?php
$child_pages = get_pages( array(
'child_of' => 46,
'post_status' => 'publish'
));
view raw child-pages.php hosted with ❤ by GitHub

Above function return the list of all child pages of parent page ID 46.

Top ↑

Filter Data Filter Data

It contain the complete object of the page like:

[ID] => 48
[post_author] => 0
[post_date] => 2021-05-11 13:38:47
[post_date_gmt] => 2021-05-11 13:38:47
[post_content] => 
[post_title] => Blog
[post_excerpt] => 
[post_status] => publish
[comment_status] => closed
[ping_status] => closed
[post_password] => 
[post_name] => blog
[to_ping] => 
[pinged] => 
[post_modified] => 2021-05-11 13:38:47
[post_modified_gmt] => 2021-05-11 13:38:47
[post_content_filtered] => 
[post_parent] => 46
[guid] => https://example.com/wordpress/blog/
[menu_order] => 0
[post_type] => page
[post_mime_type] => 
[comment_count] => 0
[filter] => raw

So, Lets get only required fields with PHP array_map() function as:

$child_pages = array_map( function( $item ) {
    return array(
        'ID' => $item->ID,
        'post_title' => $item->post_title,
        'post_status' => $item->post_status,
        'post_parent' => $item->post_parent,
        'post_date' => $item->post_date,
        'post_modified' => $item->post_modified,
    );
}, $child_pages );

Top ↑

Generate Nested Tree Generate Nested Tree

Now, We have a filtered page list so lets build a nested page tree with below function:

<?php
/**
* Build the nested page tree
*
* @todo Change the `prefix_` with your own unique string.
*
* @param array $childs.
* @param int $parent_id.
* @return array
*/
if( ! function_exists( 'prefix_build_tree' ) ) :
function prefix_build_tree( $childs = array(), $parent_id = 0) {
$tree = array();
foreach ($childs as $child_id => $single_page ) {
$single_page = (array) $single_page;
if ($single_page[ 'post_parent' ] == $parent_id) {
$children = prefix_build_tree( $childs, $single_page['ID'] );
if ( $children ) {
$single_page['children'] = $children;
}
$tree[] = $single_page;
}
}
return $tree;
}
endif;

Top ↑

Build HTML Markup Build HTML Markup

Now, We have a nested pages array lets display it with <ul> and <li> tags.

Use below code snippet to build the HTML markup:

<?php
function prefix_page_tree_markup( $page_id = 0 ) {
$pages = prefix_get_page_tree( $page_id );
if( empty( $pages ) ) {
if( is_user_logged_in() ) {
echo '<p>No Post Found!</p>';
}
return;
}
echo '<ul>';
foreach( $pages as $page ) {
echo '<li><a href="'.$page['link'].'">'. $page['post_title'] . '</a>';
if( ! empty( $page['children'] ) ) {
echo '<ol>';
foreach( $page['children'] as $child_1 ) {
echo '<li><a href="'.$child_1['link'].'">'. $child_1['post_title'] . '</a>';
if( ! empty( $child_1['children'] ) ) {
echo '<ol>';
foreach( $child_1['children'] as $child_2 ) {
echo '<li><a href="'.$child_2['link'].'">'. $child_2['post_title'] . '</a>';
if( ! empty( $child_2['children'] ) ) {
echo '<ol>';
foreach( $child_2['children'] as $child_3 ) {
echo '<li><a href="'.$child_3['link'].'">'. $child_3['post_title'] . '</a>';
echo '</li>';
}
echo '</ol>';
}
echo '</li>';
}
echo '</ol>';
}
echo '</li>';
}
echo '</ol>';
}
echo '</li>';
}
echo '</ul>';
}
%d bloggers like this: