I am trying to display a list of all child pages using wp_query and so far I have created a function that retrieves all the child pages for the current page, however I need to sort these pages into 2 lists by the custom field.

The custom field is called type and it is a select field with the following values:

product and about I need to split the list of pages into 2 groups based on the field value and I can't seem to group them by the custom field.

I need the output to be:

- Page 1
- Page 2
- Page 3

- Page 1
- Page 2
- Page 3

So far I have a list of all the pages with no way of separating them and adding the value of the custom field in between.

function get_child_pages($page_id, $post_type = 'page')
    // Set up the objects needed
    $custom_wp_query = new WP_Query();
    $all_wp_pages = $custom_wp_query->query(array('post_type' => $post_type, 'posts_per_page' => -1, 'order' => 'ASC', 'orderby' => 'meta_value', 'meta_key' => 'type', 'value' => 'Product',));

    // Filter through all pages and find specified page's children
    $page_children = get_page_children($page_id, $all_wp_pages);

    return $page_children;

foreach (get_child_pages(wp_get_post_parent_id(get_the_ID())) as $s) {
  echo '<li><a href="' . get_the_permalink($s->ID) . '">' . get_the_title($s->ID) . '</a></li>';


You're close. You have:

foreach (get_child_pages(wp_get_post_parent_id(get_the_ID())) as $s) {
  echo '<li><a href="' . get_the_permalink($s->ID) . '">' . get_the_title($s->ID) . '</a></li>';

We need to add a layer above that to show the two lists. However we can't assume that the posts of one type will all come out together (i.e. all of one category, then all of the next). That means we can't just spit it all out in the order it comes in.

Here's a way utilizing a holding object to first group the posts by their value of that field:

//this will hold the post IDs sorted by outer groups
$list_groups = array(); 

foreach (get_child_pages(wp_get_post_parent_id(get_the_ID())) as $s) {

    //get the category of this post
    $list_category = get_post_meta( $s->ID, "type", true );

    //if this is the first post of that category, initialize the array
    if ( ! isset( $list_groups[ $list_category ] ) ){
        $list_groups[ $list_category ] = array();

    //add this post ID to that category in our holding array
    $list_groups[ $list_category ][] = $s->ID;


//at this point we have an array ($list_groups) that has an inner array of post IDs for each category

foreach ( $list_groups as $category_name => $category_posts ){

    echo "<div class='category-group'><h2>$category_name</h2><ul>";

    foreach ( $category_posts as $category_post_id ){

        $p_permalink = get_the_permalink( $category_post_id );
        $p_title = get_the_title( $category_post_id );

        echo "<li><a href='$p_permalink'>$p_title</a></li>";


    echo "</ul></div>";


So what we've done is first created a holding array that ends up looking like this:


It's just an array holding arrays for each type, and in those arrays are the IDs of the posts that belong there.

Then we loop through that holding array and spit them out by category.

Sidenote: your wp_query looks to be limiting the results to just one of the two categories. I could be misreading that but if you only get one category out check it.

  • This did the trick! Thank you @the_hobbes how do I display the label of the "type" field as opposed to the value? – Neelam Khan Feb 6 '19 at 10:35
  • Meta data has a key and a value. Right now this snippet shows the value. The key would just be "type". I will take a guess that what you mean is that when you set the meta data you have a select box with options like <option value="VAL">TEXT</option> and here you want to show TEXT instead of VAL. Unfortunately you are only saving VAL to the database. You would have to write a function or other way to convert your VALs back to the TEXTs (or better, have both the dropdown and this output pull the VAL & TEXT pairs from a common place). – tmdesigned Feb 6 '19 at 13:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.