“pagination” (but not really) and queries using custom posts types

More of a conceptual question here, than a strict code question:

Working on a site for a musician who wants to list concerts, both upcoming and past. These are custom post types that use a custom field for the date of the show (formatted as yyyymmdd). For queries and sorting, the date of the show is the critical bit of data, as opposed to the publish date of the post, which is kind of irrelevant.

Here’s the page, which gives future and past shows for the current year: http://dev.bobpassaro.com/david/concerts/

The query to generate this (two queries and loops, actually):

<?php 
    //Query $args for upcoming concerts, ordered soonest to furthest in future
    $upcoming_args = array(
        'post_type' => 'concert',
        'meta_key' => 'date',
        'orderby' => 'meta_value_num',
        'order' => 'ASC',
        'posts_per_page' => -1,
        'meta_query' => array(
            array(
                'key' => 'date',
                'value' => date('Ymd'),
                'compare' => '>=',
            ),
        )
    );

    //Query $args for past concerts, ordered most recent to oldest
    $past_args = array(
        'post_type' => 'concert',
        'meta_key' => 'date',
        'orderby' => 'meta_value_num',
        'order' => 'DESC',
        'posts_per_page' => -1,
        'meta_query' => array(
            array(
                'key' => 'date',
                'value' => array(date('Y') . '0101',date('Ymd')),
                'compare' => 'BETWEEN',
            ),
        )
    );
?>

You’ll see also (at the bottom of that page) that I sort of “paginated” the older concerts, grouping them by year. (Regular WP pagination with custom post types is a pain, but it’s not what I want, anyway. I don’t want pages with equal numbers of concerts, I want pages with concerts grouped by year.) So what I’ve done is create another template with a similar query:

<?php 
    //Query $args for past concerts, grouped by year
    $concert_year = substr($post->post_name,0,4);
    $year_args = array(
        'post_type' => 'concert',
        'meta_key' => 'date',
        'orderby' => 'meta_value_num',
        'order' => 'DESC',
        'posts_per_page' => -1,
        'meta_query' => array(
            array(
                'key' => 'date',
                'value' => array($concert_year . '0101', $concert_year . '1231'),
                'compare' => 'BETWEEN',
            ),
        )
    );
?>

This is used in a custom template that I assign to pages that I set up for each year. (The content of these pages is actually empty, but the page slug gets used to set the $concert_year variable above, which then allows the query to pull the proper set of concerts.) I then use a regular WP menu at the bottom of these pages that includes all these pages and allows people to look back at shows performed in previous years.

This all functions as I want, but it’s a pretty kludgy solution. I mean, when we get to 2015, I’ll have to create a new page for 2014, otherwise 2014 concerts won’t be showing up anywhere. I’d like that to just happen dynamically. I also have all these essentially blank/empty pages (one for each past year), whose only function is to call the template and be used in the WP menu (that is, their only function is to allow users to select the url associated with each year and set $concert_year for use in the query.)

Thoughts on a better approach this problem?

2 Answers
2

This is a tough question because there are so many possible solutions. 😉

I think the easiest way is to create a custom taxonomy “year” and add it automatically to the CPT post on save using the save_post() hook and wp_set_object_terms().

You could then simply use get_terms() to get a list of years (you’ll only get ones that have concerts by default) and just link to the terms archive by using get_term_link(). You could still use the default CPT archive to show the concerts from the current year.

Leave a Comment