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 want to save two versions of my custom meta box data called "sidebar". I want to compare a new and old version of this data later on, so that is why I want to save a copy of the current "sidebar" to a field called "sidebar_old", just before saving a new version. Here's my attempt at doing just that:

add_action('pre_post_update', 'content_old_save');

function content_old_save() {
    global $post;
    $sidebar_old = get_post_meta($post->ID, 'sidebar', true);

    update_post_meta($post->ID, "sidebar_old", $sidebar_old); // current/old sidebar

This is how I save the new version:

add_action('save_post', 'sidebar_title_update');

function sidebar_title_update($post_id) {
    global $post;

    if ( defined('DOING_AUTOSAVE') && DOING_AUTOSAVE ) {
    return $post_id;

    update_post_meta($post->ID, "sidebar", $_POST["sidebar"]); // new sidebar

Thing is, only the new sidebar value is inserted into the database, to both "sidebar" and "sidebar_old", so somehow the new value is already inserted into the db even before pre_post_update?

share|improve this question
up vote 3 down vote accepted

that could be caused by post revision being saved, and you should use wp_insert_post_data anytime you want to do something before the post is saved, here is an example plugin i just cooked up to test it and it looks like this:

enter image description here

Plugin Name: wpse37901
Plugin URI: http://en.bainternet.info
Description: answer to  http://wordpress.stackexchange.com/questions/37901/save-both-current-and-new-version-of-post-meta
Version: 1.0
Author: Bainternet
Author URI: http://en.bainternet.info

add_action('save_post', 'sidebar_title_update');

function sidebar_title_update($post_id) {
    // verify if this is an auto save routine. 
    // If it is our form has not been submitted, so we dont want to do anything
    if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) 

    // verify this came from the our screen and with proper authorization,
    // because save_post can be triggered at other times

    if ( !wp_verify_nonce( $_POST['wpse37901_noncename'], plugin_basename( __FILE__ ) ) )

    // Check permissions
    if ( 'post' == $_POST['post_type'] ) 
        if ( !current_user_can( 'edit_post', $post_id ) )

    // OK, we're authenticated: we need to find and save the data

    if (isset($_POST['sidebar'])){      
        //save new
        update_post_meta($post_id, "sidebar", $_POST["sidebar"]); // new sidebar

add_action( 'add_meta_boxes', 'wpse37901_add_custom_box' );

function wpse37901_add_custom_box() {
        __( 'wpse37901 test field'),


function wpse37901_store_revision($data,$postarr){
    global $post;
    if ($data['post_type'] !== 'revision' && isset($_POST['sidebar'])){
        //save old
            //get last saved data
        $sidebar_old = get_post_meta($post->ID, 'sidebar', true);
            //only store if value updated
        if ($_POST['sidebar'] != $sidebar_old){
                //get stored revisions
            $sidebar_old_saved = get_post_meta($post->ID, 'sidebar_old', true);
                //add last to revisions
            $sidebar_old_saved[] = array('date' => date("j, n, Y  H:i:s"), 'value' =>$sidebar_old);
                //update revisions array
            update_post_meta($post->ID, "sidebar_old", $sidebar_old_saved);
    return $data;

function wpse37901_inner_custom_box( $post ) {
    // Use nonce for verification
    wp_nonce_field( plugin_basename( __FILE__ ), 'wpse37901_noncename' );

    $sidebar_saved = get_post_meta($post->ID, 'sidebar', true);
    // The actual fields for data entry
    echo '<label for="sidebar">';
    _e("For testing");
    echo '</label> ';
    echo '<input type="text" id="sidebar" name="sidebar" value="'.$sidebar_saved.'" size="25" />';
    $sidebar_revisions = get_post_meta($post->ID, 'sidebar_old', true);
    if (!empty($sidebar_revisions)){
        if (is_array($sidebar_revisions)){
            echo '<ul>';
            foreach($sidebar_revisions as $r){
                echo '<li>'.$r['date'].' : '.$r['value'].'</li>'; 
            echo '</ul>';

share|improve this answer
Thank you very much, this works just great! – Marc Jan 5 '12 at 8:47
Glad i could help :) – Bainternet Jan 5 '12 at 10: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.