1
votes

Hey fellow WordPress dev's / php masters. Long story short, I am using WordPress (and I never use WordPress - sorry!) and when I go to view the individual post rendered from single.php, the 'have_posts()' function is returning false. The template is rendered and I am not having any issues with the template rendering, I am simply having an issue with 'have_posts()' showing false and not outputting the blog post.

I downloaded WordPress 5.0.3, am running on MAMP and have used this method previously without any issues. All in all, I am trying to really keep my template files organized and I am using get_template_part to retrieve sections of the theme.

My current structure is:

single.php -

<?php
    get_template_part('template-parts/blog/_single/blog-post-banner'); // Renders perfect
?>
<div class="light-grey">
    <div class="container">
        <div class="row no-margin">
            <div class="col s12 l9 mb-0-l">
                <?php get_template_part('template-parts/blog/_single/blog-post'); // Renders perfect ?>
            </div>
            <div class="col s12 l3 mb-0-l">
                <?php get_template_part('template-parts/blog/side-bar'); // Renders perfect ?>
            </div>
        </div>
    </div>
</div>

And of course the real culprit the blog-post partial -

<?php 
if (have_posts()) : 
    the_post(); ?>
    <div class="row no-margin">
        <div class="col s12 no-margin relative">
            <img src="<?php the_post_thumbnail_url('medium_size'); ?>" alt="<?php the_title(); ?>" class="block">
        </div>
        <div class="col s12">
            <div class="white p-2-s p-3-l">
                <?php the_content(); ?>
            </div>
        </div>
    </div>
<?php else :?>
    <div class="col s12 no-margin">
        <div class="white p-2-s p-3-l"><p>Sorry, we couldn't find the post you were looking for.</p></div>
    </div>
<?php endif; ?>

Again, the templates are rendering perfect but the 'have_posts()' is returning false and spitting out my 'else' part of my statement. I have used this method in another template and it worked perfectly before (although I will admit, I love to develop in node and WordPress and php have really made me beat my head against the wall at times lol). Is there something I missed?

I have checked my functions.php which I have written from scratch, and there isn't a single thing in there that might affect the post but if you need to see it, I would be happy to share it (I have disabled each portion of the functions.php to check if it would help and no luck). I don't have any plugins added, not even the default included ones (I am a dork that wants to build most everything from scratch so I know how it works).

Am I wrong in that the output to 'have_posts()' should be true on the single.php page? Did I do something wrong with my partials? The banner does use the 'the_title()' tag and 'the_date()' tag but both php tags are properly closed. Would really appreciate some insight on why I am getting false on this. Thanks everyone!

** EDIT ** - When I went to debug the blog-post partial and var_dump the have_posts(), I placed it above the if statement and everything rendered. Looked like so:

<?php 
var_dump(have_posts()); // <---------------- Added this and it rendered
if (have_posts()) : 
    the_post(); ?>

The var_dump output false but then if I did it a second time, it now renders true. Any ideas as to why? For the time being, I am storing a have_posts() in a random variable so there is no output and the post is now showing. While I am happy the post is now showing, I know this isn't necessarily a 'solid fix'. Any ideas with this?

1
I'm not a WP-guru, but if you look at the source of have_posts() you can see that it rewinds the index when reaching the end, and then returning false. Could it be, that you are looping somewhere else, without this rewinding happening at the end? It seems that you rewind on the first call to have_posts(), since it returns true the second time. Reference to The Loop.Jeppe
@Jeppe That is a good point, I have a loop in the sidebar that shows the some 'recent' posts. But this partial is called after the blog post. Do you think this still might affect it?Benjamin
@Jeppe I might add that I checked all potential loops with no luck and what I find more interesting is that I have created a simple custom post type called 'news' and using the exact same template for the single news post type outputs perfectly. Seems to be an issue only with the blog articles. This is so strange...Benjamin

1 Answers

0
votes

So first I just want to say, @Jeppe you had it right the whole time. If I could mark your comment correct (and if you can, please show me how) I would.

To anyone else who stumbles across this post, it comes down to using the 'rewind_posts()' function. All in all, I have a loop somewhere in my code, that I can't identify as the culprit, that is essentially forcing my 'have_posts()' function to return false because I haven't reset it / rewound it according to WordPress.

My solution was to simply take my old code:

<?php 
    if (have_posts) :
        the_post;
?>

and add the rewind_posts() function above the if statement:

<?php 
    rewind_posts(); // <---------- This guy right here.
    if (have_posts) :
        the_post;
?> 

This will rewind WordPress's loop and allow have_posts() to print true.