How to Add Meta Boxes to Provide Extra Content for WordPress Posts

I started a new blog several months back and I wanted to include extra boxes on the WordPress edit/add post screen to provide extra “behind the scenes” data.
More specifically I started to learn more about how meta tags (HTML elements that aren’t shown in the browser unless “viewing source”) can influence what is shown when a web page is shared to social networks like Facebook, Google+ and Twitter, and on search engines.
Wanting to control each aspect of the sharing for each site, I decided to create the necessary fields to allow me to do that on a post-by-post basis.

Examples of Meta Tags and Open Graph Tags

There are elements in HTML called “open graph tags” and when used will be the first place specific web sites, like Facebook and Google+, will look to learn about the content (rather than guessing).
A few examples of these tags include: og:title, og:image, and og:description. When included in between the “head” HTML tags of a web page, sites (Facebook for example) will use the values when the URL to the web page is shared.
There are also Twitter-specific meta tags that can be added to create media rich Twitter cards when the URL is shared.
Here’s how the Facebook Open Graphs would look within the HTML code when viewing the behind the scenes (or source) code:
<meta content="This is the Open Graph or Facebook specific title" />
<meta content="http://web-site-example.com/images/example-image.png" />
<meta name="description" content="This is the Open Graph or Facebook specific description" />
So, what’s the point? If you want to have the ability to a) explicitly tell Facebook what data to use when displaying your content so it doesn’t guess which can be embarassing especially when it uses an ad image as the image, and b) have more control over your call to action, etc. when your content is shared throughout Facebook (or Twitter, etc. – whatever the case may be).

Creating the Boxes to Add the Extra Data Into WordPress Posts

Now, this post isn’t about sharing content to Facebook or Google+, it’s about adding the Meta boxes to posts to provide extra data, so I don’t want to pigeon hole this idea for just the “social sharing” concept.
I just wanted to provide an example of one purpose that they could be used for. Meta boxes are the foundation of why many plugins are built, and they also exist for many themes. Really, they just provide a way to include extra data for posts (and pages in some cases). Custom post types are borne from them.
In this example I will show you how to include one panel with one text box to add a value. Then I will explain how to retrieve that information within a template file. The code can be modified to include more than one text box (or other form element) to add to the functionality. It’s easier to just start with one and you could work up from there.
Here’s the code which can be placed in the functions.php file to create a box beneath the post edit and add screens:
<?php
add_action( 'add_meta_boxes', 'm_param_meta_box_add' );
function m_param_meta_box_add() {
    add_meta_box( 'm_param_post', 'Box Title', 'm_param_post_meta_box_cb', 'post', 'normal', 'high' );
}

function m_param_post_meta_box_cb( $post )
{
    $values = get_post_custom( $post->ID );
    if ( isset( $values['m_meta_description'] ) ) {
        $m_meta_description_text = esc_attr( $values['m_meta_description'][0] );
    }
    wp_nonce_field( 'my_meta_box_nonce', 'meta_box_nonce' );

?>
<table class="form-table">
<tr valign="top">
<th scope="row"><label for="m_meta_description">Meta Description (max 160)</label></th>
<td><textarea rows="5" cols="100" name="m_meta_description"><?php echo $m_meta_description_text; ?></textarea></td>
</tr>
</table>

<?php
} // close m_param_post_meta_box_cb function

