Skip to content

Visual Revisions fail to restore meta controlled by Classic Meta Boxes #78130

@karthikeya-io

Description

@karthikeya-io

Description

  1. Restoring a revision via the Visual Revisions screen does not successfully restore meta values that are controlled by a Classic Meta Box. However, meta controlled by a Gutenberg block/sidebar restores correctly. In the classic revisions screen, both restore properly.
  2. In the Visual Revisions sidebar, long meta keys overlap visually with the diff text values , making it unreadable.

#74742 (comment)

Step-by-step reproduction instructions

  1. Register one classic meta box and one Gutenberg sidebar meta field, ensuring both support revisions.
  2. Create a new post.
  3. Enter a value into the "Classic Meta Field" (meta box).
  4. Enter a value into the "Gutenberg Meta Field" (sidebar panel).
  5. Publish or save the post.
  6. Modify both values and update the post to generate a revision.
  7. Open the Visual Revisions screen.
  8. Observe the UI: Look at the "Meta" section in the right sidebar and notice that the long meta keys overlap with the value text.
  9. Click Restore to revert to the previous revision.
  10. Observe the result: The Gutenberg Meta Field will have successfully restored to its previous value, but the Classic Meta Field will remain at the newer value.
Code I used to register the meta:

<?php
/**
 * Plugin Name: MyGuten Separate Meta Test
 * Description: Classic meta box + Gutenberg sidebar meta field, both REST and revision enabled.
 * Version: 1.0.0
 */

if (!defined('ABSPATH')) {
    exit;
}

const MYGUTEN_CLASSIC_META_KEY = 'myguten_classic_meta_field';
const MYGUTEN_GUTENBERG_META_KEY = 'myguten_gutenberg_meta_field';

/**
 * Register meta fields.
 */
add_action('init', function() {
    $common_args = [
        'type'              => 'string',
        'single'            => true,
        'show_in_rest'      => true,
        'revisions_enabled' => true,
        'sanitize_callback' => 'sanitize_text_field',
        'auth_callback'     => function () {
            return current_user_can('edit_posts');
        },
    ];

    register_post_meta('post', MYGUTEN_CLASSIC_META_KEY, $common_args);
    register_post_meta('post', MYGUTEN_GUTENBERG_META_KEY, $common_args);
});

/**
 * Show meta fields in revisions
 */
add_filter( '_wp_post_revision_fields', function( $fields ) {
    $fields[ MYGUTEN_CLASSIC_META_KEY ] = 'Classic Meta Field';
    $fields[ MYGUTEN_GUTENBERG_META_KEY ] = 'Gutenberg Meta Field';
    return $fields;
} );

/**
 * Enqueue Block Editor Assets
 */
add_action('enqueue_block_editor_assets', function() {
    $script_path = plugin_dir_path(__FILE__) . 'sidebar.js';
    wp_enqueue_script(
        'myguten-meta-sidebar',
        plugin_dir_url(__FILE__) . 'sidebar.js',
        ['wp-plugins', 'wp-edit-post', 'wp-element', 'wp-components', 'wp-data', 'wp-core-data'],
        file_exists($script_path) ? filemtime($script_path) : '1.0.0',
        true
    );
});

/**
 * Classic Meta Box Setup
 */
add_action('add_meta_boxes', function() {
    add_meta_box(
        'myguten_classic_meta_box',
        'Classic Meta Field',
        'myguten_render_classic_meta_box',
        'post',
        'side'
    );
});

function myguten_render_classic_meta_box($post) {
    $value = get_post_meta($post->ID, MYGUTEN_CLASSIC_META_KEY, true);
    wp_nonce_field('myguten_save_classic_meta', 'myguten_nonce');
    
    printf(
        '<input type="text" name="%1$s" value="%2$s" style="width:100%%;" />',
        esc_attr(MYGUTEN_CLASSIC_META_KEY),
        esc_attr($value)
    );
}

/**
 * Save Classic Meta
 */
add_action('save_post_post', function($post_id) {
    if (!isset($_POST['myguten_nonce']) || !wp_verify_nonce($_POST['myguten_nonce'], 'myguten_save_classic_meta')) {
        return;
    }

    if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) return;
    if (!current_user_can('edit_post', $post_id)) return;

    if (isset($_POST['myguten_classic_meta_field'])) {
        update_post_meta($post_id, MYGUTEN_CLASSIC_META_KEY, sanitize_text_field(wp_unslash($_POST['myguten_classic_meta_field'])));
    }
});
( function ( wp ) {
    const { registerPlugin } = wp.plugins;
    const { PluginDocumentSettingPanel } = wp.editPost;
    const { TextControl } = wp.components;
    const { useSelect, useDispatch } = wp.data; // Added useDispatch for more control if needed
    const { useEntityProp } = wp.coreData;
    const { createElement: el } = wp.element;
    const { __ } = wp.i18n; // For translations

    const META_KEY = 'myguten_gutenberg_meta_field';

    function MyGutenMetaPanel() {
        const postType = useSelect( ( select ) => {
            return select( 'core/editor' ).getCurrentPostType();
        }, [] );

        if ( ! [ 'post' ].includes( postType ) ) {
            return null;
        }

        const [ meta, setMeta ] = useEntityProp( 'postType', postType, 'meta' );

        const value = meta?.[ META_KEY ] || '';

        const updateValue = ( newValue ) => {
            setMeta( {
                ...meta,
                [ META_KEY ]: newValue,
            } );
        };

        return el(
            PluginDocumentSettingPanel,
            {
                name: 'myguten-meta-sidebar-panel',
                title: __( 'Meta block Field', 'my-text-domain' ),
                className: 'myguten-meta-sidebar-panel',
            },
            el( TextControl, {
                label: __( 'Gutenberg Meta Field', 'my-text-domain' ),
                value: value,
                onChange: updateValue,
                help: __( 'This field saves to separate Gutenberg post meta.', 'my-text-domain' ),
            } )
        );
    }

    registerPlugin( 'myguten-meta-sidebar', {
        render: MyGutenMetaPanel,
        // Optional: icon: 'admin-settings',
    } );
} )( window.wp );

Screenshots, screen recording, code snippet

Classic Revisions Visual Revisions
classic-revisions.mp4
visual-revision.mp4

Environment info

No response

Please confirm that you have searched existing issues in the repo.

  • Yes

Please confirm that you have tested with all plugins deactivated except Gutenberg.

  • Yes

Please confirm which theme type you used for testing.

  • Block
  • Classic
  • Hybrid (e.g. classic with theme.json)
  • Not sure

Metadata

Metadata

Labels

[Feature] HistoryHistory, undo, redo, revisions, autosave.[Status] In ProgressTracking issues with work in progress[Type] BugAn existing feature does not function as intended

Type

No type
No fields configured for issues without a type.

Projects

Status
✅ Done

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions