Ask your WordPress questions! Pay money and get answers fast! Comodo Trusted Site Seal
Official PayPal Seal

How do I add 'recent' and 'weird taxonomy' to post_class? WordPress

  • SOLVED

Hi there,

Having a little fun with a colleague's site but this is well beyond me. I need to add a pair of filters to <?php post_class(); ?>.

1. add a 'recent' class if the post's date added is less than 30 days.

2. add the 'theme' this post belongs to. Note that this is set up strangely. Content is organized by themes in the site. For some reason they didn't use a custom taxonomy. Here's how they've set it up to get the 'theme' in the single template:

<blockquote><?php
$bcs = wp_get_object_terms($post->ID, 'good_ideas_themes');
foreach ($bcs as $bc) {
if ($bc->parent == 0) {
$first_theme = $bc->name;
$first_theme_id = $bc->term_id;
$first_theme_parent_id = $bc->parent;
break;
}
}
echo '<h2 style="text-transform: capitalize;">' . $first_theme . '</h2>';
?>
</blockquote>

Can this be used to create a filter in post_class?

Answers (2)

2011-09-24

Grégory Viguier answers:

Hello cwulff.

For the "weird taxonomy", this should work :

function post_term_class($classes) {
global $post;
$weird_tax = wp_get_object_terms($post->ID, 'good_ideas_themes');
if (count($weird_tax))
$classes[] = $weird_tax[0]->slug;
return $classes;
}
add_filter('post_class', 'post_term_class');


I'm looking for the recent class and be back.


Grégory Viguier comments:

And the full code with "recent" and "theme" classes :

function post_term_class($classes) {
global $post;
$weird_tax = wp_get_object_terms($post->ID, 'good_ideas_themes');
if (count($weird_tax))
$classes[] = $weird_tax[0]->slug;

$today = date('Ymd');
$day_end = explode('-', $post->post_date);
if ($day_end[1] == 12) {
$day_end[0] = intval($day_end[0]) + 1;
$day_end[1] = '01';
} else {
$day_end[1] = intval($day_end[1]) + 1;
}
$end = implode('', $day_end);
if ($today < $end)
$classes[] = 'recent';

return $classes;
}
add_filter('post_class', 'post_term_class');


Grégory Viguier comments:

Ho, I found a little bug with the dates, I'm on it.


Christopher comments:

Thanks Gregory. Just realized that the site calls all the posts in queries in functions.php. I can add <div> to them but it echoes out the "id=..." part rather than running it.

