Thursday, January 26, 2017

How to create own Custom Post Type in wordpress

Mostly people think that WordPress  is yet another blogging platform, but they don’t know that WordPress as evolved and, is being used for pretty much everything we can expect,  that includes as e-commerce platform, online marketplace, blogging, corporate websites, real estate portals, forums, SAAS dashboard etc.,

One of the biggest reason of this success is the custom post types feature provided by the WordPress.  In WordPress everything is a post, including every page and blog post. WordPress by default supports only few post types. However we can create as many custom post types as we want in the WordPress. In this article

we will show how can you create a custom post type in WordPress from scratch.


What is a Custom-post Type in WordPress?

Custom post types are the user defined post types that do not come bundled with the default WordPress installations.
The user has to add this post type by either custom developed WordPress theme or a custom made plug in to enhance the functionality of the WordPress blog beyond the normal. By default WordPress comes with the following post types
  1.     Post
  2.     Page
  3.     Nav Menu
  4.     Attachment
  5.     Revision
You can create your own post type and call them wherever you want ex. If you are developing a cooking – recipe website, you can create a custom post type called recipe which will accept cover images and recipe ingredients.

We can enhance it with many custom fields and even custom fields. There are many use cases where the custom post type makes sense like, portfolio, Testimonial, E-commerce Product Listing, Polls etc.

For creating a custom post types we have two options
1.    Using default functions.php file to hook a post type
2.    Creating a new plug-in for the functionality

Both the method works well with the implementations, however, it is recommended to make a plug-in for a custom pos type unless the plug-in itself is not highly dependent on the functionality of the included theme.

The main problem with registering the custom types in the functions.php is that we have to take the backup every time we update the theme or manually add the functionality to new theme every time we change the theme.

But, if you use plug-in to define the custom post type you don’t have to bother too about the custom post types when updating and changing the theme.
Let’s get started with the basic function,

// Custom post type function
function create_custom_post_type_recipes() {

    register_post_type( 'recipes',
    //Custom post types options
        array(
            'labels' => array(
                'name' => __( 'Recipes' ),
                'singular_name' => __( 'Recipe' )
            ),
            'public' => true,
            'has_archive' => true,
            'rewrite' => array('slug' => 'recipes'),
        )
    );
}
// Adding a hook to trigger the function
add_action( 'init', ' create_custom_post_type_recipes ' ); 
 
In above code, we have added a function to register the custom post type recipes in WordPress. The function accepts the array of argument for configurations, the labels indicates singular and plural form of the post type display names.

The other options are used to extend the behaviour of the post type, like changing the url structure and its public visibility.

We can add many more feature to the post types including the translation ready labels,

/*
* Custom post type function
*/

function create_custom_post_type_recipes() {

// Set UI labels for Custom Post Type
    $labels = array(
        'name'                => _x( 'Recipes', 'Post Type Name',
                                           'themedomain' ),
        'singular_name'       => _x( 'Recipe', 'Post Type Singular Name',
                                         'themedomain' ),
        'menu_name'           => __( 'Recipes', 'themedomain' ),
        'parent_item_colon'   => __( 'Parent Recipe', 'themedomain' ),
        'all_items'           => __( 'All Recipes', 'themedomain'),
        'view_item'           => __( 'View Recipe', 'themedomain' ),
        'add_new_item'        => __( 'Add New Recipe', 'themedomain' ),
        'add_new'             => __( 'Add New', 'themedomain' ),
        'edit_item'           => __( 'Edit Recipe', 'themedomain' ),
        'update_item'         => __( 'Update Recipe', 'themedomain' ),
        'search_items'        => __( 'Search Recipe', 'themedomain' ),
        'not_found'           => __( 'Not Found', 'themedomain' ),
        'not_found_in_trash'  => __( 'Not found in Trash',
                                            'themedomain' ),
    );
   
// Few other options for Custom Post Type
   
    $args = array(
        'label'               => __( 'recipes', 'themedomain' ),
        'description'         => __( 'Recipe Details', 'themedomain' ),
        'labels'              => $labels,
        // Features that a custom post type should support into the post editor
        'supports'            => array( 'title', 'editor', 'excerpt', 'author', 'thumbnail', 'comments', 'revisions', 'custom-fields', ),
        // Here we can create the custom taxonomies for the custom post type for easy listing. Like a recipe can be of different course, dinner, lunch or breakfast
        'taxonomies'          => array( 'course' ),
        // If we have a hierarchical custom post where we can set up the parent child relationship, we can use this option as true   
        'hierarchical'        => false,
        'public'              => true,
        'show_ui'             => true,
        'show_in_menu'        => true,
        'show_in_nav_menus'   => true,
        'show_in_admin_bar'   => true,
        'menu_position'       => 4,
        'can_export'          => true,
        'has_archive'         => true,
        'exclude_from_search' => false,
        'publicly_queryable'  => true,
        'capability_type'     => 'page',
    );
   
    // Registering your Custom Post Type
    register_post_type( 'recipes', $args );

}
 

