Gutenberg: Codemirror Field Formatting Broken and Not Saving In Meta Box

Created on 2 Feb 2019  路  10Comments  路  Source: WordPress/gutenberg

When using Codemirror with a textarea meta box field, there are 3 issues:

  1. Textarea appears blank until it is clicked on.
  2. The line numbers do not have a proper gutter and cover the content.
  3. The value does not save when the post is updated.

I have confirmed this issue exists when using vanilla meta boxes as well as 3rd party libraries such as CMB2 and ACF.

Here is a screenshot of what the textarea looks like before clicked on:
image

Here is a screenshot of what the textarea looks like once clicked on:
image

I have confirmed the issue on multiple sites and themes.

To Reproduce
For the purposes of this test case I am using the following specs:

  1. WordPress 5.0.3
  2. Twentynineteen theme.
  3. No plugins.
  4. Linux based Apache2.

Here is very crude code added directly to the functions.php file of the theme:

  1. Registers the meta box.
  2. Queues necessary code mirror calls.
  3. Saves the meta box on post save.
add_action( 'add_meta_boxes_page', 'codemirror_test_register_meta_box' );
add_action( 'save_post_page', 'codemirror_test_save_meta_box');
add_action( 'admin_enqueue_scripts', 'codemirror_test_que_code_editor' );
function codemirror_test_que_code_editor() {
    wp_enqueue_code_editor( array(
        'type'       => 'htmlmixed',
    ));
    wp_add_inline_script( 'code-editor', '
        jQuery( document ).ready( function() {
           wp.codeEditor.initialize( $( \'[id="codemirror-test-field"]\' ) );
        });'
    );
}
function codemirror_test_register_meta_box() {
    add_meta_box( 'codemirror-test', 'Codemirror With Block Editor Enabled Test', 'codemirror_test_render_meta_box', 'page', 'advanced', 'default');
}

function codemirror_test_save_meta_box( $post_id ) {
    if ( wp_is_post_autosave( $post_id ) ) {
        return;
    }
    if ( isset( $_POST['codemirror-test-field'] ) ) {
        update_post_meta( $post_id, 'codemirror-test-field', $_POST['codemirror-test-field'] );
    } else {
        delete_post_meta( $post_id, 'codemirror-test-field' );
    }
}

function codemirror_test_render_meta_box( $post ) {
    ?>
    <textarea
            id="codemirror-test-field"
            class="widefat"
            name="codemirror-test-field"
            rows="8"><?php echo esc_textarea( get_post_meta( $post->ID, 'codemirror-test-field', true ) ); ?></textarea>
    <?php
}

If I use a filter to turn off the block editor and bring back the classic editor the meta box works as expected with correct formatting and saving of data.

add_filter( 'use_block_editor_for_post_type', '__return_false' );

image

[Feature] Meta Boxes [Type] Help Request

Most helpful comment

Encountered the same problem regarding the field formatting but I found a solution to this.

If you add a key called codemirror to the wp_enqueue_code_editor array then you can configure the editor a bit more. In this array you need to set autoRefresh to true and this should solve the problem as shown in the initial screenshots above.

My solution:

wp_enqueue_code_editor(array(
      'type' => 'text/html',
      'codemirror' => array(
            'autoRefresh' => true
      )
   ));

Also note that I don't think you can set the type to htmlmixed in the wp_enqueue_code_editor itself. As quoted here:

wp_enqueue_code_editor( array(
'type' => 'htmlmixed',
));

Wordpress is looking for a different kind of "type" which it then checks against a list of possible entries. Wordpress then appends a number of options to the settings for CodeMirror. So if you use 'type' => text/html (as shown in my solution) it will set the mode of CodeMirror to htmlmixed plus a number of predefined options which work well with HTML. For full control of the configuration just add your desired settings to the codemirror array alongside the autoRefresh key.

Checkout the Wordpress source for other acceptable "types" and the options that each of them append: https://developer.wordpress.org/reference/functions/wp_get_code_editor_settings/#source

Also check out the CodeMirror manual for further reference about "autoRefresh" along with the other things you can configure: https://codemirror.net/doc/manual.html#addon_autorefresh

Hope this helps to fix the field formatting part of the problem!

All 10 comments

Are there any JavaScript errors in the console? Any additional information might help.

No console errors and no PHP errors.

Hello! I can reproduce this, and have additional info. This has been the main reason I've been unable to convert sites over to the new editor.

STEPS TO REPRODUCE:

  1. add custom metabox to page edit screen
  2. add textarea and apply CodeMirror editor via wp_enqueue_code_editor

SYMPTOMS (same as above):

  1. appears empty on page load, content appears when in focus
  2. formatting is off - indentation of content is underneath and to left of line numbers, etc.
  3. content does not update on save.

For the content not updating on save, it may be similar to this issue:
https://github.com/WordPress/gutenberg/issues/7176
...but for CodeMirror instead of TinyMCE.

In case the symptoms are dependent on how things are built, here's a Gist example of a 1-file plugin that illustrates this issue. It will add a CodeMirror editor in a metabox on the page edit screen, for adding and loading page-specific CSS. I'm testing on a blank installation of WP 5.0.3 and the Twenty Nineteen theme (1.2).
https://gist.github.com/mindpalette/dc8c9a38feb2dfa6bcaccd9d79dd12b1

The plugin should function normally if you disable/remove the block that loads CodeMirror, on lines 59 - 69:

// apply code editor /* $settings = wp_enqueue_code_editor( array( 'type' => 'text/css' ) ); if (false !== $settings) { wp_add_inline_script( 'code-editor', sprintf( 'jQuery( function() { wp.codeEditor.initialize( "'.$f.'", %s ); } );', wp_json_encode( $settings ) ) ); } */

I'm having the same issue. Was trying to copy the codemirror values over to the textarea via javascript but haven't had much luck. Let me know if you have any other ideas!

I have the same problem. But it has been solved by switching to classic editor. New wordpress editor (Gutenberg) may cause the confict with Codemirror.
add_filter('use_block_editor_for_post', '__return_false');

If someone is looking for a solution with Advanced Custom Fields, the plugin ACF Code Field has been updated to work with Gutenberg. Maybe this can also be used to provide insight on how to get CodeMirror to work with Gutenberg.

Encountered the same problem regarding the field formatting but I found a solution to this.

If you add a key called codemirror to the wp_enqueue_code_editor array then you can configure the editor a bit more. In this array you need to set autoRefresh to true and this should solve the problem as shown in the initial screenshots above.

My solution:

wp_enqueue_code_editor(array(
      'type' => 'text/html',
      'codemirror' => array(
            'autoRefresh' => true
      )
   ));

Also note that I don't think you can set the type to htmlmixed in the wp_enqueue_code_editor itself. As quoted here:

wp_enqueue_code_editor( array(
'type' => 'htmlmixed',
));

Wordpress is looking for a different kind of "type" which it then checks against a list of possible entries. Wordpress then appends a number of options to the settings for CodeMirror. So if you use 'type' => text/html (as shown in my solution) it will set the mode of CodeMirror to htmlmixed plus a number of predefined options which work well with HTML. For full control of the configuration just add your desired settings to the codemirror array alongside the autoRefresh key.

Checkout the Wordpress source for other acceptable "types" and the options that each of them append: https://developer.wordpress.org/reference/functions/wp_get_code_editor_settings/#source

Also check out the CodeMirror manual for further reference about "autoRefresh" along with the other things you can configure: https://codemirror.net/doc/manual.html#addon_autorefresh

Hope this helps to fix the field formatting part of the problem!

@Demaine It works, Thank you!

I found a workaround to resolve the saving problem. Just copy the code back to the textarea on any change in the Gutenberg editor.

wp.data.subscribe(function () {
    // Obtain the CodeMirror instance
    var cm = jQuery('#codemirror-test-field').next('.CodeMirror').get(0).CodeMirror;
    cm.save(); // copy the content of the editor into the textarea.
});

Looks like there are some decent solutions proposed here. Thanks for your replies.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

mhenrylucero picture mhenrylucero  路  3Comments

ellatrix picture ellatrix  路  3Comments

moorscode picture moorscode  路  3Comments

spocke picture spocke  路  3Comments

JohnPixle picture JohnPixle  路  3Comments