loading

Using custom post types for WordPress

[Fun with code is a multi-part series. Read the rest.]

[You're reading part 1 (of 3). Read part 2. Read part 3.]

Over the past few years, I’ve written quite a bit of code and I’ve had a lot of fun doing it. I’ve got tons of useful snippets in my back pocket and I’m just itching to share them with the world. I’m going to take this opportunity to start a new series here on the Oxide blog, Fun with code. To get things started, let’s outline a problem and uncover a situation which creative code can solve.

The set-up

Oxide was approached by the Great Plains Motion Picture Co. to do the development of their new website (launching later this month). For the project we’re using WordPress, a popular platform for creating all types of websites. GPMP’s site has a focus on directors and editors, and the videos they’re each involved with. I could have just made these three different categories under Posts, but that felt cumbersome, and it would have taken a lot of weird code to be able to associate a director with a video if they are all filed under the same post type. I like the ability to categorize a post and to use that categorization to organize the content when it is presented on the front end, but this situation needed a better solution than the default functionality that WordPress offers.

By using custom post types, I am able to extend the functionality of WordPress, allowing Editors, Directors, and Videos to have their own space in the WordPress back-end, instead of being awkwardly mixed together under Posts. Now when their site administrator wants to manage, edit, or add new information on the site, it is presented in a specific way, directly on the interface, meaning they can get to what they want quicker and easier, without having to find a way through an interface that wasn’t built for their specific purpose.

Step one: create the custom post types

To begin Fun with code, I’m going to set-up a multi-part series on custom post types and taxonomies, and then focus on a couple awesome functions that I spent quite a bit of time putting together and fine-tuning in order to extend the use of custom post types and taxonomies within WordPress. Ultimately, the posts from this series will give a glimpse into what I do to give our clients a much more automated, easier to understand, and overall better experience when it comes to managing the content on their sites.

In this series, I’ll be explaining some of the things that I think are pretty useful when it comes to developing for the web. I’ll also be pulling my custom hand-written functions apart piece by piece and explaining them, hopefully teaching a little bit along the way. My goal is to make these often complex ideas digestible for just about anybody, using relatively plain language to teach and explain what exactly all this code is actually doing.

Fun begins now

Be warned, while I am going to really try to keep things as easy to understand as possible, these posts will contain some pretty technical stuff, and may not be for everyone. That said, I like to think that if anybody has the desire to learn about developing for the web, using these tutorials would be a great place to accomplish that.

Let’s say that you’ve got a need for a custom taxonomy (categories) on your posts which allows you to associate that post with another type of post somewhere else on the site. To simplify my case, I had biographies of individuals which needed to be associated with a product they had created or were involved with.

So the first thing we need are a couple of WordPress custom post types and custom taxonomies. I like to set these up via the theme’s functions.php file so I can have full control. In the first part of this series, I’m going to talk about setting up the post types.

<?php
function custom_register_post_types() {
	$labels = array(
		'name' => _x('People', 'post type general name'),
		'singular_name' => _x('Person', 'post type singular name'),
		'add_new' => __('Add New'),
		'add_new_item' => __('Add New Person'),
		'edit_item' => __('Edit Person'),
		'new_item' => __('New Person'),
		'view_item' => __('View Person'),
		'search_items' => __('Search People'),
		'not_found' =>  __('No People found'),
		'not_found_in_trash' => __('No People found in Trash'), 
		'menu_name' => 'People'
	);
	$rewrite = array(
		'slug' => 'people'
	);
	$supports = array('title','editor','excerpt','thumbnail');
	$args = array(
		'labels' => $labels,
		'public' => true,
		'show_in_menu' => true, 
		'query_var' => 'people',
		'rewrite' => $rewrite,
		'has_archive' => true, 
		'hierarchical' => false,
		'supports' => $supports
	); 
	register_post_type('people',$args);
	$labels = array(
		'name' => _x('Products', 'post type general name'),
		'singular_name' => _x('Product', 'post type singular name'),
		'add_new' => __('Add New'),
		'add_new_item' => __('Add New Product'),
		'edit_item' => __('Edit Product'),
		'new_item' => __('New Product'),
		'view_item' => __('View Product'),
		'search_items' => __('Search Products'),
		'not_found' =>  __('No Products found'),
		'not_found_in_trash' => __('No Products found in Trash'), 
		'menu_name' => 'Products'
	);
	$rewrite = array(
		'slug' => 'product'
	);
	$supports = array('title','editor','thumbnail');
	$args = array(
		'labels' => $labels,
		'public' => true,
		'show_in_menu' => true, 
		'query_var' => 'product',
		'rewrite' => $rewrite,
		'has_archive' => true, 
		'hierarchical' => false,
		'supports' => $supports
	); 
	register_post_type('product',$args);
}
add_action('init', 'custom_register_post_types', 0);
?>

Alright, let’s talk about what just happened here
First, notice I’ve started and ended the block with<?php ?>, this is just a PHP wrapper which tells the file that everything we are putting inside is PHP code. This allows you to write forward faching HTML outside of the tag, and server side PHP inside of the tag. Line 2 begins the definition of the function. First we tell the file we want to start defining the function by writing:

<?php
function custom_register_post_types() {
	//code here
}
?>

The word function, followed by a unique name, immediately followed by a set of parenthesis. The parenthesis at the end of the function name is actually a space which allows us to set default variables and pass existing variables through the function, it is for more advanced functions and we will not be using it with ours at this point, so leave it empty. We then begin the actual working code for the function inside a set of curly braces { }. The reason we wrap all of this into a function is so we can call and run the function when we need it.

The next thing you need to know is that most of this block of code is just setting up variables. In PHP, a variable is set by supplying it with a name, and defining the data it contains. We signify and call variables by using the dollar-sign $ before their indentifier. The variables I am setting are a set of nested associative arrays. An array is just a stack of data which is indexed in some way. The index is the pointers by which we can access the data in the array. With associative arrays, we set the index of the data ourselves, and for the sake of this function, the required pointers are supplied to us by the requirements of the WordPress function which sets up a custom post type.

Inside of this function, I’m actually setting up variables and running the register_post_type($post_type, $args) function twice to create two different post types. In order to register a custom post type in WordPress, we need to supply this function with all of the proper information. The first variable requried is simply a unique name for the post type. Just give it something code-friendly (no spaces or weird charcters) inside of some quotes. This is known as a string. The next one we need to supply is the array of post type arguments. Most of the values in the argument arrays are just Strings (single lines of text) or Boolean values (true or false), but some of them need to be supplied with other arrays. I like to keep all of these arrays separate, which is why I set up $labels, $rewrite, and $supports before creating the $args array. I find that doing it this way makes it easier to find and edit things when needed, or when re-using the code on a new project.

The arrays

Understanding and building an array is actually pretty simple. It is basically just a comma separated list of values inside of array();. The most simple arrays used in the block above occur on lines 19 and 47, they are not associative arrays. As you can see, we’re just providing values inside of quotes with commas in between. For the other arrays, we are actually giving a specific pointer to each piece of data. If we aren’t supplying those pointers, they are numbered in order, starting with 0. Meaning line 19 would actually mean the exact same thing if it were written as an associative array in this fashion:

<?php
$supports = array(0 => 'title', 1 => 'editor', 2 => 'excerpt', 3 => 'thumbnail');
?>

With that in mind, we can see and understand how the rest of the associative arrays are built. First with the pointer, followed by the value, followed by a comma. For the $args array, we use the other four arrays as values for their respective pointers, and finally pass the whole thing into register_post_type($post_type, $args).

Run with it

Finally, we close the function, and use another function on line 60 to connect this function to a hook provided by WordPress. This basically tells WordPress to run our function at the appropriate time in order to properly create the post types.

<?php
add_action('custom_register_post_types', 'init', 0);
?>

First, provide the name of the function we just created in quotes, then for setting up post types, we’ll use the ‘init’ hook, and finally a number for the priority. For our purposes, we would like this function to run first, so use 0.

In a language I understand, please

To summarize all that we’ve done here, I’ll read it out in plain English. We defined a function which allows us to set up variables and run more functions. We set three arrays with the appropriate pointers and values and used those arrays to help build a fourth array. We then ask another function to use that fourth array to build a WordPress post type which we have named. We then do that a second time with new values, asking the same function to build a second post type with another name. We then ask WordPress to run our container function along with it’s own default functions at the appropriate time.

Now we have our own post types to play with. I’ll be rolling out the custom taxonomies for the next installment of Fun with code.

22 Sep 2019

‘Enter’ to submit

SVG is a thing now; you should use it.

With all this talk about resolution independence and responsive design, how many times have you built something for the internet and thought, hey, it sure would be nice if I could have a vector graphic here instead of a series of pre-saved bulky images switching in and out some way or another? For example: every single logo ever, social media buttons, line art of any type. If your concern is responsiveness and you’re using images, then you’re in for trouble.…

The multiply effect is a lie

This year’s fabulous Big Omaha website is showcasing a little visual trick. Early on, when Nathan and I were discussing the intended visuals on the site, I failed to notice he was using the multiply effect in Photoshop to achieve the appearance of the red overlays – and he went forward working that into the design. To my dismay, when I went to add the red layers by simply overlaying a slightly transparent layer of red over the top of…

Fun with code at Meet The Pros

Last week I spoke at Meet The Pros and, not surprisingly, my presentation was titled Fun with code. When I had volunteered to speak way back when, I envisioned myself talking about a bunch of code stuff and making it really interesting and fun. If you’re a regular reader of the Fun with code series here, you probably don’t remember any of it being terribly interesting or fun. It may be really helpful and useful, but it’s certainly too specialized…

Detecting a retina display

A few weeks ago, we announced that oxidedesign.com was fully retina optimized. For those of you who do not know, a retina display is a monitor or device that has more pixels per inch of space than a normal display. This basically means it is harder to tell where the edges of pixels are, allowing for an extremely crisp and clean appearance. This works great on the web for things like text, but a problem arises when displaying images. Since…

Access Restriction for Live Staging Sites

We have a lot of active, ongoing projects here at Oxide, especially when it comes to the web. In order to build and make changes to sites which can still be viewable for internal or client review, we run live staging versions of them on subdomains of oxidedesign.com. Don’t bother digging around looking for a secret gem though, because you can’t get in. At least, not anymore.

Extend post types with custom taxonomies

For part two of this series, I want to show how I extended the default functionality of WordPress custom post types and taxonomies in order to build a user-friendly way to associate posts from one type to another. To recap, in part one, we set up a couple of custom post types. To start this tutorial we’ll be using a very similar function to set up the taxonomy which we will leverage for post-to-post association.