A few years ago (2015) to be exact, I needed a way to to be able to highlight some code on my website. At the time I was writing example filters for my free plugins with the developer docs pages.
I went to the community to see what I could find and came up with a plugin called WP-Syntax. This plugin had a few shortcomings so I ended up creating and maintaining a fork or it (which admittedly I often do with any 3rd party code I use)
WP-Syntax allowed for adding special <pre lang="php">
tags within the content which would automatically format and highlight code blocks. There is no UI for doing this so each block has to be manually adjusted using the the text tab of the editor. I had been using this tedious yet successful process for a long time.
But then then something magical happened…. WordPress code decided to bring back an originally scrapped idea from version 2.8 and bring code formatting to WordPress core!
WordPress core decided to integrate Codemirror as their new official code highlighting library. As you will often hear me preach, “when something becomes available in core, it is our duty as engineers to use it as the new default”. Using a code library keeps our code consistent and performant.
That takes care of the what and why, so now for the how.
To understand these obstables, one first must understand the nature of Codemirror. Codemirror uses JavaScript to target specified <textarea>
elements and turn them into code blocks based on coding language.
Obstacle #1
The first obstacle to overcome was a secret feature I built into the support area of this site which allows quick entering of code blocks into support comments via a tinymce plugin. I say “secret” because it is only available to users logged in as admins and the general public is not aware of it.
The tinymce plugin takes a block of code and wraps it in a special <code>
tag with a class
attribute specifying the language. Originally we would then replace the <code>
tag with a <pre>
tag during render so WP-Syntax could pick it up. To convert code generated by this tinymce plugin was easy enough. I simply updated the regular expression to change the <code>
into <textarea>
instead of <pre>
and we have a target-able element.
Once I had the <textarea>
in place I was able to write some JavaScript that would use the WordPress core version of Codemirror to format the code. Using the class
attributes I was able to determine the code language and everything was working as desired.
Obstacle #2
The second obstacle was converting all of the existing code block over to codemirror. As I mentioned previously, WP-Syntax used <pre>
to target code blocks but Codemirror uses <textarea>
.
I was able to write some regular expression which detected the original code blocks and converts them to the new format when a post or page is rendered. I mirrored the output to result from Obstacle #1.
Obstacle #3
Here is where it gets interesting.
WordPress 5.0 officially introduced the new block editor called Gutenberg.
If you haven’t tried Gutenberg yet, you need to. It’s the future that’s coming faster than you can imagine. Gutenberg brings a new idea to editing called “blocks”. Blocks means entering sections of special content (such as blocks of code) may be achieved by a single click or drag and drop.
This brings me back to Codemirror. With my site now supporting Gutenberg, the tedium of manually entering special <pre>
tags feels unbearable. So why not have a Codemirror block?
I did some research and found 2 existing plugins which offer a Codemirror block. Both are very cool and work seemingly fine. However, both of them roll their own version of Codemirror. While this is fine, it goes against my original belief “when something becomes available in core, it is our duty as engineers to use it as the new default”. I simply can’t justify adding a plugin to my site which loads a library which is already loaded in WordPress core. I want my site to change as WordPress core changes and not compete.
So I built my own block. A block which using the built in Codemirror.
Here are a couple of example of it in action.