5

I use TinyMce on my customizer (for obv reasons). But i encounter a problem that i do not seem to have the answer to. Let me first share you my code that are crucial:

Functions.php

// text editor

if ( ! class_exists( 'WP_Customize_Control' ) )
    return NULL;
/**
 * Class to create a custom tags control
 */
class Text_Editor_Custom_Control extends WP_Customize_Control
{
    /**
     * Render the content on the theme customizer page
     */
    public function render_content()
    {
        ?>
        <label>
            <span class="customize-text_editor"><?php echo esc_html( $this->label ); ?></span>
            <input class="wp-editor-area" type="hidden" <?php $this->link(); ?> value="<?php echo esc_textarea( $this->value() ); ?>">
            <?php
            $settings = array(
                'textarea_name' => $this->id,
                'media_buttons' => false,
                'drag_drop_upload' => false,
                'teeny' => true,
                'quicktags' => false,
                'textarea_rows' => 5,
            );
            $this->filter_editor_setting_link();
            wp_editor($this->value(), $this->id, $settings );
            ?>
        </label>
        <?php
        do_action('admin_footer');
        do_action('admin_print_footer_scripts');
    }
    private function filter_editor_setting_link() {
        add_filter( 'the_editor', function( $output ) { return preg_replace( '/<textarea/', '<textarea ' . $this->get_link(), $output, 1 ); } );
    }
}

function editor_customizer_script() {
    wp_enqueue_script( 'wp-editor-customizer', get_template_directory_uri() . '/inc/customizer.js', array( 'jquery' ), rand(), true );
}
add_action( 'customize_controls_enqueue_scripts', 'editor_customizer_script' );

Customizer.php

    // content 1 text

$wp_customize->add_setting('home_content1_text', array(
    'default' => 'Here goes an awesome title!',
    'transport' => 'postMessage',
));
$wp_customize->add_control(new Text_Editor_Custom_Control( $wp_customize, 'home_content1_text', array(
    'label' => __('Text content 1', 'DesignitMultistore'),
    'section' => 'home_content_1',
    'description' => __('Here you can add a title for your content', 'DesignitMultistore'),
    'priority' => 5,
)));

    //slider text 1 control
$wp_customize->add_setting('slider_text_1', array(
    'default' => _x('Welcome to the Designit Multistore theme for Wordpress', 'DesignitMultistore'),
    'transport' => 'postMessage',
));
$wp_customize->add_control(new Text_Editor_Custom_Control( $wp_customize, 'slider_text_1', array(
    'description' => __('The text for first image for the slider', 'DesignitMultistore'),
    'label' => __('Slider Text 1', 'DesignitMultistore'),
    'section' => 'Designit_slider_slide1',
    'priority' => 3,
)));

Customizer.JS

    ( function( $ ) {
    wp.customizerCtrlEditor = {

        init: function() {

            $(window).load(function(){
                var adjustArea = $('textarea.wp-editor-area');
                adjustArea.each(function(){
                    var tArea = $(this),
                        id = tArea.attr('id'),
                        input = $('input[data-customize-setting-link="'+ id +'"]'),
                        editor = tinyMCE.get(id),
                        setChange,
                        content;

                    if(editor){
                        editor.onChange.add(function (ed, e) {
                            ed.save();
                            content = editor.getContent();
                            clearTimeout(setChange);
                            setChange = setTimeout(function(){
                                input.val(content).trigger('change');
                            },500);
                        });
                    }

                    if(editor){
                        editor.onChange.add(function (ed, e) {
                            ed.save();
                            content = editor.getContent();
                            clearTimeout(setChange);
                            setChange = setTimeout(function(){
                                input.val(content).trigger('change');
                            },500);
                        });
                    }

                    tArea.css({
                        visibility: 'visible'
                    }).on('keyup', function(){
                        content = tArea.val();
                        clearTimeout(setChange);
                        setChange = setTimeout(function(){
                            input.val(content).trigger('change');
                        },500);
                    });
                });
            });
        }

    };

    wp.customizerCtrlEditor.init();

} )( jQuery );

Now the problem

Everything seems to work fine. I do have an TinyMce editor. Its not registering that something has been changed. And when i change something else and save it along with the changes is not saved either.

Does someone have a working example of a RTE or TinyMce editor that replaces the textarea's on the customizer?

Update

Only the last instance that i define in my customizer.php works. By now i have 14 textarea's. The text area works fine on the 14th but not on 1-13th

UPDATE 2

It seems that for each area that remains he creates that number of tinymce's within that area. So the first area has 14 tinymce's overlapping eachother. The second 13 ; the thirth 14 etc etc. Until the last has only 1 and therefor working

2

My problem has been "solved" by doing the following :

The problem is that do_action is getting called each time that i have a new class. But it needs to be called only in the last. Otherwise this creates a bunch of admin_print_footer_scripts.

Since i'm writing the code myself and i don't intend on selling this for now i can just count the number of new class instances i create. Which is 14 at this point.

So i altered it like this :

Functions.php

class Text_Editor_Custom_Control extends WP_Customize_Control
{

    /**
     * Render the content on the theme customizer page
     */
    public function render_content()
    {
        static $i = 1;
        ?>
        <label>
            <span class="customize-text_editor"><?php echo esc_html( $this->label ); ?></span>
            <input class="wp-editor-area" type="hidden" <?php $this->link(); ?> value="<?php echo esc_textarea( $this->value() ); ?>">
            <?php
            $content = $this->value();
            $editor_id = $this->id;
            $settings = array(
                'textarea_name' => $this->id,
                'media_buttons' => false,
                'drag_drop_upload' => false,
                'teeny' => true,
                'quicktags' => false,
                'textarea_rows' => 5,
            );
            wp_editor($content, $editor_id, $settings );


            if( $i == 14) {
                do_action('admin_print_footer_scripts');
            }
            $i++;

            ?>
        </label>
        <?php
    }
};

function editor_customizer_script() {
    wp_enqueue_script( 'wp-editor-customizer', get_template_directory_uri() . '/inc/customizer.js', array( 'jquery' ), false, true );
}
add_action( 'customize_controls_enqueue_scripts', 'editor_customizer_script' );

If someone knows how i can count the times i call that new class in my customizer and use it in my functions.php to know when the last time its called i can call the do_action... It would help a lot

3
  • 2
    Btw , i still find it very stupid that i don't get my bounty back. Got no help for selling my reputation and i spend hours on figuring this out on my own. Last time i will use the bounty system. I putted this answer up to help other ppl in the future hopefulle – CompactCode Apr 24 '17 at 4:31
  • Just throwing this out there - the Kirki plugin/library does support multiple editors in the customizer, so you could check out its code for ideas to use with your implementation. – Dave Romsey Apr 24 '17 at 18:53
  • 1
    Thanks , i will sure take a look at their code when i have the time to study their library! – CompactCode Apr 26 '17 at 12:32
2

SwAt.Be, your own answer helped me a bunch and I've nailed the problem of printing admin scripts after the last rendition of wp_editor. Also see how I pass JS setup function as tinymce option to sync the editor changes with WP customizer to make it work properly.

if (class_exists('WP_Customize_Control')) {
  class WP_Customize_Teeny_Control extends WP_Customize_Control {
    function __construct($manager, $id, $options) {
      parent::__construct($manager, $id, $options);

      global $num_customizer_teenies_initiated;
      $num_customizer_teenies_initiated = empty($num_customizer_teenies_initiated)
        ? 1
        : $num_customizer_teenies_initiated + 1;
    }
    function render_content() {
      global $num_customizer_teenies_initiated, $num_customizer_teenies_rendered;
      $num_customizer_teenies_rendered = empty($num_customizer_teenies_rendered)
        ? 1
        : $num_customizer_teenies_rendered + 1;

      $value = $this->value();
      ?>
        <label>
          <span class="customize-text_editor"><?php echo esc_html($this->label); ?></span>
          <input id="<?php echo $this->id ?>-link" class="wp-editor-area" type="hidden" <?php $this->link(); ?> value="<?php echo esc_textarea($value); ?>">
          <?php
            wp_editor($value, $this->id, [
              'textarea_name' => $this->id,
              'media_buttons' => false,
              'drag_drop_upload' => false,
              'teeny' => true,
              'quicktags' => false,
              'textarea_rows' => 5,
              // MAKE SURE TINYMCE CHANGES ARE LINKED TO CUSTOMIZER
              'tinymce' => [
                'setup' => "function (editor) {
                  var cb = function () {
                    var linkInput = document.getElementById('$this->id-link')
                    linkInput.value = editor.getContent()
                    linkInput.dispatchEvent(new Event('change'))
                  }
                  editor.on('Change', cb)
                  editor.on('Undo', cb)
                  editor.on('Redo', cb)
                  editor.on('KeyUp', cb) // Remove this if it seems like an overkill
                }"
              ]
            ]);
          ?>
        </label>
      <?php
      // PRINT THEM ADMIN SCRIPTS AFTER LAST EDITOR
      if ($num_customizer_teenies_rendered == $num_customizer_teenies_initiated)
        do_action('admin_print_footer_scripts');
    }
  }
}

// TRY IT
add_action('customize_register', function ($wp_customize) {
  $wp_customize->add_section('footer_section' , [
    'title' => __('Footer', 'musiccase'),
    'priority' => 100
  ]);

  // 1st EDITOR
  $wp_customize->add_setting('footer_contact', [
    'type' => 'option'
  ]);
  $wp_customize->add_control(new WP_Customize_Teeny_Control($wp_customize, 'footer_contact', [
    'label' => __('Contact Info', 'musiccase'),
    'section' => 'footer_section'
  ]));

  // 2nd EDITOR
  $wp_customize->add_setting('footer_contact_2', [
    'type' => 'option'
  ]);
  $wp_customize->add_control(new WP_Customize_Teeny_Control($wp_customize, 'footer_contact_2', [
    'label' => __('Contact Info 2', 'musiccase'),
    'section' => 'footer_section'
  ]));
}, 20);
1
  • This is an interesting approach that is for sure. I will test it out myself since i'm using this tiny mce editor in every theme that i create and every website that i develop. Thanks for sharing! – CompactCode Jul 24 '17 at 3:26
0
+50

Looks like I'm a bit too late for the answer, but as far as the count you could use this: (add the counter and __construct() to the top of your class for actual use) NOT tested but should be good to go.

<?php
class Text_Editor_Custom_Control {
    public static $counter = 0;

    function __construct() {
        self::$counter++;
        self::$lastcall= date('Y-m-d H:i:s');
    }
}

new Text_Editor_Custom_Control();
new Text_Editor_Custom_Control();
new Text_Editor_Custom_Control();

echo Text_Editor_Custom_Control::$counter;  //would be 3

echo Text_Editor_Custom_Control::$counter;  //shows datetime of last call
?>
1
  • No time to test it out but i will give you the bounty since you took the time to answer. Will comment later if it worked or not. – CompactCode May 1 '17 at 10:06
0

The problem lies inside customizer.js where you try to select the .wp-editor-area. However the input[data-customize-setting-link="'+ id +'"] does not select this input because the id returns the control instead of the setting.

To fix this

give the input .wp-editor-area an id id="tinymce-input"

and use it to select this input in your customizer.js by changing input = $('input[data-customize-setting-link="'+ id +'"]') into input = $('#tinymce-input')

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.