$sidebar .= sprintf('<div id="post-<?php the_ID(); ?>" <?php post_class(); ?>><p><span class="CityCountry">%s</span>' . chr(13),

I'm sure that I'm just formatting this wrong.


Grégory Viguier comments:

Okay, this should work properly now :

function post_term_class($classes) {
global $post;
$weird_tax = wp_get_object_terms($post->ID, 'good_ideas_themes');
if (count($weird_tax))
$classes[] = $weird_tax[0]->slug;

$today = date('Ymd');
$day_end_arr = explode('-', $post->post_date);
$day_end = $day_end_arr[0].$day_end_arr[1].$day_end_arr[2];
if ($day_end_arr[1] == 12) {
$day_end = $day_end + 8900;
} else {
$day_end = $day_end + 100;
}
if ($today < $day_end)
$classes[] = 'recent';

return $classes;
}
add_filter('post_class', 'post_term_class');


For your echo problem, it's because the_ID( ) and post_class( ) echo the result, but if you use sprintf( ), you need to return the result, not echo.
So your code should be : (if you're in the loop)
$sidebar .= sprintf('<div id="post-'.get_the_id().'" class="'.implode(' ', get_post_class()).'"><p><span class="CityCountry">%s</span>' . chr(13) . END_OF_YOUR_STRING, YOUR_CITYCOUNTRY_VALUE);
Of course, replace END_OF_YOUR_STRING and YOUR_CITYCOUNTRY_VALUE with your initial code, I can't see them in your previous code.


Christopher comments:

Hmm... the theme and the date aren't showing up in the classes, but I think it has more to do with the sprintf thing at the end than the function, because it's actually returning the same values in the classes for all 3 of the posts. You can see it here http://citiesofmigration.patienceandfortitude.com/ in the sidebar under recent good ideas. Here's the code in functions.php for the content in this section:

//returns side bar content for most recent gi
function get_most_recent_gi($limit = 5) {

global $locale;
$debug = false;
$args = array(
'orderby' => 'date',
'order' => 'DESC',
'post_type' => 'good_idea',
'meta_key' => 'good_idea_watching',
'meta_value' => 'false',
'post_status' => 'publish',
'suppress_filters' => '0'
, 'numberposts' => -1);


$result = get_posts($args);
//printf('<pre>%s</pre>',print_r($result,true));

$sidebar = '';
$post_counter = 0;
foreach ($result as $item) {



if (get_post_status(icl_object_id($item->ID, 'good_idea', true)) == 'publish') {
$custom = build_custom_array(icl_object_id($item->ID, 'good_idea', true));
} else {
$custom = build_custom_array($item->ID);
}
$city_country_id = $custom['_CPA_good_idea_city_country_post_list'];


if ($debug

)printf('<pre>initial city id %s</pre>', print_r($city_country_id, true));

$city_country_custom = '';
$city_country_post = '';
//incase we have more then one city profile we take the first id only
if (!is_numeric($city_country_id)) {
$city_country_id = get_first_id($city_country_id);
}
if ($debug

)printf('<pre>city id after prep %s</pre>', print_r($city_country_id, true));
$city_country_custom = array();
if (is_numeric($city_country_id)) {
$city_country_custom = build_custom_array($city_country_id);
}

$city_name = print_custom_array($city_country_custom, 'city_city');
$country_name = print_custom_array($city_country_custom, 'city_country');

$sidebar .= sprintf('<div id="post-'.get_the_id().'" class="'.implode(' ', get_post_class()).'"><p><span class="CityCountry">%s</span>' . chr(13),
($city_name != '' && $country_name != '') ? sprintf('%s, %s', $city_name, $country_name) : '');
$sidebar .= sprintf('<br><a href="%s"><strong class="good-idea-title">%s</strong></a> / %s&nbsp;&nbsp;</p></div>' . chr(13),
print_custom_array($custom, 'url'),
print_custom_array($custom, 'post_title'),
print_custom_array($custom, 'good_idea_organization'));
$post_counter++;
if ($post_counter == $limit)
break;
}
return $sidebar;
}


Grégory Viguier comments:

Ha yes, it's a custom loop.

$sidebar .= sprintf('<div id="post-'.$item->ID.'" class="'.implode(' ', get_post_class('', $item->ID)).'"><p><span class="CityCountry">%s</span>' . chr(13),

($city_name != '' && $country_name != '') ? sprintf('%s, %s', $city_name, $country_name) : '');


Grégory Viguier comments:

Some improvement, if my previous function doesn't work with your custom loop, this one should :

function post_term_class($classes, $class, $post_ID) {
$post = get_post($post_ID);
$weird_tax = wp_get_object_terms($post->ID, 'good_ideas_themes');
if (count($weird_tax))
$classes[] = $weird_tax[0]->slug;

$today = date('Ymd');
$day_end_arr = explode('-', $post->post_date);
$day_end = $day_end_arr[0].$day_end_arr[1].$day_end_arr[2];
if ($day_end_arr[1] == 12) {
$day_end = $day_end + 8900;
} else {
$day_end = $day_end + 100;
}
if ($today < $day_end)
$classes[] = 'recent';

return $classes;
}
add_filter('post_class', 'post_term_class', 10, 3);

By the way, the date is not added to the classes, it adds the class "recent".


Christopher comments:

No luck yet... Unfortunately it's someone else's work and I'm a little out of my depth.

Oh, and yes I meant 'recent'. You had that exactly right.


Grégory Viguier comments:

Ok, do you need these classes only in this function or for all posts in your website?


Christopher comments:

All over the place.


Grégory Viguier comments:

I don't understand why it's not working in your function, while it's perfectly fine in my tests. May be something is removing the filter.
Let's try something else : this should add the classes only in your sidebar.
function custom_post_class($post_ID) {
$classes = array();
$post = get_post($post_ID);
$new_tax = wp_get_object_terms($post->ID, 'good_ideas_themes');
if (count($new_tax))
$classes[] = $new_tax[0]->slug;

$today = date('Ymd');
$day_end_arr = explode('-', $post->post_date);
$day_end = $day_end_arr[0].$day_end_arr[1].$day_end_arr[2];
if ($day_end_arr[1] == 12) {
$day_end = $day_end + 8900;
} else {
$day_end = $day_end + 100;
}
if ($today < $day_end)
$classes[] = 'recent';

return $classes;
}


And a modification in your function :
$sidebar .= sprintf('<div id="post-'.$item->ID.'" class="'.implode(' ', get_post_class(custom_post_class($item->ID), $item->ID)).'"><p><span class="CityCountry">%s</span>' . chr(13),
($city_name != '' && $country_name != '') ? sprintf('%s, %s', $city_name, $country_name) : '');


Christopher comments:

Hey there! Well that's pretty close! It's got a weird kind of repeating thing going on, but they're showing up at least.

Where before the first sidebar post said this:

class="post-9168 post type-post status-publish format-standard hentry category-uncategorized"

it now says

class="post-14154 good_idea type-good_idea status-publish hentry category-live category-sports-live-themes recent recent"

The one after this, which is not recent, seems to replace the 'recent' with the theme (live), which is not present in the preceding one (but should be).

post-13694 good_idea type-good_idea status-publish hentry category-live category-sports-live-themes tag-sports live live


Grégory Viguier comments:

Ok.

This repeating thing is quite strange. It looks like the custom_post_class( ) function and the post_term_class( ) are working at the same time.

Tel me if you have some results with this.
First, replace the custom_post_class( ) in your custom function with an empty string (as it was before) :
$sidebar .= sprintf('<div id="post-'.$item->ID.'" class="'.implode(' ', get_post_class('', $item->ID)).'"><p><span class="CityCountry">%s</span>' . chr(13),
($city_name != '' && $country_name != '') ? sprintf('%s, %s', $city_name, $country_name) : '');

Then, in the add_filter( ) try to change the priority value (10) to 50, and if nothing happens, try with 1.
add_filter('post_class', 'post_term_class', 50, 3);


Christopher comments:

Tried them both. No change. Same results as last time.


Grégory Viguier comments:

Can you send me a message with an ftp access? It will be easier for me to find what's going on, or you can find me on skype : greg_lone


Grégory Viguier comments:

It seems to work fine now.

The classes were added twice because you added add_filter('post_class', 'post_term_class', 10, 3); twice : one in your main theme, and one in your child theme.
I've commented the one in your main theme.

Tell me if it is what you need.


Christopher comments:

*Note to anyone considering replying. Gregory is just finishing up one more thing and then the award is his, so no sense in replying. Thanks for your interest and for this wonderful community.

2011-09-24

Abdessamad Idrissi answers:

hey cwulff ,

is it resolved by Grégory, if not I can work on it :)


Christopher comments:

Hi Abdessamad,

Gregory seems to have a handle on it, but I'll let you know if things don't work out.

Thanks,
CW