Registering custom TinyMCE buttons, for admin area, to work with custom instances of wp_editor

Thanks to this answer here, I am able to use different instances of wp_editor to determine which buttons each of my differing TinyMCE instances use.

However, I’m struggling to actually get my buttons registered – they’re simply not appearing on the TinyMCE interface the way I think they should!

Read More

I’ve tried two different approaches – putting the code in my species-profiles plugin (a Custom Post Type called species in which I wish the TinyMCE instances to feature), and putting the code in my theme’s functions.php.

The code I’m using is:

function add_SF_buttons() {
    if ( ! current_user_can('edit_posts') && ! current_user_can('edit_pages') )
        return;
    if ( get_user_option('rich_editing') == 'true') {
        add_filter('mce_external_plugins', 'add_SF_buttons_plugins');
    }
}

function add_SF_buttons_plugins($plugin_array) {
    $plugin_array['pH'] = get_bloginfo('template_directory') . '/tinymce_buttons/pH/editor_plugin.js';
    $plugin_array['pH_min'] = get_bloginfo('template_directory') . '/tinymce_buttons/pH_min/editor_plugin.js';
    $plugin_array['pH_max'] = get_bloginfo('template_directory') . '/tinymce_buttons/pH_max/editor_plugin.js';
    return $plugin_array;
}

add_action( 'init', 'add_SF_buttons' );

The code I’m using to initialise the wp_editor instance as per aforementioned answer is this:

<?php
    wp_editor(
        $distribution,
        'distribution',
        array(
          'media_buttons' => false,
          'textarea_rows' => 8,
          'tabindex' => 4,
          'tinymce' => array(
            'theme_advanced_buttons1' => 'bold, italic, |, bullist, numlist, |, pH, pH_min',
            'theme_advanced_buttons2' => '',
            'theme_advanced_buttons3' => '',
            'theme_advanced_buttons4' => '',
          ),
        )
    );
?>

The plugins I’m trying to use all look like this:

(function() {
    tinymce.create('tinymce.plugins.pH', {
        init : function(ed, url) {
            ed.addButton('pH', {
                title : 'pH',
                image : url+'/pH.png',
                onclick : function() {
                    var caret = "caret_pos_holder";
                    var insert = '[pH]';
                    ed.execCommand('mceInsertContent', false, insert);
                    ed.selection.select(ed.dom.select('span#caret_pos_holder')[0]); //select the span
                    ed.dom.remove(ed.dom.select('span#caret_pos_holder')[0]); //remove the span
                }
            });
        },
        createControl : function(n, cm) {
            return null;
        },
        getInfo : function() {
            /*
             * I intentionally left the information of
             * Brett Terpstra, as his code was the
             * foundation for this.
            */
            return {
                longname : "Brett's YouTube Shortcode",
                author : 'Brett Terpstra',
                authorurl : 'http://brettterpstra.com/',
                infourl : 'http://brettterpstra.com/',
                version : "1.0"
            };
        }
    });
    tinymce.PluginManager.add('pH', tinymce.plugins.pH);
})();

As far as I’m aware, everything I’ve done there is correct? Yet the custom buttons fail to appear. I guess I’m doing something wrong – initialising them incorrectly, or something.

How the TinyMCE interface appears

Thanks in advance,

Related posts

Leave a Reply

2 comments

  1. I copied your code into my functions.php, and added a simple admin panel (‘Foo’) to display the editor. Then I created a new directory inside my current theme for the editor button, and put the editor button JS into the relevant file: /wp-content/themes/[my-theme-dir]/tinymce_buttons/pH/editor_plugin.js.

    Result: when I went to Dashboard > Foo (the panel I’d created), it worked as expected. Screenshot:

    Screenshot

    Code:

    /**
     * This function conditionally hooks the function that adds custom buttons to the TinyMCE init array
     */
    function wpse_48782_add_SF_buttons() {
        if ( ! current_user_can('edit_posts') && ! current_user_can('edit_pages') )
            return;
        if ( get_user_option('rich_editing') == 'true') {
            add_filter('mce_external_plugins', 'wpse_48782_add_SF_buttons_plugins');
        }
    }
    add_action( 'init', 'wpse_48782_add_SF_buttons' );
    
    /**
     * Adds the pH button to the TinyMCE init array
     */
    function wpse_48782_add_SF_buttons_plugins($plugin_array) {
        $plugin_array['pH'] = get_bloginfo('template_directory') . '/tinymce_buttons/pH/editor_plugin.js';
        return $plugin_array;
    }
    
    /**
     * Load a dummy admin panel to display editor
     */
    function wpse_48782_add_panel() {
        add_menu_page( 'Foo', 'foo', 'manage_options', 'foo', 'wpse_48782_render_panel' );
    }
    add_action( 'admin_menu', 'wpse_48782_add_panel' );
    
    /**
     * Callback to render the 'Foo' admin panel'
     */
    function wpse_48782_render_panel() {
        ?>
    
        <div class="wrap">
    
        <?php
    
        $distribution = 'abc';
    
        wp_editor(
            $distribution,
            'distribution',
            array(
              'media_buttons' => false,
              'textarea_rows' => 8,
              'tabindex' => 4,
              'tinymce' => array(
                'theme_advanced_buttons1' => 'bold, italic, |, bullist, numlist, |, pH, pH_min',
                'theme_advanced_buttons2' => '',
                'theme_advanced_buttons3' => '',
                'theme_advanced_buttons4' => '',
              ),
            )
        );
    
        ?>
        </div>
        <?php
    }
    

    So, you’ve basically got it right, and you must be doing something differently than what I’m doing in the stuff that you haven’t talked about in your explanation. A couple possibilities:

    1. You haven’t put the editor_plugin.js file in the right place. As mentioned above, your path leads to: [your-theme-dir]/tinymce_buttons/pH/editor_plugin.js (and the -max and -min versions). Make sure that these file exist, and that they contain the editor_plugin js you’ve posted above. If you open up your browser’s JS console, you should be able to tell at a glance whether you’ve got the paths right – you’ll get a “NetworkError” or something like that if they’re not.

    2. Plugin conflict. A very rude plugin/theme may be filtering 'mce_external_plugins' and wiping out changes that are made by other plugins (by returning an init array that is unrelated to the $pluginsArray passed to the filter). Grep through your wp-content directory for ‘mce_external_plugins’ and examine what you find; or you could try disabling all other plugins and switching to Twenty Eleven. Note that a plugin could also wipe out your settings by doing something silly at the 'tiny_mce_before_init' filter, which is the last one to fire before the editor is rendered – look for that in your content directory too.

    3. You’re putting your code in the wrong place altogether, so that it’s not being loaded by WP. I know you say that you’ve put it in your theme’s functions.php – but are you sure? Maybe you’ve put it into the wrong theme or something like that? We all have days like that 😉

    4. There’s a condition at the beginning of your first function that says: if the current user can’t edit_posts and also can’t edit_pages, don’t show them the buttons. Make sure that you’re doing your testing using a user that has at least one of these caps. (Or try commenting out this check altogether, just as a test.)

  2. Thanks to Boone’s excellent answer, I found the exact problem.

    For some reason, when there are instances of wp_editor on the page set with teeny=true, custom buttons cannot be used on any instance of wp_editor.

    If you remove the teeny=true argument, the problem disappears.