防止CKEditor过滤Radiant标签(无效的HTML标签)

时间:2012-12-30 18:17:09

标签: ruby-on-rails ckeditor radiant

我正在使用CKEditor和refinerycms(rails CMS)我还添加了radius tags的基本支持(它们是Radiant中使用的标签,另一个是rails CMS)所以我能够列出一些元素来自页面中的模型只是插入代码。 问题是radius标签模仿html:

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

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

有什么想法吗?

提前致谢

编辑:原来标签是由RefineryCMS调用的rails中的sanitize方法过滤的。

2 个答案:

答案 0 :(得分: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元素将被转换为内部零宽度空间的span。内部编辑器将有一个正常的跨度,但在源模式和通过editor#getData()方法得到的数据中,您将看到原始的r:product_listing标记。

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

答案 1 :(得分:0)

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

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

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