Adding Custom Meta Boxes to the WordPress Admin Interface

    Narayan Prusty
    Narayan Prusty
    Share

    WordPress lets us add custom meta boxes to posts, pages and custom post types via the admin interface. WordPress also provides APIs to customize the default meta boxes.

    In this tutorial, I will show you how to add new custom meta boxes, save custom meta data, validate meta data, retrieve custom meta data on the front end and also remove the default meta boxes.

    What is a Custom Meta Box?

    Custom meta boxes allow users to add additional information to posts, pages and custom post types, apart from the default set of information that WordPress takes using default meta boxes. Plugins and Themes can use custom meta boxes to take additional structured user input.

    Custom meta boxes can also be added to the dashboard and attached to the admin interface. WordPress dashboard widgets are actually meta boxes.

    In addition to the meta boxes, you can also edit the contents and appearance of the Admin Bar that is seen by those who are logged in to the admin interface.

    Editor, Custom Fields, Featured Image, Categories, and Tags on a post, page or custom post page admin interface are default meta boxes. They are created by the WordPress core.

    Custom Meta Box vs Custom Fields

    Custom fields allow users to add key/value pairs of data to a post, page or custom post type. But meta boxes can have many varieties of input fields such as color picker, file upload, drop downs, and so on.

    What is Meta Data?

    Meta Data are values of the form fields embedded in Custom Meta Boxes. WordPress stores them as key/value pairs, such as meta key and meta value. Meta key is the name of the form field and meta value is the form field value.

    Creating a Meta Box

    add_meta_box function is used to create custom meta boxes. This function is only responsible for registering and displaying custom meta boxes.

    Here is the code to add a custom meta box to WordPress posts:

    function custom_meta_box_markup()
    {
        
    }
    
    function add_custom_meta_box()
    {
        add_meta_box("demo-meta-box", "Custom Meta Box", "custom_meta_box_markup", "post", "side", "high", null);
    }
    
    add_action("add_meta_boxes", "add_custom_meta_box");

    add_meta_box should be called inside add_meta_boxes hook.

    add_meta_box takes 7 arguments. Here are the list of arguments:

    1. $id: Every meta box is identified by WordPress uniquely using its id. Provide an id and remember to prefix it to prevent overriding.
    2. $title: Title of the meta box on the admin interface.
    3. $callback: add_meta_box calls the callback to display the contents of the custom meta box.
    4. $screen: Its used to instruct WordPress in which screen to display the meta box. Possible values are "post", "page", "dashboard", "link", "attachment" or "custom_post_type" id. In the above example we are adding the custom meta box to WordPress posts screen.
    5. $context: Its used to provide the position of the custom meta on the display screen. Possible values are "normal", "advanced" and "side". In the above example we positioned the meta box on side.
    6. $priority: Its used to provide the position of the box in the provided context. Possible values are "high", "core", "default", and "low". In the above example we positioned the meta box
    7. $callback_args: Its used to provide arguments to the callback function.

    Here is how the meta box looks:

    Custom WordPress Meta Box

    Here, the custom meta box content is empty because we haven’t yet populated the content.

    Displaying Fields in a Custom Meta Box

    For demonstration purpose I will add a text input, drop down and a checkbox form field to the custom meta box.

    Here is the code:

    function custom_meta_box_markup($object)
    {
        wp_nonce_field(basename(__FILE__), "meta-box-nonce");
    
        ?>
            <div>
                <label for="meta-box-text">Text</label>
                <input name="meta-box-text" type="text" value="<?php echo get_post_meta($object->ID, "meta-box-text", true); ?>">
    
                <br>
    
                <label for="meta-box-dropdown">Dropdown</label>
                <select name="meta-box-dropdown">
                    <?php 
                        $option_values = array(1, 2, 3);
    
                        foreach($option_values as $key => $value) 
                        {
                            if($value == get_post_meta($object->ID, "meta-box-dropdown", true))
                            {
                                ?>
                                    <option selected><?php echo $value; ?></option>
                                <?php    
                            }
                            else
                            {
                                ?>
                                    <option><?php echo $value; ?></option>
                                <?php
                            }
                        }
                    ?>
                </select>
    
                <br>
    
                <label for="meta-box-checkbox">Check Box</label>
                <?php
                    $checkbox_value = get_post_meta($object->ID, "meta-box-checkbox", true);
    
                    if($checkbox_value == "")
                    {
                        ?>
                            <input name="meta-box-checkbox" type="checkbox" value="true">
                        <?php
                    }
                    else if($checkbox_value == "true")
                    {
                        ?>  
                            <input name="meta-box-checkbox" type="checkbox" value="true" checked>
                        <?php
                    }
                ?>
            </div>
        <?php  
    }

    Here is how the code works:

    • First we set the nonce field so that we can prevent CSRF attack when the form is submitted.
    • get_post_meta is used to retrieve meta data from the database. If no such meta data is present, it returns an empty string. If your user has already submitted the form earlier, then we use the meta data stored in database. Otherwise, we switch to the default value.

    Here is how the meta box looks now:

    Custom WordPress Meta Box Expanded

    Storing Meta Data

    Now we need to store the custom meta data when a user submits the form; need to save the post.

    Here is the code to save meta data when a user clicks on the ‘save draft’ or ‘publish’ button:

    function save_custom_meta_box($post_id, $post, $update)
    {
        if (!isset($_POST["meta-box-nonce"]) || !wp_verify_nonce($_POST["meta-box-nonce"], basename(__FILE__)))
            return $post_id;
    
        if(!current_user_can("edit_post", $post_id))
            return $post_id;
    
        if(defined("DOING_AUTOSAVE") && DOING_AUTOSAVE)
            return $post_id;
    
        $slug = "post";
        if($slug != $post->post_type)
            return $post_id;
    
        $meta_box_text_value = "";
        $meta_box_dropdown_value = "";
        $meta_box_checkbox_value = "";
    
        if(isset($_POST["meta-box-text"]))
        {
            $meta_box_text_value = $_POST["meta-box-text"];
        }   
        update_post_meta($post_id, "meta-box-text", $meta_box_text_value);
    
        if(isset($_POST["meta-box-dropdown"]))
        {
            $meta_box_dropdown_value = $_POST["meta-box-dropdown"];
        }   
        update_post_meta($post_id, "meta-box-dropdown", $meta_box_dropdown_value);
    
        if(isset($_POST["meta-box-checkbox"]))
        {
            $meta_box_checkbox_value = $_POST["meta-box-checkbox"];
        }   
        update_post_meta($post_id, "meta-box-checkbox", $meta_box_checkbox_value);
    }
    
    add_action("save_post", "save_custom_meta_box", 10, 3);

    Here is how the code works:
    save_post hook’s callback is triggered when a post, page and custom post type is saved. We attached a callback to save meta data.
    – We verify the nonce. If the nonce is not present or invalid then we don’t save the return the callback.
    – We check whether the current logged in admin user has permission to save meta data for that post type. If the user doesn’t have permission, then we return the callback.
    – We check if the post is being auto saved. If the save is auto saved, then we return the callback.
    – Final check is whether the post type is the same as the meta box post type. If not, then we return the callback.
    – We retrieve the values of the form fields using PHP $_POST variable and save them in database using update_post_meta. update_post_meta create a new meta data key/value in the database if the key is not present, otherwise it updates the key value.

    Removing a Meta Box

    We can remove custom meta boxes and the default WordPress core meta boxes using remove_meta_box. To remove a meta box you need its ID, screen and content.

    Here are the IDs of some important default meta boxes:

    • ‘authordiv’ – Author metabox
    • ‘categorydiv’ – Categories metabox
    • ‘commentstatusdiv’ – Comments status metabox (discussion)
    • ‘commentsdiv’ – Comments metabox
    • ‘formatdiv’ – Formats metabox
    • ‘pageparentdiv’ – Attributes metabox
    • ‘postcustom’ – Custom fields metabox
    • ‘postexcerpt’ – Excerpt metabox
    • ‘postimagediv’ – Featured image metabox
    • ‘revisionsdiv’ – Revisions metabox
    • ‘slugdiv’ – Slug metabox
    • ‘submitdiv’ – Date, status, and update/save metabox
    • ‘tagsdiv-post_tag’ – Tags metabox
    • ‘{$tax-name}div’ – Hierarchical custom taxonomies metabox
    • ‘trackbacksdiv’ – Trackbacks metabox

    Here is the code to remove custom fields meta box:

    function remove_custom_field_meta_box()
    {
        remove_meta_box("postcustom", "post", "normal");
    }
    
    add_action("do_meta_boxes", "remove_custom_field_meta_box");

    Here we triggered remove_meta_box in do_meta_boxes hook. But you cannot always call remove_meta_box inside it. For example, to remove dashboard widgets you need to call it inside wp_dashboard_setup hook.

    Final Thoughts

    WordPress Meta Box APIs are very useful if you are building a plugin or theme. SEO, Post Series, and Related Content plugins make use of custom meta boxes to take additional user information for posts.

    Frequently Asked Questions on Adding Custom Meta Boxes to WordPress

    What are the benefits of adding custom meta boxes to WordPress?

    Custom meta boxes in WordPress provide a user-friendly interface to interact with post meta data. They allow you to add additional information to your posts, pages, and custom post types beyond the default WordPress fields. This can enhance the functionality of your website, making it more interactive and engaging for your users. For instance, you can use custom meta boxes to add a custom rating system, additional text fields, image uploads, and more.

    Can I add custom meta boxes without coding knowledge?

    While adding custom meta boxes typically involves some coding, there are plugins available that can simplify the process. These plugins provide a user-friendly interface for creating and managing custom meta boxes and custom fields in WordPress. Some popular options include Advanced Custom Fields, Meta Box, and CMB2.

    How can I display the data from custom meta boxes on my website?

    To display the data from your custom meta boxes, you’ll need to edit your theme files. This typically involves adding a small snippet of PHP code to the appropriate theme file. The exact code will depend on the type of data you’re displaying and the specific meta box from which it’s being retrieved.

    Can I add custom meta boxes to custom post types?

    Yes, you can add custom meta boxes to any post type in WordPress, including custom post types. When registering your meta box, you simply need to specify the post type in the ‘post_type’ parameter of the ‘add_meta_box’ function.

    How can I style my custom meta boxes?

    Custom meta boxes can be styled using CSS. You can add custom classes to your meta boxes and then use these classes to apply styles in your theme’s CSS file. This allows you to control the appearance of your meta boxes, ensuring they fit seamlessly with the rest of your website’s design.

    Can I use custom meta boxes to add custom fields to my posts?

    Yes, one of the primary uses of custom meta boxes is to add custom fields to your posts. These fields can be used to collect and display any type of data, from simple text inputs to complex data structures.

    Are there any limitations to what I can do with custom meta boxes?

    While custom meta boxes are incredibly flexible, they do have some limitations. For instance, they cannot be used to modify the WordPress admin interface or add functionality that is not supported by the WordPress core. However, for most use cases, custom meta boxes provide a powerful and flexible solution for enhancing your website’s functionality.

    Can I use custom meta boxes to create a custom backend for my website?

    Yes, custom meta boxes can be used to create a custom backend for your website. By adding custom fields and options to your posts and pages, you can create a tailored editing experience that fits your specific needs.

    How can I ensure my custom meta boxes are secure?

    To ensure your custom meta boxes are secure, you should always validate and sanitize your data. This means checking that the data is in the expected format and removing any potentially harmful elements before saving it to the database.

    Can I add custom meta boxes to my WordPress theme?

    Yes, you can add custom meta boxes directly to your WordPress theme. However, it’s generally recommended to add them via a plugin instead. This ensures that your custom meta boxes will remain intact even if you switch themes.