Using CodeMirror CSS Editor in a WordPress Widget

WordPress uses CodeMirror for the CSS editor within its Customiser. CodeMirror provides support for syntax highlighting, linting, and code competition. Would it not be great to be able to use that in your own Widget?

>>> This article has been updated following the release of WordPress 5.8. WordPress 5.8 introduced the block editor to widget areas. Traditional widgets were still supported. However, the method, as described here, to monitor the visibility of CodeMirror element required updating.

First off, we are going to start with a basic bare-bones demo widget that allows the user to input some text to be displayed and the CSS styling to apply.

Screenshot of a basic WordPress Widget with test and testarea input boxes
Bare Bones Widget Form

This is the code for our bare-bones widget, placed into WordPress’s plugins directory. E.g. plugins/demo-css-widget/demo-css-widget.php.

When placed within a Sidebar or other widget area, the end result, using the widget’s default CSS it should look similar to this: –

Large Hello World Message in Blue
Example Output on Website

So far, we are only using a plain old, nothing fancy, <textarea> to edit our CSS. Using CodeMirror will require some JavaScript. To do this we add the following to our widget’s PHP code:-

$demo_cm_settings is used to specify settings to be passed to CodeMirror. We are creating these in PHP and localising them to a JavaScript object called demo_cm_settings. This object will be available within our JavaScript file admin.js. You can view available options in CodeMirror’s manual here.

When using CodeMirror we specify an existing <textarea>. CodeMirror dynamically modifies the webpage, creating its own elements and takes the existing content from our <textarea> and places it into its own interface.

Before we go into the details of our JavaScript we need to amend the Widget’s form rendering to invoke our JavaScript function.

The next step is to create our supporting JavaScript file that contains our main function demo_init_widget_css_editor(). I found that if the textarea was not visible when initialising CodeMirror the UI did not render correctly. To overcome this we are checking WordPress’s widget container to see if it is expanded or not. If not, we are creating a MutationObserver to delay initialisation until it is.

>>> From WordPress 5.8 traditional widgets are wrapped with new elements. As such, we need to monitor the visibility on the textarea by looking at different parent.

In function demo_init_widget_codemirror() a listener on CodeMirror’s change event is created. When invoked we obtain the text from the CodeMirror object and place that into our now hidden <textarea>. We also invoke the textarea’s change event to ensure that WordPress enables the form’s save button.

In the document ready() function a listener for WordPress’s widget-added event is created. This is to ensure that we initialise CodeMirror when our widget is added to a widget area (e.g. a sidebar) when working with WordPress’s customizer or admin pages. We are checking to see if the new widget is an instance of our widget by looking for an item with class my-demo-css-editor-textarea. This is the class name we have given to our <textarea> element.

After putting all this together our widget’s form should now look similar to this:

Screenshot of CCS Editor in a WordPress Widget
CSS Editor in a WordPress Widget’s Admin Form

And that’s it. Here is final version of our demo-css-widget.php.

Leave a Reply

Your email address will not be published. Required fields are marked *