How To Create WordPress Custom Meta Boxes

What is a Meta Boxes?

When a user updates a post, the edit screen has numerous default boxes, such as Editor, Publish, Categories, Tags, and so on. These are known as meta boxes. Custom meta boxes may be add to every post type’s edit screen by plugins.

Custom meta box content is often HTML form elements where the user inputs data relating to a Plugin’s purpose, although it may be almost any HTML you want.

Check Out WordPress Development Articles

Why We Use Meta Boxes?

Meta boxes are edit screen components that may be use to collect information about the post being change. They are useful, versatile, and modular. Your own meta box will appear on the same screen as all other post-related information, establishing a clear connection.

Users who don’t need to see meta boxes may easily hide them, while those who need them can see. On the edit screen, meta boxes can be rearrange by the user. Users may organize the edit screen in any manner they choose, providing them complete control over their editing environment.

All samples on this page are provided only for the purpose of demonstration. The code is unfit for use in a production setting. Securing input, user capabilities, nonces, and internationalization have all been purposefully left out. Always remember to take care of these crucial tasks.

Adding Meta Boxes

Use the add_meta_box() method to construct a meta box and connect its execution to the add_meta_boxes action hook.

A meta box is add to the post edit screen and the wporg_cpt edit screen in the following example.

function wporg_add_custom_box() {
    $screens = [ 'post', 'wporg_cpt' ];
    foreach ( $screens as $screen ) {
        add_meta_box(
            'wporg_box_id',                 // Unique ID
            'Custom Meta Box Title',      // Box title
            'wporg_custom_box_html',  // Content callback, must be of type callable
            $screen                            // Post type
        );
    }
}
add_action( 'add_meta_boxes', 'wporg_add_custom_box' );

The HTML for the meta box will be store in the wporg_custom_box_html function.

The example below shows how to add form elements, labels, and other HTML components.

function wporg_custom_box_html( $post ) {
    ?>
    <label for="wporg_field">Description for this field</label>
    <select name="wporg_field" id="wporg_field" class="postbox">
        <option value="">Select something...</option>
        <option value="something">Something</option>
        <option value="else">Else</option>
    </select>
    <?php
}

Note: In meta boxes, there are no submit buttons. When the user hits the Publish or Update buttons, the meta box HTML is incorporate inside the edit screen’s form elements, and all post data, including meta box values, is transfer through POST.

Only one form field, a drop-down list, is present in this example. In each given meta box, you may construct as many as you need. Consider utilizing numerous meta boxes and putting related fields together in each meta box if you have a lot of information to display. This makes the page more aesthetically appealing and organized.

Getting Values

You must retrieve and utilize stored user data from the location where it was originally save. If the data was save in the postmeta database, use get_post_meta() to get it.

The next example adds pre-populated data based on stored meta box settings to the preceding form components. In the next part, you’ll learn how to store meta box values.

function wporg_custom_box_html( $post ) {
    $value = get_post_meta( $post->ID, '_wporg_meta_key', true );
    ?>
    <label for="wporg_field">Description for this field</label>
    <select name="wporg_field" id="wporg_field" class="postbox">
        <option value="">Select something...</option>
        <option value="something" <?php selected( $value, 'something' ); ?>>Something</option>
        <option value="else" <?php selected( $value, 'else' ); ?>>Else</option>
    </select>
    <?php
}

More on the selected() function.

Saving Values

When a post type is save or change, many actions are trigger, any of which might be use to store the entered data. The save_post action hook is use in this example, although other hooks may be more suited in specific scenarios. Keep in mind that save_post might trigger many times for a single update event. Organize your data-saving strategy properly.

You may store the information you’ve typed wherever you wish, including outside of WordPress. The postmeta table is an excellent location to store data because you’re presumably working with data linked to the post.

The wporg_field field value will be save in the secret _wporg_meta_key meta key in the following example.

function wporg_save_postdata( $post_id ) {
    if ( array_key_exists( 'wporg_field', $_POST ) ) {
        update_post_meta(
            $post_id,
            '_wporg_meta_key',
            $_POST['wporg_field']
        );
    }
}
add_action( 'save_post', 'wporg_save_postdata' );

Remember to follow the security precautions described in the info box in production code!

Behind The Scenes

Normally, you don’t have to be concerned with what goes on behind the scenes. This area was add to round out the picture.

The do_meta_boxes() function is call when a post edit screen wishes to show all of the meta boxes that have been add to it. This method iterates through all meta boxes, invoking the callback for each one.
Intervening markup (such as divs, titles, and so on) is insert in between each call.

Removing Meta Boxes

Use the remove_meta_box() function to delete an existing meta box from an edit screen. The arguments supplied must be identical to those used to add the meta box with add_meta_box().


Check the source code for the options used to remove default meta boxes. wp-includes/edit-form-advanced.php is where the default add_meta_box() calls are performed.

Implementation Variants – Meta Boxes

We’ve been utilizing the procedural method to implement meta boxes so far. Many plugin authors find themselves needing to use a variety of alternative ways to build meta boxes.

1. OOP

Adding meta boxes using OOP is simple and eliminates the need to worry about naming conflicts in the global namespace.
The following example utilizes an abstract Class with static methods to conserve memory and make implementation easier.

