This article explains how to implement inline CSS styles for your TinyMCE editor based on color settings in the WordPress Customizer.
I’ve been working on a highly customized version of the WordPress Twenty Sixteen theme that I call “Beyond 2016”. It has some nice features like supporting Sass and Archive styles, more header layouts, and per page layout options. And you can download and test it now from Github if you like.
Last year, when I was building my Matt2015 child theme, I implemented Editor Formats into a theme for the first time. Since then I’ve been more and more convinced that Editor Formats can do A LOT for the WordPress editor if implemented well.
One wishlist item I’ve had to experiment with that idea is being able to dynamically generate CSS styles for the editor based on my Customizer settings. Only recently did I reach out to our handy-dandy Advanced WordPress Facebook group for help on this issue.
TL;DR (what does that mean?)
You can accomplish this by hooking into the tiny_mce_before_init hook and calling and customizing the $mceInit value. Tutorial below.
Why I Still Value AWP
If you have been a member of our Advanced WordPress Facebook group for a year or more, then you most likely know that the “advanced” value of that group waxes and wanes greatly over time. Very often it’s a great Q&A forum for less than advanced questions. Occasionally it turns into the mecca of #wpdrama. Often it’s just a hub for all thing WordPress. But increasingly rarely is it actually a place to discover truly “advanced” material.
I’ll save that full discussion for another post. For this post, I just want to say that understanding how to hook into the TinyMCE editor effectively for my wishlist was “advanced” for me and the group delivered through two very effective developers who took my challenge by the horns and made it happen:
- Kevin Hoffman is a guy I’ve always only known through our FB group and through our Slack channel. Yet the more we interact, the more I really like the guy. When I posted my question about dynamic TinyMCE styles he not only dug into the Core code for his own potential solution (which worked, but neither of us particularly liked it), he also reached out to Developer #2 for assistance.
- Samuel Wood, aka Otto, was pinged by Kevin and Otto was convinced that this could be done without having to “write” files to WordPress (which was Kevin’s solution). He circled back the next day on the subject and provided the snippet which Kevin and I both customized to do exactly what is needed. Otto also happens to be one of the lead members of the Plugin Review Team and a very long-time Core committer and .org volunteer.
So, that was most recent experience with leaning on AWP for “advanced” coding and it paid off in dividends for me, and I’ve been a member since we only had roughly 200 members (now we have 21,000+ !!!).
So, why is this issue so difficult? First, it is actually very easy to call custom CSS styles into the TinyMCE editor. That can be done with one line of code:
add_editor_style( 'editor_styles.css' );
The problem with that approach is that it’s a static CSS file, you can’t dynamically affect the styles from your Customizer settings.
So, my Googling first came up with using a PHP file and tricking your server into treating it like a CSS file. None other than Chris Coyier of CSS-Tricks provided the code to do that. And it works! You can totally do that. It just feels sooooooo wrong.
Then I thought about how Twenty Sixteen itself generates styles dynamically. It doesn’t trick your server into treating PHP files as CSS files. It creates them on the fly as inline-styles and writes them into the header. There HAD to be a way to do that but in TinyMCE directly.add_editor_style() unfortunately doesn't allow for styles generated from the Customizer. Click To Tweet
Otto to the Rescue
Here’s the solution that Otto suggested:
As you can see, he hooks into this:
add_filter( 'tiny_mce_before_init', 'kwh_add_editor_style' );
That allows you to access the array $mceInit, which outputs the default inline styles of all TinyMCE editors in WordPress.
From there, you just have to append your styles to the existing inline styles. That’s why you’ll see the comments about adding spaces before and after your styles — accounting for other styles that might come before or after your own styles.
It’s an elegant and “best practices” focused solution. Highly recommended!
Combining Editor Formats with Dynamic Styles
So here’s why I find it such a great tool. I mean, changing the background color of your editor really isn’t anything to jump up and down about. But in my case, I want to provide some useful Editor Formats which are pure HTML/CSS — no shortcodes — and that look exactly how they will look in the front-end. That’s the big wishlist item, giving users an editor that actually resembles what the post will really look like.
Here’s a preview of what I’ve got going in Beyond 2016 now:
So you’ll notice a couple things happening there:
- I have a “Block Text” item which is my main Editor Style at the moment. It has stylized fonts, border, colors.
- When I switch to one of my custom Beyond 2016 color schemes, the Block Text reflects that change completely.
- If you’re paying close attention you’ll see the background color changes, the heading colors change, and the paragraph and link colors change as well.
All together, the Editor visual styles look VERY similar to what is output on the front-end. All of this is done with Core functions, without the need of a Page Builder or Front-End editor at all.
It’s Not a Silver Bullet
Just like I said in my Editor Formats article, this method isn’t going to replace Page Builders and Front-End editors. Those still have a really great place in WordPress in general.
But consider how many WordPressers really just type into the editor and hit publish. That’s a huge amount of people. Don’t they deserve some attention to detail to make their publishing experience nice and smooth?
If you are a Theme Author and have implemented either Editor Formats or Dynamic Editor Stlyes, I’d love to give your theme a spin and see what it’s like. I believe this should be common practice for theme authors but I’m just not seeing it overall.