For today’s Tutorial I’ll be covering how to add custom post meta and meta boxes in WordPress posts. If you’re wondering what is a Post meta? In plain English a Post meta is simply metadata. Ah, that wasn’t very helpful, eh? So, meta data is simply a value associated with a key and thus therefore a post metadata is simply metadata store within a post. That either provides additional data about the post. But in our case as developers, we can utilize custom post meta to allow our plugin/theme to interact with the post to either store or display additional information.

Some examples of use cases for custom post meta are:

  • Flagging a post as featured or sponsored.
  • Storing the post view count.
  • Toggling show/hide, last modified date and/or other post components.
  • Organizing additional post data to be displayed in a post templated area. Such as review score or tabular data.

With custom meta boxes you can easily group and organize custom post meta while also providing an intuitive interface for your user to add, update, or delete the custom post meta without them ever interacting the Back end. Have I lost you yet? Anyways, you can read more into WordPress post meta in the official documentations here. Now this is what we will be creating.

The end product of this tutorialThe end product of this tutorial

A review post meta to help the user store and display a review star rating and verdict in a presentable matter. The front-end component to display the custom post meta data and back-end to allow the user to update and make changes to the metadata. To get started, here’s what you’ll need:

  • A local or remote WordPress site, your preference.
  • FTP access to your site theme or plugin to make changes.
  • Classic Editor plugin(optional) if you prefer it over Gutenberg block editor.

Step 1: The basics

Before we do any coding, I should probably take some time to cover the basics for anyone new to WordPress. Your meta boxes by default will be displayed in the panel located at the bottom of the editor in both classic and Gutenberg. Also referred to as the advance panel in Gutenberg.

How to toggle your metaboxes in WordPressHow to toggle your metaboxes in WordPress

To toggle the display of different meta boxes in Gutenberg. Next to setting cog button open the 3 dots menu and select options. Here you find all the available meta boxes, but the ones we’ll be interested in are the ones in Advanced panel. Likewise, you find the similar setting options in classic editor under the Screen Options. Now if they don’t show up when we add our custom Post meta boxes. Be sure have them enabled in these settings.

Step 2: Setting up

Now we can begin coding. It’s up to you where you want to implement your custom meta. It can be either placed in your theme function.php or in a plugin. To keep things simple, I’d be doing it the way I usually implement post meta. By creating a directory for my custom meta in my theme, then include them in function.php using Require_once and a conditional statement for it to be only required when the logged user is an editor or administrator like so:

//function.php
$user = wp_get_current_user();
$allowed_roles = array('editor', 'administrator', 'author');
if( array_intersect($allowed_roles, $user->roles ) ) {
    require_once('JDX2_customPostMeta/JDX2_ReviewSummary.php');
}

Once you have all that sorted out, here’s the skeleton code for our custom Post meta and meta box in JDX2_ReviewSummary.php. With the sequential steps where we are filling in the different functions. Feel free to skip ahead to the parts you need or just follow along 😛

<?php
//JDX2_ReviewSummary.php
function JDX2_review_summary_meta()
{

}
add_action('add_meta_boxes', 'JDX2_review_summary_meta');
function JDX2_review_summary_metaBox($post){

}
function JDX2_review_summary_meta_save($post_id)
{

}
add_action('save_post', 'JDX2_review_summary_meta_save');

Step 3: Adding post meta

Before adding the meta box we should define our post meta by using add_post_meta() function.
add_post_meta() function reference:

add_post_meta( int $post_id, string $meta_key, mixed $meta_value, bool $unique = false )
By simply using add_post_meta your new custom meta should be available to use via "Custom fields" box. Which looks something like this:

WordPress Custom fields metabox exampleWordPress Custom fields metabox example
Not really user friendly eh? Now that’s where add_meta_box() comes into play, allowing us to define our own meta box and group the meta we just added into something more presentable.
add_meta_box() function reference:
add_meta_box( string $id, string $title, callable $callback, 
string|array|WP_Screen $screen = null, string $context = 'advanced', s
tring $priority = 'default', array $callback_args = null )

the final JDX2_review_summary_meta function code:

function JDX2_review_summary_meta(){
    add_post_meta(get_the_ID(), 'JDX2-rating', '', true);
    add_post_meta(get_the_ID(), 'JDX2-verdict', '', true);
    add_post_meta(get_the_ID(), 'JDX2-recommend','', true);
    add_meta_box('rev_meta', __('Jason\'s Review Summary', 'revmeta-textdomain'), 
    'review_summary_metaBox', 'post');
}

Step 4: Implementing the meta box

Now that we got the setup part, implementing the metaBox callback function is pretty straight forward html form input fields paired with retrieving the saved meta data to be displayed in their corresponding fields in which will be using the get_post_meta() to retrieve the post metadata in an array. Thereafter we will use the keys we defined earlier to retrieve the value.

