
Learning how to create custom WordPress meta boxes allow you to make professional UI elements for yourself and your clients. This WordPress meta box tutorial will show you how to add admin UI elements to the edit post/page screens.
Important Before you begin reading, you might want to read Take Your WordPress Meta Box to the Next Level. This PHP class will let you create meta boxes fast with the flexibility you need as a developer. Full documentation walks you step-by-step. Create custom WordPress Meta Box UI elements for your projects with ease.
Creating a custom WordPress meta box lets you make clean UI elements for you and your clients. The default WordPress custom fields are functional, but IMHO, and if you can pull it off, using a WordPress meta box is the way to go. It will give your project that professional touch.
This WordPress meta box tutorial will show you how to quickly add a clean UI for some custom fields. You will even learn how you can hide these fields and prevent them from appearing in the custom fields area.
Getting Started with WordPress Meta Boxes
The code for your meta box will pretty much go in one of two places: in a plugin file or in your functions.php file. This tutorial will cover the latter (for those of you creating plugins, you will be able to adapt the code for your use as well). I like tutorials with code examples and lots of comments, with that said, lets dive right in:
I recommend that you download the sample files or cut + paste the code and markup below in the appropriate places as indicated. There are three sample files (you will also need to create a folder and name it custom):
/current_theme_folder/functions.php /current_theme_folder/custom/meta.php /current_theme_folder/custom/meta.css
/current_theme_folder/functions.php file:
<?php
define('MY_WORDPRESS_FOLDER',$_SERVER['DOCUMENT_ROOT']);
define('MY_THEME_FOLDER',str_replace("\\",'/',dirname(__FILE__)));
define('MY_THEME_PATH','/' . substr(MY_THEME_FOLDER,stripos(MY_THEME_FOLDER,'wp-content')));
add_action('admin_init','my_meta_init');
function my_meta_init()
{
// review the function reference for parameter details
// http://codex.wordpress.org/Function_Reference/wp_enqueue_script
// http://codex.wordpress.org/Function_Reference/wp_enqueue_style
//wp_enqueue_script('my_meta_js', MY_THEME_PATH . '/custom/meta.js', array('jquery'));
wp_enqueue_style('my_meta_css', MY_THEME_PATH . '/custom/meta.css');
// review the function reference for parameter details
// http://codex.wordpress.org/Function_Reference/add_meta_box
// add a meta box for each of the wordpress page types: posts and pages
foreach (array('post','page') as $type)
{
add_meta_box('my_all_meta', 'My Custom Meta Box', 'my_meta_setup', $type, 'normal', 'high');
}
// add a callback function to save any data a user enters in
add_action('save_post','my_meta_save');
}
function my_meta_setup()
{
global $post;
// using an underscore, prevents the meta variable
// from showing up in the custom fields section
$meta = get_post_meta($post->ID,'_my_meta',TRUE);
// instead of writing HTML here, lets do an include
include(MY_THEME_FOLDER . '/custom/meta.php');
// create a custom nonce for submit verification later
echo '<input type="hidden" name="my_meta_noncename" value="' . wp_create_nonce(__FILE__) . '" />';
}
function my_meta_save($post_id)
{
// authentication checks
// make sure data came from our meta box
if (!wp_verify_nonce($_POST['my_meta_noncename'],__FILE__)) return $post_id;
// check user permissions
if ($_POST['post_type'] == 'page')
{
if (!current_user_can('edit_page', $post_id)) return $post_id;
}
else
{
if (!current_user_can('edit_post', $post_id)) return $post_id;
}
// authentication passed, save data
// var types
// single: _my_meta[var]
// array: _my_meta[var][]
// grouped array: _my_meta[var_group][0][var_1], _my_meta[var_group][0][var_2]
$current_data = get_post_meta($post_id, '_my_meta', TRUE);
$new_data = $_POST['_my_meta'];
my_meta_clean($new_data);
if ($current_data)
{
if (is_null($new_data)) delete_post_meta($post_id,'_my_meta');
else update_post_meta($post_id,'_my_meta',$new_data);
}
elseif (!is_null($new_data))
{
add_post_meta($post_id,'_my_meta',$new_data,TRUE);
}
return $post_id;
}
function my_meta_clean(&$arr)
{
if (is_array($arr))
{
foreach ($arr as $i => $v)
{
if (is_array($arr[$i]))
{
my_meta_clean($arr[$i]);
if (!count($arr[$i]))
{
unset($arr[$i]);
}
}
else
{
if (trim($arr[$i]) == '')
{
unset($arr[$i]);
}
}
}
if (!count($arr))
{
$arr = NULL;
}
}
}
?>
/current_theme_folder/custom/meta.php file:
<div class="my_meta_control"> <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras orci lorem, bibendum in pharetra ac, luctus ut mauris. Phasellus dapibus elit et justo malesuada eget <code>functions.php</code>.</p> <label>Name</label> <p> <input type="text" name="_my_meta[name]" value="<?php if(!empty($meta['name'])) echo $meta['name']; ?>"/> <span>Enter in a name</span> </p> <label>Description <span>(optional)</span></label> <p> <textarea name="_my_meta[description]" rows="3"><?php if(!empty($meta['description'])) echo $meta['description']; ?></textarea> <span>Enter in a description</span> </p> </div>
/current_theme_folder/custom/meta.css file:
.my_meta_control .description
{ display:none; }
.my_meta_control label
{ display:block; font-weight:bold; margin:6px; margin-bottom:0; margin-top:12px; }
.my_meta_control label span
{ display:inline; font-weight:normal; }
.my_meta_control span
{ color:#999; display:block; }
.my_meta_control textarea, .my_meta_control input[type='text']
{ margin-bottom:3px; width:99%; }
.my_meta_control h4
{ color:#999; font-size:1em; margin:15px 6px; text-transform:uppercase; }
If you’ve set everything up correctly you should see the following meta box in a edit post or edit page screen:

Using The Meta Box Values In Your Template
Being able to create the values is just the first part, now you need to do something with those values. Most likely you will be displaying the values in your post or page templates.
Remember the example above uses a single variable (_my_meta) to store values as an array, so when you get the meta value back from WordPress it will be an array and you will have to access the values using array syntax. Doing this is pretty straight forward:
$my_meta = get_post_meta($post->ID,'_my_meta',TRUE); echo $my_meta['name']; echo $my_meta['description'];
The global $post variable should always be available, but here are some other methods you can use to get the current post or page ID which you will need to use with get_post_meta():
// using $post global variable
echo $post->ID;
// get a page by its path (recommended over using a page ID)
$page = get_page_by_path('company/contact-us');
echo $page->ID;
// if you are working in the loop
echo get_the_ID();
The above code and markup will help you produce clean UI elements for your next WordPress project. Like any tutorial, consider this a starting point for you to do great things. I hope you’ve enjoyed!

I got an problem with the “function save_details(){
global $post;
update_post_meta($post->ID, “example”, $_POST["example"]);”.
Sometimes it just don’t save it, after I click “Update post”, it gone.
Any ideia?
Does the custom meta box appear for all posts and page dashboards in the admin? Can I have the meta box(es) appear in only certain type of pages?
Hello,
Thanks for a great tutorial. Everything is work for me. But there is one problem… how I add a select box in meta.php ? I add like:
Current Status
<option value="Pending">Pending
<option value="In Process">In Process
<option value="Shipped">Shipped
<option value="Delivereds">Delivered
Choose Status
but its not work. Please tell me how I add select, radio & checkbox ?
Thanks again.
Hello!
Thank you very much for this tutorial, you have just saved med allot of time on a project Im working on.
Wish you a great day and thank you again for your time and making your knowledge available to the rest of us.
Best regards Victor
Awesome! You saved me research time so now I can work on modifying this to suit my needs. It’s working perfect for me and retrieving _my_meta in the template file. Just a little modification and parsing and this is perfect for adding meta key words to the head of any page template.
This is great.. I have one question.. how do I add the parts to my post within the loop..
I tried something this but it didn’t work
Hi
Thanks for a great insight to metaboxes!!
However I would like to use the standard:
ID,’metaA’,true) ) : ?>
ID, ‘metaA’, true) ?>
How does that work with your method?
Kind regards
And without coding ;o)
if ( get_post_meta($post->ID,’dato1′,true) ) :
echo get_post_meta($post->ID, ‘dato1′, true)
endif
trying to get the output of one of my text areas to display as a list of links. here’s what i got but it isn’t working. please help. thanks!
ID, ‘_presentation_title["links"]‘, true);
if($source){
$source = explode(“\n”, $source); ?>
<? for($i = 0;$i
<a href="”>
oh i’m guessing my code wasn’t displaying. here’s the link i got the code from and just replaced CUSTOM_FIELD_NAME with _presentation_title["links"]
but it’s still not outputting anything.
try gist.github.com for your code … also if you haven’t tried wpalchemy, give that a go, its documented and you might just fall in love.
it took me forever to figure the code out above, it’ll take me forever x2 to figure wpalchemy lol i’ll try it out though. do you think i’ll be able to output a list of links like the link i showed you earlier?
The install videos are pretty basic, additionally there are some examples that should get you up and running pretty quickly, and it has a nice handy repeating fields feature.
wpalchemy essentially abstracts the code above, making it easier to handle and use.
where to use this comment ??
i mean in which file ??
$my_meta = get_post_meta($post->ID,’_my_meta’,TRUE);
echo $my_meta['name'];
echo $my_meta['description'];
Wonderful tutorial. Worked perfect for me.
Namskar,
Everything is work for me.Thanks for a great tutorial.
Dude,
This is awsome. It works like a charm.
So I’m using it!
However I would like to extend the fields listed in the meta box. I do this in the mets.php file. Every field I create works however I come across one thing that I can’t seem to get working.
I want to add an upload-file field so the user (CMS-end not front-end) can upload a image.
I created the field and I can select the file I would like to upload. Now I need a button that sais “Upload”. The problem is not how to create the button but the problem is how to upload the file.
Maybe this has nothing to do with your script and it should be done with some PHP, but I hoped you have a solution for me!
Thnx in advance.
Oh and did I mention that your tutorial is Awsome!
M.
When I update a page the metabox data is not saved.
I made a few basic changes that I assume should not affect the ability to save.
Instead of running this as part of a theme I added it to a plugin, so the changes I made are: I include the main.php file from may plugin, I changed the path from the theme dir to the plugin dir.
I metabox shows up, the css is applied, it works like normal but I can not save the metabox data.
I am on wordpress 3.4.2
Thanks,
for this document of the wp meta box
this is work grate
For adding the files through wordpress meta box. See full tutorial at: http://wordpressapi.com/2010/11/22/file-upload-with-add_meta_box-or-custom_post_type-in-wordpress/