When I add set_transient code to my cpt query, I get a Fatal error: Call to a member function have_posts() on string ... on line 30

Line 30 is basically: if($graduate_student_query->have_posts()) : ?>

Without the set_transient the query works just fine, but it's obviously not best practices. Where should the set_transient go?

        if ( false === ( $graduate_student_query = get_transient( 'graduate_student_query' ) ) ) {
            $graduate_student_query = new WP_Query(array(
                'post_type' => 'people',
                'role' => 'leadership',
                'meta_key' => 'ecpt_people_alpha',
                'orderby' => 'meta_value',
                'order' => 'ASC',
                'posts_per_page' => '-1'));         
    set_transient( 'graduate_student_query', $graduate_student_query, 2592000 );
 if($graduate_student_query->have_posts()) : ?>
 {some HTML code}
  <?php while ($graduate_student_query->have_posts()) : $graduate_student_query->the_post(); ?>

Do I need to establish the set_transient outside of this loop, at the top of the template document?

  • What do you get if you var_dump() $graduate_student_query before the if() clause?
    – mrwweb
    Apr 3 '15 at 16:07
  • var_dump($graduate_student_query); immediately before renders: string(0)""
    – timmyg
    Apr 3 '15 at 16:26
  • Ok. Next, set delete_transient('graduate_student_query'); right at the top of your snippet. Then var_dump() $graduate_student_query right after you set it. That'll make sure your WP_Query is working. (You also may just have accidentally set some junk value for the transient once.) This can be handy too: wordpress.org/plugins/transients-manager
    – mrwweb
    Apr 3 '15 at 17:18

Submitting a full blown answer now that we've figured it out.

Transients can be hard to troubleshoot because if you save the wrong value to the database at first, you can be looking at an old—and bad—value, even if the code that sets your transient is now correct.

The two ways you can fix this are to temporarily use delete_transient() or use a plugin like Transients Manager. The plugin has the advantage of showing you the value of transients as well which can speed up troubleshooting.

In the example above, the simplest way is just to start the snippet like this:

delete_transient('graduate_student_query'); // this is the magic
if ( false === ( $graduate_student_query = get_transient( 'graduate_student_query' ) ) ) {
    // etc...

That means the old value gets cleared, the full code runs, the transient is resaved, and you get to see if you used the correct value now.

Then be sure to remove delete_transient() from the code. Otherwise, you're deleting it and regenerating it every time and your code is even more inefficient than it was before!

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.