add_action( 'init', 'create_custom_post_type_recipes', 0 );

The above code will add features like featured images, custom fields support, revision, etc.
We also added a custom taxonomy called course to allow better categorization of the recipes.

 The recipes we want to add does not include hierarchical relationship like parent and child, but if you want to add some sub recipe of sauces or a tangy starter with the recipe you are always welcomed to make them hierarchical.
The WordPress allows us to make our themes and plug-ins ready for translation. For this we has to use something called text domain. Here as you can see, we have many time returned word themedomain that is called the text domain.

You can change the textdomain in of your theme inside the style sheet named style.css which is inside your root directory of your theme.

Now we have accomplished the task of recognizing of our custom post type by the WordPress, but we still need to tell WordPress how should it display the custom post type.

There are two method of displaying your custom post type inside the website
1.    WordPress Default page and Archive template
2.    Custom Post Type single.php and archive.php

Display using default Archive Template

WordPress  out of the box supports the basic display of the custom post types. The easiest method to see it in the action is to follow the general WordPress hierarchical url pattern.
Use  http://yourdomain.com/recipes/

In case you are not using the custom permalinks you can also use the default post archive url like this,

http://yourdomain.com/?post_type=recipes

replace the post type value with your custom post type. Now visit the link, You will see the default archive.php page of your theme which is listing the post of your custom post type.

 

Using Custom Single and Archive Templates for Custom Post Type


If you don’t like the default appearance of the custom post type page, you can easily create a custom archive template.

For this you will have to create a file called archive-{posttype}.php  in the root directory of your theme, where you should replace the posttype with the name of your custom post type. In this case we will create a file called archive-recipes.php.

The easiest way to do is to copy the default archive page and make a new copy with name archive-recipes.php. Now edit the template according to your own requirements. So now whenever the request to your custom post type archive page is made WordPress will automatically pickup the archive-recipes.php and display it to the user.

Follow the same steps to create the single-recipes.php file. This files will be called whenever a user will request to view the single recipe.

This was all basic stuffs, now we will see one quick case how we can use it.

 

Displaying Latest posts from Custom Post Types on your Home Page


WordPress generally does not mix the content of your custom post type with the default post. Suppose you want to Display the latest three recipes on your homepage, only thing you have to do is add the following code inside your functions.php file
add_action( 'pre_get_posts', 'get_latest_recipes' );

function get_latest_recipes( $query ) {
    if ( is_home() && $query->is_main_query() )
       
    $queryObject = new WP_Query( 'post_type=recipes&posts_per_page=3' );
// The Loop!
if ($queryObject->have_posts()) {
    while ($queryObject->have_posts()) {
        $queryObject->the_post();
        ?>

        <a href="<?php the_permalink(); ?>"><?php the_title(); ?></a><br/>
    <?php
    }
        ?>

    }

Replace the query parameter recipes with your custom post type name.
We hope that this article will help you the way WordPress uses the custom post type feature.

 If you liked this article, then subscribe to our blog feeds.
 Any suggestions are welcomed in comment section.

3 comments:

  1. Really a nice article, I have a query
    How can i use the my custom post as a hierarchical child of another custom post type?

    ReplyDelete
    Replies
    1. You can easily do this using a plugin: https://wordpress.org/plugins/cpt-onomies/

      Delete
  2. This comment has been removed by the author.

    ReplyDelete