February 3, 2020
12min Read
Liam C.
Do you want to create a WordPress custom post type? It’s an excellent and useful way to organize your website if you’re running several types of content all at once.
In this tutorial, you will learn how to make a WordPress custom post type by building a site-specific plugin.
WordPress provides a few default post types, such as Post, Page, Revision, and Attachment. On a small scale, they will represent your blog topic just fine. However, they might not be sufficient after your content becomes more diverse.
That’s where the WordPress custom post type comes into play. In short, it is an additional post type that you create based on your needs. With it, you’ll be able to group your posts more specifically.
Creating a custom post type in WordPress is more efficient than assigning categories to your posts. That’s because categorizing articles places them on the same list, commonly in the Post section. The problem is, if you have more than one broad topic, it will be difficult for you to keep track of them.
On the other hand, it lets you choose a more suitable section for your post right from the start. This should help you classify your content better and more seamlessly.
WordPress custom post type has its own menu in the WordPress admin area, which leads to a list of posts of that particular type.
In the example above, if a user goes to the Custom Articles database section of your site, the posts from Post, or Page will not be included. That’s because they belong to their own types.
Not only that, you can help readers narrow down their searches further by grouping posts on your Custom Articles into different categories, like Review, Tutorial, etc. Such a great convenience for your visitors, right?
When creating a new post type, you have several customization options. You can choose where the menu appears in the admin area, whether that type of post is included in search results, whether it supports excerpts, whether comments are allowed, and so on.
What’s great is that you can also change various pieces of text, such as renaming Add New Post as Add New Custom Article, replace the Featured Image text with Add Poster, and the list goes on.
Moreover, WordPress custom post type allows you to enable the custom field feature in the post editor. Thanks to this, it’s possible to provide more details about your content.
Take a look at our Custom Articles post type example. Besides having the article as its main content, you have the option to add custom fields for information like Author, Reading Time, and so on.
However, any custom fields you create are available on all post types. Therefore, a plugin is required to limit a specific field to only appear for a certain post type. We will explain how to do this later on, so keep on reading.
To begin, let’s learn how to write a new function that calls the register_post_type() function. It should come with two parameters:
IMPORTANT: Remember that the functions must be hooked to the init action hook. Otherwise, your WordPress custom post type will not register correctly.
Lastly, all custom functions should be prefixed to avoid conflicts with other plugins or theme functions. To make them unique, we’ll be using Hostinger Tutorials initials for this example – ht.
The initial code to add a new custom post type should look like this:
// The custom function MUST be hooked to the init action hook add_action( 'init', 'ht_custom_post_custom_article' ); // A custom function that calls register_post_type function ht_custom_post_custom_article() { // Set various pieces of text, $labels is used inside the $args array $labels = array( 'name' => _x( 'Custom Articles', 'post type general name' ), 'singular_name' => _x( 'Custom Article', 'post type singular name' ), ... ); // Set various pieces of information about the post type $args = array( 'labels' => $labels, 'description' => 'My custom post type', 'public' => true, ... ); // Register the post type with all the information contained in the $arguments array register_post_type( 'article', $args ); }
Since the $args and $labels are both arrays, it’s better to write the $labels variable first and then the $args variable. Once that is done, you can register the code.
Now, we are going to discuss $args and $labels arrays that we will use to customize the WordPress custom post type.
$args is short for argument and this variable is used to contain arrays. Array, on the other hand, is a data structure that stores elements (key and value pairs) of an object (WordPress custom post type).
There are many arrays in $args, but we’re going to list only the most commonly used. Keep in mind, however, that they are all optional.
The first array in the $args variable is $labels. What’s unique, is that it’s made to contain other arrays. Therefore, it is crucial to create a variable named $labels to hold all the key and value pairs in a separate section. This reduces the risk of writing incorrect code and to make the function somewhat more cleaner.
Below are some of the most important keys for the $labels array:
You can take a look at the full list of $args and $labels arguments on the WordPress Codex page for register_post_type().
One of the keys in the $args array is supports. This is a simple array where you write the list of post editor features you want to enable for your WordPress custom post type. By default, only title and editor are enabled.
However, you can also write FALSE instead of an array. By doing this, you will disable all post-editing features including the title and content area. That way posts can’t be edited but they are still fully visible.
Here is the list of post editor features you can enable in the supports array:
To create a WordPress custom type, you can either build a site-specific plugin, download a normal plugin, or edit your functions.php file.
The third method is not recommended because your custom post type data might be overwritten after theme update. The second method is also not reliable since your data will disappear once you deactivate the tool.
Therefore, we are going to proceed with the first option – building a site-specific plugin. Basically, it’s a custom tool that you can build by yourself for specific tasks.
What’s great about it is that you can keep the data even if you decide to update your theme or deactivate the plugin. It’s also highly customizable.
However, this method can get a bit technical. That’s why, to help you get started, we encourage you to read our tutorial on how to create a WordPress plugin, as well.
Now that we know what elements are required for the function, we can build our plugin, write the custom functions, and hook them to the init action hook.
This is how a finished WordPress custom post type should look like:
<?php /* Plugin Name: My Custom Post Types Description: Add post types for custom articles Author: Hostinger Dev */ // Hook <strong>lc_custom_post_custom_article()</strong> to the init action hook add_action( 'init', 'ht_custom_post_custom_article' ); // The custom function to register a custom article post type function ht_custom_post_custom_article() { // Set the labels, this variable is used in the $args array $labels = array( 'name' => __( 'Custom Articles' ), 'singular_name' => __( 'Custom Article' ), 'add_new' => __( 'Add New Custom Article' ), 'add_new_item' => __( 'Add New Custom Article' ), 'edit_item' => __( 'Edit Custom Article' ), 'new_item' => __( 'New Custom Article' ), 'all_items' => __( 'All Custom Articles' ), 'view_item' => __( 'View Custom Article' ), 'search_items' => __( 'Search Custom Article' ), 'featured_image' => 'Poster', 'set_featured_image' => 'Add Poster' ); // The arguments for our post type, to be entered as parameter 2 of register_post_type() $args = array( 'labels' => $labels, 'description' => 'Holds our custom article post specific data', 'public' => true, 'menu_position' => 5, 'supports' => array( 'title', 'editor', 'thumbnail', 'excerpt', 'comments', 'custom-fields' ), 'has_archive' => true, 'show_in_admin_bar' => true, 'show_in_nav_menus' => true, 'query_var' => true, ); // Call the actual WordPress function // Parameter 1 is a name for the post type // Parameter 2 is the $args array register_post_type( 'article', $args); }
Now, to turn this code into a plugin, follow the steps below:
Congratulations, you have just installed a site-specific plugin to create a WordPress custom post type!
To begin customizing your new post types, you just have to upload two corresponding template files to your theme’s main directory. Names of these template files should look like this:
The {post-type} part of the file names must be the name from parameter 1 of register_post_type(). In this example, the file names should be single-article.php and archive-article.php
If you don’t create templates, WordPress will use single.php and archive.php instead, which keeps all your posts and archives identical.
That being said, the best way to start is to duplicate single.php or archive.php and rename them as above. That way the overall structure is identical to the rest of your theme and all required template tags are already in place. Thus, it will be easier for you to style the template later.
Here’s how to upload your template files:
Once the template files have been uploaded, it’s time to display the WordPress custom post types on the front page.
Custom post types are not displayed on the front page by default. That’s why you have to write a new function that calls the set method of WordPress’ WP_Query object. Let’s take a look at the code structure first:
// Hook our custom function to the pre_get_posts action hook add_action( 'pre_get_posts', 'add_article_to_frontpage' ); // Alter the main query function add_article_to_frontpage( $query ) { if ( is_home() && $query->is_main_query() ) { $query->set( 'post_type', array( 'post', 'article' ) ); } return $query; }
In this function, $query->set() takes two parameters:
The first one is the property you want to change. In our case, we want to change the post_type.
The second parameter is the array that you want as the value of the post_type property (post and article).
As you can see, the array starts with ‘post’. This is because it is the default post type in WordPress and we still want to include it on the front page. If you only want to display custom posts on the front page, you can remove it.
In this example, we’ll add ‘article’ to the array, meaning that the front page will show all regular posts and all custom article posts.
Now, to achieve this, you can paste the code to your theme functions file (functions.php) or to the site-specific plugin that you have created. Again, to prevent any data loss, we’ll be using the second option.
You can visit your website now. All posts from the default and custom post types should be available on the front page.
Once you have created a new WordPress custom post type, you might want to add a custom field so you can provide more details about your content.
There are two ways to do this – using the standard WordPress custom field or a plugin and each has its own advantages and disadvantages. We’ll begin with the default one.
WordPress provides us with a built-in tool to add a custom field. What’s great, it is pretty easy to use.
Unfortunately, custom fields won’t show up by default on the front-end of your page. To make them visible, you need to insert the_meta() or echo get_post_meta() function to the theme file that’s responsible for displaying your posts.
Now that we have two post types, we can either edit single.php or single-article.php. It depends on where you want the custom field to be.
Let’s say we want to add an Author custom field for the custom articles posts. We’ll need to enter the code in single-article.php. Here are the steps:
get_template_part( 'template-parts/post/content', get_post_format() );
If you visit your website, you will see the Author custom field below the post.
While it is simple to use, adding custom fields directly from WordPress is not necessarily the best option. That’s because once you’ve added a custom field, it will be available for all types of posts. This can make it difficult to find the field you need for a specific post type.
Therefore, you might want to try the Advanced Custom Fields plugin. It limits certain custom fields so that they are only selectable on a chosen post type. This is how you use the tool:
NOTE: After this plugin is enabled, you will no longer see the default WordPress custom field on your post editor.
Since this field is created via a plugin, you must use that plugin’s functions to display it. These steps to insert the function are similar to the default WordPress custom field. The only difference is that you have to enter the_post( ‘key’ ); code instead.
WordPress custom post type is the perfect solution to organize your website, especially if it focuses on more than one subject. You will have the power to divide your content based on the information that they contain.
With a little bit of WordPress and PHP skills, you can easily follow all the steps yourself.
Good luck and be sure to leave a comment below if you have any questions!
September 23 2020
I was stuck on this item. Up till now! Great tutorial very clear. Thanks!
Tomislav T.
Replied on November 18 2020
Happy to help, Peter.