add_action( 'save_post', 'cd_meta_box_save' );
function cd_meta_box_save( $post_id )
{
    // Bail if we're doing an auto save
    if( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) return;

    // if our nonce isn't there, or we can't verify it, bail
    if( !isset( $_POST['meta_box_nonce'] ) || !wp_verify_nonce( $_POST['meta_box_nonce'], 'my_meta_box_nonce' ) ) return;

    // if our current user can't edit this post, bail
    if( !current_user_can( 'edit_post' ) ) return;

    // Make sure your data is set before trying to save it
    if( isset( $_POST['m_meta_description'] ) ) {
        update_post_meta( $post_id, 'm_meta_description', wp_kses( $_POST['m_meta_description'], $allowed ) );
    }    
}
?>
In the above code, you would change “Box Title” to name the box that all your custom fields will be encased in.
I created a custom field called “m_meta_description” so you can duplicate/modify that as desired.
Then I created an HTML table to display the multi-line text box for the input of the “meta description.” Of course, other form elements can be used. A single line text box can be easily swapped in the above code for example.
Ultimately we save the custom values when the post is saved.
That’s it, the code above is all that is needed to display the custom fields (and their values when they exist) and save the values after saving a post.
Now, we can learn how to retrieve the values for use in template files.

Retrieving Custom Values Within Template Files

In my example where I created extra boxes for social sharing meta values, I needed to retrieve the values for use in the header between the “head” HTML tags. There are two ways to do that. One is by editing a template file directly to access the values in the custom fields and then display them, and another is to use some WordPress “actions” to “inject” the values between the HTML head tags.
I will show both options here as one may be more appropriate for your situation. You might not need to add anything in the header, but perhaps a sidebar or single post page, so the second set of commands below will offer guidance in those situations.
Here is the code for retrieving the custom values and inserting them into meta tags in between the “head” HTML tags using a WordPress hook. This code can be added to a custom plugin or to the functions.php template file.
<?php
add_action('wp_head', 'add_to_wp_head');
function add_to_wp_head( )
{
    if (is_single())
    {
        global $post;
        $m_meta_description = get_post_meta($post->ID, 'm_meta_description', true);
        echo '<meta name="description" content="' . $m_meta_description . '"/>';
    }
}
?>
The code would be very similar for retrieving the value in a template file as for including the value in the head with a WordPress hook. I’m not suggesting here though that modifying a theme with custom code is a good idea, because unless you are very organized, you may lose the functionality if you ever update the theme files, or use an entirely different theme.
But perhaps in a pinch you want to get this working until you have more time to write a plugin. Whatever the reason, let’s take a look at how we can get the custom field value from within the… say, the single.php template file.
<?php
$m_meta_description = get_post_meta($post->ID, 'm_meta_description', true);
echo 'Here is the meta_description custom field value: ' . $m_meta_description;
?>
For the above code we are not “injecting” the code into any of WordPress’s code so there is no need for an “action” or “hook.” Also, we already have access to the $post variable providing we are in the loop so there is no need to re-declare it. And of course, there is no need to check if we are looking at a single post since we are executing this code within the single.php file.

Are There any Other Purposes for These Custom Fields?

I spoke of why I used these custom fields in WordPress already. Twitter, Facebook, and Google+ being the 3 biggest social sharing networks (arguably), and having a distinct audience (for the most part)… our content could benefit from being shared in unique ways.
I only touched on it briefly before, but each of the sharing sites, while they may fall back on standard meta data or Open Graph tags, each have a default place that they look to retrieve pertinent information about a given web page.
The most pertinent of the information for a page on the web would be title, description, and image (and maybe video in some cases). Now, each site has different maximums for each of those fields, and they all display images differently, plus like I mentioned, the audience for each is unique. So, it makes sense to use different data for each site, yeah?
Now, as for other reasons to use custom fields… consider if you use the same sort of data in a post often. As an example, you might create a unique summary for a post when reviewing a restaurant for example. Well, if that summary is in a separate field, it can be shown differently. Perhaps there is different criteria that you review the restaurants based on. Those can now be done in custom fields.
Or what about ingredients for a recipe? When in their own fields they could be used later in different ways, like for sorting.
Or for the affiliate marketers out there, maybe you want to link the featured image to the affiliate product that you are discussing. You can upload the featured image like you would normally do but wrap it in an anchor tag as it gets printed to the screen, using a custom field as the affiliate URL.
The possibilities are endless, and now you are equipped to jump in and test them out for yourself.

Comments

Popular Posts