Customizing TinyMCE without Advanced TinyMCE

Advanced TinyMCE is a useful plugin; it lets you add all of the buttons that WordPress “hides.” When you need to add ‘Word-like’ WYSIWIG editing to a WordPress site, it’s probably your best choice. But most of the time, giving your users a ‘Word-like’ interface is a bad idea. (Admit it!)

After spending some time trying to write TinyMCE plugins to get around Advanced TinyMCE’s main weakness (in my own use & experience) I have found that customizing TinyMCE for WordPress without Advanced TinyMCE is more effective than using the plugin. It’s faster than fighting with TinyMCE and it makes adding buttons more deliberate (a good thing when you’re trying to K.I.S.S.)

My main complaint with the plugin is that the “Styles” dropdown is poorly implemented. If you include the Styles dropdown, but do not check “Import the current theme CSS classes”, styles are imported from tinymce-advanced/css/tadv-styles.css (required styles for the TinyMCE editor) and tinymce-advanced/css/tadv-mce.css (user styles for the TinyMCE editor). tadv-styles.css includes the aligncenter, alignleft, alignright, wp-caption, wp-caption-dd, and wp-Gallery styles, which for most purposes, should not be available to your user.

I have not seen this documented elsewhere, but I also had trouble getting the Styles dropdown to consistently display styles imported form tadv-mce.css on a client’s computer. I do not know if this was a caching issue, related to their browser, or what… but it was a problem with Advanced TinyMCE that I couldn’t fix.

I couldn’t get Advanced TinyMCE to behave the way I needed it to (only two styles in the Styles dropdown menu, to keep it simple; as few buttons in the Visual editor as possible; and an approximation of the website’s styles in the editor), so I uninstalled the plugin and added the following code to my functions.php file:

Add styles to your TinyMCE editor

function childtheme_mce_css($wp) {
return $wp .= ',' . get_bloginfo('stylesheet_directory') . '/css/mce.css';
}
add_filter( 'mce_css', 'childtheme_mce_css' );

Customize buttons

function childtheme_mce_btns2($orig) {
return array('formatselect', 'styleselect', '|', 'pastetext', 'pasteword', 'removeformat', '|', 'outdent', 'indent', '|', 'undo', 'redo', 'wp_help', 'mymenubutton' );
}
add_filter( 'mce_buttons_2', 'childtheme_mce_btns2', 999 );

Specify Styles visible in Styles dropdown (styleselect)

function childtheme_tiny_mce_before_init( $init_array ) {
$init_array['theme_advanced_styles'] = "1st Option=classname1;2nd Option=classname2;3rd Option=classname3";
return $init_array;
}
add_filter( 'tiny_mce_before_init', 'childtheme_tiny_mce_before_init' );

These lines of code take advantage of the Rich Text Editor Filters, not well particularly well documented, but there’s enough out there to piece it all together.

In other projects, I’ve also found it useful to be able to extend what’s allowed to pass through the TinyMCE filter as “good” HTML.

Allow iFrames (good for GoogleMaps embed code)

