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!

4
  • 1
    Can't you simply use a :last-of-type selector? Commented Jan 28, 2011 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? Commented Jan 28, 2011 at 14:21
  • @nikic Nope, it has to be done in PHP ;/ Commented Jan 28, 2011 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 ? Commented Jan 28, 2011 at 14:23

7 Answers 7

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

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

4 Comments

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.
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
+1 - The user only needs a basic counter(the mysql part is irrelevant, it's just part of the example).
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.
4

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; ?>

2 Comments

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)
Thanks @honk31 the problem with untested pseudocode is you don't actually test it, of course current_post is an index value!
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. ;)

Comments

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.

Comments

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; ?>

Comments

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
    }
 }
 ?>

Comments

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

Comments

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.