Tag Archives: tinymce

Using init callbacks with TinyMCE and wp_editor() in WordPress

WordPress 3.3 introduced wp_editor(). It’s a big improvement over the earlier hacks needed to get a TinyMCE instance on the WP front end. But it broke the feature in my BuddyPress Docs that detected idle time. The problem, in short, was two-fold: my idle-detection JavaScript was loading before the editor was initialized, and it wasn’t detecting key presses inside of the TinyMCE iframe. The solution to both parts of the problem required passing callbacks to the TinyMCE initialization array, in the setup array. It took me a long time to figure out how to do this, so for posterity’s sake, here are some takeaways.

First, the code:

[code language=”php”]
function bp_docs_add_idle_function_to_tinymce( $initArray ) {
if ( bp_docs_is_bp_docs_page() ) {

$initArray[‘setup’] = ‘function(ed) {
ed.onInit.add(
function(ed) {
_initJQuery();

// Set up listeners
jQuery(‘#’ + ed.id + ‘_parent’).bind(‘mousemove’,function (evt){
_active(evt);
});

bp_docs_load_idle();

}
);

ed.onKeyDown.add(
function(ed) {
_active();
}
);
}’;
}

return $initArray;
}
add_filter( ‘tiny_mce_before_init’, ‘bp_docs_add_idle_function_to_tinymce’ );
[/code]

Some notes:

  • I’m passing a ‘setup’ parameter to the TinyMCE init array by filtering tiny_mce_before_init
  • Only do this when you’re editing a BuddyPress Doc – that’s the bp_docs_is_bp_docs_page() check. I don’t want to mess with every instance of TinyMCE on the installation.
  • The setup parameter has to be a string. This gets tricky when the string is supposed to define an unnamed JS callback, because you have to be very careful about escaping quotes. As a string, your callback has to be wrapped in quotes. Also, when WP prints the TinyMCE parameters (and when it sees that your paramater begins with the string ‘function’) it’s going to wrap it in double-quotes. After lots of messing around, I was able to get this to work by using escaped single-quotes. (If you need to double-embed quotes – like a chain of callbacks – use escaped double-quotes.)
  • Where possible, use TinyMCE’s native events. ed.onKeyDown is one of them. It allows me to call my _active() function whenever a key is pressed inside the editor.
  • There are some kinds of actions that aren’t really detectable using TinyMCE’s events. For instance, I wanted to be able to detect when someone was moving their mouse around the iframe and especially TinyMCE’s toolbar. You can see this where I’m binding my callback to mousemove in the TinyMCE _parent element.
  • _initJQuery() and bp_docs_load_idle() are my own functions that need to run after the editor has finished setting up. That’s why they, along with the bind, are called in a callback of ed.onInit – that’s the generic place to put things that need to happen once the editor is up and running.

TinyMCE in Buddypress

I threw a little something together today to add WYSIWYG editing to BuddyPress, using TinyMCE. I want to be careful about the tags I allow, so I’m whitelisting, which is a bit tedious. As a result, there are only a few buttons available: a, em, strong, ul, ol, li. It’s a start, though.

Seems to work everywhere in BP: forums, wire, messages, profile pages.

A note about TinyMCE: WP ships with TinyMCE, and I thought it made sense to use that version instead of attaching one to this plugin. I think that the path to TinyMCE (line 20 of the plugin) should work on all installations, but you may have to tinker if you don’t see it popping up in the head of your BP pages. Moreover, the language files for WP’s version of TinyMCE are misnamed, which means that they don’t work right out of the box (at least for me they don’t). You may need to change the name of wp-includes/js/tinymce/langs/wp-langs-en.php to en.php in order to get the hover and help text in the TinyMCE box to work.

Download the plugin here. Don’t use in a production environment unless you are very certain that you are satisfied with the security of this plugin!