Creating A Customizable Post List Template in WordPress With Advanced Custom Fields
I’ve mentioned Advanced Custom Fields in previous articles before and thought it’s time to put my money where my mouth is and show you how it can be used to create great features with relative ease.
In this article we’ll use ACF to create a page template, which allows users to list posts based on category, status or any other criteria.
Let’s get started.
The Benefits of a Post List Page
Currently, WordPress doesn’t really allow you to list your posts on your own terms. There are category and date archives sure, but you can’t easily list your posts alphabetically or list the contents of a single category. What possible use would this be?
An alphabetical archive could be very helpful as a kind of directory for your posts. Probably not on the front page, but you could create an archive page for this. As for categories, think of a web developer who would like to post personal blog entries and coding related ones. Being able to list posts on a page by category would allow our coder friend to show his “Code” category on the front page and show the “Personal” category on a separate page.
What We’ll Need
On a very basic level we’ll need two things to make this happen. A custom page template and options on the admin side that allow users to control the content of the post list. A large part of this project would be taken up by the creation of the admin options. We would need select dropdowns, radios and text fields at least, not to mention the PHP to fill these with data.
To make things easier on us and more modular for our users, we’ll be using Advanced Custom Fields to create the options for us. Before we get started let’s try and map out what we want to allow our users to be able to do.
Creating a Page Template
This aspect of the tutorial is covered in-depth in the Creating WordPress Page Templates article. In a nutshell: you will need to create a file anywhere inside your theme. If you are using a third-party theme, I suggest creating a child theme and adding the template there. If you need to brush up on this stuff the linked article is a great resource.
In my example I will be extending Twenty Fourteen with this functionality so everyone can follow along. In my child theme I have added a file named
post-list.php. Inside this file I’ve copied the contents of Twenty Fourteen’s fullwidth template as a starting point. All I’ve modified is the template name at the top.
This will be fine for now, all we need is for this template to show up in ACF. If you haven’t already done so, make sure to activate your child theme.
We will be building a custom query for our template page using the
WP_Query class. I will take a look at the arguments we can use with this class and translate the most common ones into options. Let’s get started:
- Authors: Authors can be selected easily with ACF and they can be passed to the
WP_Queryclass pretty easily so why not? We’ll need to use the User field type and allow multiple authors to be selected.
- Categories: Using the Taxonomy field type we can let users select multiple categories. In this example we will not be handling tags or custom taxonomies. For best results we would need to use a taxonomy query which is a bit more difficult to assemble and would really need a repeater field which is a premium addon.
- Category Include/Exclude: By adding a Radio Button field we can
- Post Status: By creating a custom Checkbox section where users can set the status of posts they would like to show we can offer the opportunity of showing upcoming posts or drafts.
- Post Type: Another Checkbox section would allow users to set the post type to show. This would allow the listing of pages or any other custom post type
- Posts Per Page: This Number field would let the user choose how many posts to show. If we allow -1 we can ensure that users can list all posts on one page.
- Order By: A custom Select field gives uses the option to set the ordering of posts
- Order: A simple Radio Button field gives allows for the control of the order direction.
- Has Featured Image: This option would be a simple Radio Button. It would translation to a mets query which would restrict posts to ones with featured images if checked.
Sounds good. Let’s create these in ACF.
You have three choices at this point. If you’ve never used ACF before I suggest using the admin to create these options for yourself manually. This way you can learn how it all works.
If you don’t have time or you’re an ACF veteran. I have two options for you: XML export or the PHP code for the options. You can create these yourself by going to the “Export” section inside the “Custom Fields” menu.
Click here to download the XML export file. You can import this using the regular WordPress importer in the Tools section. If you would rather use the PHP code just include the code block below into your plugin or your theme’s functions file.
And here’s what it looks like on the front-end:
1.6 million WordPress Superheroes read and trust our blog. Join them and get daily posts delivered to your inbox - free!
Implementing Our Options
To implement our options we’ll use the
WP_Query class to create a custom query and a custom loop. The generalized form looks like this:
Let’s start filling this out by making it work in Twenty Fourteen. The arguments array for
WP_Query simply defines that we want to grab the post post type. This will result in the first 10 posts being returned. Now that we have some posts returned, let’s concentrate on displaying with them.
Looking at Twenty Fourteen’s index file we can see that methods for displaying posts, pagination and displaying “no posts found” text have already been implemented. Here’s the same code as above with these blanks filled in.
Feel free to use your own functions here or code your display logic right there if you’re just running a quick test. Let’s turn our attention to the meat of things – populating the list with the correct posts.
We can retrieve the selected authors using
get_field( 'authors' ). The returned value will be an empty array if no authors are selected. It will return an array of author data arrays if there are authors selected.
We can use the
author__in parameter passed to
WP_Query to pass our data. This parameter should be empty (if we can return posts from anyone) or an array of IDs if we want specific authors only. This means we’ll have to distill our author array to IDs.
This task is simplified by the fact that the user ID is always the first member of the sub-arrays. This way we can use
$authors = array_map('current', $authors); to “collapse” the
$author multidimensional array into a one dimensional list of users which we can pass to our query.
Our job is a lot easier with categories since that can be set to return just the IDs. We can pass the result straight to our query.
By amending our previous example we can make sure that we use the
category__in parameter when set to include and the
category__not_in parameter when set to exclude.
Other Simple Parameters
All other parameters used except the featured image option return their values in the same form that is accepted by the arguments of our query. Here’s an example where I’ve added the post status, post type, posts per page, order by and order parameters to the query.
To use this setting we’ll need to create a meta query. Meta queries allow us to list posts based on the value of post meta fields. The ID of a post’s featured image is stored in the post meta table with a key of
_thumbnail_id. If our users just want posts with featured images we’ll add a meta query which makes sure this value isn’t empty.
Putting It All Together
Let’s incorporate everything we’ve talked about above into a single code block. The following block of code is the whole page template. It includes the structure of the site, our custom query and the listing and pagination of posts.
Note that since we are creating a custom query and a custom loop we need to use the
the_post() functions as methods within the current instance. If this sounds difficult just remember to use
$postlist->have_posts() instead of
have_posts() and all will be well.
I think the power of ACF becomes apparent through this example and I hope you’ll start using it more and more in your projects. It allows us to create a familiar interface for users across options pages, post pages, category and even user pages.
Now that option creation and the admin interface is taken care of there really is no excuse for not implementing awesome features in your upcoming themes and plugins.
If you’ve made something great with ACF or you use a different options framework we would love to hear your thoughts and experiences in the comments below.