If you haven’t already, feel free to read the first post in the Super Custom WP series that introduces the topic and explores the concepts behind posts in more detail.
One of the ways to take advantage of WordPress as a real infrastructure is through the use of Custom Post Types. Custom post types allow us to take advantage of all of the functionality wrapped up in the core WordPress experience. If you’ve ever used a contact form plugin or e-commerce solution, you’ve used a custom post type. Even default WordPress options like Pages and Media are built on the same custom post type engine. If there’s the ability to ‘Add New X’ on the site, it’s really just a custom post type.
See WordPress docs on Custom Post Types.
As you begin to deal with larger clients who have more involved datasets, you’ll start looking for new ways to store that data. One of the benefits of using Custom Post Types is that the default is simple, but as extensible as needed. In fact, by the end of this series, we’ll be taking our simple custom post type and adding the endpoints into the sites API.
Not sure what an API really is? Just think of it as an extremely simple and universal way to access the website’s data, especially outside of the scope of the website itself. Think your client might want an app? Or perhaps just a special private page to display their mountains of data more cohesively? By sharing all of your data through an API, you can update once and see results everywhere. Your custom post type can be the gateway to data management that make your clients sing.
Ontological Quandary – Where do custom post types belong- in a theme or a plugin?
There is no firm answer to this question, and a lot of differing opinions. Generally, we like to think of plugins altering ‘functionality’ and themes altering ‘style’. This dichotomy starts to break down when we’re making custom themes that bring unique functionality to our clients, or we’re making a plugin that needs to include some opinions on how it’s own elements are ‘styled’.
For me, I like to bundle all functionality into the theme. I might make plugins for a client if they come back for new features, but generally I like to keep everything in one place. I don’t expect my clients to change their theme, because the theme is a large part of what they paid for. If they plan on changing their theme out, custom post types are the first things that can go wrong, whether they’re actually coded into the theme or not.
However, if the post type can be displayed using the basic
single.php template of a default WordPress theme, or if your custom post type will never actually be seen on the front end, then I’d recommend creating a separate plugin. Or if you’re not even using a custom theme. This will help your users maintain access to the data if the theme gets changed/updated.
Otherwise, I find it easier to just declare everything in the theme. Another aspect of this is that adding custom template files (the way your new posts are displayed on the front-end of the site) is not as easy in plugin develop. You generally end up creating a lot shortcodes or using other, less simple methods.
Assuming you’ve decided to include your custom post types into your theme (and all future meta we’ll be incorporating later on), I definitely recommend taking a moment to think about folder structure.
Keeping our Functions.php File Sane
Even the most basic of themes will take advantage of the
functions.php file. What starts as this convenient doorway to core functionality becomes a cluttered mess.
We’ll start by creating a subfolder in your theme and naming it
/inc (abbreviated for
/includes). Now we can save each separate file in that folder and have our
functions.php manually collect them.
There’s no right way to organize your functions, but there’s definitely a wrong way, which is just pasting everything to the bottom as you write it (we’ll call this ‘Coincidentally Chronological’).
For the most part, you’ll probably end up organizing one of two way: categorically by post type, systematically by function. Imagine that for each custom post type you make, you’ll have about three or four functions:
- A function to register (create) the post type
- A function to create a series of meta information fields (the topic of part 2)
- A function to register our meta with the WP REST API (the topic of part 3)
In order to organize by function, I’d create a file that registers all my custom post types, another file that defines all my metaboxes, and a third file that handles all my rest API activities:
Alternatively, we can organize by post type and include all the functions that pertain to a particular post type in one file:
Again, there is no right way to do any of this, just a lot of opinions. Organizing by function (example 1) would probably result in less code overall, because you can generally bundle similar actions within one function. However, the difference would be negligible, so I would recommend organizing by whatever feels right and whatever can give you the most speed and peace of mind while developing.
require_once() function to include these files in your
Part 1 Overview on Data Organization
It might feel strange to discuss organizing files that we haven’t even explained yet, but I think it’s helpful to start with at least a few clear conceptual boxes in which to place our code. It’s easy to throw everything at the bottom of
functions.php, but it becomes overwhelming as time goes on. For the sake of this tutorial, I’ll be a little opinionated, but it doesn’t mean that my methods are right for you and your current project.
In this post, we discussed:
- What our overall goals for the series are – advanced data organization and features for our custom WordPress themes
- Whether we should develop in the plugin or the theme – I generally end up throwing everything in the theme, but there are a lot of different opinions out there
- How to keep our functions.php file sane – by creating separate files for different functions OR different post types
Stay tuned for Part 2 – Custom Post Type Basics, when we’ll take a look at the nitty-gritty of the
register_post_type() function as well as some different ways to display that data on the front-end of the site, from template files to custom queries and shortcodes.