Adding a custom WordPress editor via javascript

Working on a project today I needed to have 99 WordPress rich editors (powered by TinyMCE) on one page, and let me tell you, this absolutely kills the page load time!

In the first iteration I’d done this purely in PHP using wp_editor, like this…

$value = ''; //this is the current value if there is one
wp_editor($value, 'riklewis_textarea', array(
  'textarea_name' => 'riklewis_textarea',
  'textarea_rows' => '5',
  'teeny' => true,
));

The last parameter defines the editor settings, of which there are many, but I wanted to use “teeny” in order to reduce the toolbar down to a single line – I didn’t need the advanced options for this project.

Having added several seconds to the page load time, I knew I had to do something about this.  And then I remembered that the Advanced Custom Fields plugin had a WYSIWYG editor field type with a “Delay Initialization” option.  It’s nice, looks like this…

Then as soon as you click on the textarea, that’s when it changes into the editor, so quick you barely notice…

So I wanted to replicate the same kind of behaviour.  Immediately and predictably, I turned to Google.  Most of the advice I found looked really hacky and horrible, and I thought there must be a better way.

Then I discovered the correct way to do it, which was added in WordPress 4.8.  It uses a combination of PHP and javascript to let you initialise on the front end, when you’re ready.  For example, it could be on an AJAX response, or some user interaction.

Firstly you need to make sure that the javascript files required are enqueued, which is easily done…

function riklewis_admin_scripts() {
  if($something===true) { //add a condition - don't do this on every admin page!
    wp_enqueue_editor();
  }
}
add_action('admin_enqueue_scripts', 'riklewis_admin_scripts');

You also need to output the textarea field that’s going to be converted to the rich editor…

echo '<textarea id="riklewis_textarea" name="riklewis_textarea" rows="5">' . $value . '</textarea>';

Then you need to initialise the editor like this…

wp.editor.initialize("riklewis_textarea", {
  tinymce: true,
  quicktags: true
});

The wp variable should be in the global scope, if you’ve correctly enqueued the javascript (see above).  This automatically uses the default WordPress editor settings, as long as you switch on “Visual” (tinymce) and/or “Text” (quicktags) – took me some debugging to figure this part out.

I couldn’t see any way of setting “Teeny” to match what I had originally, but I found that I could override the toolbar buttons like this…

jQuery(document).on('tinymce-editor-setup', function (event, editor) {
  editor.settings.toolbar1 = 'bold,italic,underline,blockquote,strikethrough,bullist,numlist,alignleft,aligncenter,alignright,undo,redo,link'; //Teeny -fullscreen
});

For a full list of toolbar button options, take a look at the toolbar control documentation.

In the end I decided that I didn’t want the user to start with the textarea, so I actually hid that and displayed the current value as rendered HTML, with a button to launch the editor…

When this button is clicked the textarea is shown and the editor is initialised, as well as hiding the rendered HTML, so it looks like this…

Now my page load time is back to how it was before, and I’m very happy with the final result.  I also decided to switch off the “Text” mode by setting “quicktags” to false.

I hope it takes you less time to find this post then it took me to figure out this was the correct, up to date, way of achieving this!