TinyMCE作为评论编辑器-编码问题

时间:2019-12-17 作者:Tinstar

我已经在前端和后端实现了TinyMCE作为我的评论表单,使用了以下代码(来源于这里的一些问题):

// Enable TinyMCE as frontend comment editor for new comments
function wpse_64243_comment_editor( $field ) {

    if (!is_single()) return $field; //only on single post pages.

    global $post;
    ob_start();

    wp_editor( \'\', \'comment\', array(
        \'textarea_rows\' => 15
    ) );

    $editor = ob_get_contents();
    ob_end_clean();

    //make sure comment media is attached to parent post
    $editor = str_replace( \'post_id=0\', \'post_id=\'.get_the_ID(), $editor );
    return $editor;
}

add_filter( \'comment_form_field_comment\', \'wpse_64243_comment_editor\' );

// Enable TinyMCE as the backend comments editor
function cort_remove_editor_quicktags( $settings, $id ){
    global $pagenow; 
    if ( $id == \'content\' && $pagenow === \'comment.php\' ){
        $settings[\'tinymce\'] = true;
    }
    return $settings;
}

add_filter( \'wp_editor_settings\', \'cort_remove_editor_quicktags\', 10, 2 );
但每次我去编辑它时,注释编码都会变得有点奇怪。虽然任何格式都会在管理视图中正确显示,并且页面上的所有标记都是粗体/斜体,但每当我尝试使用TinyMCE编辑文本时,我都会得到以下结果:

<!--On TinyMCE, in visual mode-->
<strong>asdfjkasld;f</strong>

<em>hjkdlhfaskdjfas</em>

<!--On TinyMCE, in text mode-->
&lt;strong&gt;asdfjkasld;f&lt;/strong&gt;

&lt;em&gt;hjkdlhfaskdjfas&lt;/em&gt;
如果我通过删除编码的标签并通过TinyMCE重新格式化来“修复”样式,那么下次在该注释上点击Edit时,我会得到与上述相同的结果。

据我所知,这与TinyMCE没有解码编码的文本有关,因为我在正常环境之外设置了它。我已经尝试更改中的编码实体tiny_mce_before_init, 但这并没有奏效。有没有什么钩子可以在帖子到达TinyMCE之前过滤帖子的实际内容?还是这是一条死胡同?

1 个回复
最合适的回答,由SO网友:Tinstar 整理而成

It\'s still unclear to me why this is happening, because all the encoding of < and > for comments looks the same as posts do in the database view, so I\'m still unsure why TinyMCE is treating post_content vs comment_content differently. But ultimately, all that needs to happen is for the existing escaped HTML tags to get decoded when editing on the backend.

jQuery( document ).on( \'tinymce-editor-init\', function( event, editor ) {
    function htmlDecode(input) {
        var doc = new DOMParser().parseFromString(input, "text/html");
        return doc.documentElement.textContent;
    }

    function fixTinyMCEComments() {
        var parent = document.querySelector("#content_ifr").contentDocument.children[0].querySelector("#tinymce");
        Array.from(parent.children).forEach(function(p) {
            p.innerHTML = htmlDecode(p.innerHTML);
        });
    }

    fixTinyMCEComments();
});

Register it wherever your admin_enqueue_scripts is called in functions.php - I enqueue it only on comment.php:

// Enable TinyMCE as the backend comments editor
function load_backend_comments_editor( $settings, $id ){
    global $pagenow; 
    if ( $id == \'content\' && $pagenow === \'comment.php\' ){
        $settings[\'tinymce\'] = true;
        wp_enqueue_script( \'mytheme-admin\' );
    }
    return $settings;
}
add_filter( \'wp_editor_settings\', \'load_backend_comments_editor\', 10, 2 );

This is a bit of a hack, because the implementation depends on TinyMCE maintaining its current node tree, but since this is on the backend for something that likely won\'t continue to be edited after a month or so, I\'m okay with it. Any improvements are welcome, though!