WordPress.org

Ready to get started?Download WordPress

Forums

[resolved] Sorting by custom fields with the posts_orderby filter (15 posts)

  1. gab.ro
    Member
    Posted 2 years ago #

    Hello,

    Does anyone know of a way to use the posts_orderby filter for sorting posts by custom fields?

    What I'm looking for is something like this:

    add_filter('posts_orderby', 'custom_order');
    
    function custom_order(){
    	$orderby = 'blah, blah, blah, my_meta_key, blah, blah, blah';
    	return $orderby;
    }

    I know sorting posts by custom field is also possible with

    query_posts('meta_key=my_meta_key');

    But what I'm interested in is doing it with the posts_orderby filter.

    Thanks a million. This question has been haunting me for the past 2 or 3 years.

  2. vtxyzzy
    Member
    Posted 2 years ago #

    Unless you use 'meta_key=my_meta_key' in your query, you must use a JOIN filter to join the postmeta table so the meta_key/value will be available for the orderby filter.

  3. gab.ro
    Member
    Posted 2 years ago #

    Wow! I can't believe I didn't know about the posts_join filter. Thanks!

  4. vtxyzzy
    Member
    Posted 2 years ago #

  5. gab.ro
    Member
    Posted 2 years ago #

    Thanks again!

  6. jacobdubail
    Member
    Posted 1 year ago #

    Hey guys,

    Picking up this thread. Hopefully someone will be able to help.

    Here's my query:

    $args = array(
    	'post_type'      => array( 'projects', 'post' ),
    	'posts_per_page' => -1,
    	'post_status' => 'publish'
    	'orderby'     => 'meta_value',
    	'order'       => 'DESC',
    	'meta_key'    => 'code'
    );
    
    $projects = new WP_Query( $args );

    My problem is the posts don't have the meta_key of code so they won't appear in my loop. I'm thinking that I can use the posts_orderby filter along with a couple other filters to get the job done. Only problem, I can't figure out how to setup the filters. Any help?

    Many thanks,
    Jacob

  7. vtxyzzy
    Member
    Posted 1 year ago #

    See the article I referenced above for the filter functions.

    You will need to eliminate the 'orderby', 'order', and 'meta_key' parameters from $args and handle the meta value in the filters.

    This is UNTESTED.

    Create a sort_key field with the fields filter (change the 0 to 9999999' if you want missing code's to sort before the projects, assuming order is DESC):

    $mam_global_fields = ', IFNULL(pm.meta_value,0) AS sort_key';

    Set the join filter to join the postmeta table:

    $mam_global_join = " LEFT JOIN $wpdb->postmeta pm ON (pm.post_id = $wpdb->posts.ID AND pm.meta_key = 'code')";

    Set the order to the sort_key:

    $mam_global_orderby = 'sort_key DESC';
  8. jacobdubail
    Member
    Posted 1 year ago #

    Thanks vtxyzzy,

    I really appreciate your response!

    Here's what I've done:

    in my front-page template:

    $args = array(
    	'post_type'      => array( 'projects', 'post' ),
    	'posts_per_page' => -1,
    	'post_status' => 'publish'
    );
    		$mam_global_fields  = ', IFNULL(pm.meta_value,0) AS sort_key';
    		$mam_global_join    = " LEFT JOIN $wpdb->postmeta pm ON (pm.post_id = $wpdb->posts.ID AND pm.meta_key = 'code')";
    		$mam_global_orderby = 'sort_key DESC';
    
    $projects = new WP_Query( $args );

    In my functions.php:

    function mam_posts_fields($fields) {
       global $mam_global_fields;
       if ( $mam_global_fields ) {
    		$fields .= ( preg_match('/^(\s+)?,/', $mam_global_fields) ) ? $mam_global_fields : ", $mam_global_fields";
    	}
       return ( $fields ) ? $fields : '';
    }
    
    function mam_posts_join($join) {
       global $mam_global_join;
       if ( $mam_global_join && $join ) {
    		$join .= ' ' . $mam_global_join;
    	}
       return ( $join ) ? $join : '';
    }
    
    function mam_posts_orderby($orderby) {
       global $mam_global_orderby;
       if ( $mam_global_orderby && $orderby ) {
    		$orderby = $mam_global_orderby;
    	}
       return ( $orderby ) ? $orderby : '';
    }
    
    add_filter( 'posts_fields',  'mam_posts_fields'  );
    add_filter( 'posts_join',    'mam_posts_join'    );
    add_filter( 'posts_orderby', 'mam_posts_orderby' );

    When I load the page, I get an error:

    Parse error: syntax error, unexpected T_VARIABLE in .../wp-content/themes/ncm/functions.php on line 246

    Which is this variable: global $mam_global_fields;

    Can't find any syntax errors, but no matter what I do, I can't get the page to load with this code. Any ideas?

    Thanks again,
    Jacob

  9. vtxyzzy
    Member
    Posted 1 year ago #

    When I copy the code you posted and compile it, I get no errors either. The actual error may be on an earlier line. Put your functions.php file in a pastebin and post a link to it here.

  10. jacobdubail
    Member
    Posted 1 year ago #

    You're quick! Much appreciated.

    http://pastebin.com/327Pvcj2

    When I remove the new code, everything works fine.

    Thanks again for your help. This topic has eluded me for some time.

    -J

  11. vtxyzzy
    Member
    Posted 1 year ago #

    Don't know what is going on, but in the pastebin there is no line 246. It ends on 215.

  12. jacobdubail
    Member
    Posted 1 year ago #

    I cleaned out a bunch of commented functions that I use on some sites. It's kind of a catch all functions.php that I use on all my sites. Would you like me to repost with all of the commented code?

    -J

  13. vtxyzzy
    Member
    Posted 1 year ago #

    I get no errors on the code you posted, so I am at a loss to explain the problem.

    Have you tried using just the code you posted?

  14. jacobdubail
    Member
    Posted 1 year ago #

    I'll give it a try right now. Did you update to 3.4, yet?

  15. vtxyzzy
    Member
    Posted 1 year ago #

    Not yet, I am in the middle of a couple of projects and don't have time right now to back everything up on multiple sites. Besides, I have not tested it yet on any of my non-production sites.

Topic Closed

This topic has been closed to new replies.

About this Topic