3

I've created a PHP while statement that displays 8 posts from WordPress in a particular layout. Now I would like to keep running this loop until all the posts are displayed. So what I've done is created a variable called posts_displayed, and I'm using that to set the post_offset and incrementing it each time a post is displayed. The original code worked as expected, but when I added the additional while statement around it, no posts are displayed.

I've updated the code such that there is one main query and loop with four different queries and loops within. The problem I am encountering now is on line 131, where I am getting an unexpected endwhile error.

    <?php $posts_displayed = 0; ?>

<?php 
   $main_query = new WP_Query( array(
     'category_name' => 'Travel',
   )); 
?>

<?php if ( $main_query->have_posts() ) : ?>
  <?php while ( $posts_displayed < ($main_query->post_count)  ) ?>

<?php 
   $first_query = new WP_Query( array(
     'category_name' => 'Travel',
      'posts_per_page' => 2,
      'offset' => $posts_displayed,
   )); 
?>

<div class="row row__padding--bottom homepage__row--one">

<?php if ( $first_query->have_posts() ) : ?>
  <?php while ( $first_query->have_posts() ) : $first_query->the_post(); ?>

    <div class="col-sm-12 col-md-6">
        <div class="journal__latest" style="background: url(<?php echo get_the_post_thumbnail_url( $post_id, 'large' ); ?>) !important; background-size: cover !important; background-position: center center !important; background-repeat: no-repeat !important;">

        </div>
        <div class="post__info--container">
          <a href="<?php echo esc_url( get_permalink()); ?>"><h4><?php the_title(); ?></h4></a>
        </div>
   </div>

  <?php endwhile; ?>
  <?php wp_reset_postdata(); ?>

<?php endif; ?>

</div>

<?php 
   $second_query = new WP_Query( array(
     'category_name' => 'Travel',
      'posts_per_page' => 3,
       'offset' => posts_displayed,
   )); 
?>

<div class="row row__padding--bottom">

<?php if ( $second_query->have_posts() ) : ?>
  <?php while ( $second_query->have_posts() ) : $second_query->the_post(); ?>


    <div class="col-12 col-md-4">
        <div class="portfolio__featured" style="background: url(<?php echo get_the_post_thumbnail_url( $post_id, 'large' ); ?>) !important; !important; background-size: cover !important; background-position: center center !important; background-repeat: no-repeat !important;">

        </div>
        <div class="post__info--container">
          <a href="<?php echo esc_url( get_permalink()); ?>"><h4><?php the_title(); ?></h4></a>
       </div>
    </div>

  <?php endwhile; ?>
  <?php wp_reset_postdata(); ?>

<?php endif; ?>

</div>

<?php 
   // the query
   $third_query = new WP_Query( array(
     'category_name' => 'Travel',
      'posts_per_page' => 1,
     'offset' => posts_displayed,
   )); 
?>

<div class="row row__padding--bottom">

<?php if ( $third_query->have_posts() ) : ?>
  <?php while ( $third_query->have_posts() ) : $third_query->the_post(); ?>

    <div class="col-12">
        <div class="journal__featured" style="background: url(<?php echo get_the_post_thumbnail_url( $post_id, 'large' ); ?>) !important; !important; background-size: cover !important; background-position: center center !important; background-repeat: no-repeat !important;">

        </div>
        <div class="post__info--container">
            <a href="<?php echo esc_url( get_permalink()); ?>"><h4><?php the_title(); ?></h4></a>
        </div>
    </div>

  <?php endwhile; ?>
  <?php wp_reset_postdata(); ?>

<?php endif; ?>

</div>

<?php 
   // the query
   $fourth_query = new WP_Query( array(
     'category_name' => 'Travel',
      'posts_per_page' => 2,
     'offset' => posts_displayed,
   )); 
?>

<div class="row row__padding--bottom">

