64x64 icon dark hosting
Choose a hosting plan here and get a free year's subscription to Tuts+ (worth $180).

Building a Dynamic Custom Post Type Plugin


Start a hosting plan from $3.92/mo and get a free year on Tuts+ (normally $180)

Often, you get to make a choice and decide how you will implement a certain functionality. WordpPress has a pretty flexible approach for almost any problem, and in this tutorial we are going to take a look at how flexible the custom post type API is.

There are many things you can do with custom post types, including generating and managing certain posts on some custom pages, slideshows, galleries, portfolio items even. Some people don't know they exist yet, others don't fully understand their options and how to use them. We are going to try, in the following steps, to build a specific plugin that uses custom post types at it's best. To be more exact, we are going to build a plugin that creates one custom post type, that creates and manages dynamically, other custom post types (it's like Inception in here!).

Step 1 The Plan

Before we even begin starting, we are going to take an in detail look at what we are going to build in this tutorial, how and why. The purpose of this tutorial is to help familiarize yourself with custom post types in WordPress.

To do this we are going to build a plugin that creates one main custom post type, then use the posts in that custom post type, with a settings meta box, to create additional, dynamic custom post types based on the meta box interface options. This will help you understand in detail all the custom post options and some of the possibilities it can give. For the purposes of this tutorial, it is implied that you have a working Apache server with PHP and MySQL running, and WordPress installed, so that you can test the plugin code on a 3.0+ version of WordPress.

Each post is going to be interpreted as a new custom post type and we are going to save the configuration options of each post in custom fields using a meta box with a lot of forms, checkboxes, dropdown boxes and textboxes that will store and show the data, making it easy for the user to modify anything.

Because the plugin has 450 lines of code, not every line of code will exist in the tutorial as most code is repeated and just the variables are different. But all of the functionality of the plugin will be explained and the source code given as an example.

Step 2 Creating and Understanding the Hooks

If we want to get to the custom post type functionality, the metabox functionality, and we want to save data on update or publish action, we need hooks, and we need to implement them specifically in order to get the desired effect.

We are only going to need three hooks in this tutorial, no filters, nothing else at the core functionality. First we need a hook to generate the custom post type in its callback function. For that we are going to use the init tag hook and the callback function by the name of 'init_custom_post_types'. This is where all the magic happens, namely this is where we declare our custom post types and where we make them dynamic by extracting the values from the database and generating dynamic custom post types in a loop. This part of the code will be discussed later on.

Another hook that we need is the 'add_meta_boxes' tag hook that points to the callback function 'cpt_add_meta_boxes' and is used to generate the meta boxes inside the main custom post type that generates all the other custom post types. This is where we create the forms that will store and update the data we need to manipulate to create our functionality.

The last hook we use is 'save_post' with the callback function of 'cpt_save_postdata' and the purpose of saving the meta box posted data. When the page of the main custom post type is submitted in the admin panel by the user, all the form fields are submitted and this is the hook that we use to grab that content and save/update it in the database for later use.

Step 3 Creating the Main Custom Post Type

First, we need to create a general custom post type that is going to handle all the dynamic content. To do this, first we create a generic custom post type using hard coded data like in the next example. First we create the labels. The labels parameter is one of the main argument values that is interpreted as an array. The array values are given by their identifiers, specifically name for the main general name of the custom post type that is usually a plural string of the custom post type name, singular_name for the custom post type object name in the singular, add_new the add new string text, add_new_item that is the default add new post/page text, edit_item as the default text for edit post or page, all_items is used for showing all the custom post type names text where requested (example: all cars), view_items and search_items are used just like the previous example just for the obviously different purposes, not_found, not_fount_in_trash, parent_item_colon are also replacement texts used for certain pages of the posts (custom post types) functionality that you might want to change for any custom post type that you create.

In the next example, the $labels array uses CPT in replacing the default post/posts/page/pages text. I guess it is not necessary for some readers but just to be sure I don't miss the idea, CPT stands for Custom Post Type and is and will be used in a number of ways during the tutorial.

An important note, this code is inserted into the init_custom_post_types callback function for it to work properly.

The main array needed for generating the custom post type is the $args array, used for the sole purpose of setting the main options of the custom post type and managing its functionality.

  • The first array variable is named labels and we previously took care of the structure of that value.
  • public – a boolean variable, true or false, that represents the availability of the custom post type, if it is public for the admin interface or by front-end users in the theme.
  • publicly_queryable – again a boolean value that sets if the front end has the capability of querying the results of the custom post type.
  • show_ui – a boolean stating if default admin content is generated for the custom post type or not.
  • show_in_menu – yet another boolean variable that requires show_ui to be true to function, as its purpose is to show or not to show the post type in the menu of the WordPress admin panel.
  • query_var – creates a query var key for this custom post type. You can use it as boolean or string, if it's true it's default, false disables query var key use and string sets a custom key. In our example we use the default value and set it to true.
  • rewrite – this prevents rewrites for this post type.
  • capability_type – at last, a string that sets if the custom post type is a post or a page, in a plain text string. We are using post.
  • has_archive – this parameter enables post archives and uses post_type by default as archive slug.
  • hierarchical – a boolean that sets if the post type is hierarchical or not, i.e. if it allows parents to be specified or not.
  • menu_position – a string representing the position for the post type to show in the menu. The values go approximately from 5 up until 100.
  • supports – this value has an array value again, this time with values like title, editor, thumbnail, custom-fields, trackbacks, revisions, page-attributes and post-formats.

