Whenever you’re working with archive templates in WordPress, posts are typically listed by date in descending order. That is, the most recent posts are listed at the top, and then it goes from there.
Lately, I’ve been working on a few projects that integrate with third-party APIs. These APIs return dates – sometimes two dates, a start date, and an end date – for a given event and customers want to use that information to list posts rather than the date of the post. That is, they want custom archive templates.
It’s not too hard to do this, but before doing so, I think it’s important to give some background information on how the project is built so there’s a bit more context around why, say, a custom query is needed and why you may or may not need to look into pre_get_posts.
I’ll start with a TL;DR first, though. That way, you can get the idea before reading the whole thing.
Custom Archive Templates
So the TL;DR behind the whole thing is this:
- the date information as provided by the third-party API is kept in the post meta data table,
- the key is the start date, and the value is the actual date,
- I order the content in descending order and by the meta value.
Pagination can be a bit of an issue, and if you use a custom post type, then you’ll need some extra parameters, but there’s the general idea.
Now for the whole set up.
Custom Post Types
When it comes to interfacing with third-party APIs, I’m a big fan of custom post types because I tend to think of them as a hybrid between models and views.
- The model component includes anything that’s tangentially related and can be written to the database. This means any taxonomy information or post meta data.
- The view component is generally anything that goes into the template that can leverage any pre-existing template tags are anything that may need to be created that also reads information from the database.
For this post, I’m going to use acme-event as the custom post type.
Post Meta Data
I set the dates in the post meta data rather than on the post itself because if something is going to happen in the future and the data is set on the post record itself, then WordPress will treat it as a scheduled post which is un-published.
Instead, I’d rather have the post published and then change the way meta data is displayed in the template.
WordPress makes a subtle distinction with pagination in its code base. That is, the query variable for sites without a static home page uses paged and the opposite case uses page.
This matters when you’re constructing the arguments for the query which I’ll get to momentarily.
Archive Pages Only
Remember that whenever you’re introducing pagination, you only want to change the query whenever you’re on the actual archive page.
This means you don’t care about cases when you’re in the administrative area of WordPress and you don’t want to alter the query for non-custom-post-type archives. To that end, you’ll want to make sure that you’re setting the query variable properly in the pre_get_posts callback.
Note that I can show a function for how to do this, but because of how we write code in WordPress – that is, some write procedural code, others write object-oriented code – I’ll simply display it in procedural code.
Bringing It All Together
First, I’ll build the query:
Note that in the code above there is an argument for paged. I’ll talk about the code for this momentarily.
Then the template will include whatever information you opt to display. I’m choosing not to share the code for my template in this post because it’s irrelevant to the greater idea at hand.
Plus, you have everything you need to display the content.
Next, I’ll set pagination. First, I need to do this using the pre_get_posts hook to make sure the proper query variable is set:
Then I’ll implement the pagination using the custom query:
And after that, I’ll reset the global $post variable using wp_reset_postdata() just in case any thing from the original post needs to be used.
This is generally considered good housekeeping whenever you use a custom query, anyway.
Below is a list of functions, pages, and references that you may find useful as it relates to the code above or any future work you may do.
- The full code in this post.
If you’ve been working with WordPress for a long time, some of these may seem redundant. In other cases, it may seem new, or it may shed light on areas of the WordPress APIs that you didn’t know exist (at least that was the case for me).
Why Bother With All Of This?
This may come off as a long post for a seemingly simple task, but the information is a bit scattered all over the web as it relates to doing something like this.
So I wanted to try to bring it all together with explanations, example code, and links to pages that may be of interest depending on how the implementation is done.
After all, many of us are using WordPress beyond basic content management at this point, but that doesn’t mean we shouldn’t leverage it’s built-in functions and APIs when possible.