skip to Main Content

I’m currently trying to fetch all my pages from different post types and display them on a single page with a WP Query but I wanted to display them in such a template in the HTML instead of it all coming as a big list of course I’m not entirely sure if this is even possible

 Parent 
    Child 
 Parent 
    Child 
 Parent 
 Parent 
 Parent

This is what I’m using so far

$args = array(
    'post_type'=> 'page',
    'orderby'    => 'title',
    'post_status' => 'publish',
    'order'    => 'ASC',
    'posts_per_page' => 20, 
    );
    $result = new WP_Query($args);
?>
    <section>
    <h2><?php echo $post_type; ?></h2>
        <?php
        while ($result->have_posts()) { 
            $result->the_post();
            $post = get_post();
            ?>
                <ul>
                    <li class="">
                        <a href=""><?php echo the_title(); ?></a>

                    </li>
                </ul>
            <?php
        }
        wp_reset_postdata();

        ?>
   </section>
   <?php } 

I tried using wp_list_pages but I’m not sure how to use that for different post types and also I would like to have limited posts per page not display everything

2

Answers


  1. WP_Query is not the right tool for the job!

    WordPress has special functions for what you’re looking for:

    get_pagesDocs
    wp_list_pagesDocs

    "I tried using wp_list_pages but I’m not sure how to use that for different post types"

    Well, that’s why docs are here for!

    For example, wp_list_pages accept an argument called post_type which lets you specify which "post type" you’re interested in, and its default value is the wordpress "page" type. If you want to change it to your custom post type then you could use something like this:

    $args = array(
      'post_type' => 'your_custom_post_type'
    );
    
    wp_list_pages($args);
    

    "also I would like to have limited posts per page not display everything"

    Again, there is docs for that!

    if you use get_pages for example, then there is an argument for limiting the number of pages shown on the page and that’s called number. The number argument is an integer and represents the number of pages to return and its default is 0(all pages).

    Using get_pages also you could specify your custom post type to query. The argument for that is called post_type and its default value is the wordpress "page" type.

    $args = array(
      'post_type' => 'your_custom_post_type',
      'number'    => 20
    );
    
    $your_pages = get_pages($args);
    
    foreach ($your_pages as $page) {
      echo $page->post_title;
    }
    

    If you really need/want to use WP_Qery then you could do it like this:

    WP_Qery + get_pages

    $args = array(
      'post_type' => 'page',
      'orderby'    => 'title',
      'post_status' => 'publish',
      'order'    => 'ASC',
      'posts_per_page' => 20,
    );
    
    $results = new WP_Query($args);
    
    if ($results) {
      while ($results->have_posts()) {
        $results->the_post();
    
        echo "<h3>" . get_the_title() . "<h3>";
    
        $sub_pages_args = array(
          'child_of' => get_the_ID(),
        );
    
        $sub_pages = get_pages($sub_pages_args);
    
        echo "<ul>";
        foreach ($sub_pages as $sub_page) {
          echo "<li>";
          echo $sub_page->post_title;
          echo "</li>";
        }
        echo "</ul>";
      }
    }
    
    wp_reset_postdata();
    

    Which will output this:

     Parent Title
        Child Title
     Parent Title
        Child Title
     Parent Title
     Parent Title
     Parent Title
    

    Fully tested and works on wordpress 5.8.

    Login or Signup to reply.
  2. $pages = get_pages();
    if ($pages) {
        foreach ($pages as $page) {
            if ($page->post_parent == 0) {
                echo $page->post_title . ' — ' . $page->ID;
                $sub_pages = get_pages(array('child_of' => $page->ID));
                foreach ($sub_pages as $sub_page) {
                    echo ' — ' . $sub_page->post_title . ' — ' . $sub_page->ID;
                }
            }
        }
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search