Syncing custom TinyMCE and Quicktags editors for instant update

Published: · Reading time: 5 min

When implementing an instant update preview area with the WordPress Classic Editor, an appearance issue arises when working in different modes. This problem, its causes, and the solution are explained below.

  1. Problem
  2. How it works in WordPress
  3. Solution

Problem

When utilizing the WordPress Classic Editor for implementing an instant update of a specific preview area, the content renders differently based on the editing mode.

This discrepancy arises because the Classic Editor in WordPress has two modes, each with a separate text editor:

  1. Visual mode uses the TinyMCE editor
  2. Text mode uses the Quicktags editor
WordPress Classic Editor
WordPress Classic Editor

TinyMCE is a WYSIWYG editor that produces ready-to-use HTML code, while the Quicktags editor is a simple text editor allowing users to manually insert HTML tags.

💡 NOTE: As of time of writing this article the WordPress was using a version 4.9.11 of TinyMCE editor.

On the other hand the Quicktags editor is a simple Text editor, which allows users to insert HTML tags manually.

The issue occurs when switching between modes, leading to potential stripping of changes, such as tags, from the Quicktags editor. This can result in undesired outcomes when instantly outputting content to a designated area, as the HTML differs.

Notably, this is visible for text content, displayed as paragraphs in Visual mode and as regular text in Text mode.

WordPress Classic Editor Visual mode
Visual mode
WordPress Classic Editor Text mode
Text mode

How it works in WordPress

In the WordPress View page, there is no visible difference; the output text appears exactly as it does in the TinyMCE (Visual mode), even if edited in the Quicktags editor (Text mode).

This consistency is achieved through the application of the wpautop function, which wraps text inside a p element after saving or publishing a post.

Solution

When creating a custom text editor in WordPress, such as in a plugin, and aiming to mimic its logic, synchronization of values in both editor modes is necessary.

Assuming the Classic Editor is initialized with both modes, here’s how to sync the values:

You can store the value of the editor in a variable, since the TinyMCE is the default one, you can get its value and store as a default:

let editorValue = window.tinymce.activeEditor.getContent()

The editorValue variable will hold the editor value, which you can use to insert in a live preview area. E.g.:

const preview = document.getElementById('preview')

preview.innerHTML = editorValue

The TinyMCE will have its own change handler function which you can specify when initializing. Inside the change handler function you should write the TinyMCE editor’s value to the editorValue variable.

const id = 'editor'
let editorValue = window.tinymce.activeEditor.getContent()

window.tinymce.init({
  id: id,
  selector: '#' + id,
  setup: function(editor) {
    editor.on('keyup change undo redo', (e) => {
      editorValue = editor.getContent()
    })
  }
})

For the Quicktags editor, we need to add an eventListener, and run the value of the textarea through the wpautop function.

Since WordPress has only a PHP version of the wpautop function, we can use a JavaScript version of the this funciton.

You can install it as an npm package or copy paste it from GitHub.

import wpautop from 'wpautop'

const id = 'editor'
let editorValue = window.tinymce.activeEditor.getContent()

window.QTags.instances[id].canvas.addEventListener('keyup', (e) => {
  const formattedValue = wpautop(e.target.value)
  editorValue = formattedValue
})

Now, the content value is stored in one place, ensuring consistency between the editor modes. This prevents visual artifacts and glitches when working in both modes.

Like this article? Share it on: