I'm with a non-profit that paid for development of a custom post type plugin that will help us track endangered plants that we're keeping in cultivation, rescued from development. We're mostly happy with it, but need a bit of help. Our plugin is called nasc_report and we have multiple "authors" who are generating reports. The plants are cared for over time, so each year we ask for a census to be taken. So I'd like the default sort order to be ruled first by author (each author's posts will be grouped) and then by nasc_population_code (A to Z), and then by date (most recent on top). This will produce little groups of our cultivated plant material by population code but separate them by author.

(As an aside, our growers are assigned a separate role that only allows them to see their own entries - all entries are private - but admins unfortunately see all and can't hide all but their own; admins are also usually growers. Any ideas on that would be welcomed as well. If we could allow admins the options: "All | Private | Mine" and make "Mine" the default screen, then I'd only need to default sort by nasc_population_code and then by date.)

I've searched around but haven't found a direct answer to my question or if I have I haven't been able to understand it very well. Would I use pre_get_posts? I'm just a little lost in the code, here. Any help would be appreciated.

  • Would you please try to reduce your question a little? It's hard to understand this way, as there's a lot of "noise" in it. You can also try to use the editor format buttons like list, etc. to give it more structure. Thanks. – kaiser Sep 29 '12 at 13:37
  • I'm sorry - I thought it was fairly concise. I'm way outside my comfort zone so in discussing these topics I feel I needed to add more description to get my point across since I don't know the proper code or terms. I'm a botanist, not a programmer. – Ryan K Oct 2 '12 at 18:17
  • It's 3 years later but it must be pointed out that a question which contains an "aside" in parenthesis that occupies one COMPLETE paragraph does not even come close to "fairly concise". – jdm2112 Nov 4 '15 at 17:26

Since I just wrote a pre_get_posts answer for someone else, I will modify it slightly and see if it works for you too.

When using pre_get_posts the $query variable is passed "by reference" which means we can directly manipulate the $query object with the shortcut functions such as set_query_var. Remove the query code from your taxonomy template, and try the following in your functions.php:

function wpa_66507( $query ) {
    if ( is_post_type_archive('nasc_report ') && is_main_query() ) { //where 'nasc_report' is assumed to be your post type name
        set_query_var( 'orderby', 'author meta_value date' );
        set_query_var( 'meta_key', 'nasc_population_code' ); 
add_action( 'pre_get_posts', 'wpa_66507' );

Hope this helps. I'm a little unclear on sort orders (particularly whether they can be mixed), and I think you might need to set the posts_per_page parameter to -1 if you'd like to show all your posts on a single page without pagination.

EDIT #1:

I took another look at this and actually tested on some sample posts. It sorts by:

  1. Post author's display name (instead of author ID) - ascending
  2. Post meta key nasc_population_code - ascending
  3. Post date - descending

To do this we can no longer use the relatively simple pre_get_posts and have to do more custom SQL. I apologize in advance that I won't be able to explain it amazingly well because my own understanding is sort of limited. WordPress has a bunch of other filters that let you adjust the actual SQL query WordPress intends to perform on the database to retrieve your posts. The ones I'm using here are:

  1. posts_join - in general this links other tables to the wp_posts table
  2. posts_orderby - this controls the ordering
  3. post_limits - this controls how many posts to retrieve

The Codex entries are admittedly a little thin and I find them somewhat confusing.

edit: This solution also presumes that you have a meta key ( custom field, practically same difference ) called nasc_population_code.

So putting it all together, give this a try:

add_filter('posts_join', 'wpa_66507_join');

function wpa_66507_join( $join ) {
    if ( ! is_admin() && is_post_type_archive('nasc_report') && is_main_query() )  {

        global $wpdb;

        // join the users table so we can sort by author name
        $join .= " LEFT JOIN $wpdb->users AS author ON ( {$wpdb->posts}.post_author = author.id )";

        // join the postmeta table so we can sort by meta key
        $join .= " LEFT JOIN $wpdb->postmeta AS nasc_population_code ON ( {$wpdb->posts}.ID = nasc_population_code.post_id AND nasc_population_code.meta_key = 'nasc_population_code' )";
    return $join;

add_filter('posts_orderby', 'wpa_66507_orderby');

function wpa_66507_orderby($orderby_statement) {
    if ( ! is_admin() && is_post_type_archive('nasc_report') && is_main_query() )  {
        global $wpdb;
        $orderby_statement = "author.display_name ASC, nasc_population_code.meta_value ASC";
    return $orderby_statement;

add_filter('post_limits', 'wpa_66507_limits');

function wpa_66507_limits($limits) {
    if ( ! is_admin() && is_post_type_archive('nasc_report') && is_main_query() )  {
        $limits = "";
    return $limits;
| improve this answer | |
  • Thanks for the assistance. I have a feeling I'll need to stare at this code for a while longer this weekend to understand it. (For instance, I don't think I have a taxonomy template. These posts aren't hierarchical, although come to think of it perhaps they should be: maybe all previous posts should be nested under the most recent population code entry for that author so only the most recent one shows but the others can be expanded...) – Ryan K Sep 29 '12 at 3:37
  • Anyway, I threw the code in (nasc_report and nasc_population_code are correct) but it still default sorts by the generated title, "Report 735." I'll keep working on it. Cheers! – Ryan K Sep 29 '12 at 3:45
  • Sorry it didn't work. I wasn't sure that pre_get_posts would work for such a complex query, or if you'd need something more advanced: like a custom query. And the reference to taxonomy template is left over from the other answer I was working on re: pre_get_posts. If you don't have one, you must be falling back to archives.php? or perhaps index.php? – helgatheviking Sep 29 '12 at 13:01
  • No worries. Perhaps I could take a different approach. If I fixed the problem so that admins by default saw only their private posts (but could see and administrate "All" if they clicked All at the top if they chose) then I could use the 'nasc_population_code' as a custom taxonomy... maybe? Perhaps it's obvious, but I seem to be in over my head and don't have the time to learn the language. Might have to go back to the original plugin developer and ask for modifications :-/ Thanks for your time and the explanations! – Ryan K Sep 29 '12 at 14:56
  • 1
    Wow! Thanks for taking another stab at this. I threw the updated version into functions.php but it still default sorts by date. To clarify, the column nasc_population_code isn't hard-coded in the plugin anywhere - would that cause a problem? The plugin developer allowed us to choose the fields we want to incorporate, such as pot size or plant height, as we may want to change them in the future easily. The columns in the custom post type are added to an array in a separate options page and given the id "nasc_field_id" hence nasc_population_code, but it should still be able to sort by it... – Ryan K Sep 29 '12 at 17:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.