20
January
2011
WordPress — How to add a custom class to a single post in the loop
Posted in: Quick Tips

While developing my website, I ran into a problem with the “Latest Portfolio Additions” section. I needed two loops – one to handle the top three entries and another to handle the bottom three. Seems simple enough. The problem occurred when it came to fitting the thumbnails into the frame. The leftmost entry in both top and bottom sections required a different margin to the other two in each respective loop.
I did some research and found that the answer lies mostly in the WordPress Codex, which you may view at http://codex.wordpress.org/The_Loop. In gaining this knowledge, my theme scripting looked like this:
<div id="portiTop">have_posts()) : $my_query->the_post(); $do_not_duplicate[] = $post->ID ?> <div class="portiTip<?php if(!is_single() && $post==$posts[0]) echo '-first';?>"><a class="vtip" title="<?php the_title(); ?>" href="<?php the_permalink(); ?>"> '')); ?> </a></div> </div> <div id="portiBottom">$do_not_duplicate, 'posts_per_page'=>3, 'category_name'=>'work')); if (have_posts()) : while (have_posts()) : the_post(); ?> <div class="portiTip<?php if(!is_single() && $post==$posts[3]) echo '-first';?>"><a class="vtip" title="<?php the_title(); ?>" href="<?php the_permalink(); ?>"> '')); ?> </a></div> </div> |
This would now output two loops containing 3 posts from the “work” category. The second loop would not duplicate the posts in the first and the $posts array would count the post number during each instance, thereby enabling me to add the “-first” suffix to the default “portiTip” class of the first holding div in each loop. This is done by referencing $posts[0] in the first loop and $posts[3] in the second (loop counts begin with 0). I used an if statement to output the “-first” suffix on the first and fourth post, which is both the first post in its respective loop.
This method worked very well in the beginning, until I added posts in other categories such as the “blog” section. The $posts counter now included those posts, which means that if I added one new post to blog, the first post in the top loop would now be seen as $posts[1] instead of $posts[0] and the first post in the bottom loop would then be $posts[4] instead of $posts[3]. This removes the “-first” suffix from the div classes, which gives the leftmost entries the same margin as the others, offsetting the thumbnails from the frame.

To fix this problem, I removed the $post==$posts from the if statements and nested my own for loop within the WordPress loop, as I could not rely on the WordPress loop to do the counting for me. So for the first entry in each row the if statement catches the count and outputs the suffix to the default class, allowing me to appoint it a different margin to the others in the same row. Thereafter, an else statement would output the rest of the loop. The new scripting looks like this:
<div id="portiTop"><!--?php $my_query = new WP_Query('category_name=work&posts_per_page=3'); while ($my_query--->have_posts()) : $my_query->the_post(); $do_not_duplicate[] = $post->ID ?> <!--?php if($i == 0) : ?--> <!--?php for ($i=0; $i < 1; $i++) : ?--><!--?php endfor; ?--> <!--?php else : ?--><!--?php endif; ?--> <!--?php endwhile; ?--></div> <div id="portiBottom"><!--?php query_posts(array('post__not_in'=-->$do_not_duplicate, 'posts_per_page'=>3, 'category_name'=>'work')); if (have_posts()) : while (have_posts()) : the_post(); ?> <!--?php if($j == 0) : ?--> <!--?php for ($j=0; $j < 1; $j++) : ?--><!--?php endfor; ?--> <!--?php else : ?--><!--?php endif; ?--> <!--?php endwhile; endif; ?--></div> |
And voila! Everything is correctly placed. Of course, this method could be used to achieve many other things. Let me know in the comments what else you have done with it!
