Creating A Customizable Post List Template in WordPress With Advanced Custom Fields

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.

Advanced Custom Fields
Advanced Custom Fields. Powerful stuff.

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.

Page attributes box with our template selected
Page attributes box with our template selected

Template Options

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_Query class 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:

Template options for our page
A small part of our options. Click the image to see how all the options look.

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.

Authors

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.

Categories

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.

Category Include/Exclude

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.

Featured Images

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 have_posts() and 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.

What Next?

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.