0

私はrefinerycms(rails CMS)でCKEditorを使用しています.radiusタグ(別のrails CMSであるRadiantで使用されるタグです)の基本的なサポートも追加したので、モデルのいくつかの要素をページにリストすることができます.コードの挿入。問題は、radius タグが html を模倣していることです。

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

CKEditor を使用してページのコンテンツを変更すると、radius タグが無効な HTML であると見なされます。これは正しく、予想される動作ですが、CKEditor にそれらのタグを無視するように指示する方法が見つかりません。

何か案は?

前もって感謝します

編集: RefineryCMSによって呼び出されたレールの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 に答える