为什么不能在自定义小部件中使用wp_EDITOR?

时间:2013-01-22 作者:Goldentoa11

我一直在开发一个插件,添加一个小部件,允许您使用所见即所得编辑器编辑内容。我想通过调用wp_editor(). 我看到有人说你做不到这一点,果然,当你尝试更新小部件内容时,它崩溃了。

有人能解释一下原因吗wp_editor() 不能在小部件中使用?

我希望一旦我知道它为什么不起作用,我就想知道如何绕过它。然而,Chrome不会在控制台中显示任何错误,所以我不确定它会显示出什么情况。

谢谢,goldentoa11

3 个回复
SO网友:Ralf912

简短回答:因为在TinyMCE首先出现的地方有一个隐藏的小部件。

冗长的回答(抱歉,回答得很长):

转到Codex and copy the example widget Foo_Widget 确保我们讨论的是相同的代码。现在打开IDE(不是编辑器)并编写一个简短的测试小部件作为插件。从最小插件头开始。。。

<?php
/*
Plugin Name: Widget Test Plugin
Description: Testing plugincode
*/
。。。从codex中添加小部件代码,并将小部件注册到add_action() 呼叫现在修改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 ***/
}
转到您的博客,激活插件,转到小部件页面并拖动Foo Widget 进入侧栏。你会看到它会失败。

你看到了吗Foo Widget 左侧的描述?右键单击描述并从开发人员工具中选择“Inspect”(您有一些开发人员工具,如FireBug或Chrome DevTools,嗯?在FireFox中,您还可以选择内置的“Inspect元素”)。浏览HTML代码,您将看到“隐藏”小部件中有一个编辑器包装。wp_editor in the hidden widget

您可以在右侧的侧栏中看到一个编辑器,在左侧的“隐藏”小部件中有一个编辑器。这无法正常工作,因为TinyMCE不知道应该使用哪个编辑器。

What do we need?

我们需要一个unique 我们编辑器的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 ***/
在中修改代码form 方法再次使用上面的代码。我们使用rand() 并将此数字附加到idname 属性。但是停下来,保存这些值怎么样???

转到update 方法和添加die(var_dump($new_instance)); 在第一行。如果按Save 在小部件上,脚本将消失并打印出提交的值。你会看到有一个值wp_editor_528. 如果重新加载页面并再次保存小部件,该数字将更改为其他数字,因为它是一个随机数。

我如何知道小部件中设置了哪个随机数?只需将随机数与小部件数据一起发送即可。将此添加到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
);
在更新例程中,我们现在可以使用$new_instance[\'the_random_number\']; 因此,我们可以使用

$rand = (int) $new_instance[\'the_random_number\'];
$editor_content = $new_instance[ \'wp_editor_\' . $rand ];
die(var_dump($editor_content));
如您所见,编辑器内容将被提交,您可以保存它或对其执行任何其他操作。

Caveat

只有在TinyMCEnot 在视觉模式下(WYSIWYG模式)。在按“保存”之前,必须切换到文本模式。否则,预定义的内容(在本例中$content = \'Hello World!\';) 已提交。我现在不知道为什么,但有一个简单的解决方法。

编写一个小jQuery脚本,在保存小部件内容之前触发对“文本”选项卡的单击。

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\' );

            }
        );
    }
);
并将其排队

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\' );
就是这样。很简单,不是吗?;)

SO网友:Blackbam

不知道wp\\u editor()为什么不能在小部件内部工作的确切答案,但小部件有一些限制。

但是wp\\u编辑器只是WordPress后端使用可视化编辑器的众多可能性之一。尝试以某种方式使用jQuery初始化可视化编辑器。我不认为您可以在小部件窗口本身内完成,但灯箱或类似的东西可能会有所帮助。

以下是一种方法:

/**
 * Add TinyMCE to multiple Textareas (usually in backend).
 */
//  add_action(\'admin_print_footer_scripts\',\'my_admin_print_footer_scripts\',99);
function my_admin_print_footer_scripts() {
    ?><script type="text/javascript">/* <![CDATA[ */
        jQuery(function($)
        {
            var i=1;
            $(\'.customEditor textarea\').each(function(e)
            {
                var id = $(this).attr(\'id\');

                if (!id)
                {
                    id = \'customEditor-\' + i++;
                    $(this).attr(\'id\',id);
                }

                tinyMCE.execCommand(\'mceAddControl\', false, id);

            });
        });
    /* ]]> */</script><?php
}

SO网友:Z. Zlatev

在widget中实现tinyMCE是完全可能的。事实上it has been already done. 为什么只打电话wp_editor() 在小部件表单中不起作用的是表单标记是使用AJAX异步传递的。尝试searching here 了解更多详细信息。

结束