简体   繁体   English

如何在自定义小部件中添加 wp_editor

[英]How to add wp_editor in custom widget

I an trying to create a image widget with wp editor.我试图用 wp 编辑器创建一个图像小部件。 I see the editor but i cant the text like make it bold or bigger nither i see the tab switch from visual to text.我看到了编辑器,但我无法将文本设为粗体或更大,我也看到选项卡从视觉切换到文本。 Following is my code: Thanks in advance.以下是我的代码:提前致谢。

<input type="hidden" id="<?php echo esc_attr($this->get_field_id('description')); ?>" name="<?php echo esc_attr($this->get_field_name('description')); ?>" value="<?php echo esc_attr($instance['description']); ?>" />
        <?php  
            $edi_name =  esc_attr($this->get_field_name('description'));
            $content = $instance['description'];
            $editor_id_new = esc_attr($this->get_field_id('description'));
            $settings = array( 'media_buttons' => false,
              'textarea_rows' => 6,
              'textarea_name' => $edi_name,
              'teeny'         => false, 
              'menubar'     => false,
              'default_editor'   => 'tinymce',
              'quicktags' => false
              );  
            wp_editor( $content, $editor_id_new, $settings );
        ?>
        <script>
        (function($){
            tinyMCE.execCommand('mceAddEditor', false, '<?php echo $this->get_field_id('description'); ?>');
        })(jQuery);
        </script>

Short answer: Because there is a hidden widget where the TinyMCE appears first. 简短的回答:因为有一个隐藏的小部件,所以TinyMCE首先出现。

Long answer (sorry, a very long answer): 长答案(很抱歉,很长答案):

Go to the Codex and copy the example widget Foo_Widget to make sure we are talking about the same code. 转到Codex并复制示例小部件Foo_Widget ,以确保我们在谈论相同的代码。 Now open your IDE (not an editor) and write a short testing widget as plugin. 现在打开您的IDE(不是编辑器),并编写一个简短的测试小部件作为插件。 Starting with a minimal plugin header... 从最小的插件头开始...

<?php
/*
Plugin Name: Widget Test Plugin
Description: Testing plugincode
*/

... adding the widget code from the codex and registering the widget with the add_action() call. ...从法典中添加小部件代码,并使用add_action()调用注册小部件。 Now modify the form method within the widget class as shown here: 现在,在小部件类中修改form方法,如下所示:

public function form( $instance ) {
    if ( isset( $instance[ 'title' ] ) ) {
        $title = $instance[ 'title' ];
    }
    else {
        $title = __( 'New title', 'text_domain' );
    }
    ?>
    <p>
    <label for="<?php echo $this->get_field_id( 'title' ); ?>"><?php _e( 'Title:' ); ?></label>
    <input class="widefat" id="<?php echo $this->get_field_id( 'title' ); ?>" name="<?php echo $this->get_field_name( 'title' ); ?>" type="text" value="<?php echo esc_attr( $title ); ?>" />
    </p>
    <?php

/*** add this code ***/
    $content   = 'Hello World!';
    $editor_id = 'widget_editor';

    $settings = array(
        'media_buttons' => false,
        'textarea_rows' => 3,
        'teeny'         => true,
    );

    wp_editor( $content, $editor_id, $settings );
/*** end editing ***/
}

Go to your blog, activate the plugin, go to the widget page and drag the Foo Widget into a sidebar. 转到您的博客,激活插件,转到小部件页面,然后将Foo Widget拖到侧栏中。 You will see it will fail. 您将看到它将会失败。

Do you see the Foo Widget description on the left side? 您是否在左侧看到Foo Widget描述? Do a right click on the description and choose 'Inspect' from your developer tools (you have some developer tools like FireBug or Chrome DevTools, huh? In FireFox you can also choose the build in 'Inspect Element'). 在描述上单击鼠标右键,然后从开发人员工具中选择“检查”(您有一些开发人员工具,例如FireBug或Chrome DevTools,是吗?在FireFox中,您还可以在“检查元素”中选择内部版本)。 Browse through the HTML code and you will see there is an editor wrap inside the 'hidden' widget. 浏览HTML代码,您将看到“隐藏”小部件内有一个编辑器包装。 隐藏小部件中的wp_editor

You can see one editor in the sidebar on the right and there is an editor in the 'hidden' widget on the left. 您可以在右侧的侧栏中看到一个编辑器,而在左侧的“隐藏”小部件中有一个编辑器。 This cannot work properly because TinyMCE don't know which editor should be used. 由于TinyMCE不知道应使用哪个编辑器,因此无法正常工作。

What do we need? 我们需要什么?

We need a unique ID for our editor. 我们需要编辑器的唯一 ID。

/*** add this code ***/
    $rand    = rand( 0, 999 );
    $ed_id   = $this->get_field_id( 'wp_editor_' . $rand );
    $ed_name = $this->get_field_name( 'wp_editor_' . $rand );

    $content   = 'Hello World!';
    $editor_id = $ed_id;

      $settings = array(
      'media_buttons' => false,
      'textarea_rows' => 3,
      'textarea_name' => $ed_name,
      'teeny'         => true,
    );

    wp_editor( $content, $editor_id, $settings );
/*** end edit ***/

Modify the code within the form method again with the code above. 使用上面的代码再次修改form方法中的代码。 We create a unique number with rand() and append this number to the id and name attributes. 我们使用rand()创建一个唯一的数字,并将该数字附加到idname属性中。 But stop, what about saving the values??? 但是停下来,保存值呢???

Go to the update method and add die(var_dump($new_instance)); 转到update方法并添加die(var_dump($new_instance)); in the first line. 在第一行。 If you press Save on the widget, the script will die and print out the submitted values. 如果在窗口小部件上按Save ,脚本将消失并打印出提交的值。 You will see there is a value like wp_editor_528 . 您将看到类似wp_editor_528的值。 If you reload the page and save the widget again, the number will be changed to something else because it is a random number. 如果重新加载页面并再次保存小部件,则该数字将更改为其他名称,因为它是随机数。

How will I know which random number was set in the widget? 我如何知道在窗口小部件中设置了哪个随机数? Simply send the random number with the widget data. 只需将随机数与小部件数据一起发送即可。 Add this to the form method 将此添加到form方法

printf(
  '<input type="hidden" id="%s" name="%s" value="%d" />',
  $this->get_field_id( 'the_random_number' ),
  $this->get_field_name( 'the_random_number' ),
  $rand
);

In the update routine, we can now access the random number with $new_instance['the_random_number']; 在更新例程中,我们现在可以使用$new_instance['the_random_number'];访问随机数$new_instance['the_random_number']; and so we can access the editor content with 这样我们就可以使用

$rand = (int) $new_instance['the_random_number'];
$editor_content = $new_instance[ 'wp_editor_' . $rand ];
die(var_dump($editor_content));

As you can see, the editor content will be submitted and you can save it or do anything else with it. 如您所见,编辑器内容将被提交,您可以保存它或对其进行任何其他操作。

Caveat 警告

The editor content is only submitted correctly if the TinyMCE is not in visual mode (WYSIWYG mode). 仅当TinyMCE 不在可视模式(“所见即所得”模式)下,才可以正确提交编辑器内容。 You have to switch to the text mode befor press 'Save'. 您必须先切换到文本模式,然后再按“保存”。 Otherwise the predefined content (in this case $content = 'Hello World!'; ) is submitted. 否则,将提交预定义的内容(在本例中$content = 'Hello World!'; )。 I don't now why, but there is a simple workaround for this. 我现在不知道为什么,但是有一个简单的解决方法。

Write a small jQuery script that triggers the click on the 'text' tab before saving the widget content. 在保存小部件内容之前,编写一个小的jQuery脚本来触发对“文本”选项卡的单击。

JavaScript (saved as widget_script.js somewhere in your theme/plugin folders): JavaScript(在主题/插件文件夹中的某个位置保存为widget_script.js ):

jQuery(document).ready(
    function($) {
        $( '.widget-control-save' ).click(
            function() {
                // grab the ID of the save button
                var saveID   = $( this ).attr( 'id' );

                // grab the 'global' ID
                var ID       = saveID.replace( /-savewidget/, '' );

                // create the ID for the random-number-input with global ID and input-ID
                var numberID = ID + '-the_random_number';

                // grab the value from input field
                var randNum  = $( '#'+numberID ).val();

                // create the ID for the text tab
                var textTab  = ID + '-wp_editor_' + randNum + '-html';

                // trigger a click
                $( '#'+textTab ).trigger( 'click' );

            }
        );
    }
);

And enqueue it 并入队

function widget_script(){

    global $pagenow;

    if ( 'widgets.php' === $pagenow )
        wp_enqueue_script( 'widget-script', plugins_url( 'widget_script.js', __FILE__ ), array( 'jquery' ), false, true );

}

add_action( 'admin_init', 'widget_script' );

That's it. 而已。 Easy, isn't it? 很简单,不是吗? ;) ;)

Actual Credit Goes To The Author Of Writting This Test Plugin @Ralf912 实际功劳归功于编写此测试插件@ Ralf912的作者

Reference URL : Why Can't wp_editor Be Used in a Custom Widget? 参考URL: 为什么不能在自定义小部件中使用wp_editor?

I made some improvements to this code in case somebody needs it:我对这段代码做了一些改进,以防有人需要它:

on the form function of the widget I updated the code:在小部件的表单 function 上,我更新了代码:

$rand = !empty( $instance['the_random_number']) ? $instance['the_random_number'] : rand( 0, 999 );

        $ed_id   = $this->get_field_id( 'wp_editor_' . $rand );
        $ed_name = $this->get_field_name( 'wp_editor_' . $rand );

        $content   = !empty( $instance['the_random_number']) ? $instance['wp_editor_' . $rand] : 'Content goes here!';          
        $editor_id = $ed_id;

        $settings = array(
        'media_buttons' => true,
        'textarea_rows' => 3,
        'textarea_name' => $ed_name,
        'teeny'         => true,
        );

        wp_editor( $content, $editor_id, $settings ); `

And I also reinitialized the editor because it was broken after save而且我还重新初始化了编辑器,因为它在保存后坏了

jQuery(document).on('widget-updated', function(e, widget){
if(widget[0].id.includes("cw_pa_text_widget")) { // if it is the right widget
    let editor ="widget-" + widget[0].id.substring(widget[0].id.indexOf('_') + 1);
    let randNum = editor + "-the_random_number";
    let wpEditorId = editor + "-wp_editor_" + document.getElementById(randNum).value;

    var settings = {
        quicktags: true,
    };
    wp.editor.initialize(wpEditorId, settings);

    //create the ID for the text tab
    var textTab  = wpEditorId + '-tmce';

    // trigger a click
    document.getElementById(textTab).click();
}}); 

Thank you.谢谢你。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM