1

I'm trying to insert a wp_editor() into a page on the front-end with AJAX. The code I have right now inserts the wp_editor elements and the needed JavaScript and CSS files, but none of the settings I used initially in wp_editor() are used when creating this TinyMCE element.

How do I pass the $settings set in PHP into the dynamically created TinyMCE instance?

I found an old question that seems to answer my question, but I don't understand how it works, and the code gives a PHP Depreciated error.

Load tinyMCE / wp_editor() via AJAX


PHP

function insert_wp_editor_callback() {

    // Empty variable
    $html = '';

    // Define the editor settings
    $content = '';  
    $editor_id = 'frontend_wp_editor';

    $settings = array(
        'media_buttons' => false,
        'textarea_rows' => 1,
        'quicktags' => false,

        'tinymce' => array(         
            'toolbar1' => 'bold,italic,undo,redo',
            'statusbar' => false,
            'resize' => 'both',
            'paste_as_text' => true
        )
    );

    // Hack to put wp_editor inside variable
    ob_start();
    wp_editor($content, $editor_id, $settings);
    $html .= ob_get_contents();
    ob_end_clean(); 

    // Get the necessary scripts to launch tinymce
    $baseurl = includes_url( 'js/tinymce' );
    $cssurl = includes_url('css/');

    global $tinymce_version, $concatenate_scripts, $compress_scripts;

    $version = 'ver=' . $tinymce_version;
    $css = $cssurl . 'editor.css';

    $compressed = $compress_scripts && $concatenate_scripts && isset($_SERVER['HTTP_ACCEPT_ENCODING'])
        && false !== stripos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip');

    if ( $compressed ) {
        $html .= "<script type='text/javascript' src='{$baseurl}/wp-tinymce.php?c=1&amp;$version'></script>\n";
    } else {
        $html .=  "<script type='text/javascript' src='{$baseurl}/tinymce.min.js?$version'></script>\n";
        $html .=  "<script type='text/javascript' src='{$baseurl}/plugins/compat3x/plugin.min.js?$version'></script>\n";
    }

    add_action( 'wp_print_footer_scripts', array( '_WP_Editors', 'editor_js' ), 50 );
    add_action( 'wp_print_footer_scripts', array( '_WP_Editors', 'enqueue_scripts' ), 1 );

    wp_register_style('tinymce_css', $css);
    wp_enqueue_style('tinymce_css');    

    // Send data
    wp_send_json_success($html);    

    wp_die();   

} add_action( 'wp_ajax_insert_wp_editor_callback', 'insert_wp_editor_callback' );
add_action( 'wp_ajax_nopriv_insert_wp_editor_callback', 'insert_wp_editor_callback' );

JavaScript

$('#insert_wp_editor').on('click', function() {
    // Data to send to function
    var data = {
        'action': 'insert_wp_editor_callback'
    };

    $.ajax({
        url: ajaxURL,
        type: 'POST',
        data: data,
        success: function(response) {
            if ( response.success === true ) {          
                // Replace element with editor
                $('#editor-placeholder').replaceWith(response.data);

                // Init TinyMCE
                tinymce.init({
                    selector: '#frontend_wp_editor'
                });
            }
        }
    });
});
1

So, after doing some more digging, I answered my own question by "connecting the dots", so to speak. There's a lot of bits and pieces of info on this topic on StackOverflow and StackExchange, but none of them really answered my question.

So here is the full working code to loading a wp_editor instance with AJAX on the front-end, including the settings provided to wp_editor.

I think there might be an even better solution, as right now, I'm having to call wp_print_footer_scripts(), which might add some unnessacary stuff, but doesn't (in my case).


PHP

function insert_wp_editor_callback() {
    $html = '';

    // Define the editor settings
    $content = '';  
    $editor_id = 'frontend_wp_editor';

    $settings = array(
        'media_buttons' => false,
        'textarea_rows' => 1,
        'quicktags' => false,

        'tinymce' => array(         
            'toolbar1' => 'bold,italic,undo,redo',
            'statusbar' => false,
            'resize' => 'both',
            'paste_as_text' => true
        )
    );

    // Grab content to put inside a variable
    ob_start();

    // Create the editor
    wp_editor($content, $editor_id, $settings); 

    // IMPORTANT
    // Adding the required scripts, styles, and wp_editor configuration
    _WP_Editors::enqueue_scripts();
    _WP_Editors::editor_js();
    print_footer_scripts();

    $html .=  ob_get_contents();

    ob_end_clean();

    // Send everything to JavaScript function
    wp_send_json_success($html);    

    wp_die();   

} add_action( 'wp_ajax_insert_wp_editor_callback', 'insert_wp_editor_callback' );
add_action( 'wp_ajax_nopriv_insert_wp_editor_callback', 'insert_wp_editor_callback' );
  • whenever you need to add JS in ajax request, it has to be wrong. You probably should not use ajax to get an "editor" in the first place. AJAX should be used to transfer data with which JS code on the front end use to dynamicaly create elements. – Mark Kaplun Aug 17 '17 at 15:49
  • @MarkKaplun Why is this" wrong"? And how would you approach this situation? I think loading the editor's JS on every page, even if it's not being used, is just adding unnessacary bloat. – Swen Aug 17 '17 at 16:31
  • assume in the JS you have a global variable you set to 4 and later you modify it. On the first request the JS is run and it is set to 4, later it is modified to 5. Now there is a new request, and the value of that global is 4 again. In general I know that many many example return HTML in ajax request, but this means that you front end handling is always coupled with server code and you can not modify one without the other. – Mark Kaplun Aug 17 '17 at 17:00
  • 1
    for what you actually want to do, I would try to look at the 4.8 text widget and learn how it is dynamicaly creates an editor. I didn't look at the code myself but IIRC they initialize the editor in JS. As for loading the editor when not needed.... maybe you have a point here but as I said before you should try to avoid loading it twice. You can load the JS only when needed and in the AJAX request load only whatever data is needed for the editor itself – Mark Kaplun Aug 17 '17 at 17:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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