1

I have a code like:

<?php $loop = some array with posts;
      while ( $loop->have_posts() ) : $loop->the_post(); ?>
            <div class="class">
                <p>(data)</p>
             </div>   
     <?php endwhile; ?>

Now I want to change the div class (from "class" to "class2") for the very last loop. How to do that?

Example:

When "some array with posts" have now 4 records then I'm getting:

<div class="class"><p>data</p></div>
<div class="class"><p>data</p></div>
<div class="class"><p>data</p></div>
<div class="class"><p>data</p></div>

And I want to get:

<div class="class"><p>data</p></div>
<div class="class"><p>data</p></div>
<div class="class"><p>data</p></div>
<div class="class2"><p>data</p></div> <!-- this one is different -->

I'm looking for something that will work always no matter how many array elements there will be.

Tanks!

Klaus Byskov Pedersen
  • 117,245
  • 29
  • 183
  • 222
anonymous
  • 1,511
  • 7
  • 26
  • 37
  • 1
    Can't you simply use a `:last-of-type` selector? – NikiC Jan 28 '11 at 14:20
  • 1
    I'm not sure, but can't you use again the $loop->have_posts() to check if that is the last one? – Bruno Costa Jan 28 '11 at 14:21
  • @nikic Nope, it has to be done in PHP ;/ – anonymous Jan 28 '11 at 14:21
  • 1
    possible duplicate of [How do you find the last element of an array while iterating using a foreach loop in php ?](http://stackoverflow.com/questions/665135/how-do-you-find-the-last-element-of-an-array-while-iterating-using-a-foreach-loop) – karim79 Jan 28 '11 at 14:23

7 Answers7

5

Lots of answers here but none refers to $wp_query->post_count and $wp_query->current_post both useful in the loop:

<?php 
$loop = array(); //some array with posts;
while ( $loop->have_posts() ) : 
    $loop->the_post();
    $class = 'class';
    if($loop->post_count == $loop->current_post+1){ // if this is the last item
        $class = 'class2';
    }?>
        <div class="<?php print $class ;?>">
            <p>(data)</p>
         </div>   
 <?php endwhile; ?>
Duncanmoo
  • 3,535
  • 2
  • 31
  • 32
  • 1
    i guess this is the correct answer, exept `current_post` starts with a zero, not a one, so post_count == current_post will never be true. guess this one is more correct: `$loop->post_count == ($loop->current_post + 1)` – honk31 Feb 13 '14 at 14:33
  • Thanks @honk31 the problem with untested pseudocode is you don't actually test it, of course current_post is an index value! – Duncanmoo Feb 14 '14 at 07:10
4
<?php
$num_rows = mysql_num_rows($result1);
$i = 0;
while ($row = mysql_fetch_array($result1, MYSQL_ASSOC)) {
    $i++;
    /*
    your code
     */
    if ( $i == ( $num_rows - 1 ) )
        //you're on last line...    
}
?>

Taken from http://www.phpbuilder.com/board/showthread.php?t=10359504 here, just adapt this to your needs and you can easily change the last iteration in the loop

benhowdle89
  • 36,900
  • 69
  • 202
  • 331
  • Note that this adds an additional database hit per pageload, you may want to consider running `mysql_fetch_array` before the while loop and then just acting on the resultant array to save database hits. – eykanal Jan 28 '11 at 14:52
  • hi eykanal, this question is nothing to do with a mysql db, but it was the loop bit that i was suggesting for the O/P – benhowdle89 Jan 28 '11 at 14:54
  • +1 - The user only needs a basic counter(the mysql part is irrelevant, it's just part of the example). – t31os Jan 28 '11 at 16:02
  • 3
    If the questioner is using `wp_query()` to produce `$loop`, they can get the total number of posts using `$loop->post_count`. See the [codex](http://codex.wordpress.org/Function_Reference/WP_Query#Properties). – Ben Sheldon Jan 29 '11 at 04:58
1

You can use a WP_query object. You have two useful instances (post_count and current_post).

// Example
<?php $query = new WP_Query(array('cat' => 112));
if ( $query->have_posts() ) : while ( $query->have_posts() ) : $query->the_post(); ?>

Then

<div class="post<? if(($query->current_post + 1) == $query->post_count) echo ' last'?>">

Easy and quick. ;)

Beeksi Waais
  • 101
  • 1
  • 1
  • 3
0

The best you can do is probably to put the final call outside the while loop, and change your while loop logic so that it exits early. Instead of:

while ($post = getPost()) {
    printPost($post);
}

do something like

$last = getPost();
$post = getPost();
while ($post != null) {
    printPost($last);
    $last = $post;
    $post = getPost();
}
printSpecial($post);

Edit: I've been assuming that you don't know the number of posts until you've iterated over them, and that the interface that returns posts until they are exhausted is the only one available. If you have a count and can access them by number, then the other suggestions will work fine. In fact, if you can count on the number of posts being small, then you might be best just to read them into an array and do it with a for loop rather than a while loop.

Tim Martin
  • 3,618
  • 6
  • 32
  • 43
0
<?php $loop = some array with posts;
      while ( $loop->have_posts() ) : $loop->the_post();
         $class = $loop->have_posts() ? 'class' : 'class2'; ?>
            <div class="<?php echo $class ?>">
                <p>(data)</p>
             </div>   
     <?php endwhile; ?>
Dogbert
  • 212,659
  • 41
  • 396
  • 397
0

If you have control over the data structure of $loop you might convert int to an iterator and use a CachingIterator on top of it. If you don't control a bit more complicated might be to build an Iterator as wrapper:

<?php
class PostIterator implements Iterator {
    private $have_post;

    function __construct($loop) {
        $this->loop = $loop;
    }

    function rewind() {
        $this->have_post = $this->loop->have_posts(); // looks like we have to call "next" to get the first element, too
    }

    function next() {
        $this->have_post = $loop->have_posts();
    }

    function valid() {
        return $this->have_post;
    }

    function key() {
        return 0; // not used in this case, better implementation might have aocunter or such
    }

    function current() {
         return $this->loop->the_post();
    }
}

$ci = new CachingIterator(new PostIterator($loop)
foreach ($ci as $data) {
    if (!$ci->hasNext()) {
         // last element
    }
 }
 ?>
johannes
  • 15,807
  • 3
  • 44
  • 57
0

Use this code in the loop, right after while ( $loop->have_posts() ) : $loop->the_post();

<?php
$postCount = 0;

// Start of The Loop

if (++$postCount == 1) {
     // FIRST POST
} 

if ($postCount == sizeof($posts)) {
     // LAST POST IN LOOP
}

// End of The Loop
?>

Source:
http://wordpress.org/support/topic/last-post-in-the-loop?replies=4#post-954762

WNRosenberg
  • 1,862
  • 5
  • 22
  • 31