Using the TinyMCE WYSIWYG editor in your WordPress plugin
Not so long ago I’ve released my latest WordPress plugin which adds a WYSIWYG editor to your text widget’s textarea. I did this by using WordPress’ core TinyMCe functionality. In my search on how to properly include the JavaScript files which are necessary for the TinyMCe editor to work i’ve encountered quite some confusion on how to properly load TinyMCE into your plugin or theme options page. This is how i’ve done it and what works quite well for over 1250 users so far.
Loading the necessary editor scripts and styles
Let’s say you want use all the functionality that is in WordPress’ post editor including media uploading. We’ll need to load some JavaScript files to make this work and of course we’ll do this using the only proper way to load a JavaScript file, by using wp_enqueue_script().
wp_enqueue_script(array('jquery', 'editor', 'thickbox', 'media-upload'));
To make the upload functionality pop-up in a nice thickbox screen, for which we’ve already enqueued the necessary JS files, we’ll need to load the thickbox css file too.
wp_enqueue_style('thickbox');
Loading TinyMCE files
WordPress has a nice function that takes care of loading the necessary TinyMCE scripts and stylesheets: wp_tiny_mce(). It isn’t documented in the WP Codex yet but that doesn’t mean it doesn’t work great. In my search to find more information about this function i’ve heard from other developers who’ve tried to load TinyMCE using wp_tiny_mce() that calling the function returned a nasty undefined function error for them. This is because you have to hook this function to admin_head. WordPress loads your plugin files before it loads /wp-admin/includes/post.php that holds the wp_tiny_mce() function so we’ll need to call it later on, so that the function is available when we call it.
add_action("admin_head","myplugin_load_tiny_mce");
function myplugin_load_tiny_mce() {
wp_tiny_mce( false ); // true gives you a stripped down version of the editor
}
Showing a WYSIWYG editor
To show a WYSIWYG editor we can use another WordPress function called the_editor(). You’ll need to provide at least one parameter which sets the content of the textarea upon loading. For now, i’ll just leave this up to an empty string and leave the rest of the parameters to it’s default value.
// Your HTML page...
<div id="poststuff">
the_editor('');
</div>
// More HTML, a save button etc..
This outputs a textarea with ‘#content’ as the ID and loads the TinyMCE editor on it. Note the wrapping div with poststuff as an ID, this is only necessary so that the CSS selectors for styling the switch buttons ( visual / html ) work.
Now, when you’ve followed the above steps you’ll notice that everything is working pretty nice except for one thing, the WP-link dialog is not working. This is because we’ll need to call one more function that preloads some TinyMCE dialogs. We’ll hook this function to the footer so it outputs the dialogs wrapped in a hidden div.
add_action( 'admin_print_footer_scripts', 'wp_tiny_mce_preload_dialogs');
UPDATE 06-07-2011 – WordPress 3.2:
Aparrently, wp_tiny_mce_preload_dialogs() no longer exists from WP3.2 on. It got replaced by wp_preload_dialogs() which is now being called from wp_quicktags(). wp_quicktags, on his turn, is being called from the_editor() function. So, if you’re using the_editor() you no longer need to manually call the function to preload any dialogs!
If you’re not using the_editor(), make sure to call wp_preload_dialogs() somewhere from your footer in the following manner:
wp_preload_dialogs( array( 'plugins' => 'wpdialogs,wplink,wpfullscreen' ) );
The result: a neat WYSIWYG editor with all the functionality the default WP post editor has.
That’s it. If you’ve correctly implemented all the above steps you should have a WYSIWYG editor up and running. Let me know if you experience any problems or know a way to improve a thing or two in the process of loading TinyMCE.