get_post_meta() function reference:
get_post_meta( int $post_id, string $key = '', bool $single = false )
Retrieves a post meta field for the given post ID.

The final JDX2_review_summary_metaBox would look this:

function JDX2_review_summary_metaBox($post){
    $reviewMeta = get_post_meta($post->ID);
?>
<p>
<div class="sm-row-content">
    <label for="JDX2-rating">Product Rating: </label>
    <input type="range" name="JDX2-rating" id="JDX2-rating" min="0" step="0.5" 
           max="5"
           value = "
           <?php echo $reviewMeta['JDX2-rating'][0]>0 ? 
                 $reviewMeta['JDX2-rating'][0]:0 ;?>
                 " 
     />
    <label name="rating" id="points">
       <?php echo $reviewMeta['JDX2-rating'][0]>0 ? 
         $reviewMeta['JDX2-rating'][0]:0 ;?>
    </label>
    <label>Stars</label>
    <br/>
<label for="JDX2-verdict">Product Verdict: </label>
    <input type="text" name="JDX2-verdict" id="JDX2-verdict" 
       placeholder="Enter your Verdict" value="
      <?php echo $reviewMeta['JDX2-verdict'][0];?>
       "
     />
<br/>
    <label class="switch">
        Would you recommend this prouct?:
    </label>
        <input type="checkbox"<?php 
         checked($reviewMeta['JDX2-recommend'][0], true); 
          ?>/>
<?php }

Step 5: Implement the save meta function

For the final step of the back-end portion of this tutorial. Is to implement the save function for the meta box metadata. The first order of business is to add a conditional check for the status of the post before performing the saving. This code would look like this:

function JDX2_review_summary_meta_save($post_id)
{ // Checks save status
    $is_autosave = wp_is_post_autosave($post_id);
    $is_revision = wp_is_post_revision($post_id);
    $is_valid_nonce = (isset($_POST['revmeta_nonce']) && 
                       wp_verify_nonce($_POST['revmeta_nonce'], 
                       basename(__FILE__))) ? 'true' : 'false';
    // Exits script depending on save status
    if ($is_autosave || $is_revision || !$is_valid_nonce) {
        return;
    }

What this will do is it will only save the metadata when the user performs a save action. Such as save as draft or update or publish. While ensuring it’s valid if you have enabled nonce for meta box. Afterwards executing the save we’ll be using the update_post_meta() function.

update_post_meta() function reference:
update_post_meta( int $post_id, string $meta_key,
 mixed $meta_value, mixed $prev_value = '' )

With a bit of simple sanitization your data is ready to be saved to the database. The final portion of the save function looks like this:

update_post_meta($post_id, 'JDX2-rating', 
sanitize_text_field($_POST['JDX2-rating']));
    $verdict=stripslashes($_POST['JDX2-verdict']);
    update_post_meta($post_id, 'JDX2-verdict', sanitize_text_field( $verdict) );
    if(isset($_POST['JDX2-recommend'])){
    update_post_meta($post_id, 'JDX2-recommend', true);
    }else{
        update_post_meta($post_id, 'JDX2-recommend', false);
    }
}
Step 6: implementing the front end

Now that the back end is complete the final step is to implement the front. Utilizing the get_post_meta() function like in step 4 we can simply retrieve the post metadata and display them. Since I’d be using stars for the rating. A bit of logic and CSS styling would be required. The front would look something like this:

<link rel="stylesheet" 
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<br/>
    <div class="rating" style=" display:inline-block; border: 1px solid;">
    <?php $reviewMeta = get_post_meta(get_the_ID());
    $floor=floor($reviewMeta['JDX2-rating'][0]);
    $half=strpos($reviewMeta['JDX2-rating'][0],'.');
    for($i=1; $i<=5;$i++){
        if($i<=$floor){
        echo"<span class=\"fa fa-star checked\" style=\"color:orange;\"></span>";
        }
        else{
            if($half && $i<=$floor+1 ){
            echo"<span class=\"fa fa-star-half\" 
                     style=\"color:orange;position:absolute;\">
                  </span>";
            echo"<span class=\"fa fa-star\"></span>";
        }else{
            echo"<span class=\"fa fa-star\"></span>";
            }
        }
        }
    echo "<br/><h1>".$reviewMeta['JDX2-verdict'][0]. "</h1><hr/>";
    if($reviewMeta['JDX2-recommend'][0]){
        echo "Would recommend:<span class=\"fa fa-thumbs-up\" style=\" color: green; \"></span> ";
    }else{
        echo "Would recommend:<span class=\"fa fa-thumbs-down\" style=\" position: absolute; color:red; \"></span> ";
    }
    ?>
</div>

Well that's it, Cheers!


Tags:Web Design, Web Development, WordPress

No comments
Back to top