Enable / Add Custom Keyboard Shortcuts To Work With WordPress’ HTML Editor

The toolbar / editor used on Stack Exchange websites (and in my plug-in WP-MarkDown) is PageDown.

This comes with three JavaScript files:

  • One that handles MarkDown to HTML conversion
  • One that handles sanitization
  • One that handles the editor (the toolbar and previewer)

Included in the latter are the MarkDown keyboard shortcuts you mentioned.

The following hasn’t been tested, but just aims to give an outline of what you need to do.

Step 1: Register & Enqueue JavaScript and styles

To get this to work on the WordPress editor first register and enqueue the above scripts (point to the correct location in your plug-in). (I’m not sure if you need to register scripts when they have dependencies prior to en-queuing them)

Since this is only for the admin we use admin_enqueue_scripts. You’ll also want to check

  • We are on the correct admin page
  • The post type (in case MarkDown is only enabled for a certain post type)

Also, a function is hooked onto the admin footer. This will print JavaScript in the footer. (You could put it in a separate file, register it and enqueue it here, but it needs to be loaded after the script for the bog standard WordPress toolbar is loaded). Hence the priority number: 100.

add_action('admin_enqueue_scripts', 'wpse49449_admin_scripts',10,1);
function wpse49449_admin_scripts($hook){
    $screen = get_current_screen();
    $post_type = $screen->post_type;

        //Enqueue only on page needed and only for the relevant post type
        if ( ('post-new.php' == $hook || 'post.php' == $hook) && $post_type == 'post' ){
             $plugin_dir = plugin_dir_url(__FILE__);
             wp_register_script('my_md_convert', $plugin_dir. 'js/pagedown/Markdown.Converter.js',array(),'1.1' );
             wp_register_script('my_md_sanit', $plugin_dir.'js/pagedown/Markdown.Sanitizer.js',array(),'1.1' );
             wp_register_script('my_md_edit',$plugin_dir. 'js/pagedown/Markdown.Editor.js',array('my_md_convert','my_md_sanit'),'1.1' );

             wp_enqueue_script('my_md_edit');
             wp_enqueue_script('jquery');

             wp_enqueue_style('my_md_style',$plugin_dir.'css/demo.css');

             add_action( 'admin_print_footer_scripts', 'wpse49449_admin_footers_script',100 );
    }
}

Step 2: Disable TinyMCE editor where appropriate

The TinyMCE will need to be disabled. But only disable it for post types where you are using the MarkDown editor. To disable the TinyMCE editor:

add_filter( 'user_can_richedit', 'wpse49449_disable_tinymce_editor'), 99 );
function wpse49449_disable_tinymce_editor(){
    //Get post type
    $screen = get_current_screen();
    $post_type = $screen->post_type;

    //Disable depending on post type

    //Return 'false' to disable TinyMCE, 'true' otherwise. 
    return false;
}

Step 3: Replace the ‘standard’ editor toolbar with the MarkDown toolbar

As noted above the function wpse49449_admin_footers_script prints some JavaScript in the footer. It

  • adds the ‘preview’ box after the text editor, #wp-content-editor-container
  • replaces the default toolbar #ed_toolbar with the MarkDown toolbar.
  • initializes the MarkDown->HTML converter
  • initializes the MarkDown editor

The function:

  function wpse49449_admin_footers_script(){
    ?> <script>

    jQuery(document).ready(function($) {                
        $('#wp-content-editor-container').after("<div id='wmd-previewcontent' class="wmd-panel wmd-preview prettyprint"></div>");

        $('#ed_toolbar').html("<div id='wmd-button-barcontent'></div>");

        var converter = new Markdown.getSanitizingConverter();
        var editor = new Markdown.Editor(converter, 'content');
        editor.run();
    });
    </script>
     <?php
    }

That should get you started :).

Step 4 Editor.js ‘workaround’

The JavaScript file Markdown.Editor.js assumes that the text area ID will be "wmd-input" + postfix where postfix is a variable set as ‘content’ in this line in step 3:

var editor = new Markdown.Editor(converter, 'content');

The problem is that the ID of the textarea is content not wmd-input. We don’t want to change the ID of the textarea, so instead we can alter the function responsible for telling the MarkDown editor the IDs of the toolbar, preview and text area (around line 249 I believe). We change this:

function PanelCollection(postfix) {
    this.buttonBar = doc.getElementById("wmd-button-bar" + postfix);
    this.preview = doc.getElementById("wmd-preview" + postfix);
    this.input = doc.getElementById("wmd-input" + postfix);
};

to this:

function PanelCollection(postfix) {
    this.buttonBar = doc.getElementById("wmd-button-bar" + postfix);
    this.preview = doc.getElementById("wmd-preview" + postfix);
    this.input = doc.getElementById(postfix);
};

Leave a Comment