I need a custom WP-Query written that will display a list of paginated pages (custom post type) in a custom order.

I have a custom post type called "courses" I have a custom post type called "events"

The "courses" custom post type has a meta key called "course_id". The "events" custom post type has a meta key called "course_id".

Currently, Im using code like the below to display a list of paginated "courses".

$args = array(
    'post_type'=> 'courses',
    'order'    => 'DESC'
query_posts( $args );

// The Loop
while ( have_posts() ) : the_post();
    echo '<li>';
    echo '</li>';

// Reset Query

What I would like to be able to do, is to display this same list of courses but ordered based on the number of related "events".


Course A -> course_id = A01
Course B -> course_id = B01
Course C -> course_id = C01

Event 01 -> course_id = A01
Event 02 -> course_id = A01
Event 03 -> course_id = B01
Event 04 -> course_id = B01
Event 05 -> course_id = B01
Event 06 -> course_id = C01

The custom WP Query will look at each "course" and course_id. It will then count the number of related "events" using the course_id as the unique key. The code would then output the "courses" as

Course B
Course A
Course C

or (if listed in ascending order):

Course C
Course A
Course B

To give you an idea of scale, there are likely to be about 200 different "courses". Each "course" is likely to have 20 - 200 "events" associated to it.

3 Answers 3


As it's not clearly stated, how (in code) the "related" CPTs are interconnected, I want to post a mostly overseen possibility for CPTs.

When you register_post_type(), you have the argument of hierarchical that should be set to true to allow for 'supports' => array( 'page-attributes' ). This then allows you to define an order manually.

enter image description here

  • What 'order' => ???? in $args should be to use that order? Apr 3, 2017 at 11:00
  • @AntonisTsimourtos There is no order key in the args array. That is something that the user must provide in the UI.
    – kaiser
    Apr 3, 2017 at 13:04
  • 1
    It is menu_order , just iplemented it into a project Apr 3, 2017 at 14:18
  • @AntonisTsimourtos The menu_order is only usable in query arguments, not during register_post_type(). Also, it is only usable when you register a hierarchical post type, as shown in this answer (which pretty much was the whole point of this answer).
    – kaiser
    Apr 3, 2017 at 20:19

First of all, Never use query_posts() :)

As for the ordering by number of events - this could be done, expensively, with a bit of custom SQL work.

A better, and easier, way would be to create another meta key (say, _event_count - the underscore prevents WordPress from displaying it automatically) for the courses which stores the number of events associated with that course.

This would have to be 'cleverly' updated whenever an event is updated: (i.e. check if the course id has changed, if it has update the course its changed from and the course its changed to, to reflect this change).

Once you have that set up, you can order by the value of the meta key _event_count.

You can create/update the _event_count meta key using update_post_meta. You will need to hook onto save_post, (checking permissions, and nonces etc), checking post type (checking its an event) and finally whether it's course id has changed or not using:

Keep in mind that the save_post is fired after WordPress has updated 'custom fields' are updated. So you will have to change course_id to _course_id (which removes it from the custom fields metabox) and create your own metabox and handle its update yourself.

For a general example in creating metabox / updating post meta see:

  • Nice idea, but how would I create the _event_count?
    – Chris
    May 3, 2012 at 12:08
  • See updated answer :) May 3, 2012 at 12:35

You should use taxonomy, not id meta box to link between 2 post types. Also I must disagree with the answer above me about query_posts(), you should use it but only for the main loop, and only once, check the codex.

  • 2
    The main query for a page happens before the template loads. when you call query_posts you are discarding that original query and running a new one, which is a waste of resources. read the link he posted about using pre_get_posts to alter the query before it happens. the codex is out of date on this subject.
    – Milo
    Jun 30, 2012 at 0:10
  • Hey, thanks for your comment, I didn't knew that sorry, apparently my answer is misleading. So I should use the pre_get_posts hook with conditional tags?
    – ItayXD
    Jun 30, 2012 at 9:37
  • 1
    we are all here to learn! yes, using pre_get_posts with conditional tags will be most efficient. I think it also has the helpful side-effect of centralizing all of your queries.
    – Milo
    Jun 30, 2012 at 17:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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