Asked  11 Months ago    Answers:  5   Viewed   10 times

I'm using a loop in wordpress to output posts. I want to wrap every three posts inside of a div. I want to use a counter to increment on each iteration of the loop but I'm not sure of the syntax that says "if $i is a multiple of 3" or "if $i is a multiple of 3 - 1".

$i = 1;
if ( $wp_query->have_posts() ) : while ( $wp_query->have_posts() ) : $wp_query->the_post();
     // If is the first post, third post etc.
     if("$i is a multiple of 3-1") {echo '<div>';}

     // post stuff...

     // if is the 3rd post, 6th post etc
     if("$i is a multiple of 3") {echo '</div>';}

$i++; endwhile; endif;

How do I make this happen? thanks!

 Answers

1

Why not do the following? This will open it and close it after the third post. Then close the ending div in the event there is not a multiple of 3 to display.

$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>';

In case you didn't know, % is the modus operator will return the remainder after the two numbers are divided.

Monday, July 12, 2021
 
mnagel
 
4

Using:

  • jQuery kill ajax request
  • ignore_user_abort()
  • ob_flush()

should do all you need in one php thread

EDIT

Take a look at nickb's answer, if you're looking for a way how to do this simply it would be following algorithm:

  1. javascript opens process.php via ajax (which will do all the work AND print status reports), you have to look up whether jQuery ajax supports continuous loading
  2. if user decides to stop refreshes you'll kill loading as show in provided link

In process.php:

ignore_user_abort(); // Script will finish in background
while(...){
  echo "Page: $in";
  ob_flush();
}

EDIT 2 requested example (bit of different and ugly, but simple). test_process.php:

// This script will write numbers from 1 to 100 into file (whatever happens)
// And sends continuously info to user
$fp = fopen( '/tmp/output.txt', 'w') or die('Failed to open');
set_time_limit( 120);
ignore_user_abort(true);

for( $i = 0; $i < 100; $i++){
    echo "<script type="text/javascript">parent.document.getElementById( 'foo').innerHTML += 'Line $i<br />';</script>";
    echo str_repeat( ' ', 2048);
    flush();
    ob_flush();
    sleep(1);
    fwrite( $fp, "$in");
}

fclose( $fp);

And main html page:

<iframe id="loadarea"></iframe><br />
<script>
function helper() {
    document.getElementById('loadarea').src = 'test_process.php';
}
function kill() {
    document.getElementById('loadarea').src = '';
}
</script>

<input type="button" onclick="helper()" value="Start">
<input type="button" onclick="kill()" value="Stop">
<div id="foo"></div>

After hitting start lines as:

Line 1
Line 2

Appeared in the div #foo. When I hit Stop, they stopped appearing but script finished in background and written all 100 numbers into file.

If you hit Start again script starts to execute from the begging (rewrite file) so would parallel request do.

For more info on http streaming see this link

Thursday, April 1, 2021
 
tadman
 
5

This should sort you out

$args = array(
    'post_type' => 'college',
    'posts_per_page' => -1,
    'order' => 'DESC',
    'orderby' => 'menu_order'
);

$the_query = new WP_Query($args);
if ($the_query->have_posts()) :
    $counter = 0;
    while ($the_query->have_posts()) : $the_query->the_post();
        if ($counter % 4 == 0) :
            echo $counter > 0 ? "</div>" : ""; // close div if it's not the first
            echo "<div class='row'>";
        endif;
        ?>
        <div class="col-3">
            <?php the_title(); ?>
        </div>
        <?php
        $counter++;

    endwhile;
endif;
wp_reset_postdata();
?>

Adapted from Wrapping a div around every third item in a foreach loop PHP

Thursday, April 1, 2021
 
KHM
 
KHM
4

try this

<?php 
$i=0;
$wrap_count = 4; // you can change this no of divs to wrap
foreach ($categories as $category) 
{ 
    $i+=1;
    if($i%$wrap_count==1)
    {
        echo '<div class="row">';
    }
?>
    <div class="col-lg-3 col-md-3">.....</div>
<?php 
    if($i%$wrap_count==0)
    {
        echo '</div>';
    }
} 

if($i%$wrap_count!=0)
{
    echo '</div>';
}
?>
Tuesday, October 12, 2021
 
sober
 
2

I think it's to do with your calculations as to when to add the various div tags, I've changed the calculations, especially only having 1 close test...

if ( 0 == ($count-1) % 5 ) {
    echo '<div class="wh-tiles-posts-left">';
} elseif ( 1 == ($count-1) % 5 ) {
    echo '<div class="wh-tiles-posts-right">';
} elseif ( 3 == ($count-1) % 5 ) {
    echo '<div class="wh-tiles-posts-left2">';
} elseif ( 4 == ($count-1) % 5 ) {
    echo '<div class="wh-tiles-posts-right2">';
}
$this->render_post_body( $count );

if ( 1 != ($count-1) % 5 ) {
    echo '</div>';
} 
Thursday, December 9, 2021
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :