TL;DR > If you googled this from something like "how to program custom post types in WordPress", here's my solution for you.
Nearly every WordPress* website I'm asked to build involves creating at least one, and often several, custom post types.
WordPress started out as a blogging platform. Each entry in the system is a post as in, "blog post". So, when you want to use WordPress for other kinds of stuff -- recipes, books, court filings, real estate listings, products, Q&As -- you have to shoehorn those things into being some kind of post. Sometimes you can get away with just using a blog post and calling it good. But sometimes you need to be able to attach other kinds of information to items that aren't really posts. Products, for example, need to track price and stock count. And you probably don't want your products mixed into a blog format with other company news. So the WordPress solution for that is custom post types. Behind the scenes, everything is still a post in the database, but you can handle different post types on a customized basis.
Closely related to post types comes the necessity of custom taxonomies used to tag and categorize things.
Taxonomy is a fancy word for "how to categorize stuff". WordPress provides tags and categories for this. But, again, if you're trying to sell shoes, you probably want to be able to find things by size, color and style.
Custom post types and taxonomies are a common enough problem that you can easily find plugins to create them for you. I'm sure many of them are just fine if you're looking just to plug and play. Add the plugin, go to the post types settings page in your admin and play around. All that's fine.
But when you're paying someone to build you a custom web site you don't want to worry about it. And when you're building a website for someone, you don't want them to stumble across a custom post type settings page in their administration panel, and you don't want them to start messing with those settings and breaking their site.
So instead many developers (dare I say the best of us) create custom post types programmatically. We build them to order, to do what the client wants and to work without any settings page in the administration panel (or if we do have settings, they're the ones the client needs to be able to set for business reasons). We build them to the exact requirements of the project, so there is no extra code included for all-purpose cases slowing things down.
A few years ago I was learning to build these, working with a fantastic teacher, Tonya Mork. The rudiments of the method I use today are what I learned from her.
Over time I've rewritten that custom post type code more times than I care to admit. The goal from the beginning was to be able to re-use code from one project to the next. Each rewrite has been an attempt to balance the ability to re-use with the demand for making the code as lean and clean as possible.
Every developer will find that happy place between reusability and efficiency differently. A few weeks ago, I was working on a website for a home builder when I finally landed in my happy place, where I thought to myself, "This code is where I come down on the custom post types and taxonomies problem."
It's a root file, a configuration file, and three clean classes:
- a main Plugin class to interface with WordPress,
- a PostType class, and
- a Taxonomy class.
If you don't know what a class is, that's ok. The beauty of it is that each class is a "black box" that does the single thing you need it to do without any "side effects" anywhere else in the program.
From one project to the next, the particulars for each post type and taxonomy can be laid out in the configuration file, and the plugin does the rest, all without the client worrying about (or tampering with) any settings.
I've posted the code on Github for any developers who may stumble across this. And, if you should happen to find it useful, or see anything by way of suggestion, pull requests are welcome.
* Until mid-2018, I was a WordPress enthusiast. I don't recommend building most websites with WordPress any more. But because it has such a large market share in the web business, working on WordPress projects is hard to avoid.