Sort Custom Posts by Custom Field

Oxygen Builder and Advanced Custom Fields is a great combination that allows you to create any type of content you like and display it beautifully. Unfortunately by default WordPress will sort your custom posts according to the published date in reverse chronological order. But what if you don’t want them sorted by published date and would rather sort them by one of your custom fields?

I recently came across this issue recently with a custom post type I created, events. Here is the page which displays a timeline of up coming events https://livingwisdom.com.au/events/ . The problem I was having is that I needed to sort them by the custom field “start_date” rather than the default published date. This way they can be displayed in the order of the actual date of the event rather than when it was published.

This tutorial assumes you know how to use Advanced Custom Fields and CPT UI to create your custom posts and add them using Oxygens’ Easy Posts so we won’t go into that at this stage.

If we want to change the sort behaviour we will need to change the query used to include custom query parameters.

The default value of Query Params in manual mode is:

author_name=admin&category_name=uncategorized&posts_per_page=2

We need to replace this with our own custom code. If we refer to the WordPress codex https://developer.wordpress.org/reference/classes/wp_query/ we will see that the examples of wp_query are written differently than Oxygen which expects the query to be a string rather than PHP code. We will fix this shortly. If we scroll down the examples we will find one very similar to what we need, there is a section titled ‘orderby’ with ‘meta_value’ and custom post type:

<?php
$args = array(
    'post_type'  => 'my_custom_post_type',
    'meta_key'   => 'age',
    'orderby'    => 'meta_value_num',
    'order'      => 'ASC',
    'meta_query' => array(
        array(
            'key'     => 'age',
            'value'   => array( 3, 4 ),
            'compare' => 'IN',
        ),
    ),
);
$query = new WP_Query( $args );

We can modify this to our needs. Firstly our custom post type is named ‘event’ and the custom field that we want to sort on is named “start_field” which is a date field.

<?php
$args = array(
    'post_type'  => 'event',
    'meta_key'   => 'start_field',
    'orderby'    => 'meta_value_num',
    'order'      => 'ASC'
);
$query = new WP_Query( $args );

Next go to our “event” archive template and add a code block to the bottom. and copy and paste the code above into the PHP & HTML section and replace the “$query = new WP_Query( $args );” part with “echo build_query( $args );” This will echo out the query string.

Next copy the resultant rendered text, open the Easy Posts / Query, select “manual” for WP Query type and paste in the Query Params text area.

You can now delete the code block we used to generate the query string.

The custom posts should now sort in the Start Date order.

WANT TO WORK WITH FIRTH WEB WORKS?

Interested to find out what we can do for you? Fill out our Project Enquiry Survey and we will get back to you with a custom solution tailored to fill your unique needs.
Project Enquiry Survey
If you want to purchase a block of time for us to work on your website, click on the "Purchase Service Time" button.
Purchase Service Time
If you want to book a video conference call using Google Meet, click the "Book a Meeting" button below.
Book a Meeting

4 comments on “Sort Custom Posts by Custom Field”

  1. Amazing post, thank you so much for this!

    I’ve got a question if you can help. How do I make it hide expired events? I noticed yours only shows future events.

    Let me know, thanks.

  2. The client just deletes the event after it has happened. You probably could include something like this in the query:

    ‘meta_query’ => array(
    array(
    ‘key’ => ‘start_field’,
    ‘value’ => date(“Y-m-d”),
    ‘compare’ => ‘>=’,
    ),

    Haven’t tested it but it should work.

  3. Hi, I just love this tutorial and it already helps me a lot.
    The meta_query for auto hide would give me the current date instead of being the variable for today.
    ‘value’ => date(“Y-m-d”),

    Could you please help me a little more?

  4. Great post Lee.

    My question is like the others. To auto drop off the old events without customer intervention ‘value’ => date(“Y-m-d”) will work everytime in PHP.

    However how do you translate that to a parameter string to evaluate todays date?

    Cheers

    Stef

Leave a Reply

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

Firth Web Works ©2024 All Rights Reserved | Privacy Policy
Top homephoneenvelopechevron-downcross-circle linkedin facebook pinterest youtube rss twitter instagram facebook-blank rss-blank linkedin-blank pinterest youtube twitter instagram