add_filter('tiny_mce_before_init', create_function( '$init_array',
     '$init_array["extended_valid_elements"] = "iframe[id|class|title|style|align|frameborder|height|longdesc|marginheight|marginwidth|name|scrolling|src|width]";
return $init_array;') );

Read More

Edit 12/17/2010: I’ve closed the comments on this post because it’s over a year old. I haven’t worked on this since then, but people do still use the hack. If you have questions about customizing TinyMCE for WordPress, the WordPress support forum is a good place to start.

This entry was posted in wordpress and tagged , , , , . Bookmark the permalink. Comments are closed, but you can leave a trackback: Trackback URL.

22 Comments

  1. Posted December 3, 2009 at 1:45 am | Permalink

    Well, I have to say; This example is solve my BIG headache.. I try using the TinyMCE Advance in wordpress and its so Wasted! All I wanted was the Style Dropdown menu!

    This is MUCH easier way then editing and configuring plugins…

    Thank you for your article…

  2. Posted December 14, 2009 at 2:56 am | Permalink

    I cannot believe this hasn’t gotten a lot more attention in the past. I’ve been looking for similar functionality for months and even opened a similar feature request in WordPress Trac.

    What I love best about this is that selecting a sentence fragment inserts a span tag and selecting a complete sentence or paragraph inserts a p tag. Now I just wish there was a way to insert a div tag and substitute some span tags with em or strong tags! If you know if this is possible, please enlighten!

    Thank you for this informational post!

  3. Posted December 26, 2009 at 5:51 pm | Permalink

    Yeah, I gotta thank you for this as well. This is a step closer to making TinyMCE a better tool for editors. I just wish there was a way to specify when to use certain tags, like a div instead of a p or em instead of span. Thanks for writing this!

  4. Posted January 23, 2010 at 6:55 am | Permalink

    Thank you so much! This is fantastic!
    For anyone who is interested, you can also edit the options available in the format dropdown as well. Just make a minor adjustment to the “Specify Styles” code mentioned in this article:

    function childtheme_tiny_mce_before_init( $init_array ) {
    $init_array['theme_advanced_styles'] =
    "1st Option=classname1;" .
    "2nd Option=classname2;" .
    "3rd Option=classname3"
    ;
    $init_array['theme_advanced_blockformats'] = "p,h4,h5,h6";
    return $init_array;
    }
    add_filter( 'tiny_mce_before_init', 'childtheme_tiny_mce_before_init' );

    (I also cleaned a bit for the style dropdown list so it is easier to read/edit.)

    You can see that you just specify which blockformats to include in the list.

    • Posted February 8, 2010 at 6:46 pm | Permalink

      Thanks Esther.. and (don for that extra bit)
      but it’s not working correctly.. i must have missed something…

      if I want to add a style called “bigstyles” … then this no? ….

      function childtheme_tiny_mce_before_init( $init_array ) {
      $init_array['theme_advanced_styles'] =
      "bigstyles=bigstyles;" .
      "2nd Option=classname2;" .
      "3rd Option=classname3"
      ;
      $init_array['theme_advanced_blockformats'] = "bigstyles, p,h4,h5,h6";
      return $init_array;
      }
      add_filter( 'tiny_mce_before_init', 'childtheme_tiny_mce_before_init' );

      • Esther
        Posted February 9, 2010 at 10:24 am | Permalink

        I think you’ve mistakenly replaced 1st Option with bigstyles; ie: "1st Option=bigstyles" not "bigstyles=bigstyles"

    • slimsam
      Posted May 5, 2010 at 10:07 am | Permalink

      Caution: When I added Don’s code — it made everything go white. The install is now broken. I used the editor from Appearance>Editor and I edited functions.php. I tried re-installing the original code and it;s still broken.

      • slimsam
        Posted May 5, 2010 at 10:24 am | Permalink

        Perhaps my mistake was that I added Don’s code *in addition to Esther’s* — I should have read carefully and *replaced* one of Esther’s functions — alas I’m just learning…my bad

        BTW — when I add Esther’s code to functions.php in the ‘Thematic’ theme, it doesn’t show up in the editor. Any ideas?

        Thanks for posting this fix — once I learn how to use it it will be very useful.

  5. Posted February 9, 2010 at 5:28 pm | Permalink

    AH ok it works perfectly! In the WYSIWYG i was looking under Format not Styles! (stupid mistake) thanks!

    • Posted February 12, 2010 at 9:26 pm | Permalink

      Excellent! This worked perfectly. Although I am now having difficulty adding the “pagebreak” button. Could you elaborate on this? Do i need to add the plugin first?

      Thanks for your help!

  6. Zid
    Posted February 12, 2010 at 11:55 pm | Permalink

    Hi,

    I’ve tried to copy and paste your codes into my functions.php but still no lucky yet. I got a blank white page. Which functions.php? Is it under wp-includes folder?

    Thank you.

  7. Posted March 31, 2010 at 4:31 am | Permalink

    Wonderful. All I wanted was to add one style to TinyMCE (I have a quicktag in the HTML editor), and I’ve been struggling to find a quick and simple solution. TinyMCE Advanced is clever stuff, but total overkill for what I wanted. Your solution is ideal.

    Thanks very much.

  8. Posted April 11, 2010 at 11:50 am | Permalink

    Yes, this is great.

    This could easily be turned into a plugin, with an editor. It helps me understand some of how to make TinyMCE more friendly. As people are saying, it’s suprising that more has not been addressed in this area.

    In my observation, as coders we like to introduce cool features, but what is needed more now, is to take harmful or confusing features away from our users. In this light, to provide a carefully-selected list of styles to choose from, which would be a great way to go with.

    I see that the Styles drop-down has some very handy default behaviors. As mentioned, if you select text, the class is applied as a span, and if not, it’s applied as a class.

    Also, if you select “Styles” from the drop-down, it will cancel out the class in question, which is VERY handy.

    Now, in some ways it might be nice to be able to control which things could be span-level, and which block-level. OTOH, that would confuse people.

    Also, you could specify the naming of the styles such that it was obvious which ones were meant for paragraphs, and which meant for spans.

    And, you could set up formatting in mce.css, to manage this as well. Let’s say you only wanted a class to apply to a block-level element. You could give span-level CSS to neutralize its behavior on the span level.

    This all goes farther towards creating a bulletproof experience for users. A lot of my clients get very confused when something doesn’t go the way they expect it to, and so clarity and simplicity are very important.

  9. John
    Posted June 5, 2010 at 6:46 am | Permalink

    This might seem like a dumb question but where does this pulls your sytles from, or what stylesheet would you store your styles in?

    • Esther
      Posted June 7, 2010 at 10:22 am | Permalink

      In my example, I’m getting styles from: get_bloginfo('stylesheet_directory') . '/css/mce.css'; (line 2 of the code block labeled “Add styles to your TinyMCE editor”)

  10. nudin
    Posted June 14, 2010 at 1:19 am | Permalink

    thanks for clever solution. tinymce wasted my time.

    but i need your help – i am still blur – where to put your code in the function.php actually.

    pls help.

    thanks very much.

  11. Mickey
    Posted July 8, 2010 at 1:48 am | Permalink

    Hi.

    This is awesome, thanks! all working perfectly. I was also wasting my time with tiny mce adv.. but am wondering if you have any advice on how to stop tiny mce wrapping every line break in tags? I want my client to be able to highlight a block of text and wrap it in one style… eg. putting a block of text AND links in one box with padding. This works fine adding a style with padding to my my tag with your method but if there are line break then I get several small boxes…basically I want tiny mce to use tags for line breaks……….hope you understand that!

    thanks!

    • Mickey
      Posted July 8, 2010 at 1:51 am | Permalink

      the post took my tags away.. I want tiny mce to use linebreak tags for line breaks……(not paragraph tags)

  12. Posted November 15, 2010 at 6:05 pm | Permalink

    helpful post.
    the semi colons in this line should be commas
    `$init_array['theme_advanced_styles'] = “1st Option=classname1;2nd Option=classname2;3rd Option=classname3`

  13. Chris
    Posted December 16, 2010 at 11:01 pm | Permalink

    This code helped me a great deal but I have one specific question which I am hoping you can explain.

    Many of my clients continue to screw things up on their site whenever shortcodes are used within the WYSIWYG editor.

    They either delete the shortcode or they somehow modify it which results in incorrect information being presented.

    What I am looking for is some simple way by which specific shortcodes are replaced with actual html or an image or an uneditable area within the WYSIWYG area.

    My ideal solution would be to be able to define a specific shortcode and have it act similar to the way that the tag is deal with or better yet the way an “image” is dealt with.

    I just want to represent the shortcode in a slick div box within the editor and when you hover over it then you get an edit button like when an image is inserted. THis could be as simple as just having a delete button as well so the rest is manual.

    Can you please show a simple way to do this?

    • Esther
      Posted December 17, 2010 at 9:40 am | Permalink

      I think the WordPress or TinyMCE forums would be a better place to ask this question, I made this post because it’s something I discovered for my own project — I’m by no means a TinyMCE expert/enthusiast. You could also try IRC.
      http://wordpress.org/support/
      http://tinymce.moxiecode.com/punbb/index.php

4 Trackbacks

  1. By Losing it[1] » Blog Archive » A small tweak on March 31, 2010 at 4:44 am

    [...] after multiple searches, I was delighted to find Customizing TinyMCE without Advanced TinyMCE by Esther S White, which offered a simple solution: add a few lines of code to your theme’s [...]

  2. [...] agan, refer to Esther’s article for [...]

  3. By Wordpress as a CMS on July 1, 2010 at 2:44 pm

    [...] This post has all the necessary info. I’ve tweaked it a bit so that it references the main stylesheet, so I don’t have to maintain two stylesheets. [...]

  4. [...] Antwort habe ich in Esthers Blog gefunden. Nach ein paar kurzen Schritten kann man dann das gewünschte Wort markieren und eine [...]