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:

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:
-
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. -
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$pluginsArraypassed 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. -
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 😉 -
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.)