Home » Blog » Order Posts by Custom Key revisited

Order Posts by Custom Key revisited

I’ve gotten quite a few questions about how to get this to work on a specific page, or only within a specific category. I actually had the same issue when building the script originally. The trick is that you can’t just use the conditional tags in the functions page. At that point, it’s already too late because the queries have already been run. You have to create a function and then run it as a filter on one of the early WordPress initializing functions. I chose the wp() function. Here is my revised code (nearly straight from the client’s site).

add_action('wp', 'check_page');
function check_page () {
	if (is_page('The Page Name')) {
		add_filter('get_previous_post_sort', 'sort_it');
		add_filter('get_next_post_sort', 'sort_it');
		add_filter('posts_orderby', 'sort_it' );
		add_filter('posts_join', 'join_it' );
		add_filter('posts_where', 'where_it' );

		function sort_it () {
			global $wpdb;

			return " $wpdb->postmeta.meta_value DESC ";

		function join_it( $join ) {
			global $wpdb;

			$join .= " LEFT JOIN $wpdb->postmeta ON($wpdb->posts.ID = $wpdb->postmeta.post_id) ";

		  return $join;

		function where_it( $where ) {
			global $wpdb;
			$where .= "AND $wpdb->postmeta.meta_key = 'Price' ";

		  return $where;

In our case, we were sorting by the “Price” meta key and we were sorting from highest to lowest price. I hope this helps clear things up. Thanks to Paul Gray for sending us an email asking for some clarification.

How Can We Help You?

You can fill out the form below to reach out to us about your project. We promise not to resell your contact information or to send you spam (we hate it too).


  1. nate says:

    This is exactly what I’m looking for – one question on useage – when running check page (is_page), how do you trigger it to run on a page running custom posts? Do you simple enter a category name or number or something more involved than that?

  2. Brandon says:

    @nate – You would use this in the exact same way. We’re checking what page we’re requesting by hooking into the wp action. We then add our filters on the query if it’s the right page. So, in our example above, you’d simply put your custom page’s name in place of “The Page Name.”

    Make sense?

  3. jean says:

    Hi, I think your solution is exactly what I was looking for but being a php nono I am having trouble making it work. I would very much appreciate a little help !
    I have 2 custom fields 1 called “special” with value “1″ to retrieve posts ,this works fine using code found on WP Codex. I would like to list them on page sorted ASC using a 2nd custom field called “tri” with value from 1 to XX. I have found the theme function.php file and pasted code after changing page name but how do I wrap the code with php tags
    all I get is php errors
    do I put php tags before “add_action….” ?
    or just after “add_action….” ?
    all I get is php errors again
    What am I doing wrong ???
    Thanks for help

  4. Brandon says:

    @jean – Yes, you definitely have to wrap the php code in php tags “<?php” and “?>” respectively in the functions.php file. Were you able to get the query sorted out? Seems like it would be as simple as adding a a condition to the where_it function. I’m not sure why you’re doing that though. Seems like it would be much easier to assign posts to a certain category and just call those posts in via the query_posts(‘&cat=category-id-here’). You can still use our sorting functions using this method. In fact, this is how we do it on our client’s site.

  5. wami says:

    First, thank you so much for this code, it´s exactly what I´m missing so long.

    I´ve copied the code above and put it in my functions.php, but now when I open my homepage I get an php-error:

    Parse error: syntax error, unexpected T_FUNCTION

    Have you an idea why?



  6. Brandon says:

    @wami – It’s hard to tell without seeing what you’re doing exactly. That error is usually caused by not finishing a line with a semi-color, closing parenthesis in a function or closing a brace in defining or specifying an array. Take a look just above the line that it’s erroring out at something like that. If you don’t find anything, feel free to contact me through out need help page and I can take a look for you.

  7. mezzomind says:

    Thanks for this!

    I did run into a small issue that was driving me crazy for about 10 minutes. I was getting an error about the ‘wpdb’ class not being able to be converted to a string. After some quick research into the ‘wpdb’ class and its use I realized the problem.

    The source code has encoded ‘>’ characters, %gt; which inside of php quotes is just read as string content. So instead of $wpdb->postmeta we have $wpdb->postmeta, which was the source of my error. Anyone copying and pasting this code could encounter this issue as well.

    Good Day,

  8. Brandon says:

    @mezzomind – I didn’t realize that it copy/pasted like that. That must be a function of the plugin we’re using to output our source code. I’ll see what I can do to fix this.

  9. nowimproved says:

    Thank you , that worked great.

    Now my only problem is , I replaced Price with startdate. I am trying to sort by the custom fields july 24 june 4 dec 9 etc.. Is this possible?

  10. Brandon says:

    @nowimproved – You’d have to do some MySQL magic and convert those strings to dates and compare that way. If you’re trying to order by date thought, why not just use the built in date ordering? You could just post each entry on the date you’re trying to order by.

  11. Hello,
    Can anyone help me? I have been up for a day and half trying figure this out. I am a newbie so i’m totally self taught. with that being said can someone tell me how get this code to work? I would like it so that once the event date has passed the even no longer shows.I want the events to be sorted by the custom event_date field and then not be shown once the event_date has passed.
    I enter the event_date format 03/14/2011
    Below is the code is have. I’m using it and a function for all the archive category pages. Could someone please please help me?
    add_filter(‘posts_join’, ‘new_join’ );
    function new_join($pjoin){
    global $wpdb;
    $pjoin .= “LEFT JOIN (
    SELECT *
    FROM $wpdb->postmeta
    WHERE meta_key = ‘event_date’
    AND STR_TO_DATE(meta_value,’%m/%d/%Y %H:%i:%s’) >= CURDATE() ) AS metasort
    ON $wpdb->posts.ID = metasort.post_id”;
    return ($pjoin);

    add_filter(‘posts_orderby’, ‘new_order’ );
    function new_order( $orderby ){
    global $wpdb;
    $orderby = “metasort.meta_value, ‘%m/%d/%Y %H:%i:%s’ ASC”;

    return $orderby;

Leave a Reply

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