abstract class WPOrg_Meta_Box {
 
 
    /**
     * Set up and add the meta box.
     */
    public static function add() {
        $screens = [ 'post', 'wporg_cpt' ];
        foreach ( $screens as $screen ) {
            add_meta_box(
                'wporg_box_id',          // Unique ID
                'Custom Meta Box Title', // Box title
                [ self::class, 'html' ],   // Content callback, must be of type callable
                $screen                  // Post type
            );
        }
    }
 
 
    /**
     * Save the meta box selections.
     *
     * @param int $post_id  The post ID.
     */
    public static function save( int $post_id ) {
        if ( array_key_exists( 'wporg_field', $_POST ) ) {
            update_post_meta(
                $post_id,
                '_wporg_meta_key',
                $_POST['wporg_field']
            );
        }
    }
 
 
    /**
     * Display the meta box HTML to the user.
     *
     * @param \WP_Post $post   Post object.
     */
    public static function html( $post ) {
        $value = get_post_meta( $post->ID, '_wporg_meta_key', true );
        ?>
        <label for="wporg_field">Description for this field</label>
        <select name="wporg_field" id="wporg_field" class="postbox">
            <option value="">Select something...</option>
            <option value="something" <?php selected( $value, 'something' ); ?>>Something</option>
            <option value="else" <?php selected( $value, 'else' ); ?>>Else</option>
        </select>
        <?php
    }
}
 
add_action( 'add_meta_boxes', [ 'WPOrg_Meta_Box', 'add' ] );
add_action( 'save_post', [ 'WPOrg_Meta_Box', 'save' ] );

2. AJAX

Because the meta box’s HTML components are included within the edit screen’s form tags, the usual approach is to parse meta box data from the $_POST super global after the user has submitted the page.

With AJAX, you may improve the default experience by doing activities depending on user input and behavior, regardless of whether they’ve submitted the page.

Define a Trigger

The trigger, which might be a link click, a value change, or any other JavaScript event, must first be defined.

We’ll use change as our trigger for making an AJAX request in the example below.

/*jslint browser: true, plusplus: true */
(function ($, window, document) {
    'use strict';
    // execute when the DOM is ready
    $(document).ready(function () {
        // js 'change' event triggered on the wporg_field form field
        $('#wporg_field').on('change', function () {
            // our code
        });
    });
}(jQuery, window, document));

Client Side Code

Next, we must specify what we want the trigger to perform, i.e., we must write our client-side code.

We’ll perform a POST request in the example below, and the result will either be success or failure, indicating if the value of the wporg_field is legitimate.

/*jslint browser: true, plusplus: true */
(function ($, window, document) {
    'use strict';
    // execute when the DOM is ready
    $(document).ready(function () {
        // js 'change' event triggered on the wporg_field form field
        $('#wporg_field').on('change', function () {
            // jQuery post method, a shorthand for $.ajax with POST
            $.post(wporg_meta_box_obj.url,                        // or ajaxurl
                   {
                       action: 'wporg_ajax_change',               // POST data, action
                       wporg_field_value: $('#wporg_field').val() // POST data, wporg_field_value
                   }, function (data) {
                        // handle response data
                        if (data === 'success') {
                            // perform our success logic
                        } else if (data === 'failure') {
                            // perform our failure logic
                        } else {
                            // do nothing
                        }
                    }
            );
        });
    });
}(jQuery, window, document));

We dynamically retrieved the WordPress AJAX file URL from the wporg_meta_box_obj JavaScript custom object, which we will construct in the following step.

Note: Instead of building a new custom JavaScript object, you may utilize the ajaxurl predefined JavaScript variable if your meta box just requires the WordPress AJAX file URL. Only in the WordPress Administration is this feature available. Before executing any logic, make sure it isn’t empty.

Enqueue Client Side Code

Our code will now be placed in a script file and enqueued on our edit screens.

The AJAX capability will be added to the edit screens of the following post types in the example below: post, wporg_cpt.

The script file will be located in /plugin-name/admin/meta-boxes/js/admin.js, with plugin-name referring to the main plugin folder and /plugin-name/plugin.php referring to the function’s calling file.

function wporg_meta_box_scripts()
{
    // get current admin screen, or null
    $screen = get_current_screen();
    // verify admin screen object
    if (is_object($screen)) {
        // enqueue only for specific post types
        if (in_array($screen->post_type, ['post', 'wporg_cpt'])) {
            // enqueue script
            wp_enqueue_script('wporg_meta_box_script', plugin_dir_url(__FILE__) . 'admin/meta-boxes/js/admin.js', ['jquery']);
            // localize script, create a custom js object
            wp_localize_script(
                'wporg_meta_box_script',
                'wporg_meta_box_obj',
                [
                    'url' => admin_url('admin-ajax.php'),
                ]
            );
        }
    }
}
add_action('admin_enqueue_scripts', 'wporg_meta_box_scripts');

Server Side Code

The final step is to develop the server-side code that will process the request.

function wporg_meta_box_scripts() {
     // Get current admin screen, or null.
    $screen = get_current_screen();
    // Verify admin screen object before use.
    if ( is_object( $screen ) ) {
        // Enqueue only for specific post types.
        if ( in_array( $screen->post_type, [ 'post', 'wporg_cpt' ], true ) ) {
            wp_enqueue_script( 'wporg_meta_box_script', plugin_dir_url( __FILE__ ) . 'admin/meta-boxes/js/admin.js', [ 'jquery' ], '1.0.0', true );
            wp_localize_script(
                'wporg_meta_box_script',
                'wporg_meta_box_obj',
                [
                    'url' => admin_url( 'admin-ajax.php' ),
                ]
            );
        }
    }
}
add_action( 'admin_enqueue_scripts', 'wporg_meta_box_scripts' );

As a final note, the code shown on this page is missing crucial security-related activities. Make certain that such actions are included in your production code.

That’s all for this article if you have any queries please contact us through our website or email us at [email protected]

Leave a Comment