Metaboxes: Part 2

In my previous post I had gone over the very basic process in getting a Metabox container set up within my Portfolio post editor. At the moment, the code example I gave doesn't do anything useful. Let's change that. But first, a note on organization: I try to make it a habit to keep everything as compartmentalized as possible. Good programming practices dictate that not only should the code itself be self-documenting, but you should also be able to gain a general understanding about a piece of code's purpose simply by its place in the file system. I've created a folder in my theme called "metaboxes" that will now contain the markup and logic in generating the contents of the corresponding metabox. So now, calling and rendering our metaboxes looks like this:

add_action('add_meta_boxes', 'mm_add_meta_boxes');
function mm_add_meta_boxes(){
    add_meta_box('portfolio_author_info', 'Portfolio Author Information', 'mm_render_portfolio_metabox', 'portfolio');
}
function mm_render_portfolio_metabox($post){
    include 'metaboxes/portfolio_author_info.php';
}

Looks a little nicer, right? Now we aren't mixing our metabox's internal markup with our theme's logic. This is the part where we can actually start adding some fields to our shiny new metabox:

/*metaboxes/portfolio_author_info.php*/
<div class="mm_meta">
    <label for="_mm_portfolio_designer">Designer:</label> 
    <input name="_mm_portfolio_designer" type="text" value="<?php echo get_post_meta($post->ID, '_mm_portfolio_designer', true); ?>" />
</div>
 
<div class="mm_meta">
    <label for="_mm_portfolio_developer">Developer:</label> 
    <input name="_mm_portfolio_developer" type="text" value="<?php echo get_post_meta($post->ID, '_mm_portfolio_developer', true); ?>" />
</div>
 
<div class="mm_meta">
    <label for="_mm_portfolio_url">URL:</label> 
    <input name="_mm_portfolio_url" type="text" value="<?php echo get_post_meta($post->ID, '_mm_portfolio_url', true); ?>" />
</div>

Easy, right? This is a fully-functioning example of a few of my own metabox fields for my Portfolio items. PHP developers should know what's going on here, but I'll still break it down anyway for clarity's sake.

  1. Remember in the previous chapter I had made a small note about the $post object being passed into our metabox callback? This is where it comes in handy. Despite the fact that we're in a separate file, the $post variable is still in scope. We still have access to all of the current post's information, which means we can grab any metadata that might have been previously saved.
  2. In each value attribute for each input field, I'm making a call to get_post_meta to grab the relevant metadata regardless of whether or not the information actually exists. This way, the field can be prepopulated with current data.
  3. Notice how the second argument of get_post_meta - the Meta Key - is prepended with an underscore. This tells Wordpress that we don't want this particular piece of metadata to be populated within the Custom Fields area in our Post Editor. It's a personal preference of mine that I set my own metabox information apart from the general Custom Fields area, but this is completely optional. Arguments can be made for or against this approach, but it all boils down to what *you* decide is best for your theme

Awesome! Everything is coming together nicely. But..... nothing is being saved yet. How do we tell Wordpress that we want to attach the data our editors enter to the post in the form of metadata? Here comes another Action Hook:

/*functions.php*/
add_action('save_post', 'mm_save_post_metadata');
function mm_save_post_metadata($post_id){
    if(get_post_type($post_id)==='portfolio'){
        update_post_meta($post_id, '_mm_portfolio_designer', $_POST['_mm_portfolio_designer']);
        update_post_meta($post_id, '_mm_portfolio_developer', $_POST['_mm_portfolio_developer']);
        update_post_meta($post_id, '_mm_portfolio_url', $_POST['_mm_portfolio_url']);
    }
}

This is an extremely basic implementation of hooking into the save_post action. This action is called after a given post has been saved or updated. As you can see, all we're doing here is saving our Metadata as long as the current post type is 'portfolio'. Notice that only the post ID is passed into the callback, and not the post object itself. There are much better and more secure ways of handling our information here, but this just gives you an idea into how everything works. Now we have full access to the information we save to our posts and can call it from within our Post Templates to display everything to the end-user. This concludes the second chapter on Metaboxes. We now have a fully-functioning Metabox, but things can be done to make it better and more secure.

Written by maiorano84 on Wednesday February 18, 2015
Permalink -

« At a Glance: DOM Parsing | Metaboxes: Part 1 »