Extending the WordPress editor as part of a custom theme

Categories Guides ,

In software development recognizing the “proper” way, according to principles such as reusability, simplicity, and isolation, is one edge of a sword that cuts in both directions. Many will find a gut instinct against coding hacks that don’t reach those goals, even if the efficiency they generate frees up more time in other areas.

What’s discussed here is likely not a technique you’d want to use in building something professionally. It’s a shortcut towards adding bespoke features quickly. Are there better ways? Absolutely. Worthy of your time? ¯\_(ツ)_/¯

 Making your template a TinyMCE plugin

So let’s throw reusability/isolation out the window, and stick with simplicity. We don’t have to create a separate plugin, in name, scope, packaging, version-control, etc. to add new features. We’ll settle for separate files/folders within our theme itself.

TinyMCE is at it’s core a JavaScript application, so we’re going to add a JS file to our theme.

Create the file theme/js/tinymce.plugin.js

(function () {
    tinymce.PluginManager.add('theme_custom_plugin', function (editor, url) {
      // plugin code will go here
    });
})();

Now add the following to theme/functions.php

function my_mce_external_plugins($plugin_array)
{
    $plugin_array['theme_custom_plugin'] = get_template_directory_uri() . '/js/tinymce.plugin.js';
    return $plugin_array;
}
add_filter('mce_external_plugins', 'my_mce_external_plugins');

That was easy … and now we have a custom TinyMCE plugin to play with.

 Plugin usage examples

What can we do with it? Chances are if you’re reading this, then you already know why you wanted to add something to the WordPress editor, and since it’s just TinyMCE there are plenty of resources out there. If so, maybe skip to the last section of this post. Otherwise, example incoming…

Menu of parameterized HTML snippets

This is one of my favorites. A TinyMCE menu of dialogs that ask for inputs, and generates structured output in the editor. For blogs where you’re wearing all the hats, theming, coding, writing … it’s a wonderful optimization you’re in total control of. In the case of BinaryBabel.org, here’s a couple of shortcuts for using Highlight.js and FontAwesome.

 » 

Add the following to your theme/js/tinymce.plugin.js file

editor.addButton('my_insert', {
    type: 'menubutton',
    text: 'Insert Custom',
    menu: [
        {
            text: 'Code',
            onclick: function () {
                editor.windowManager.open({
                    title: 'Insert Code',
                    body: [{
                        type: 'textbox',
                        name: 'lang',
                        label: 'Language'
                    }, {
                        type: 'textbox',
                        name: 'code',
                        label: 'Snippet',
                        multiline: true,
                        minWidth: 400,
                        minHeight: 200
                    }],
                    onsubmit: function (e) {
                        var entityMap = {
                            '&': '&',
                            '<': '&lt;',
                            '>': '&gt;',
                            '"': '&quot;',
                            "'": '&#39;',
                            '/': '&#x2F;',
                            '`': '&#x60;',
                            '=': '&#x3D;'
                        };
                        var code = String(e.data.code).replace(/[&<>"'`=\/]/g, function (s) {
                            return entityMap[s];
                        });
                        editor.insertContent('<pre class="code ' + e.data.lang + '">' + code + '</pre>');
                    }
                });
            }
        },
        {
            text: 'Icon',
            onclick: function () {
                editor.windowManager.open({
                    title: 'Insert Icon',
                    body: [{
                        type: 'textbox',
                        name: 'i_class',
                        label: 'Icon Class'
                    }],
                    onsubmit: function (e) {
                        editor.insertContent('<i class="' + e.data.i_class + '"></i>');
                    }
                });
            }
        }
    ]
});

Add the following to theme/functions.php

function my_mce_buttons($buttons)
{
    array_push($buttons, 'my_insert');
    return $buttons;
}
add_filter('mce_buttons', 'my_mce_buttons');

 Where to now captain?

  • Take a look at the TinyMCE Advanced Topics section for more information on adding buttons and features to TinyMCE.
    • Place any editor related javascript into your theme’s tinymce.plugin.js
  • Take a look at the WordPress Codex for information on setting TinyMCE configuration options.
    • Place any configuration changes into functions.php