WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I have a query for a custom post type:

$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
$books = new WP_Query(array(
    'post_type' => 'wiki',
    'posts_per_page' => '50',
    'paged' => $paged

And i want to loop through these posts using the loop-books.php:

<?php get_template_part( 'loop', 'books' ); ?>

Inside the loop-books.php i have these, just like the regular loop.php, i just changed the have_posts and the_post function to work with the $books query:

<?php if ( $books->have_posts() ) : ?>      
    <?php while ($books->have_posts()) : $books->the_post(); ?>
        <?php the_title(); ?><br/>
    <?php endwhile; ?>
<?php endif; ?>

But after this, i get a php error:

Fatal error: Call to a member function have_posts() on a non-object in .../loop-books.php on line 1

So looks like the $books variable is not available inside the get_template_part function. How can i resolve this issue? If i put the $books query inside the loop-books.php its working fine, but i want to separate them.

share|improve this question
try removing the $books-> from loop-books.php & I hope it will work. – Rohit Pande Nov 27 '12 at 12:42
If i remove the $books-> part it will use a default query so thats not good for me. – passatgt Nov 27 '12 at 12:45
if you are using something like: <?php $paged = (get_query_var('paged')) ? get_query_var('paged') : 1; $books = new WP_Query(array( 'post_type' => 'wiki', 'posts_per_page' => '50', 'paged' => $paged )); ?> and here you load the get_template_part query. And after this if you reset postdata then I think my solution will work properly. – Rohit Pande Nov 27 '12 at 12:48
up vote 4 down vote accepted

You will either need to globalize $books (if you want to stick to get_template_part() ) or use

require( locate_template( 'loop-books.php' ) );

instead of get_template_part( 'loop', 'books' );. This issue is caused by $books in loop-books.php being defined only in the scope of get_template_part().

share|improve this answer
This. Though, if the $books query is specific to the loop-books.php template-part file, I would recommend just putting the $books = new WP_Query() call inside the template-part file. – Chip Bennett Nov 27 '12 at 12:56
Thanks. Whats your opinion, which one is the better solution? – passatgt Nov 27 '12 at 12:57
Same, same @Chip - I'd also put it in the same file and avoid the issue in the first place. Answered this bearing in mind that the OP wanted to separate the two. – Johannes Pille Nov 27 '12 at 13:00
@passatgt As far as which is the better, see the above comments, I'd rather go with one file and be done with it. If you must separate them, I'd go with the locate_template() option, to not clutter the global namespace. – Johannes Pille Nov 27 '12 at 13:01
Ok, thanks. The reason i want to seperate them is because i want to use the same loop with other queries too based on other categories/taxonomies – passatgt Nov 27 '12 at 13:06

An alternate method: open/close the loop, and then use loop-books.php to contain just the markup for the loop content. e.g.:

$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
// Get books query
$books = new WP_Query(array(
    'post_type' => 'wiki',
    'posts_per_page' => '50',
    'paged' => $paged
// Open books loop
if ( $books->have_posts() ) :     
    while ($books->have_posts()) : $books->the_post();
        // Get loop markup
        get_template_part( 'loop', 'books' );
// Close books loop

Then, inside of loop-books.php:

<?php the_title(); ?><br/>
share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

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