0

我将CKEditor与refinerycms(rails CMS)一起使用我还添加了对半径标签的基本支持(它们是Radiant中使用的标签,另一个rails CMS)所以我可以在页面中列出模型中的一些元素插入代码。问题是半径标签模仿html:

<r:product_listing category="products" list_as="grid"/>

当使用 CKEditor 修改页面内容时,它认为半径标签是无效的 HTML,这是正确的和预期的行为,但我找不到告诉 CKEditor 忽略这些标签的方法。

有任何想法吗?

提前致谢

编辑:原来标签正在被RefineryCMS调用的rails中的sanitize方法过滤。

4

2 回答 2

3

自定义标签有哪些问题?在哪些浏览器上?

我检查了 CKEditor 保留了这个标签,但是用它包装了整个内容。为避免这种情况,您必须编辑CKEDITOR.dtd,即:

CKEDITOR.dtd.$empty[ 'r:product_listing' ] = 1;

但这可能还不够。为了获得更好的支持,您需要对此对象进行更多更改 - 特别重要的是定义可以是其父对象以及它是内联标记。例如:

CKEDITOR.dtd.p[ 'r:product_listing' ] = 1; // it is allowed in <p> tag
CKEDITOR.dtd.$inline[ 'r:product_listing' ] = 1;

这可能还不够——例如,您很可能没有复制和粘贴支持。

因此,如果您需要更可靠的支持,我会尝试一些不同的方式。使用CKEDITOR.dataProcessor,您可以在将数据加载到编辑器中并在检索数据时将其转换回该标签时将此标签转换为正常标签。

示例解决方案:

// We still need this, because this tag has to be parsed correctly.
CKEDITOR.dtd.p[ 'r:product_listing' ] = 1;
CKEDITOR.dtd.$inline[ 'r:product_listing' ] = 1;
CKEDITOR.dtd.$empty[ 'r:product_listing' ] = 1;

CKEDITOR.replace( 'editor1', {
    on: {
        instanceReady: function( evt ) {
            var editor = evt.editor;

            // Add filter for html->data transformation.
            editor.dataProcessor.dataFilter.addRules( {
                elements: {
                    'r:product_listing': function( element ) {
                        // Span isn't self closing element - change that.
                        element.isEmpty = false;
                        // Save original element name in data-saved-name attribute.
                        element.attributes[ 'data-saved-name' ] = element.name;
                        // Change name to span.
                        element.name = 'span';
                        // Push zero width space, because empty span would be removed.
                        element.children.push( new CKEDITOR.htmlParser.text( '\u200b' ) );
                    }
                }
            } );

            // Add filter for data->html transformation.
            editor.dataProcessor.htmlFilter.addRules( {
                elements: {
                    span: function( element ) {
                        // Restore everything.
                        if ( element.attributes[ 'data-saved-name' ] ) {
                            element.isEmpty = true;
                            element.children = [];
                            element.name = element.attributes[ 'data-saved-name' ];
                            delete element.attributes[ 'data-saved-name' ]
                        }
                    }
                }
            } );
        }
    }
} );

现在r:product_listing元素将被转换为跨度,其内部具有零宽度空间。在编辑器内部会有一个正常的跨度,但在源模式和通过editor#getData()方法获取的数据中,您会看到原始r:product_listing标签。

我认为这个解决方案应该是最安全的。例如复制和粘贴作品。

于 2012-12-30T21:12:29.563 回答
0

您也可以添加为受保护的源,因此不会进行过滤或解析。

config.protectedSource.push(/<r:product_listing[\s\S]*?\/>/g);

只需将这些行添加到您的 config.js([\s\S]*? 用于任何随机内容)
查看http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-protectedSource

于 2013-12-02T10:07:28.100 回答