Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

I'm trying to use the tinyMCE in the Wordpress front end and not using wp_editor() because I need the editor to be created through Ajax (something that a wp_editor can't handle as far as I know).

Does anyone know where in the Wordpress core they create the functionality where an image within the tinyMCE textarea can be clicked to edit its settings?

Alternatively, if you know of a way to make wp_editor work with Ajax, that would be awesome.

share|improve this question

1 Answer 1

up vote 1 down vote accepted

To your primary question:

It's a tinymce plugin and can be found here: wp-includes/js/tinymce/plugins/wpeditimage/

I'm not sure but I guess you would have to rewrite some code if you want to use it with a non-wp instance of tinymce. Never tried it, but I'm pretty sure it will not work out of the box.

Second question: Actually it's not too hard to get tinymce working with ajax. The main problem with tinymce is: it needs (js)settings (and some markup), which gets generated when you call wp_editor and gets stored in the global js object tinyMCEPreInit.mceInit[##editor-id##].

( Open your console on a normal post edit screen and inspect this object by typing its name (tinyMCEPreInit) in the console. At least in Chrome & Safari it works like this )

So it needs those settings, and of course all necessary js/css files already inside the page.

Two options here:

Clean, good way would be too complety build this settings object on your own. Basically you would clone this from the standard 'content' tinymce post edit instance ( by inspecting it in the console & copy the content ). Rewrite this settings to an php array and use localize script ( or whatever ) to inject it where needed. Enqueuing the scripts should be easy as something like wp_enqueue_script( 'tinymce' );. I would have to look this up, but there is a function to load all scripts.

Second, hackish way doing it:

If you know where you need this functionality, create a hidden instance of wp_editor on page load. This will take care of all necessary stuff. Like:

echo "<div class='remove-afterwards' style='display: none;'>";
       wp_editor('','content');
echo "</div>";

On document.ready you can safely remove this node if you think it "uglifies" your markup. You won't need it anymore. We just need the js settings as reference (read on).

Next two steps:

First: Your Ajax call / function should execute a normal wp_editor and return the markup. Just notice that wp_editor always echos its output, you can use php object buffer to prevent this but thats up to you.

Append the response resp. the wp_editor created markup to your page.

Second Step, and I just can give you an idea where to start:

After you inserted the markup to your page you will have to find the ID of the textarea, it's the same as used by the wp_editor function, but to keep things dynamic you would do something like

newid = $('##container##').find('textarea').attr('id');

This textarea will be wrapped by a div with the class .wp-editor-wrap, we need this conatainer node. Something like this should work:

parent = $('#'+id).closest('.wp-editor-wrap');

This can happen inside your ajax success callback after the markup has been appended. Now you need to create a function to add the tinymce instance, and I will copy the function I use. It's a bit outdated, from a time when I didn't know much about all this kind of things, I should revise it, but it works:

    // handles dynamic creation of TinyMCE instances
    tinymce : function(newid, parent) 
    {
        // get settings from native WP Editor 
        var settings = tinyMCEPreInit.mceInit['content'];

        // overwrite new editor id to settings
        settings['elements'] = newid;

        // add changed settings object to tinyMCEPreInit Object
        tinyMCEPreInit.mceInit[newid] = settings;

        // doesn't wok without, but don't really know what this does
        qtsettings = {
            'buttons' : '', 
            'disabled_buttons' : '', 
            'id' : newid
        };

        // add qt settings for the new instance as well
        tinyMCEPreInit.qtInit[newid] = qtsettings;

        // create new instance
        var ed = new tinymce.Editor(newid, settings);

        // render new instance
        ed.render();

        // add quicktags
        var qt = new QTags(qtsettings);

        // hackish..set a short delay to reset the new editor to visual mode and hide qt buttons
        // this is necessary :/
        setTimeout( function() {
            $(parent).removeClass('html-active').addClass('tmce-active');
            QTags._buttonsInit(); 
        }, 
        750);
    }

This function is part of a larger object, so you will have to bend it to your needs.

Thats it, or well, it's a start. Never tried this from the front end. Maybe there are some more things to do in this frontend case or I made a mistake in the above explanation. If you don't need Quicktags, you may get rid of the qt parts...and so on, you will have to play with it. However, it should give you an idea where to start the game :)

share|improve this answer
    
Wow, I really appreciate you taking the time to respond with such a thorough answer. I think it's going to take me a little while to digest this and test it out in my project buy I'll be sure to report back. Thanks again! –  Sam Apr 11 '12 at 4:50

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.