Changing Archive Sorting

Sorting Made SimpleGot another quick tip for you. FYI, these quick tips are things I use on my personal sites. Simple and handy tricks.

With my Genesis Explained series, and all the sub-series sections, I wanted to change the order of the posts in the archives because it is helpful to read them in the order they were written. First, I chose to use tags instead of categories to organize the series. In general I try to really weigh my categories so I use as few as possible. We can debate all of that, but that is just my choice. This would work with categories or other archives too.

Then I setup this simple little code in my functions.php file to make the change happen

add_action( 'genesis_before_loop', 'ntg_do_query' );
/** Changes the Query before the Loop */
function ntg_do_query() {

    if( is_tag( array( 'genesis-explained', 'actions', 'filters', 'functions', 'admin' ) ) ){
        global $query_string;

        query_posts( wp_parse_args( $query_string, array( 'orderby' => 'date', 'order' => 'ASC' ) ) );
    }

}

This is designed to work with Genesis, in other themes you have to handle this differently.

Now a quick walk though. Line 1 loads the “action.” For more details on what that means, check out my Genesis Explained series. Line 5 is the beginning of the magic. I use an if() statement with the is_tag() function to only run the code that changes the sorting order on tags. You can read up on conditional tags in the WordPress Codex. You can also find out more about how to use the is_tag() function there. In short, this checks to see if the archive being shown is any of those 5 tag archives. I can keep adding to it if I have more archives that need to be sorted like this.

The next line, “global $query_string;” makes that variable available for line 8 to use. I am using 2 functions on line 8. You can read about query_posts() and wp_parse_args() in the codex. You may also want to check out the arguments that can be used with query_posts() in the WP_Query() article of the codex.

Since this is a quick tip, I’ll just give you the short version here.

query_posts() basically changes the query, that is the information being looked up in the database. You can make up your own queries, but I wanted to use most of the existing query, just change 2 values. So I used wp_parse_args(), which basically combines arguments. It is pretty handy and I use it for lots of things. The second part of the function, “array( ‘orderby’ => ‘date’, ‘order’ => ‘ASC’ )” gets merged with the first part. It either adds new information or replaces existing code automatically. Very handy.

Speaking of that second part, “array( ‘orderby’ => ‘date’, ‘order’ => ‘ASC’ ),” that is what changes the query. The tag information, paging, and pretty much everything else normally loaded on a tag archive page are left alone. I’m just making sure that this is sorting posts by date and running them from oldest to newest. I could probably drop “orderby’ => ‘date'” from that, but on the off chance that WordPress ever changes the default, I won’t have to go edit this value to keep my sorting exactly the way I want it.

Hope this helps.

Comments

  1. You should really be doing this before the query is made, not afterwards. While it won’t cause any issues in this case (other than increased database queries), if you were to include a parameter like ‘posts_per_page’ you’d have real issues.

    Here’s more information on customizing the query: http://www.billerickson.net/customize-the-wordpress-query/

    And here’s the specific code you’d run in this case (untested): https://gist.github.com/1535891

    • Bill, that is a very good point. Since this is just for “sorting” I handle it the “easy” way, so I can use the built in conditional tags. Changing the posts_per_page is a real beast if you do it wrong. Based on the work arounds I had to do for my plugin, where I was limited on how to interact with the query, it can be extremely frustrating.

  2. Hey Nick, is there a way to “orderby” alphabetical?

    • Nevermind, I figured it out using your code + researching wp_parse_args! Thought I’d share the code:
      /** Change the sort/orderby */
      add_action('genesis_before_loop', 'whc_before_loop');
      function whc_before_loop () {
      global $query_string;
      query_posts( wp_parse_args( $query_string, array( 'post_type' => 'your-cpt-name', 'posts_per_page'=>10, 'orderby'=>'title','order'=>'ASC') ) );
      }