The main args array is used in the next register_post_type function that has the first parameter the custom post type name (in our case CPT) and the second the $args variable.

This pretty much covers creating our main custom post type, with the example given and explained above.

Step 4 Coding the Meta Box

First, we covered hooks, one of the hooks implemented a tag that had a callback function made specifically for meta box implementation. That function looks like this:

Inside the function we have the add_meta_box function that has the default parameters for implementing a meta box, namely, the unique meta box id, the title of it, the callback function and the custom post type where it should be applied, also last but not least, the position (we are going to set it to normal as we want it right under the editor).

That's it for generating using the API, but what do we fill it with? Well, we need to fill it with all of the previously discussed options from step 3 and to do this, we are going to create form fields and fill them up with data depending on their type.

Some Will Be Checkboxes

We are using checkboxes for the array arguments that need boolean values. Checked is true and unchecked is false.

Others Will Be Drop Down Boxes

Some array arguments require multiple elements to choose from. For this we are using drop down boxes with hardcoded values that fit our needs.

And Others Text Fields

We are going to store string values in these form fields.

You may have noticed that they are filled with PHP variables and are functioning with data. But where are these variables coming from you may ask yourself, and what about the data? To answer this question we must go to the next step and save the form fields created just now. But because I don't want to make you go back and forward through the steps, I will ask you to assume that all the data is saved somehow in the database, I will show you how, and all we need to do is extract it into variables like in the following example:

In our meta box callback function we declare the global variable $post to get the current post id later and because the data is stored as a custom post, we are going to use the get_post_meta function to get the meta key value stored for each variable like the example above, where the first parameter is the post id, the second is the meta key and the third is a boolean telling the function to return a string and not an array.

There are a number of 27 variables used in this tutorial stored as custom posts and they look like this:

What you need to understand is that they are all extracted the same way, there's nothing special or different on this long list of variables except their values. Of course, the idea is that this code gets the data from the database and is used later on in each form field to show that data in the admin panel meta box as a selected value, as a string, or as a checked checkbox for boolean values. All the functionality can be seen better in the attached downloadable files.

As a result so far, this is how a custom post of the custom post type meta box content looks like based on our implementation.

Step 5 Saving the Data

All that form data submitted from the meta box needs to be saved into the database so that it may be used later to make the custom post type dynamic and also in the functionality of the meta box. To save the data we have the cpt_save_postdata function as a callback function that we created to do just that. But this function needs to be filled with functionality that actually saves the data. So, how do we save the data for all of these elements. The easy and most obvious answer is custom fields. We are going to store all these values in custom fields of the main custom post type individual post, as it is much easier to manage later when we extract them based on a certain queried post.

Here is all the code required to run in the previously specified function in order to save all the data we need.

First, we extract the variables like we previously did in the top of the meta box functionality, and then we update them using the update_post_meta function, that we give the parameters: post id, meta key name, new value, old value. Voila, we have updated the custom field of one value. We need to repeat the process as you see in the above example to cover all the values and all the options we need.

That's it for saving the data.

Step 6 Creating the Dynamic Custom Post Types

So how do we take all that data we just saved and make it dynamic? how do we use it to generate custom post types? Easy, we query the main custom post type, and for each loop post we extract the custom fields and place the data inside the array accordingly.

Let's take a look at how to do that. First, we place this code right under the main custom post type code, inside the init_custom_post_types function. And so, we start by creating the query:

We create a variable named $the_query in which we store the contents of the invoked main class function wp_query with the parameters of an array that has the value of the post_type the name of the main custom post type, namely, CPT. Then we start the loop. Inside the loop we generate the variables that we want to hold the values we need by using the same approach in extracting them from the database as custom fields:

Because we are now inside the query loop, we can use a global $post variable to get the ID we need. Also you might have noticed a few conditions set by an if here and there for most variables. These exist because the true boolean value or certain other string values need to be converted correctly from the "on" string they represent into the true boolean value they need to be.

After all of this is taken care of, we will insert the variables into the array of the dynamic custom post type implementation:

The post title is being used as the main name of the custom post type and the meta box settings as the rest of the properties. That is all, all that is needed to implement the dynamic custom post types into WordPress. What you might have noticed is that we also close the loop at the end of the previous code.


Custom post types are not hard to handle and they are pretty flexible in any functionality that you might require even with other hooks, filters or custom functions. In this tutorial we managed to cover a specific dynamic implementation of custom post type management in a single plugin, explained, with code and files, for your needs. Of course, the use of custom post type does not limit to these examples as it can be used in many types of implementations, plugins and themes tangled in many hooks, queried in different ways, filtered or manipulated in a lot of ways.