11

I have a query for a custom post type:

<?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 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.

3
  • try removing the $books-> from loop-books.php & I hope it will work. Nov 27, 2012 at 12:42
  • If i remove the $books-> part it will use a default query so thats not good for me.
    – passatgt
    Nov 27, 2012 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. Nov 27, 2012 at 12:48

2 Answers 2

6

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().

6
  • 2
    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. Nov 27, 2012 at 12:56
  • Thanks. Whats your opinion, which one is the better solution?
    – passatgt
    Nov 27, 2012 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. Nov 27, 2012 at 13:00
  • 1
    @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. Nov 27, 2012 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, 2012 at 13:06
9

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

<?php
$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
    endwhile;
endif;
?>

Then, inside of loop-books.php:

<?php the_title(); ?><br/>

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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