180 responses to “How to Use Multiple WordPress WYSIWYG Visual Editors”

  1. Adam

    Dimas,

    Its easier than that.

    WAY easier.

    Like one line of code easier.

    $metabox->the_field('description'); 
    the_editor($metabox->get_the_value(), $metabox->get_the_name());     
    

  2. Adam

    It should also be possible to pass custom values for the TinyMCE init options to the_editor. There are a number of filters you can use too, which you may be able to work with to give different values in different situations (by looking at what is there already). That should give you the flexibility to deal with each differently

  3. Horia Ancas

    Hi Dimas,
    I am very glad to see WPAlchemy evolving and even though I don’t need this functionality right now, it’s welcome.
    I’ll test drive it this days :)

  4. Adam

    Dimas,

    Sorry, I forgot to mention that. I also noticed the lack of switching. However, you should be able to overcome that with some JavaScript.

    From the code:

    /**
     * Display visual editor forms: TinyMCE, or HTML, or both.
     *
     * The amount of rows the text area will have for the content has to be between
     * 3 and 100 or will default at 12. There is only one option used for all users,
     * named 'default_post_edit_rows'.
     *
     * If the user can not use the rich editor (TinyMCE), then the switch button
     * will not be displayed.
     *
     * @since 2.1.0
     *
     * @param string $content Textarea content.
     * @param string $id Optional, default is 'content'. HTML ID attribute value.
     * @param string $prev_id Optional, default is 'title'. HTML ID name for switching back and forth between visual editors.
     * @param bool $media_buttons Optional, default is true. Whether to display media buttons.
     * @param int $tab_index Optional, default is 2. Tabindex for textarea element.
     */
    

    Theoretically, $prev_id should be the thing… however, “title” makes no sense for a default and its not used as far as I can tell. I think its time for a rewrite and a patch. I hate it when I find these things… its just more work for me. ;)

    I think there is a way to overcome the problems with filters, but when I submit my patch I’ll try to make it easier to distinguish instances.

  5. David

    Dimas you legend!! Thanks for the multiple WYSIWYG stuff, I shall give this a try over the weekend.

    Thanks :)

  6. Ross Chapman

    So what happens if you put HTML in the WYSIWYG?

  7. Adam

    Ah ha!!!

    Ok I’ve gotten the Visual/HTML tabs to work. Again, its just a matter of poking around things.

    if ( user_can_richedit() )
    	wp_enqueue_script('editor');
    wp_enqueue_script('word-count'); //if you want it
    

    Now the Style for the text area used by the HTML tab isn’t quite right but that’s easy to fix.

  8. Dasha

    Dimas, thanks a lot for taking time and writing this up! It’s huge help in learning WP.

    @Adam, very helpful comments – thank you :)

  9. Kathy

    Adam’s code does bring the editor into play (complete w/ HTML/richtext toggling). but the above enqueue_script(‘editor’) breaks things for me…. throwing up all kinds of jQuery isn’t defined errors. the problem w/ ‘the_editor’ is that there is only 1 default height value- so if you have 3 or 4 of them for different reasons, then you end up w/ an absurdly long post page.

    Anybody have any ideas on how to hide the standard post editor when a template isn’t going to be using it?

  10. David

    Hi Dimas, You know the line above the standard wysiwyg, which features the add image, add video etc buttons? Could that be added to each additional wysiwyg also? Reason I ask, I am using a google maps plugin which adds an additional icon to this list for adding maps and streetview, I would ideally love to be able to have this icon and the row it is with above each additional meta wysiwyg. Thanks

  11. Kathy

    i did figure out the answer to my question from above. in case anybody else would like to use jquery to hide the WP post box based on template… i added this to the document.ready function:

    ID,'_wp_page_template',TRUE);
    	if ('template-home.php' == $template_file ) {
    			
    		echo "$('#postdivrich').hide();";
    			
    } ?>
    
  12. Robert

    This was very useful to me in my current project. However, i needed to customize the buttons available in the TinyMCE toolbar. WP provides the tiny_mce_before_init and other filters to customize the buttons but that affects the main editor as well as my additional ones.

    So the solution is to create your own TinyMCE ‘settings’ array before calling tinyMCE.execCommand like so:

    settings = {mode:"specific_textareas", width:"100%", theme:"advanced", skin:"wp_theme", theme_advanced_buttons1:"bold,italic,strikethrough,underline,|,bullist,numlist,blockquote,|,justifyleft,justifycenter,justifyright,|,link,unlink,|,spellchecker,|,formatselect,forecolor,|,pastetext,pasteword,removeformat,|,outdent,indent,|,undo,redo,|,code", theme_advanced_buttons2:"", theme_advanced_buttons3:"", theme_advanced_buttons4:"", language:"en", spellchecker_languages:"+English=en,Danish=da,Dutch=nl,Finnish=fi,French=fr,German=de,Italian=it,Polish=pl,Portuguese=pt,Spanish=es,Swedish=sv", theme_advanced_toolbar_location:"top", theme_advanced_toolbar_align:"left", theme_advanced_statusbar_location:"bottom", theme_advanced_resizing:"1", theme_advanced_resize_horizontal:"", dialog_type:"modal", relative_urls:"", remove_script_host:"", convert_urls:"", apply_source_formatting:"", remove_linebreaks:"1", gecko_spellcheck:"1", entities:"38,amp,60,lt,62,gt", accessibility_focus:"1", tabfocus_elements:"major-publishing-actions", media_strict:"", paste_remove_styles:"1", paste_remove_spans:"1", paste_strip_class_attributes:"all", wpeditimage_disable_captions:"", plugins:"safari,inlinepopups,spellchecker,paste,wordpress,tabfocus"};
    // then the code from your tutorial:
    		jQuery(function($)
    		{
    			var i=1;
    			$('.wysiwyg-editor').each(function(e)
    			{
    				var id = $(this).attr('id');
    
    				if (!id)
    				{
    					id = 'wysiwyg-editor-' + i++;
    					$(this).attr('id',id);
    				}
    				// here we assign our custom settings before creating our wysiwyg
    				tinyMCE.settings = settings;
    				tinyMCE.execCommand('mceAddControl', false, id);
    
    			});
    		});
    

    Note that I have added the ‘code’ button to my toolbar which effectively replaces the need for the Visual/HTML tabs.

    Hope this is useful to someone…

  13. Robert

    By the way, if you want to only include your extra scripts and styles on the WP post pages use this:

    global $pagenow;
    if ( in_array( $pagenow, array('post.php', 'post-new.php') ) ) {
        ...your code to enqueue scripts, styles etc...
    }
    
  14. shawn

    Thank you so much for the code sample.

    Like David, I am also curious how to go about adding in the wp gallery buttons to each instance. Would love to see how it is done if someone has the time for an example snippet.

  15. kathy

    that is super cool Robert. Thank you for sharing! you wouldn’t happen to know how to add buttons that are added to the regular tinyMCE editor by plugins such as Link to Post would you?

  16. Adam

    Dimas,

    I’ve been thinking about this and your code takes WordPress into the realm of the generalized CMS. One thing that the current custom post feature gets wrong is that each post type can, at best, belong to its own hierarchy. That’s by design but I might want to have a page which is a press release and another which is a project description and provide adequate controls to content authors so they don’t need to know markup.

    Fine that’s why we all use custom metaboxes. So in a pathological case lets say I have 10 “variations” for a page. I could just put all the meta boxes in there all the time but that provides the opportunity for confusion and you run the risk of getting bad data if someone populates content in multiple metaboxes (assuming they’re mutually exclusive).

    What would be a GREAT addition to your code is a drop down, or similar control that lets you select the post “sub type” (to coin a phrase). It is effectively a drop down list of some or all of the metaboxes added. As the user selects an option, that metabox will become visible and as an option theEditor disappears.

    I’m thinking something like:

    $custom_metabox = new WPAlchemy_MetaBox(array
    (
    	'id' => '_custom_meta', 
    	'title' => 'My Custom Meta',
    	'template' => TEMPLATEPATH . '/custom/meta.php', 
            'switcher' => array(
                'include' => true, // this should be implied by the presence of the array?
                'hideEditor' => true,
                'title' => 'optional different title',
                'position' => 3 //something to give you control over the order in the list. 
          )
    ));
    

    Now maybe it needs to be a different class that you create after the fact but I think that this will really work well for a huge number of use cases.

  17. Robert

    @Dimas – You’re welcome. It’s what open source is all about – sharing.

    @kathy
    Well, you could study the plugin you mentioned and see how they do it. There is a codex page about this here: http://codex.wordpress.org/TinyMCE but not much in terms of useful code. You can check out the links there tho.
    To add buttons to a particular toolbar area you can use these filters: mce_buttons, mce_buttons_2, mce_buttons_3, mce_buttons_4
    To manipulate the complete tinyMCE settings array use: tiny_mce_before_init
    And to add yor own tinyMCE ‘plugin’ you can use: mce_external_plugins
    If you’re adding your own buttons, you need to write a ‘plugin’ to tell the button what to do when it’s clicked.

    So to add a button and a plugin handling the button to tinyMCE you’d do:

    if ( get_user_option('rich_editing') == 'true' ) {
        add_filter( 'mce_external_plugins', 'add_my_tinymce_plugin' );
        add_filter( 'mce_buttons', 'add_my_tinymce_button');
    }
    

    Then, you need to know how set up your plugin code and your button but that’s a lengthy tutorial, not so suited for a comment :). However, you should be able to study existing plugin code to gain that insight.

  18. Kathy

    @Robert- Thanks for the reply! I will check into that more tomorrow when I am feeling fresher. Between this and trying to add upload functionality to the meta boxes my brain is a touch fried tonight. And i just watched 3 eps of the Jersey Short, which I am sure killed a few brain cells.

    thankfully the plugin code for LinkToPost is already complete. I studied it a bit and saw how they were adding it to the regular editor, but ran into a wall trying to add it to the editors I called w/ the code from this post (And your code for the settings array) for the meta boxes. i’d also liked to add the media/image button, so hopefully things will look clearer to me tomorrow.

  19. Robert

    @kathy

    1. I am also trying to add file upload functionality to the meta boxes. I have tried the approach outlined here: http://austinpassy.com/2010/03/creating-custom-metaboxs-and-the-built-in-uploader/ and it works OK by using the WP built in Thickbox media popup.

    However, this seemed a bit of a roundabout way so now I’m getting lower into the hierarchy and looking at using the SWFUploader object directly so I can just have an “Upload Files” and “Cancel” button right in my metabox. I got it to work on a basic level (it’s uploading files and attaching them to the post) but now the trick is to create the user feedback UI just like the media uploader does. This involves writing a whole lot of JS handlers for the SWFUpload events.

    You also have to create your own media-upload.php script that handles the actual file upload and attaches it to the post (if that’s what you want) based on the async-upload.php from the wp-admin folder.

    2. To add the LinkToPost custom button, you should be able to add it’s handle to one of the ‘theme_advanced_buttons*’ elements as well as add the corresponding plugin handle to the ‘plugins’ element. Not sure if there is anything more to it…

    3. The media/image buttons are not part of the wysiwyg as such and they are added separately. You can study the ‘the_editor()’ function to see what it does but basically, the media buttons are added via:

    <div id="media-buttons" class="hide-if-no-js">
    <?php do_action( 'media_buttons' ); ?>
    </div>
    
  20. kathy

    @Robert! Thanks again… with the help of your reply and some fresh eyes I have the Link2Post button conditionally showing in TinyMCE. Not ever having fooled w/ tinyMCE I didn’t know I needed both the button and plugin handles.

    I had been using the old version of Valum’s Ajax Upload and wp_handle_upload in my theme options panel pretty successfully. I have not been able to duplicate that with the updated script. And haven’t come close to getting it to work w/ the metaboxes. The upside was that uploading an image in this way is super easy for the user end. Click the button select the file and I automatically saved it to my theme options array and had jquery show the image and generate a remove button. The downside is that it doesn’t go through the Media manager, so it isn’t attached to anything, isn’t in the DB, doesn’t have captions/alt-text, AND you can upload the same image a gazillion times which could take up lots of space on the server.

    I really appreciate the info you’ve provided. I had been searching for something along those lines but wasn’t finding much. some stuff in the codex is still very shrouded in mystery.

  21. kathy

    @Robert-

    I wanted to share what I did to get the media uploader working on multiple buttons in the meta boxes (And not interfere w/ the regular post media buttons). By pulling the post_ID into a variable I can preserve the ability to ‘insert to post’ immediately after the manager finishes ‘crunching’ the image, w/o having to click over to the Media Library tab.

    I still haven’t decided if I like the ajaxupload method better, but i do like that this gets the images into the DB as attachments and while it is 2 more steps than AjaxUpload (Insert to post and save) those steps are already familiar and expected. and another thing it has going for me right now is that it works while i still can’t get my head around the new AjaxUpload. :)

    jQuery.noConflict();
    jQuery(document).ready(function($) {

    var ww = $('input[name=post_ID]').val();
    var which_button;

    $('.meta_upload_button').each(function() {

    var button = $(this);

    $(this).click(function() {
    which_button = button;
    window.send_to_editor=window.send_to_editor_clone;
    tb_show('', 'media-upload.php?post_id=' + ww + '&type=image&TB_iframe=true');
    return false;
    });

    window.send_to_editor_clone = function(html){
    imgurl = $('img',html).attr('src');
    forminput = which_button.prev('input');
    forminput.val(imgurl);

    tb_remove();
    }

    }); //end each

    }); //end document ready

    in case my code doesn’t display properly here is the pastebin: http://pastebin.com/nCz0Z0nv

    now just to mix up a little more code for remove buttons and image previews

  22. Christian

    Hello everybody!

    First i want to say big thanks to Dimas to share this class and the documentation with us: Thank you very very much!!!

    So far everything works fine for me – i just experienced two little problems:

    1. If i want to use a WYSIWYG editor in a repeatable area where i want to work with a button to add an item (“have_fields_and_multi”) the added editors dont work – it shows with a small textfield but its not possible to select the textfiled. Anybody who can reproduce this?

    If i use it with an automatic repeating area (“have_fields_and_one”) everything works fine.

    2. @Robert: I tried to costumize the TINYMCEs buttons with your code – but i am not able to get that working. I have added the line with the setting directly in the line before “jQuery(function($)”, after “/* <![CDATA[ */" – and i have added "tinyMCE.settings = settings;" in the line before "tinyMCE.execCommand('mceAddControl', false, id);"

    After i have added the code the WYSIWYG editor is not shown – i get a normal textarea.

    Kind regards,

    Christian

  23. Robert

    @Christian

    Note that I have used a textarea with a class of: wysiwyg-editor. the original example wraps the textarea in a div of class: customEditor.

    You need to look at the line:

    $('.wysiwyg-editor').each(function(e)

    and replace it with the original:

    $('.customEditor textarea').each(function(e)

    if your HTML is based on the original tutorial.

1 2 3 8

Leave a Reply