Earlier this year I talked about removing stopwords from sort queries.

Sadly I ran into a problem where the code wasn’t working.

The Original Code

Here’s the original code.

add_filter( 'posts_orderby', function( $orderby, \WP_Query $q ) {
    if( 'SPECIFIC_POST_TYPE' !== $q->get( 'post_type' ) )
        return $orderby;
 
    global $wpdb;
 
    // Adjust this to your needs:
    $matches = [ 'the ', 'an ', 'a ' ];
 
    return sprintf(
        " %s %s ",
        MYSITE_shows_posts_orderby_sql( $matches, " LOWER( {$wpdb->posts}.post_title) " ),
        'ASC' === strtoupper( $q->get( 'order' ) ) ? 'ASC' : 'DESC'
    );
 
}, 10, 2 );
 
function MYSITE_shows_posts_orderby_sql( &$matches, $sql )
{
    if( empty( $matches ) || ! is_array( $matches ) )
        return $sql;
 
    $sql = sprintf( " TRIM( LEADING '%s' FROM ( %s ) ) ", $matches[0], $sql );
    array_shift( $matches );
    return MYSITE_shows_posts_orderby_sql( $matches, $sql );
}

This worked, mostly, but it somehow broke pagination. Every page restarted the order. This had to do with complications with the Genesis theme but more importantly it messed up the order on the back of WordPress and it didn’t play well with FacetWP. So I rewrote it a little to be more specific:

The New Code

if ( !is_admin() ) {
	
	add_filter( 'posts_orderby', function( $orderby, \WP_Query $q ) {
		
		// If this isn't an archive page, don't change $orderby
		if ( !is_archive() ) return $orderby;
		
		// If the post type isn't a SPECIFIC_POST_TYPE, don't change $orderby
		if ( 'SPECIFIC_POST_TYPE' !== $q->get( 'post_type' ) ) return $orderby;

		// If the sort isn't based on title, don't change $orderby
		$fwp_sort  = ( isset( $_GET['fwp_sort'] ) )? sanitize_text_field( $_GET['fwp_sort'] ) : 'empty';
		$fwp_array = array( 'title_asc', 'title_desc', 'empty');
		if ( !in_array( $fwp_sort, $fwp_array ) ) return $orderby;

		// Okay! Time to go!
		global $wpdb;

		// Adjust this to your needs:
		$matches = [ 'the ', 'an ', 'a ' ];

		// Return our customized $orderby
		return sprintf(
			" %s %s ",
			MY_CUSTOM_posts_orderby_sql( $matches, " LOWER( {$wpdb->posts}.post_title) " ),
			'ASC' === strtoupper( $q->get( 'order' ) ) ? 'ASC' : 'DESC'
		);

	}, 10, 2 );

	function MY_CUSTOM_posts_orderby_sql( &$matches, $sql ) {
		if( empty( $matches ) || ! is_array( $matches ) )
			return $sql;

		$sql = sprintf( " TRIM( LEADING '%s' FROM ( %s ) ) ", $matches[0], $sql );
		array_shift( $matches );
		return lwtv_shows_posts_orderby_sql( $matches, $sql );
	}
}

First of all, I got smart about only loading this when it needed to be loaded. Next I told it to only sort on archive pages, because I was also outputting recently added lists in other places. Finally I forced it to understand Facet, and that if I wasn’t sorting by alphabetical, it didn’t matter at all.

Reader Interactions

Leave a Reply

Your email address will not be published. Required fields are marked *

%d bloggers like this: