Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rerun loop after every third post? (Wordpress)

Tags:

php

wordpress

I have a problem in my template (wordpress). I want to create a portfolio page which contains 3 columns and which can display posts in my portfolio page (without jumping a new page). And I need to repeat these three posts after each third post. I will assign "hidden" class to my duplicate posts and when clicking at the column, class shall set as "block". I have a code:

<?php get_header(); ?>
<section> <div class="container container-bazar container-gallery"><?php 
$array = array();
    $count = 0;
    $i = 0;
$args = array(
    'posts_per_page' =>  -1,
    'post_type' => 'gallery',
);
$gallery = new WP_Query( $args );
if($gallery->have_posts()) :
while($gallery->have_posts()) :
        $gallery->the_post(); ?>
<div class="col-1 boxes<?php if( $count%3 == 0 ) { echo '-1'; }; $count++; ?>">
    <div class="post" id="post-<?php the_ID(); ?>">
        <figure class="indent-bot">
            <a href="<?php the_permalink(); ?>" rel="nofollow">
                <?php the_post_thumbnail(array(380,220,true)); ?>
            </a>
        </figure>
        <div class="col-1-content">
            <strong class="title-3">
                <a href="<?php the_permalink(); ?>" rel="nofollow">
                    <?php the_title(); ?>
                </a>
            </strong>
            <div class="entry">
                <a href="<?php the_permalink(); ?>" rel="nofollow">
                    <?php the_excerpt(); ?>
                </a>
            </div><!-- .entry -->
        </div><!-- .col-1-content-->
    </div><!-- .post -->
</div> <!-- .boxes -->
<?php endwhile; ?>
<?php while($gallery->have_posts()) :
$gallery->the_post();?>
<?php $imgaddr1 = get_post_meta($post->ID, 'imgaddr1', true);
$imgaddr2 = get_post_meta($post->ID, 'imgaddr2', true);
$imgssilka1 = get_post_meta($post->ID, 'imgssilka1', true);
$imgssilka2 = get_post_meta($post->ID, 'imgssilka2', true);
$namecolor1 = get_post_meta($post->ID, 'namecolor1', true);
$namecolor2 = get_post_meta($post->ID, 'namecolor2', true);
$numbercolor1 = get_post_meta($post->ID, 'numbercolor1', true);
$numbercolor2 = get_post_meta($post->ID, 'numbercolor2', true); ?>
</div>
        <div class="full clearfix">
            <div class="inner">
                <figure class="indent-bot1">
                    <a href="<?php the_permalink(); ?>" rel="nofollow">
                        <?php the_post_thumbnail(array(960,690)); ?>
                    </a>
                </figure>
                <div class="row">
                    <div class="col-md-5">
                        <div class="inf-1">
                            <h4>Информация</h4>
                        </div>
                        <div class="inf-2">
                            <h5><?php the_title(); ?></h5>
                            <div class="desc">
                                <?php the_excerpt(); ?>
                            </div>
                        </div>
                        <div class="clearfix"></div>
                    </div>
                    <div class="col-md-7 border-left">
                        <div class="inf-1">
                            <h4>Приложенные Цвета</h4>
                        </div>
                        <div class="inf-2">
                            <ul>
                                <li class="first-child">
                                    <a href="<?php echo $imgssilka1; ?>" class="img-block">
                                        <img src="<?php echo $imgaddr1; ?>">
                                    </a>
                                    <div class="txt">
                                        <strong><?php echo $namecolor1; ?></strong>
                                        <span><?php echo $numbercolor1; ?></span>
                                    </div>
                                </li>
                                <li class="last-child">
                                    <a href="<?php echo $imgssilka2; ?>" class="img-block">
                                        <img src="<?php echo $imgaddr2; ?>">
                                    </a>
                                    <div class="txt">
                                        <strong><?php echo $namecolor2; ?></strong>
                                        <span><?php echo $numbercolor2; ?></span>
                                    </div>
                                </li>
                            </ul>
                        </div>
                        <div class="clearfix"></div>
                    </div>
                </div>
            </div><!-- .inner -->
        </div>
<div class="container container-bazar container-gallery">
<?php endwhile; 
else: 
endif; ?>
</div><!-- .container -->
</section>
<?php get_footer(); ?>

but this code displays posts sequentially.

like image 571
harley Avatar asked Jun 08 '15 06:06

harley


2 Answers

$i = 1;
//added before to ensure it gets opened
echo '<div>';
if ( $wp_query->have_posts() ) : while ( $wp_query->have_posts() ) : $wp_query->the_post();
     // post stuff...

     // if multiple of 3 close div and open a new div
     if($i % 3 == 0) {echo '</div><div>';}

$i++; endwhile; endif;
//make sure open div is closed
echo '</div>';
like image 130
user3561203 Avatar answered Nov 08 '22 18:11

user3561203


This is quite an unusual setup which had me thinking. There is a way without rerunning the loop

HERE IS HOW

  • You need to run your loop only once. In stead of the default loop, we will pull out our posts array from our query and run our posts through a foreach loop. This is where we will start things

  • We need to split our content up so we can get two blocks with post data, and this need to be saved into an array which we will use later. To achieve this, build two concatenated strings of data ( one string with the first block of data and the second one with the second block of data ) which will be saved in two separate variables.

  • Once this is done, we need to add our divs to form blocks of posts containing three posts, each with a unique class. This goes for both sets of string

  • Now we need to calculate new array keys so we can build a new array of post data sorted so we have a sequence of a block of post data with three posts from string one, then a block of post data with the same three posts from string two etc

  • Finally, because our array of posts is still mixed and is out of order, we will sort the array so the keys are numerical, then we can use a last foreach loop to output our post data

