One of the WordPress features that enables powerful customization of the system are custom post types. Let’s see what are they and how to implement them.
What Are Custom Post Types?
In object-oriented programming, each entity in the real system is represented by a corresponding class. For example, a product or an order would be represented as PHP classes. In WordPress, product and order would be created as post types. In other words, a post type is a custom data structure that allows you to apply any logic specifically to that post type. You will see how it works in practice shortly.
How to Create a Custom Post Type?
A custom post type can be created in two ways: using a plugin that handles all the work under the hood or directly in the theme. The latter provides more control over customization and allows you to keep the post type configuration consistent between the environments. So, let’s see how to create a custom post type directly inside the theme.
Each post type must have its unique name in the system. You can name it anything, as long as it does not interfere with the built-in post types:
- post
- page
- attachment
- revision
- nav_menu_item
- custom_css
- customize_changeset
or functions:
- action
- author
- order
- theme
Also, it is a good practice to prefix the name to avoid potential conflict with any installed plugins. Having these in mind, you will create a PHP file in the following location: wp-content/themes/mytheme/post-types/mys_portfolio.php, where mys_portfolio is the name of your custom post type (mys_ is the prefix and can be anything you want).
First, you will hook a PHP function to the WordPress init action:
<?php
add_action('init', 'mys_register_portfolio');
function mys_register_portfolio() {
}
This means that mys_register_portfolio function will be executed during the initialization of the WordPress CMS. Inside that function, you will call the WordPress’ built-in function register_post_type:
<?php
add_action('init', 'mys_register_portfolio');
function mys_register_portfolio() {
$args = array();
register_post_type('mys_portfolio', $args);
}
After that, add the following line at the beginning of the functions.php:
require_once __DIR__ . '/post-types/mys_portfolio.php';
The code from above has created a custom post type called mys_portfolio with the default configuration. Fortunately, the configuration can be customized:
<?php
add_action('init', 'mys_register_portfolio');
function mys_register_portfolio() {
register_post_type('mys_portfolio', array(
'labels' => array(
'name' => __('Portfolios', 'exp'),
'singular_name' => __('Portfolio', 'exp'),
'add_new_item' => 'Add New Portfolio',
'new_item' => 'New Portfolio',
'view_item' => 'View Portfolio',
'search_item' => 'Search Portfolio'
),
'has_archive' => true,
'show_in_menu' => true,
'show_in_nav_menus' => true,
'menu_position' => 20,
'supports' => array(
'title',
'editor',
'author',
'thumbnail',
'excerpt',
'trackbacks',
'comments',
'revisions',
'page-attributes',
'post-formats'
),
'rewrite' => array(
'slug' => 'portfolio'
),
'hierarchical' => true,
'taxonomies' => array()
));
}
Note that the register_post_type options listed above are the most important ones. For the full list, check the documentation.
Querying Custom Post Types
The default template file for showing the list of posts is archive.php, while the default file that shows a single post is called single.php. These files can be overridden to be specific to the custom post type. If you create a file called archive-mys_portfolio.php, it will be loaded when a user tries to open the list of posts for that post type. Similarly, if a file called single-mys_portfolio.php has been created, it will be loaded when a user tries to open a single post that belongs to that custom post type.
It is also possible to get custom post type posts anywhere in the theme using WP_Query:
<?php
$args = [
'posts_per_page' => 3,
'post_type' => 'mys_portfolio',
'post_status' => 'publish',
'orderby' => 'date',
'order' => 'DESC'
];
$article_query = new WP_Query($args);
if($article_query->have_posts()) {
while($article_query->have_posts()) {
$article_query->the_post();
}
}
?>
Conclusion
Custom post types make WordPress suitable for creating any type of Web site. Apart from a blog, you can create personal portfolios, corporate presentations, e-commerce sites and much more.