How to use the new Dashicons for custom TinyMCE buttons?

I’ve been following a tutorial on Tuts+ (linked from the WordPress Codex) on how to interact with the TinyMCE editor to add buttons. Following the example code on that article, I have a JS file which adds the buttons to TinyMCE. The relevant snipped of JS that adds the icon is:

ed.addButton('dropcap', {
    title : 'DropCap',
    cmd : 'dropcap',
    image : url + '/dropcap.png'
});

Now this was fine pre WP 3.8, however since Dashicons were introduced it looks outdated to use static PNG’s for TinyMCE buttons… Since 3.8 I’ve updated my custom post types to use Dashicons, but was wondering what is the correct way to get TinyMCE buttons using Dashicons as well? There’s a handy guide from James Coster on how to use Dashicons which may be relevant (though I assume there’s no need to place calls to enqueue the Dashicons scripts as they’ll already be loaded in the back-end).

Related posts

Leave a Reply

4 comments

  1. Add Dashicon

    All buttons inside the TinyMCE have a class, also your custom button. Include (use wp_enqueue_style() a stylesheet with styling with Dashicons, like the follow example.

    .myicon:before {
        content: '2605';
        display: inline-block;
        -webkit-font-smoothing: antialiased;
        font: normal 16px/1 'dashicons';
        vertical-align: top;
    }
    

    On default is the Dashicon active on each edit page, but add the dashicon to the depends stylesheet and it was also includes.

    Helper

    See this plugin to find the right font, how tos and examples to include inside the WordPress back end.

    TinyMCE and WordPress 3.9

    Small hint from my side to develop on this topic. The next release of WP 3.9 have the TinyMCE 4.0* include with a new API and the Tuts Tutorial is not the best resource for find solutions in this topic. See the follow two links and check you current developemt with the WP 3.9-beta.

    Source Examples, 3.0 vs 4.0

    TinyMCE 3

      tinyMCE.onAddEditor.add(function(mgr, ed) {
        var editor = $('#' + ed.editorId + '.atjs');
        if (editor.length == 1) {
          ed.onInit.add(function(ed, l) {
            $(ed.contentDocument.activeElement).atwho({settings go here});
          });
        }
      });
    

    TinyMCE 4

    tinymce.init({
      selector: "#mce",
      init_instance_callback: function(editor) {
        $(editor.contentDocument.activeElement).atwho(at_config);
      }
    });
    
  2. To style the icons using the Dashicons CSS files that are already loaded in the WP dashboard requires adding some extra CSS. In the latest beta of WordPress (3.9), TinyMCE 4.0 is used so I’m not sure this will work on earlier versions (however a modified version may suit, adjusting for the different classes outputted by previous TinyMCE buttons). In WP 3.9 (and TinyMCE 4.0), icons on the editor are outputted e.g.

    <div id="mce_16" class="mce-widget mce-btn" tabindex="-1" aria-labelledby="mce_16" role="button" aria-label="DropCap">
        <button role="presentation" type="button" tabindex="-1">
            <i class="mce-ico mce-i-dropcap"></i>
        </button>
    </div>
    

    There are 2 stages, first add a function to enqueue a custom stylesheet into the WP admin (which will be used to style the new buttons).

    add_action( 'admin_enqueue_scripts', 'se12334_stylesheet_to_admin' );
    /**
     * Add stylesheet to the admin pages
     */
    function se12334_stylesheet_to_admin() {
        wp_enqueue_style( 'custom-mce-style', get_template_directory_uri() . 'PATH/TO/CSS.FILE' );
    }
    

    Then secondly, following the James Koster’s guide on using Dashicons, a simple css selector of :before can applied to your icons CSS class. In the example case in the original question the CSS class would be mce-i-dropcap

    .CUSTOM_MCE_BUTTON_CLASS:before {
        font-family: "dashicons";
        content: "f100";
    }
    

    Though be sure to also remove the call to add an image in the original JS ed.addButton function and the font icon will be used instead

    Note that the admin_enqueue_scripts function will be called on every admin page so if your custom stylesheet is large it could slow down load times (though a minified stylesheet with only icon definitions in isn’t likely to have a large impact on load times anyway).

  3. An easy solution is to use Base64 encoded SVG image like this

    ed.addButton('dropcap', {
        ...
        'image'      => 'data:image/svg+xml;base64,{{BASE64}}',
        ...
    }
    

    Where {{BASE}} is the SVG image encoded with Base64.

    I use these pre-installed Linux command to download the SVG from Github abd encode it (using twitter icon as example):

    #!/usr/bin/env bash
    icon=twitter
    svg64=$(wget -O- -nv https://raw.githubusercontent.com/WordPress/dashicons/master/svg/$icon.svg | base64 -w 0) > /dev/null 2>&1 
    echo $svg64
    

    Output:

    PD94bWwgdmVyc2lvb[...]Cg==
    
  4. Here’s your easy solution (hopefully this will help other people too):

    1) add a custom class for icon, in this example “myicons”

    (function () {
        tinymce.PluginManager.add('twitter_button_plugin', function (editor, url) {
            editor.addButton('mce_tweet_button', {
                title: 'Insert tweet',
                icon: 'myicons dashicons-twitter',
                onclick: function() {
                    ...
                }
            });
        });
    })();
    

    2) Enqueue your admin stylesheet file

    function load_custom_wp_admin_style() {
       wp_enqueue_style( 'custom_wp_admin_css', 'URL/TO/custom_admin_style.css' );
    }
    add_action( 'admin_enqueue_scripts', 'load_custom_wp_admin_style' );
    

    3) Then in your custom_admin_style.css file add this:

    /**
     * TinyMCE add support for dashicons
     */
    i.mce-i-myicon {
        font: 400 20px/1 dashicons;
        padding: 0;
        vertical-align: top;
        speak: none;
        -webkit-font-smoothing: antialiased;
        -moz-osx-font-smoothing: grayscale;
        margin-left: -2px;
        padding-right: 2px
    }