Note: This is now outdated, I’ll be updating it soon. It still works, but can now be done in jsut a few lines of code.
One of Checkmate’s features is the ability to select multiple categories as feature categories. It wasn’t until far after the release a user brought up the fact it didn’t work…at all. So I set off to fix it thinking it was a trivial task using query_posts or get_posts. I was wrong. To keep everything as compatible as could be and offer the ease of use I intended took some digging. I ended up skipping all of WordPress’s functions and going strait to the database by writing a custom function.
Chicks Dig Database Queries
After thinking about writing a query and digging through the WordPress codex, I decided to do a quick search and found one already written and ready to. I can not for the life of me find the original post but it was in the WordPress help forum. A big dating game kiss goes to whoever posted it.
And here it is the almighty query:
$querystr = "SELECT * FROM $wpdb->posts LEFT JOIN $wpdb->postmeta ON($wpdb->posts.ID = $wpdb->postmeta.post_id) LEFT JOIN $wpdb->term_relationships ON($wpdb->posts.ID = $wpdb->term_relationships.object_id) LEFT JOIN $wpdb->term_taxonomy ON($wpdb->term_relationships.term_taxonomy_id = $wpdb->term_taxonomy.term_taxonomy_id) WHERE $wpdb->term_taxonomy.term_id IN ($feature_cats) AND $wpdb->term_taxonomy.taxonomy = 'category' AND $wpdb->posts.post_status = 'publish' AND $wpdb->posts.post_type = 'post' ORDER BY $wpdb->posts.post_date DESC LIMIT 1";
This is the meat and potatoes of everything. Notice I set the limit to only one. You may want to set this higher or put it into a variable and chosen some other way. What this is doing(in short) is taking the category IDs and matching them with posts that belong to those categories by filtering everything else out. It then checks for published posts, the post_type = post is important; else it will grab pages and everything else it can get its grubby database hands on. Next we’ll wrap it up into a function.
Function You!
Lets use that query in something useful. Commented code is at the bottom of this post.
<?
function cm_feature_post(){
global $wpdb, $post;
$feature_cats = get_option('cm_featureId');
$querystr = "SELECT * FROM $wpdb->posts
LEFT JOIN $wpdb->postmeta ON($wpdb->posts.ID = $wpdb->postmeta.post_id)
LEFT JOIN $wpdb->term_relationships ON($wpdb->posts.ID = $wpdb->term_relationships.object_id)
LEFT JOIN $wpdb->term_taxonomy ON($wpdb->term_relationships.term_taxonomy_id = $wpdb->term_taxonomy.term_taxonomy_id)
WHERE $wpdb->term_taxonomy.term_id IN ($feature_cats)
AND $wpdb->term_taxonomy.taxonomy = 'category'
AND $wpdb->posts.post_status = 'publish'
AND $wpdb->posts.post_type = 'post'
ORDER BY $wpdb->posts.post_date DESC
LIMIT 1";
$featurepost = $wpdb->get_results($querystr);
foreach ($featurepost as $post):
setup_postdata($post);
$feature_post = $post->ID;
?>
<?php endforeach;
}
?>
Give the function a unique name so it doesn’t clash with anything. In this example I’m calling the featured categories from an option on the themes options page into the $featured_cats variable. You could easily do this as a simple string also, all you need is a comma separated list of the category ID’s(e.g. 1,3,42).
Klaatu Barada Nikto
Output the post through your normal html template tags. This is copied straight out of Checkmate.
<?
function cm_feature_post(){
global $wpdb, $post;
//pull in the category IDs from an option page
$feature_cats = get_option('cm_featureId');
//the query to get the feature posts you want out of the databse
$querystr = "SELECT * FROM $wpdb->posts
LEFT JOIN $wpdb->postmeta ON($wpdb->posts.ID = $wpdb->postmeta.post_id)
LEFT JOIN $wpdb->term_relationships ON($wpdb->posts.ID = $wpdb->term_relationships.object_id)
LEFT JOIN $wpdb->term_taxonomy ON($wpdb->term_relationships.term_taxonomy_id = $wpdb->term_taxonomy.term_taxonomy_id)
WHERE $wpdb->term_taxonomy.term_id IN ($feature_cats)
AND $wpdb->term_taxonomy.taxonomy = 'category'
AND $wpdb->posts.post_status = 'publish'
AND $wpdb->posts.post_type = 'post'
ORDER BY $wpdb->posts.post_date DESC
LIMIT 1";
//run the query through the database and grab the results
$featurepost = $wpdb->get_results($querystr);
//loop through the posts
foreach ($featurepost as $post):
//setup post data for easy use
setup_postdata($post);
//I use this to skip the feature post in another loop
$feature_post = $post->ID;
?>
<div class="feature clearfix">
<h2><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h2>
<p class="meta">
Posted on <?php the_time('M j, Y'); ?> by <?php the_author_posts_link(); ?></a>
</p>
<?php //get thumbnail (custom field)
$featureimage = get_post_meta($post->ID, 'feature_image', true); ?>
<?php if($featureimage !== '') { ?>
<a href="<?php the_permalink() ?>" rel="bookmark" title="Permanent Link to <?php the_title_attribute(); ?>">
<img src="<?php echo $featureimage; ?>" alt="<?php the_title(); ?>" /></a>
<?php } else { } ?>
<?php the_content('Continue Reading'); ?>
</div>
<?php endforeach;
}
?>
Using the Function: Bonus Hidden Track
Now this function can be called by using the <?php cm_feature_post(); ?> and it will output your featured posts but you probably want regular posts.
After your feature posts start another loop. Then add this little diddy of a line after the loop. This will detect your feature post via the $feature_post = $post->ID; in your function.
<?php if( $post->ID == $feature_post ) continue; update_post_caches($posts); ?>



5 Comments
sweet custom queries. thanks!
re: syntax issue - i’ve actually been meaning to look at using this plugin to show code.
Chad,
I tried it out, it works great, I just wanted a jQuery solution.
Instead of the “almighty query,” why couldn’t you have used the WordPress API instead? Something like this:
query_posts(array('category__in' => $feature_cats, 'showposts' => 1));Also, in the query why join the postmeta table?
Austin,
Because I didn’t know that was possible. I’ll have to read more about that.
Leave a comment
Get a Trackback link
1 Trackbacks/Pingbacks
Click to show or hide trackbacks