I have an interesting problem I am trying to solve. Here is my situations:

  • I have create a custom post type for "events".
  • For each event post I require custom fields to be entered for the event start date/time.
  • In addition, each event can be assigned to a custom taxonomy I have created specifically to assign each event to one or more "event categories" (my custom taxonomy).
  • I have create a public template which calls all posts belong to this custom post type and am correctly filtering the query to ONLY display events were the event start/date and time is greater than todays date.
  • All of the above is working correctly.

The only thing I am currently having problems with is displaying all the events for a specific taxonomy term.

In other words... along with each event listing I am including all terms associated with the event from my custom taxonomy (event categories).

So, there issue here is that each taxonomy term (correctly) shows up as a link but when you select the term the corresponding terms archive page is not ordering the corresponding results by the event date/time custom field and it is not excluding events which are older than todays date.

Based upon this page: http://codex.wordpress.org/images/1/18/Template_Hierarchy.png

I have figure out that one is able to create a custom archive page for all terms belonging to a custom taxonomy by naming the archive file as follows:

taxonomy-event_categories.php (where "event_categories") is the name for my custom taxonomy.

Sooooooooo.... As mentioned the only thing I believe I need a solution for is the correct code to insert to achieve the two issues mentioned above.

Here is the code I am using which works in display my event list correctly organized by the event start date/time while removing all events older than today.

    //Get the metadata for each child page
    global $custom_metabox_event_dates;
    $meta1  = $custom_metabox_event_dates->the_meta();
       $today = time();
       $arrMonthNums = array("01" => "01", "02" => "02", "03" => "03", "04" => "04", "05" => "05", "06" => "06", "07" => "07", "08" => "08", "09" => "09", "10" => "10", "11" => "11", "12" => "12");
       $arrMonthNames = array("01" => "JANUARY", "02" => "FEBRUARY", "03" => "MARCH", "04" => "APRIL", "05" => "MAY", "06" => "JUNE", "07" => "JULY", "08" => "AUGUST", "09" => "SEPTEMBER", "10" => "OCTOBER", "11" => "NOVEMBER", "12" => "DECEMBER");
    query_posts('post_type=events&showposts=-1&meta_key=' . $custom_metabox_event_dates->get_the_name('combined_datetime') . '&meta_compare=>=&meta_value=' . $today . '&orderby=meta_value&order=ASC'); 

  <?php if (have_posts()) : while (have_posts()) : the_post(); ?>
    <?php  //Get all Events and run a check against current date
    global $custom_metabox_event_dates; 
    global $custom_metabox_event_details; 
    $meta1          = $custom_metabox_event_dates->the_meta(); 
    $meta2          = $custom_metabox_event_details->the_meta();
    $meta_start_date    = $meta1['event_start_date'];
    $meta_end_date  = $meta1['event_end_date'];
    $meta_start_time    = $meta1['event_start_time'];
    $meta_end_time  = $meta1['event_end_time'];
    $meta_location_city = $meta2['event_location_city'];
    $meta_event_type    = $meta2['event_type'];
    $show_date      = strtotime($meta_start_date);
        if($show_date >= $today) { ?>
            $show_month = date('m', $show_date);
            if ($arrMonthNums[$show_month] == $show_month) {
            echo "<div id='category-events-list-month-title'>EVENTS IN ".$arrMonthNames[$show_month]."</div>"; 
            $arrMonthNums[$show_month] = "printed";
        if($show_date == $today) { 
           <?php } ?>
    <div id="category-events-list-container-group">
                     <div id="category-events-list-container-left">
            <div id="event-entry-list-date"><?php echo $meta_start_date ?></div>
            <div id="event-entry-list-time"><?php echo $meta_start_time ?> - <?php echo $meta_end_time ?></div>
            <div id="category-events-list-container-right">
        <div id="category-articles-list-title"><a href="<?php the_permalink() ?>"><?php echo the_title(); ?></a></div>
        <div id="category-articles-list-excerpt">
        <span>EVENT TYPE: <?php echo get_the_term_list($post->ID, 'event_types', '', ', ',''); ?> </span><br />
        <span>LOCATION: <?php echo $meta_location_city ?></span><br />
        <?php echo substr(get_the_excerpt(),0,250); echo '...  ' ?></div>
    <?php } ?>
<?php endwhile; endif; ?>

Please keep in mind that I am not asking how to change the query above so it just displays posts for one term... Rather, somehow I need to get the archive page to recognize which term was clicked and essentially pass that through the query along with the ordering/filtering I am doing above.

I am assuming this is probably a simple answer which involves the "loop" which I have yet to master.


Here is the code for the archive page which needs to be modified so when a term is clicked from the results list above so it ONLY shows the same results but only for the term selected AND sorted by date/time AND eliminating any events earlier than todays date.

<?php if (have_posts()) : ?>
      <?php $post = $posts[0]; // Hack. Set $post so that the_date() works. ?>
      <?php /* If this is a category archive */ if (is_category()) { ?>
        <div id="category-title-articles">Archive for the &#8216;<?php single_cat_title(); ?>&#8217; Category</div>
      <?php /* If this is a tag archive */ } elseif( is_tag() ) { ?>
        <div id="category-title-articles">Posts Tagged &#8216;<?php single_tag_title(); ?>&#8217;</div>
      <?php } ?>
<?php while (have_posts()) : the_post(); ?>
<div id="category-articles-list-container-group">
<?php endwhile; ?>
<div class="navigation">
<div class="alignleft"><?php next_posts_link('&laquo; Older Entries') ?></div>
<div class="alignright"><?php previous_posts_link('Newer Entries &raquo;') ?></div>
<?php else :
    if ( is_category() ) { // If this is a category archive
        printf("<h2 class='center'>Sorry, but there aren't any posts in the %s category yet.</h2>", single_cat_title('',false));
    } else if ( is_date() ) { // If this is a date archive
        echo("<h2>Sorry, but there aren't any posts with this date.</h2>");
    } else if ( is_author() ) { // If this is a category archive
        $userdata = get_userdatabylogin(get_query_var('author_name'));
        printf("<h2 class='center'>Sorry, but there aren't any posts by %s yet.</h2>", $userdata->display_name);
    } else {
        echo("<h2 class='center'>No posts found.</h2>");
endif; ?>

Thanks in advance,



1 Answer 1


The most efficient way is probably to hook into the pre_get_posts action and add your time comparison there. This way you don't have to worry about the rest or the query options as they will still work. It should look like this (untested), and be placed in a plugin or theme functions file (not in the page template file, the query will already have been executed):

add_action('pre_get_posts', 'add_event_date_criteria');
function add_event_date_criteria(&$query)
    // We only want to filter on "public" pages
    // You can add other selections, like here:
    //  - Only on a term page for our custom taxonomy
    if (!is_admin() &&
        is_tax('event_types')) {
        global $custom_metabox_event_dates;
        $query->set('meta_key', $custom_metabox_event_dates->get_the_name('combined_datetime'));
        $query->set('meta_compare', '>=');
        $query->set('meta_value', time());
        $query->set('orderby', 'meta_value');
        $query->set('order', 'asc');

You define the scope of this extra filter with the contents of the if() test. Currently we don't do it on admin pages (you wouldn't be able to access old content), and only do it on specific taxonomy pages. You should find out for yourself how wide or how narrow you want this.

If you can't solve it this way, you can do the main query again without losing the "page specific query" by adding the different query vars to the main $wp_query objects, and calling $wp_query->get_posts() again. Since we did not call $wp_query->parse_query(), the page-specific query args will not be cleared. It would look like this:

global $custom_metabox_event_dates;
$wp_query->set('meta_key', $custom_metabox_event_dates->get_the_name('combined_datetime'));
$wp_query->set('meta_compare', '>=');
$wp_query->set('meta_value', time());
$wp_query->set('orderby', 'meta_value');
$wp_query->set('order', 'asc');

You can place this in your template files (not functions.php, but taxonomy-event_types.php or other "real" template files). Remember that you "throw away" one database call this way, so it is not the most optimal solution.

  • Hi Jan --- I clarified the question above by including the code from the archive page which I need to modify so its shows the correct posts. I need this archive page code to just display results from my previous query as you pointed out but only for the term which was clicked by the visitor AND sorted by date (as my code shows above) AND eliminating all posts earlier than todays date (as shown in the code above). Commented Nov 4, 2010 at 14:17
  • @NetConstuctor: I updated my answer with an example of pre_get_posts that will add your date filter on the pages you want.
    – Jan Fabry
    Commented Nov 4, 2010 at 15:23
  • @jan -- this worked perfectly but is there not a way to include that function within the actual template page so I don't have to input it into my functions file and possibly forget about it? Commented Nov 5, 2010 at 9:25
  • 1
    @NetConstuctor: You can do this in your template file, but then you "waste" one query, since WP::main() already calls query_posts() while setting up the page. But if you don't mind that, you can try placing it in the top of your template page, and calling $wp_query->get_posts() again. This should execute the normal page query (since we don't pass in new query parameters, the existing ones stay), and add yours.
    – Jan Fabry
    Commented Nov 5, 2010 at 11:31
  • @Jan... i just noticed an issue with this code. it seems like its effecting other post types. for example for my regular pages the second level down now don't show up. do you have a suggested fix? Commented Nov 5, 2010 at 14:40

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.