JsRender にて HTML エスケープしつつ <br> は適用する
目的
以下のようなデータを JsRender を利用しレンダリングする要件があるとします。
{
"id": 1,
"description": "<p>タグ:\r\n<p>タグは要素が段落であることを示します"
}
description
には改行コードが含まているため、<br>
タグに変換したうえで表示することが目的ですが、文章に含まれている HTMLタグ等はエンコードして表示する必要があります。
解決策
テンプレートタグ {{> ...}}
は使用せず、コンバータを作成して対応する。
テンプレートタグ {{> ...}}
を使用することでタグ等のエンコードは可能ですが、 <br>
タグもエンコードされてしまいます。
そこで、HTMLエンコードを行ったうえで改行コードの変換を行うコンバータを作成して利用します。
const data = {
"id": 1,
"description": "<p>タグ:\r\n<p>タグは要素が段落であることを示します"
};
// コンバータ作成
$.views.converters("escape", function(val) {
return $.views.converters.html(val).replace(/(\r\n|\r|\n)/g, "<br>"); // 改行コード変換
});
const template = $.templates("#template");
const htmlOutput = template.render(data);
$("#result").html(htmlOutput);
<script id="template" type="text/x-jsrender">
<p>{{escape:description}}</p>
</script>
<div id="result"></div>
説明
コンバータはレンダリング前にデータ変換処理など任意の処理を挟む機能で、コンバータの登録は以下の部分で行っています。
$.views.converters("escape", function(val) {
return $.views.converters.html(val).replace(/(\r\n|\r|\n)/g, "<br>"); // 改行コード変換
});
ここでは、HTML エンコード処理と改行コードの変換処理を行っています。
テンプレート HTML 側で {{escape:description}}
というように表記することで、上記の処理が行われた結果がレンダリングされます。
改行コード変換前の HTML エンコード処理ですが、自前で作成するのではく組み込みの HTML エンコード処理 $.views.converters.html(val)
を利用することで流用しています。
( 上記のメソッドで {{>...}}
と同じエンコーダーを宣言的に利用できます)
Built-in HTML encoder | JsRender/JsViews
JsRender includes an HTML encoder, which you can use programmatically as follows:
var myHtmlEncodedString = $.views.converters.html(myString);
The same encoder is accessed declaratively as a converter, as in the following two > examples:
{{html:myExpression}}
{{>myExpression}}
今回はコンバータを利用しましたが、ヘルパーでも同様の対応が可能です。
特定のテンプレートやレンダリングで適用させたい場合はヘルパーを用いると良いかもしれません。
おわり。
Discussion