<?php if ( $fourth_query->have_posts() ) : ?>
  <?php while ( $fourth_query->have_posts() ) : $fourth_query->the_post(); ?>

    <div class="col-sm-12 col-md-6">
        <div class="journal__featured" style="background: url(<?php echo get_the_post_thumbnail_url( $post_id, 'large' ); ?>) !important; !important; background-size: cover !important; background-position: center center !important; background-repeat: no-repeat !important;">

        </div>
        <div class="post__info--container">
            <a href="<?php echo esc_url( get_permalink()); ?>"><h4><?php the_title(); ?></h4></a>
        </div>
    </div>

  <?php endwhile; ?>
  <?php wp_reset_postdata(); ?>

<?php endif; ?>

</div>

<?php endwhile; ?>

<?php else : ?>
  <p><?php __('No News'); ?></p>
<?php endif; ?>
4
  • 1
    Why are you querying the database so many times? Why not query it once for all the posts, then arrange them in the layout you want? I think it would make the code much readable. Commented Aug 23, 2019 at 15:22
  • @muka.gergely If I only query once then how could I then display 2 posts in a certain way, then 3 posts a certain way, and so on? Commented Aug 23, 2019 at 15:54
  • Just iterate over the array that would be in $the_query variable, and arrange the items (each item would be a post) as you see fit. Commented Aug 23, 2019 at 16:05
  • @muka.gergely I get that, I just don't know how I would be able to arrange it such that the first two are in one row, followed by a row of three and so on. And then once the pattern of 8 is complete then start it over again Commented Aug 23, 2019 at 16:13

1 Answer 1

1

I see that your code has a few issues. First of all in your first if

if ( $the_query->have_posts() )

$the_query is still undefined, as a result it does not have posts, you are defining $the_query a few lines of code below as an Instance of the WP_Query class .

Secondly you call wp_reset_postdata() conditionally, meaning that if the query did not have posts post data would not be reset.

And of course you are querying your database too many times which I don't see why you would need it.

I did some quick corrections (notice the below code is untested, I just applied quick solution I could think of)

<?php
$the_query = new WP_Query(
    array(
        'category_name'  => 'Travel',
        'posts_per_page' => 64,
    )
);
?>
<div class="row row__padding--bottom">
    <?php
    if ( $the_query->have_posts() ) :
        $i         = 0;
        $class_map = [
            0 => 'col-md-6',
            1 => 'col-md-6',
            6 => 'col-md-6',
            7 => 'col-md-6',
            2 => 'col-md-4',
            3 => 'col-md-4',
            4 => 'col-md-4',
            5 => 'col-md-12',
        ];
        while ( $the_query->have_posts() ) :
            $the_query->the_post();
            ?>
            <div class="col-sm-12 <?php echo esc_attr( $class_map[ $i % 8 ] ); ?>">
                <div class="journal__featured" style="background: url(<?php the_post_thumbnail_url( 'large' ); ?>) !important; !important; background-size: cover !important; background-position: center center !important; background-repeat: no-repeat !important;">
                </div>
                <div class="post__info--container">
                    <a href="<?php the_permalink(); ?>"><h4><?php the_title(); ?></h4></a>
                </div>
            </div>
            <?php
            if ( 1 === ($i % 8) || 4 === ($i % 8) || 5 === ($i % 8) ) {
                echo '</div><div class="row row__padding--bottom">';
            }
            $i++;
        endwhile;
    else :
        echo '<p>' . esc_html( __( 'No News' ) ) . '</p>';
    endif;
    wp_reset_postdata();
    ?>
</div>
<?php

Hope it works for you!

Cheers!

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks for helping me out! Works almost perfectly, I just want to remove the the posts per page part so that it displays all posts. When I did that, all the posts after the first 8 have the "col-md-12" class. So I think I need to reset the i variable every 8 iterations?
if you want to do that, even though i do not recommend it ( In some cases we might talk about thousands posts ) , you would set 'posts_per_page' => -1 and then replace the output of the class like so <?php echo esc_attr( $class_map[ $i % 8 ] ); ?> and then in the if statements if ( 1 === $i % 8 || .... )
Good point, so I would set posts_per_page to say 64, and then implement your solution

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.