HERE IS THE CODE

Just a note or two before I post the code

  • You need to modify the classes etc to suite your needs

  • The code is not fully tested, but the div blocks and sorting works as expected

  • I have commented the code to make it easier to follow

Finally, the code

$args = array(
    'posts_per_page' =>  -1,
    'post_type' => 'gallery',
);
$gallery = new WP_Query( $args );

// Check if we have posts before we continue
if( $gallery->have_posts() ) {

    // Use the array of posts and a foreach loop to build out super array
    foreach ( $gallery->posts as $key=>$post ) {
        // Setup postdata so we can make use of template tags
        setup_postdata( $post );

        // Setup/define our first variable which will hold our first set of post data
        $output = '';

        // Open a new div on the first post and every 3rd one there after to hold three posts
        if ( $key%3 == 0 ) {
            // We will call this class "first-x" where x represents the block count
            $output .= '<div class="first-' . floor( $key / 3 ) . '">';
        }

        // Concatenate your first loop into a string to our first variable $output
        $output .= '<div class="post" id="post-' . $post->ID . '">
                <figure class="indent-bot">
                    <a href="' . get_the_permalink() . '" rel="nofollow">
                        ' . get_the_post_thumbnail( $post->ID, array( 380,220,true ) ) . '
                    </a>
                </figure>
                <div class="col-1-content">
                    <strong class="title-3">
                        <a href="' . get_the_permalink() . '" rel="nofollow">
                            ' . get_the_title() . '
                        </a>
                    </strong>
                    <div class="entry">
                        <a href="' . get_the_permalink() . '" rel="nofollow">
                            ' . get_the_excerpt() . '
                        </a>
                    </div><!-- .entry -->
                </div><!-- .col-1-content-->
            </div><!-- .post -->
        </div> <!-- .boxes -->';

        // Add our closing div after every third post or the last post if there is less than three
        if ( $key%3 == 2 || !array_key_exists( ( $key + 1 ), $gallery->posts ) ) {
            $output .= '</div>';
        }

        // Create our new array of post data split in two and use with new array keys
        $new_posts_array[floor( $key / 3 ) * 3 + $key] = $output;

        // Setup/define our second variable which will hold the second set of post data from our posts
        // This is the set that you would like to hide
        $output_1 = '';

        // Open a new div on the first post and every 3rd one there after to hold three posts
        if ( ( $key%3 ) == 0 ) {
            // This block of posts will use class "second-x" where x represents the block count
            $output_1 .= '<div class="second-' . floor( $key / 3 ) . '">';
        }

        $imgaddr1     = get_post_meta( $post->ID, 'imgaddr1',     true );
        $imgaddr2     = get_post_meta( $post->ID, 'imgaddr2',     true );
        $imgssilka1   = get_post_meta( $post->ID, 'imgssilka1',   true );
        $imgssilka2   = get_post_meta( $post->ID, 'imgssilka2',   true );
        $namecolor1   = get_post_meta( $post->ID, 'namecolor1',   true );
        $namecolor2   = get_post_meta( $post->ID, 'namecolor2',   true );
        $numbercolor1 = get_post_meta( $post->ID, 'numbercolor1', true );
        $numbercolor2 = get_post_meta( $post->ID, 'numbercolor2', true ); 

        // Concatenate your second set of post data into a string to our second variable $output_1
        $output_1 .= '<div class="full clearfix">
            <div class="inner">
                <figure class="indent-bot1">
                    <a href="' . get_the_permalink() . '" rel="nofollow">
                        ' . get_the_post_thumbnail(  $post->ID, array( 960, 690 ) ) . '
                    </a>
                </figure>
                <div class="row">
                    <div class="col-md-5">
                        <div class="inf-1">
                            <h4>Информация</h4>
                        </div>
                        <div class="inf-2">
                            <h5>' . get_the_title() . '</h5>
                            <div class="desc">
                                ' . get_the_excerpt() . '
                            </div>
                        </div>
                        <div class="clearfix"></div>
                    </div>
                    <div class="col-md-7 border-left">
                        <div class="inf-1">
                            <h4>Приложенные Цвета</h4>
                        </div>
                        <div class="inf-2">
                            <ul>
                                <li class="first-child">
                                    <a href="' . $imgssilka1 . '" class="img-block">
                                        <img src="' . $imgaddr1 . '">
                                    </a>
                                    <div class="txt">
                                        <strong>' . $namecolor1 . '</strong>
                                        <span>' . $numbercolor1 . '</span>
                                    </div>
                                </li>
                                <li class="last-child">
                                    <a href="' . $imgssilka2 . '" class="img-block">
                                        <img src="' . $imgaddr2 . '">
                                    </a>
                                    <div class="txt">
                                        <strong>' . $namecolor2 . '</strong>
                                        <span>' . $numbercolor2 . '</span>
                                    </div>
                                </li>
                            </ul>
                        </div>
                        <div class="clearfix"></div>
                    </div>
                </div>
            </div><!-- .inner -->
        </div>';

        // Add our closing div after every third post or the last post if there is less than three
        if ( $key%3 == 2 || !array_key_exists( ( $key + 1 ), $gallery->posts ) ) {
            $output_1 .= '</div>';
        }

        // Create our new array of post data split in two and use with new array keys
        $new_posts_array[( floor( $key / 3 ) + 1 ) * 3 + $key] = $output_1;         


    }
    wp_reset_postdata();

    // Sort our new array so that the keys are numerical again
    ksort( $new_posts_array );

    // Run a foreach loop to output our posts as we need. No need to modify anything here
    foreach ( $new_posts_array as $v )
        echo $v;
}
like image 37
Pieter Goosen Avatar answered Nov 08 '22 19:11

Pieter Goosen