WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I'm having trouble getting my custom post meta field to save and I'm not quite sure why. I was following the tutorial located at http://blog.teamtreehouse.com/create-your-first-wordpress-custom-post-type and had some pretty big difficulty de-coding the special character explosion that happened all over that post... Any help is much appreciated.

add_action("admin_init", "admin_init");

function admin_init(){
  add_meta_box("job_location", "Job Location", "location_callback", "job_or_internship", "side", "default");
  add_meta_box("start_date", "Start Date", "start_callback", "job_or_internship", "side", "default");

function location_callback(){
  global $post;
  $custom = get_post_custom($post_ID);
  $location_callback = $custom["location_callback"];
  <label>Job Location:</label>
  <input name="year_completed" value="<?php echo $location_callback; ?>">

function start_callback() {
  global $post;
  $custom = get_post_custom($post_ID);
  $start_callback = $custom["start_callback"][0];
  <label>Start Date:</label>
  <input name="start_callback" value="<?php echo $start_callback; ?>">

add_action('save_post', 'save_details');
function save_details(){
  global $post;

  update_post_meta($post_ID, "location_callback", $_POST["location_callback"]);
  update_post_meta($post_ID, "start_callback", $_POST["start_callback"]);
share|improve this question
See this answer. – toscho Jun 8 '13 at 19:11
Where should that be added? I'm assuming in the save_details() function, but am I trying to wrap both update_post_meta()'s in this if? Can you give a little insight into what I should be trying to do? – Jake Lisby Jun 8 '13 at 19:18
up vote 4 down vote accepted

Register your save handler with two accepted arguments:

add_action('save_post', 'save_details', 10, 2 );

You get two important parameters now:

function save_details( $post_id, $post ) {}

The first is the post ID, the second the complete post object. Do not rely on a global post object. In some situations it is not available, bulk edit for example.

Then use a nonce filed in your metabox output to make sure you handle only values sent per your box:

echo wp_nonce_field( 'job_location', '_nonce_job_location' );

In your save handler validate the nonce with:

if ( ! wp_verify_nonce( $_POST[ '_nonce_job_location' ], 'job_location' ) )

During an auto-save request the extra fields are not sent, so do not do anything when DOING_AUTOSAVE ist defined:

if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE )

And test if the user is allowed to edit the current post:

if ( ! current_user_can( 'edit_post', $post_id ) )

After all these checks you can save or delete the data.

share|improve this answer
This is a great explanation. Thanks so much for your help with this! – Jake Lisby Jun 9 '13 at 20:08

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.