47 Responses to “Using the TinyMCE WYSIWYG editor in your WordPress plugin”
Danny, great tutorial! One thing – how do I use the_editor() with get_option and update_option so I can save and retrieve what my user typed in there?
DAnny,
That definitely helps, I should have looked there before! My problem now is that the editor is permanently stuck in “HTML” mode and clicking on “Visual” does nothing. Likewise, I can’t add links, or anything. JS debugging gives me this error whenever I click “Visual”:
Error: switchEditors is not defined
Do you know what I missed here? I followed your instructions above closely. Thanks much.
Hi!
First of all, thanks for writing this post, there are a lot snippets around but no complete guide..at least i didn’t found one.
May be it’s because I’m using the german version of wordpress but using wp_tiny_mce AND the_editor leads to some (localization) errors which are adressed by this trac ticket:
http://core.trac.wordpress.org/ticket/15102
On the other hand, using the_editor with different id’s is working fine for me. Only tried this with WP3.2RC1
Thanks
After I open up your Rss feed it appears to be to be a lot of junk, is the issue on my side?
Have you noticed any issues with this code in IE8 and 3.2?
I had two plugins using custom TinyMCE stuff and they both suffer the following issue:
Under 3.2, Ie8, the Link button generates this blank box instead of helping make a link:
http://i.imgur.com/lJJeO.png
I haven’t, but I put a ticket in:
http://core.trac.wordpress.org/ticket/18102
Sidenote: nice review of my Conditional Widgets plugin – small world!
Hi Danny,
As my first plugin, I’m trying to do a variation on yours, but I’m starting knowing very little and trying to figure things out as I go. Good start, huh? Anyway, I was going through your code and came to a part that has to do with the wp_tiny_mce_preload_dialogs() function you discuss above. There is the following if-statement in the add_hooks function of backend.php that appears to be a check of the version of WordPress that is being used:
if((int) get_bloginfo(‘version’) >= 3.2)
But should it be “(float)” instead of “(int)”? For example, if the version being used is 3.2, won’t (int)3.2 return the integer 3 and, therefore, not be >= 3.2?
Please remember, I said I’m starting knowing very little.
Thanks,
Tim
Not stupid, just a good challenge for me. Glad it helped.
It looks like you’ve added the ability to use the widget multiple times on a page. When I tried to do that with 1.0.6, the second widget, upon creation, would have values in the title and text from the first widget and wouldn’t save the new text I tried to put in. Now, with 1.0.7 I can do that. Awesome!
Thanks and great work!
Tim
I’m newer than new here so please don’t get annoyed. I downloaded WYSIWYG Widget the other day.. of course I can’t get it to work. I read the above but I don’t know where to go to input the scripting… I’m very confused, but I don’t want plain text- please help!
Hi Danny,
Really good.
But not working for me.
I’m making a plugin wich is adding TinyMce on the fly with javascript and tinyMCE.execCommand(‘mceAddControl’, false, … )
My problem is the WP-link dialog is not working.
What could i do please ?
Hi Danny,
I am with WP 3.2.1.
It’s ok, i’ve fixed my problem.
If just forgot a hook for jquery.
Tanks,
Yann
I’ve implemented your solution but I get this javascript error when trying to insert an image into the editor :
Uncaught TypeError: Object [object DOMWindow] has no method ‘send_to_editor’
I’m using WP 3.2.1
Nevermind my previous post I was adding my actions too late and they weren’t even executed.
My bad…
Hi, great article, but i am having still one bug.
I am using WordPress 3.2.1
And i am trying to add wysiwyg editor in my plugin, everything renders fine. But the problem i have is that the upload/insert links not working and nothing pops-up :/ What might be the reason?
Hi Danny,
Thanks for the great tutorial. However, the Upload/Insert media buttons aren’t displaying in my custom menu page. I’m using WordPress 3.2.1. What could I be missing?
I have the same issue (http://wordpress.org/support/topic/media-upload-buttons-dont-work-as-expected?replies=1). That’s sad to hear .. :(
Thanks.
Very nice, but it appears that the CSS stylesheet is missing for the HTML/tiny view, ( 3.2.1 )
I’ve used this method of adding multiple editors before, however the link popup window doesn’t work because of interfering ID’s.
When the main editor is in VISUAL mode, when the other mce_editors loads the link pop does appear, but the ‘add link’ button doesn’t do anything and reloads the entire page.
However, when I switch the main editor to HTML, and reload the page (so VISUAL doesn’t load), the link button works on all the additional editors?
So it seems the main editor JS is interfering with the generated editors.
I haven’t found a solution yet.
Nice tutorial dude!
but i have some trouble here, I have plug the_editor() to my custom widget, but its won’t to save.
any solution??
the script doesn’t replace the text area, even I change the id.
So it $_POST[] with empty text area
Awesome! I thought implementing tinyMCE editor would definitely take some time. But your guide made it very easy (implementing it on WordPress 3.2 is simpler, I should say). It works like a charm, thanks a lot!
Thanks for this article Danny. Very helpful!
“wp_tiny_mce( false, array( ‘editor_selector’ => ‘wysiwyig_editor’ ) );”
thx buddy this helped me a lot ;-)
Hi,
the script is working great, but it clears (line breaks) when switching between WYSIWYG editor and HTML editor.
How can I set it not to clear line breaks?
Thanks! This works on 3.3.1 on custom post types, but doesn’t work when trying to multiple editors to the media uploads window.
Adding meta boxes to the media upload box requires manipulating the fields as a string, as wp_editor() is a function I cannot see how to output this as a string to the fields, and call javascript to enable the boxes?
I’ve seen people using ob:
ob_start();
wp_editor(“”,$editor_id,$editor_settings);
$ic = ob_get_clean( );
But I cannot get it to work.
Hi Tom, i didn’t understand what you try to archieve but
it should be:
ob_start();
wp_editor(“”,$editor_id,$editor_settings);
$ic = ob_get_contents( );
ob_end_clean();
then simply echo $ic.
if you try to dynamically add an editor instance (via ajax)there a some more things to do in order to get the editor working.
Hi Kai
THanks for the reply, yes I noticed that. I have the editor dynamically added, but I don’t know what else is needed via javascript in order to enable the editor?
Before I try to answer this question. Are you adding this editor where the native editor is already present (any post/page/cpt edit screen) or somewhere else.
I think so yes. I’m trying to add the editor to the media upload window, see screenshot of my example:
http://tinypic.com/view.php?pic=14ipno3&s=5
The editor is being called on the page edit window, but the media upload is called in an i-frame so this is separate I believe.
Well ok, never done or tried this before.
Just to make sure we have the same base situation:
I’ve made a quick test by using this example to add the Editor as an extra field:
http://www.billerickson.net/wordpress-add-custom-fields-media-gallery/
This works so far, and the editor markup shows up.
I guess you know how to add custom js script to the window.
This is far from complete/perfect but should give you an idea where to start:
http://pastebin.com/HB7tNbCE
This has to be called on the media uploader. I didn’t try this with new uploads but on the media library tab this works.
Switching between visual mode and html, Quicktags..those things won’t work yet.
But maybe this is helpful for you though.
well, Bill Erickson does not have an actual example but the ‘html’ example is the technic i’ve used.
amazing thank you Kai, I shall try and implement this tommorow
Hey Tom,
i’ve got this working on my local server.
Maybe it’s better if we stop spamming Dannys blog. Feel free to contact me via mail and i’ll send you the two files i have. kai {AT.ungestaltbar.de}
Hi
Thanks for the tutorial. I am trying to load wp_editor through wordpress admin ajax but I am not able to display it properly. No icons but visual/html and media upload are displayed. Also it is not working as normal. But without ajax everything is fine.
I saw the source and see that the wp adds some js in the footer for tinymce. But how to do the same when loaded via ajax.
Thanks.
Hey All,
First off, thanks for the great resource!
However, im having some issues getting it to work, for me, the
wp_tiny_mce( false, array( “editor_selector” => “wysiwyig_editor” ) );
does not work :( and since theres already a editor on the page, i cannot use the “the_editor()” call.
Im on wordpress 3.3.1, trying to tweak an existing plugin (i know, baaaad) to have the pretty editor. (the plugin is ‘enhanced header / footer injections’)
I’ve added an action (next to the existing actions) for it like so;
add_action( ‘admin_print_footer_scripts’, ‘nlws_efhi_admin_footer’);
And defined the function ‘below that’ like so;
function nlws_efhi_admin_footer() {
wp_preload_dialogs( array( ‘plugins’ => ‘wpdialogs,wplink,wpfullscreen’ ) );
}
But it totally seems to skip over the wp_tiny_mce calls i made, i made those inside an action wich i tried to add to ‘admin_head’ and later ‘wp_head’, but with no succes (in backend)
So, does anybody know if the above still works in 3.3.1? and if so, can you spot from the (semi good) description above what im doing wrong??
To me, the problem appears to be that the wp_tiny_mce calls dont work, but im unsure how to verify/debug this.
Any help highly appreciated.
Best regards,
Olivier
I just noticed the order in which i explain my issue is a bit vague (prolly not helped by my lumberjack english skills) so to follow up, a little elaboration;
I added the wp_tiny_mce calls to an action;
add_action( ‘wp_head’, ‘nlws_ehfi_load_tiny_mce’);
Wich points to the function;
function nlws_ehfi_load_tiny_mce() {
wp_tiny_mce( false, array(“editor_selector” => “wysiwyig_editor1″) ); // true gives you a stripped down version of the editor
wp_tiny_mce( false, array(“editor_selector” => “wysiwyig_editor2″) );
}
Wich in turn should enable it for 2 textareas in the page, with class wysiwyig_editor1 & wysiwyig_editor2
That, however, doesnt happen, searching for a reason ive been looking at the wp_preload_dialogs call, but i just tested with a quicky echo and that part actually does work, so its just the wp_tiny_mce calls that dont work :(
Any ideas?
Thanks in advance, sorry for the vague message before this
Best regards,
Olivier
Thanks Bro it’s working great for me. but i have one question.
When i insert an image in editor and press the submit button then how can i get the image contents?
Please Reply
Thanks
Thanks, but useless. Given that there is no mention of WHERE to put these various commands. And don’t say ‘functions.php’. My WP installation has about 30 of them.
Hey Danny,
Great post, very useful! How would I go about having multiple WYSIWYG editors on one theme options page? They seem to be interfering with one another.
Thanks again,
Thijs.