Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@willmot
Created December 1, 2011 16:29
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save willmot/1417986 to your computer and use it in GitHub Desktop.
Save willmot/1417986 to your computer and use it in GitHub Desktop.
Show sticky posts on category archive pages
/**
* Adds sticky posts to your category archive
* pages.
*
* Works in exactly the same way as sticky posts work
* on the homepage, including all the negatives like
* breaking the posts_per_page and only showing
* them on page 1 etc.
*
* @param array $posts
* @param object $wp_query
* @author Tom Willmot - http://github.com/willmot/
* @return array $posts
*/
function hm_category_sticky_posts( $posts, $wp_query ) {
global $wp_the_query;
// Don't continue if this isn't a category query, we're not in the main query or we're in the admin
if ( ! $wp_query->is_category || $wp_query !== $wp_the_query || is_admin() )
return $posts;
global $wpdb;
$q = $wp_query->query_vars;
$page = absint( $q['paged'] );
if ( empty( $page ) )
$page = 1;
$post_type = $q['post_type'];
$sticky_posts = get_option( 'sticky_posts' );
if ( $wp_query->is_category && $page <= 1 && is_array( $sticky_posts ) && !empty( $sticky_posts ) && ! $q['ignore_sticky_posts'] ) {
$num_posts = count( $posts );
$sticky_offset = 0;
// Loop over posts and relocate stickies to the front.
for ( $i = 0; $i < $num_posts; $i++ ) {
if ( in_array( $posts[$i]->ID, $sticky_posts ) ) {
$sticky_post = $posts[$i];
// Remove sticky from current position
array_splice( $posts, $i, 1 );
// Move to front, after other stickies
array_splice( $posts, $sticky_offset, 0, array( $sticky_post ) );
// Increment the sticky offset. The next sticky will be placed at this offset.
$sticky_offset++;
// Remove post from sticky posts array
$offset = array_search( $sticky_post->ID, $sticky_posts );
unset( $sticky_posts[$offset] );
}
}
// If any posts have been excluded specifically, Ignore those that are sticky.
if ( !empty( $sticky_posts ) && !empty( $q['post__not_in'] ) )
$sticky_posts = array_diff( $sticky_posts, $q['post__not_in'] );
// Fetch sticky posts that weren't in the query results
if ( !empty( $sticky_posts ) ) {
$stickies__in = implode( ',', array_map( 'absint', $sticky_posts ));
// honor post type(s) if not set to any
$stickies_where = '';
if ( 'any' != $post_type && '' != $post_type ) {
if ( is_array( $post_type ) )
$post_types = join( "', '", $post_type );
else
$post_types = $post_type;
$stickies_where = "AND $wpdb->posts.post_type IN ('" . $post_types . "')";
}
$stickies = $wpdb->get_results( "SELECT wp_posts.* FROM $wpdb->posts INNER JOIN wp_term_relationships ON (wp_posts.ID = wp_term_relationships.object_id) WHERE 1=1 AND ( wp_term_relationships.term_taxonomy_id IN (" . get_term( $wp_query->query_vars['cat'], 'category' )->term_taxonomy_id . ") ) AND $wpdb->posts.ID IN ($stickies__in) $stickies_where" );
foreach ( $stickies as $sticky_post ) {
// Ignore sticky posts are not published.
if ( 'publish' != $sticky_post->post_status )
continue;
array_splice( $posts, $sticky_offset, 0, array( $sticky_post ) );
$sticky_offset++;
}
}
}
return $posts;
}
add_filter( 'the_posts', 'hm_category_sticky_posts', 10, 2 );
@willmot
Copy link
Author

willmot commented Dec 1, 2011

Just copy this into your themes functions.php file and your good to go.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment