Skip to content

Instantly share code, notes, and snippets.

@roborourke
Created January 17, 2012 11:04
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save roborourke/1626247 to your computer and use it in GitHub Desktop.
Save roborourke/1626247 to your computer and use it in GitHub Desktop.
Better sticky post handling for WordPress
<?php
/**
* Fixes sticky post ordering in WordPress anywhere the order is not explicitly defined.
*
* Updates a post's menu order whenever the sticky posts option is updated
*
* Props to Simon Fransson of http://dessibelle.se/ for a bugfix where 'unstickied' posts were not updated
*
* @param Array $stickies An array of post IDs
*
* @return Array The original array passed in
*/
add_filter( 'pre_update_option_sticky_posts', 'fix_sticky_posts' );
function fix_sticky_posts( $stickies ) {
$old_stickies = array_diff( get_option( 'sticky_posts' ), $stickies );
foreach( $stickies as $sticky )
wp_update_post( array( 'ID' => $sticky, 'menu_order' => -1 ) );
foreach( $old_stickies as $sticky )
wp_update_post( array( 'ID' => $sticky, 'menu_order' => 0 ) );
return $stickies;
}
/**
* Rewrites the query to sort by menu_order first and then date in standard lists - ignore if date archive and also ignore if the 'ignore_sticky_posts' flag is set
*/
add_action( 'pre_get_posts', 'sticky_posts_query' );
function sticky_posts_query( $q ) {
if ( ! is_admin() && ( ! isset( $q->query_vars[ 'ignore_sticky_posts' ] ) || ( isset( $q->query_vars[ 'ignore_sticky_posts' ] ) && ! $q->query_vars[ 'ignore_sticky_posts' ] ) ) && ! isset( $q->query_vars[ 'year' ] ) && ! $q->query_vars[ 'monthnum' ] && ! $q->query_vars[ 'day' ] && ! isset( $q->query_vars[ 'orderby' ] ) )
$q->query_vars[ 'orderby' ] = 'menu_order date';
return $q;
}
?>
@JboyJW
Copy link

JboyJW commented Jun 4, 2016

In case you miss the comment on your Interconnect IT post, please make the following updates to get this working in WP 4.5.2:
– Change the menu order of the sticky posts from -1 to 1. The order is descending order so you want the 1’s first then the 0’s.
– Update sticky_posts_query function to not check whether year isset because it’s always set and the $q is passed by reference, so no return needed and I’m using the updated set function to set the orderby:
function sticky_posts_query( $q ) { if ( ! is_admin() && ( ! isset( $q->query_vars[ ‘ignore_sticky_posts’ ] ) || ( isset( $q->query_vars[ ‘ignore_sticky_posts’ ] ) && ! $q->query_vars[ ‘ignore_sticky_posts’ ] ) ) && ! $q->query_vars[ ‘year’ ] && ! $q->query_vars[ ‘monthnum’ ] && ! $q->query_vars[ ‘day’ ] && ! isset( $q->query_vars[ ‘orderby’ ] ) ) { $q->set(‘orderby’, ‘menu_order date’); } }

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