在可视化编辑器中保留粘贴的预格式化代码(带有选项卡)

时间:2017-10-16 作者:cavameta

我需要一个manual code 到我的函数php到extend the visual editor from removing tabs 粘贴代码块时。

我在这个网站上找到了这段代码,但它不能像我想要的那样工作。如果我得到:

add_filter(\'tiny_mce_before_init\', \'tiny_mce_before_init\');
function tiny_mce_before_init($init) {
    $init[\'setup\'] = "function(ed) {
        ed.onBeforeSetContent.add(function(ed, o) {
            if ( o.content.indexOf(\'<pre\') != -1) {
                o.content = o.content.replace(/<pre[^>]*>[\\\\s\\\\S]+?<\\\\/pre>/g, function(a) {
                    return a.replace(/(\\\\r\\\\n|\\\\n)/g, \'<br />\');
                });
            }
        });
    }";
    return $init;
}
然后粘贴到Visual中,我得到:

add_filter(\'tiny_mce_before_init\', \'tiny_mce_before_init\');
function tiny_mce_before_init($init) {
$init[\'setup\'] = "function(ed) {
ed.onBeforeSetContent.add(function(ed, o) {
if ( o.content.indexOf(\'<pre\') != -1) {
o.content = o.content.replace(/<pre[^>]*>[\\\\s\\\\S]+?<\\\\/pre>/g, function(a) {
return a.replace(/(\\\\r\\\\n|\\\\n)/g, \'<br />\');
});
}
});
}";
return $init;
}
我知道TinyMCE设置不打算保留选项卡,因为“它会占用空间”。。。

我需要一个manual paste & go 解决方案,而不是安装处理大量其他内容的插件的链接。在编辑器之间切换也不允许更改任何内容。有可能吗?

感谢您的阅读和帮助!

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

我的回答是,在TinyMCE和Wordpress的对话中没有解决这个问题的方法。但是There are diffrent approaches to work with coding material.

我在另一次讨论中分享了这一点,但在你的问题中,这可能是一个更好的背景。

This solution 已经为我工作多年了,and I love it. 这种方法使用“中间人”在编辑和wpautop() 问题。它也handles the entity char problems 在编辑器之间切换。

只需粘贴到函数中即可。php

如何使用:在编辑器中创建默认的预格式化文本块,就像使用工具栏中的下拉菜单一样。然后在编辑器中单击它-就像您对图像所做的那样。显示要粘贴或编辑的区域,请将其发送回。只需再次单击预块即可进行编辑。

它看起来很重,但很轻。没有modals API或其他什么。但是jQuery必须在“全局范围”中,因为它talks with tinyMCE API. 多拉设计$ 无法使用和the jQuery text clutter the code down. 主要是创建占用空间的HTML元素。

How it works: 非常简单,不用“触摸”它-不要弄乱它。值得一试!

/**
 * PRE Handler
 * Solves <pre> handle in Wordpress tinyMCE editor
 * TAB support
 * TAB support to TEXT editor
 * Simple cleanup with Undo
 * Push cleanup (experimental)
 * Moves empty code chunks to beginning
**/


function entex_tiny_mce_before_init(){
    add_filter(\'tiny_mce_before_init\', function($mceInit){
        $mceInit[\'setup\'] = \'ua_TinyMCE_setup_callback\';
        return $mceInit;
    });
    add_action(\'before_wp_tiny_mce\', \'entex_TinyMCE_javascript\');
}
add_action(\'after_setup_theme\', \'entex_tiny_mce_before_init\');


function entex_TinyMCE_javascript() {

    echo \'<script type="text/javascript">\'."\\n";
    ?>

    var ua_tinyMCE_invoked = 0;

    function ua_TinyMCE_setup_callback(ed){

        if(ua_tinyMCE_invoked) return;
        ua_tinyMCE_invoked = 1;

        ed.on(\'init\', function(e) {
            jQuery(ed.getBody()).on(\'click\', \'pre\', function() {
                ua_TinyMCE_edit_pre(ed, this);
                return false;
            });
        });
    }

    function ua_TinyMCE_helper_cleanBeginnings(str, find, replace){
        return str.replace(new RegExp(find, \'g\'), replace);
    }

    function ua_TinyMCE_edit_pre(ed, obj) {
        var jQueryE = jQuery(obj); 
        var jQueryB = jQuery(ed.getBody());
        var content = jQuery(\'<textarea/>\').html(jQueryE.html()).text();
        content = content.replace(/(<br>)/g, \'\');
        /* add whatever stuff to manipulate here */
        //content = content.replace(/   /g, \'\\t\');
        var data = content;


        var jQueryL = jQuery(\'<div />\').css({
            \'position\': \'fixed\',
            \'box-sizing\': \'border-box\',
            \'background-color\': \'rgba(255, 255, 255, 0.85\',
            \'border\': \'3px solid #ccc\',
            \'padding\': \'10px\',
            \'z-index\': \'9992\',
            \'height\': \'auto\',
            \'width\': \'80%\',
            \'left\': \'50%\',
            \'margin-left\': \'-40%\',
            \'top\': \'5%\'
        });

        var jQueryT = jQuery(\'<textarea />\').keydown(function(e){

            if ( e.which != 9 ) return;
            var start = this.selectionStart;
            var end = this.selectionEnd;
            this.value = this.value.substr( 0, start ) + "\\t" + this.value.substr( end );
            this.selectionStart = this.selectionEnd = start + 1;
            e.preventDefault();
            return false;

        }).attr(\'wrap\', \'soft\').css({
            \'height\': \'98%\',
            \'width\': \'88%\',
            \'min-height\': \'300px\',
            \'tab-size\': \'3\',
            \'font-family\': \'courier new\',
            \'box-sizing\': \'border-box\'
        });

        jQuery(\'#wpcontent\').css(\'position\', \'relative\').append(jQueryL);
        jQueryL.append(jQueryT);
        jQueryL.append(
            jQuery(\'<div />\').css({
                \'width\': \'10%\',
                \'height\': \'100%\',
                \'position\': \'absolute\',
                \'top\': \'0px\',
                \'right\': \'10px\',
                \'padding-top\': \'10px\',
                \'box-sizing\': \'border-box\'
            }).append(
                jQuery(\'<a />\').attr(\'title\', \'Send to element\').click(function(){

                    var encodedStr = jQueryT.val().replace(/[\\u00A0-\\u9999<>\\&]/gim, function(i) {
                        return \'&#\'+i.charCodeAt(0)+\';\';
                    });

                    jQueryE.html(encodedStr);
                    ed.focus();
                    jQueryL.remove();
                    return false;

                }).text(\'Send\').addClass(\'button button-primary\').css({
                    \'display\': \'block\',
                    \'width\': \'100%\',
                    \'margin-bottom\': \'5px\',
                    \'text-align\': \'center\',
                    \'box-sizing\': \'border-box\'
                }), 

                jQuery(\'<a />\').attr(\'title\', \'Cleanup\').click(function(){

                    var data = jQueryT.val();
                    var original = data;
                    data = data.replace(/(\\r\\n|\\n|\\r)/gm, "\\r\\n");
                    var workspace = data.replace(/(\\r\\n|\\n|\\r)/gm, \'\');

                    if(/^\\s/.test(workspace)) {
                        var search_string = workspace.replace(/^\\s+|\\s+$/g, \'\');
                        if(search_string){
                            var firstChar = search_string[0];
                            var remove = workspace.substr(0, workspace.indexOf(firstChar));
                            remove = "\\r\\n" + remove;
                            data = ua_TinyMCE_helper_cleanBeginnings(data, remove, "\\r\\n");
                        }
                        data = data.replace(/   /g, "\\t");
                        data = data.replace(/^\\s+|\\s+$/g, \'\');
                    } else {
                        data = data.replace(/^\\s+|\\s+$/g, \'\');
                    }
                    if(data != original){
                        jQueryT.data(\'original\', original);
                        if(!jQuery(\'#ua-TinyMCE-btt-undo\').get(0)){
                        jQuery(this).after(
                            jQuery(\'<a />\').attr(\'title\', \'Undo\').click(function(){
                                jQueryT.val(jQueryT.data(\'original\'));
                                jQuery(this).remove();
                                return false;

                            }).text(\'Undo\').addClass(\'button\').css({
                                \'display\': \'block\',
                                \'width\': \'100%\',
                                \'margin-bottom\': \'5px\',
                                \'text-align\': \'center\',
                                \'box-sizing\': \'border-box\'
                            }).attr(\'id\', \'ua-TinyMCE-btt-undo\')
                        );
                        }
                    }
                    data = data.replace(/   /g, "\\t");
                    jQueryT.val(data);
                    return false;

                }).text(\'Cleanup\').addClass(\'button\').css({
                    \'display\': \'block\',
                    \'width\': \'100%\',
                    \'margin-bottom\': \'5px\',
                    \'text-align\': \'center\',
                    \'box-sizing\': \'border-box\'
                }),

                jQuery(\'<a />\').attr(\'title\', \'Close\').click(function(){

                    ed.focus();
                    jQueryL.remove();
                    return false;

                }).text(\'Close\').addClass(\'button\').css({
                    \'display\': \'block\',
                    \'width\': \'100%\',
                    \'margin-bottom\': \'5px\',
                    \'text-align\': \'center\',
                    \'box-sizing\': \'border-box\'
                }),

                jQuery(\'<a />\').attr(\'title\', \'Remove all data\').click(function(){

                    jQueryT.val(\'\').focus();
                    return false;

                }).text(\'Delete\').addClass(\'button\').css({
                    \'display\': \'block\',
                    \'width\': \'100%\',
                    \'margin-bottom\': \'0px\',
                    \'position\': \'absolute\',
                    \'bottom\': \'10px\',
                    \'background-color\': \'#D54E21\',
                    \'color\': \'#fff\',
                    \'text-align\': \'center\',
                    \'box-sizing\': \'border-box\'
                })
            )
        );
        jQueryT.val(content).focus();
        return false;
    }

    // WP EDITOR
    jQuery(document).ready(function($){
        if($(\'textarea#content\').get(0)){
            $(\'textarea#content\').on(\'keydown\', function(e){
                if ( e.which != 9 ) return;
                var start = this.selectionStart;
                var end = this.selectionEnd;
                this.value = this.value.substr( 0, start ) + "\\t" + this.value.substr( end );
                this.selectionStart = this.selectionEnd = start + 1;
                e.preventDefault();
                return false;
            }).css(\'tab-size\', \'3\');
        }
    });

    <?php
    echo \'</script>\'."\\n";
}
这种方法is not a hack 或者一种陈腐的preg match解决方案。它生成与默认API相同的转换。

The PUSH cleanup 如果粘贴来自PHP类或其他类的代码,并且想要呈现的块或剪切掉的函数“之前”有很多空间或选项卡,则可以使用。它计算第一条现有直线上的空间。

使其:

                    if(search_string){
                        var firstChar = search_string[0];
                        var remove = workspace.substr(0, workspace.indexOf(firstChar));
                        remove = "\\r\\n" + remove;
                        data = ua_TinyMCE_helper_cleanBeginnings(data, remove, "\\r\\n");
                    }
对此:

if(search_string){
    var firstChar = search_string[0];
    var remove = workspace.substr(0, workspace.indexOf(firstChar));
    remove = "\\r\\n" + remove;
    data = ua_TinyMCE_helper_cleanBeginnings(data, remove, "\\r\\n");
}
Note, 这是非常原始的,如果您了解jQuery,那么可以很容易地定制它。此函数also add TAB supportText editor.

提示:您应该为所有pre/editor/code元素指定管理CSS选项卡大小:3,以匹配和同步“视觉”方面。

请使用它,发表评论,我将尝试指导任何改进。

结束