I'm working on a WordPress site for my band and I'd like to mark every 3rd post on our blog page to have a special class applied to it, anybody have any pointers on how to achieve this? Any help is very very appreciated, thanks! rock n roll.
5 Answers
My approach. No extra function, no filter. :)
<?php $GLOBALS['wpdb']->current_post = 0; ?>
<div <?php post_class( 0 === ++$GLOBALS['wpdb']->current_post % 3 ? 'third' : '' ); ?>>
Alternative:
<div <?php post_class( 0 === ++$GLOBALS['wpdb']->wpse_post_counter % 3 ? 'third' : '' ); ?>>
-
this killed it @toscho! turns out this one worked the best since im using this on a category page and a fn was styling posts everywhere. thanks man, +1. i dont think i have the privs to +1 yet officially.– Zoran MMar 9, 2012 at 2:43
-
1Doesn't this actually affect the Globals value (due to the pre-increment operator) and potentially screw up something else that might be depending on the current_post count property? I mean, the likelihood is slim, right, but wouldn't it be safer to just do ( 0 === ( $GLOBALS['wpdb']->current_post + 1 ) % 3 ? 'third' : '' ) ? Mar 14, 2012 at 12:59
-
1@TomAuger For some not so obvious reason it doesn’t seem to have any side effect. But from a perspective of elegance – you are right. I added a better example. :)– fuxia ♦Mar 14, 2012 at 16:49
-
4
As an addition to @helgathevikings answer
Use the post_class() fn without polluting the global namespace
- Using
static
variables inside a class allows the same behavior as having global variables: They stay in place and don't change, unless you don't alter them. - Even better (as @Milo suggested in the comments), take the current post from the DB class.
function wpse44845_add_special_post_class( $classes )
{
// Thanks to @Milo and @TomAuger for the heads-up in the comments
0 === $GLOBALS['wpdb']->current_post %3 AND $classes[] = 'YOUR CLASS';
return $classes;
}
add_filter( 'post_class','wpse44845_add_special_post_class' );
Update
We could utilize the current_post
property of the global $wp_query
object. Let's use an anonymous function, with the use
keyword, to pass on the global $wp_query
by reference (PHP 5.3+):
add_filter( 'post_class', function( $classes ) use ( &$wp_query )
{
0 === $wp_query->current_post %3 AND $classes[] = 'YOUR CLASS';
return $classes;
} );
Further on, we could restrict it to the main loop with a in_the_loop()
conditional check.
-
1i like it. don't quite understand static variables. one more thing to learn today! Mar 8, 2012 at 15:33
-
3
-
-
thank you dudes so much, really appreciate the help! adding this in right now!– Zoran MMar 9, 2012 at 2:11
-
ah this function is badass @kaiser and beautifully simple! turns out i needed something just for a category page. this shall save me later on in life my friend, thanks for learning me something new. +11!– Zoran MMar 9, 2012 at 2:49
if your theme uses post_class() to generate post classes you could try. i'm not 100% sure how it will handle pagination b/c i don't have enough posts on my local install to test it out
add_filter('post_class','wpa_44845');
global $current_count;
$current_count = 1;
function wpa_44845( $classes ){
global $current_count;
if ($current_count %3 == 0 ) $classes[] = 'special-class';
$current_count++;
return $classes;
}
-
Not 100% sure, but I guess you could use a
static
var instead of aglobal
to keep the namespace clean. Anyway: +1.– kaiserMar 8, 2012 at 12:36 -
you mean change both global $current_count to static $current_count? doesn't seem to do anything when i test it. not familiar enough w/ variable scope, though i agree it is better to not pollute the namespace if you can. Mar 8, 2012 at 14:22
-
-
3you could also use
$wpdb->current_post
without having to create another variable.– MiloMar 8, 2012 at 14:49
$i = 0;
if ( have_posts ) :
while( have_posts ) :
the_post();
$class = 'class="BASIC-CLASS';
if ( 0 === ( $i % 3 ) )
$class .= 'YOUR-SPECIAL-CLASS';
$class .= '"';
echo "<div {$class}>";
// do stuff
echo '</div>';
$i++;
endwhile;
endif;
There are also ways to do this with CSS and javascript.
With CSS3 you target every third post with an nth-child selector.
article.post:nth-child(3n+0)
{
background-color: #777;
}
Or with jQuery, you could add the CSS class using the same technique.
jQuery(function($) {
$( "article.post:nth-child(3n+0)" ).addClass("custom-class");
});