Single page theme that uses pages for the content

I’m making a one page site. On the page I want to run WP_Query three or four times to pull in those 3-4 pages.

The page looks a bit like this:

Read More
<div class="row">
 <?php

    $args = array( 'pagename' => 'page-1'); 

    $the_query = new WP_Query( $args );

    // The Loop
    if ( $the_query->have_posts() ) :
    while ( $the_query->have_posts() ) : $the_query->the_post();
      get_template_part('content');
    endwhile;
    endif;

    // Reset Post Data
    wp_reset_postdata();
?>
</div>


<div class="row">
 <?php

    $args = array( 'pagename' => 'page-2'); 

    $the_query = new WP_Query( $args );

    // The Loop
    if ( $the_query->have_posts() ) :
    while ( $the_query->have_posts() ) : $the_query->the_post();
      get_template_part('content');
    endwhile;
    endif;

    // Reset Post Data
    wp_reset_postdata();
?>
</div>

<div class="row">
 <?php

    $args = array( 'pagename' => 'page-3'); 

    $the_query = new WP_Query( $args );

    // The Loop
    if ( $the_query->have_posts() ) :
    while ( $the_query->have_posts() ) : $the_query->the_post();
      get_template_part('content');
    endwhile;
    endif;

    // Reset Post Data
    wp_reset_postdata();
?>
</div>

Of course I’m repeating myself here, and that’s a bit of a waste. What I want to do is function-ize this instance of WP_Query. Here’s what I’ve done, but it doesn’t seem to return anything at all. It has to be something stupid, but I can’t see what it could be (in functions.php):

/**
 * Functionize wp_query
 *
 * @since 0.1
 */
function waterstreet_fetch_page( $pagename ){
    $args = array( 'pagename' => $pagename ); 

    $the_query = new WP_Query( $args );

    // The Loop
    if ( $the_query->have_posts() ) :
    while ( $the_query->have_posts() ) : $the_query->the_post();
      get_template_part('content');
    endwhile;
    endif;

    // Reset Post Data
    wp_reset_postdata();
}

Then of course, in my template files, I want to be able to just run:

<div class="row">
    <?php waterstreet_fetch_page('page-1'); ?>
</div>

<div class="row">
    <?php waterstreet_fetch_page('page-2'); ?>
</div>

<div class="row">
    <?php waterstreet_fetch_page('page-3'); ?>
</div>

Advice welcome! Thanks.

Related posts

Leave a Reply

2 comments

  1. How-to simplify your life

    I’d go a fairly simpler route:

    • Add a “main/parent” page
    • Apply your template there
    • Add “child” pages to this main page
    • Alter the query to include them

    Code example as plugin for a quick test

    Here’s an (untested) plugin that modifies the query args to not only reduce it to a single query, but modify the main query, so no performance increase has to be taken.

    Explanation

    I’m not sure how you could retrieve the parent post (current) ID inside the function. I guess you have to set it manually. Anyway: Try it with get_queried_object_id() (which will likely not work) or see if you could retrieve it from the $query object. You could also attach a second filter to post_clauses and just change the arguments in this filter (where get_queried_object_id() should already be present – or not).

    The nice thing that this function does is to attach the orderby value as menu_order, so you can make use of what the page post type supports by default. Imo you should always make as much use of what core offers as possible.

    <?php
    /** Plugin Name: (#70317) »kaiser« Fetch all child posts */
    /**
     * Calls the child pages
     * 
     * @param  object $query
     * @return object $query
     */
    function wpse70317_pre_get_posts( $query )
    {
        if (
            ! $query->is_home()
            OR ! $query->is_front_page()
            OR ! $query->is_main_query()
            )
        {
            return $query;
        }
    
        $query->set( 'post_type', 'page' );
        $query->set( 'post_status', 'inherit' );
    
        // Allow the menu order (meta value) to be used
        // ... and start with 0 and count up
        $query->set( 'order', 'ASC' );
        $query->set( 'orderby', 'menu_order' );
    
        // Change this to your parent posts ID
        $query->set( 'post_parent', 1 );
    
        return $query;
    }
    add_action( 'pre_get_posts', 'wpse70317_pre_get_posts' );
    
  2. If you replace page slugs with their IDs, then you can use ‘post__in’ query parameter and ‘page’ as the post_type in a single query:

    <?php
    
    $args = array( 'post_type' => 'page', 'post__in' => array(2, 3, 5)); 
    
    $the_query = new WP_Query( $args );
    
    // The Loop
    if ( $the_query->have_posts() ) :
    while ( $the_query->have_posts() ) : $the_query->the_post();
      get_template_part('content');
    endwhile;
    endif;
    
    ?>