Node.jsでEJSテンプレートエンジンを使う
2016/04/04
EJSテンプレートエンジンはEJS
パッケージのejs
モジュールで提供されています。
EJSテンプレートでは主に下のような記法を使用することができます。
<% %>
・・・任意のJavaScriptコードを埋め込みます。埋め込まれたJavaScriptコードは実行されますが、結果が出力されることはありません。変数を定義すると、以降その変数の値を使用することができます。<%= %>
・・・任意のJavaScript式を埋め込みます。埋め込まれたJavaScript式の値が出力されます。ただし、値はHTMLエスケープされます。<%- %>
・・・任意のJavaScript式を埋め込みます。埋め込まれたJavaScript式の値が出力されます。ただし、値はHTMLエスケープされません。-%>
・・・%>
の代わりに-%>
を使用すると-%>
の直後の改行が行われなくなります。<%_ _%>
・・・<% %>
の代わりに<%_ _%>
を使用するとホワイトスペースが取り除かれます。
EJSテンプレートエンジンによるレンダリング結果を取得するにはejs.render
関数を呼び出します。
第1引数にテンプレートを指定します。
第2引数にデータを指定します。
返り値としてレンダリング結果が得られます。
サンプルコード1
コマンドライン引数として与えられたEJSテンプレートファイルを読み込み、コマンドライン引数として与えられたJSON形式のデータファイルを読み込み、レンダリング結果を取得し、コマンドライン引数として与えられたファイルに書き込みます。
なお、文字コードがUTF-8
のテキストファイルを読み込むとテキストの先頭にBOMが付加されていることがあるため、stripBom
関数でBOMを取り除いています。
stripBom
関数の詳細に関しては下の記事を参照してください。
▼ejs-render.js
var fs = require('fs');
var stripBom = require('strip-bom');
var ejs = require('ejs');
if (process.argv.length < 5) {
console.error('lack argument.');
process.exit(1);
}
fs.readFile(process.argv[2], 'utf-8', function (err, template) {
if (err) {
console.error(err);
process.exit(1);
}
else {
fs.readFile(process.argv[3], 'utf-8', function (err, data) {
if (err) {
console.error(err);
process.exit(1);
}
else {
var result = ejs.render(stripBom(template), JSON.parse(stripBom(data)));
fs.writeFile(process.argv[4], result, 'utf-8', function (err) {
if (err) {
console.error(err);
process.exit(1);
}
else {
console.log('finished!!');
}
});
}
});
}
});
▼使用パッケージ
▼実行結果
現在のフォルダには下のような内容のtemplate.ejs
という名称のEJSテンプレートが存在しています。
このテンプレートでは<% %>
の中で変数n
を定義し、後で使用しています(なお、このテンプレートではテンプレート中で変数が定義できることを示すために変数n
を定義し、変数vocabulary
の要素数をカウントしていますが、実際にはvocabulary.length
を使えば新しく変数を定義する必要はありません)。また、HTMLタグを出力する場合には、HTMLエスケープされないようにするため<%- %>
を使用しています。また、改行させたくない場所では-%>
を使用しています。
<%
var n = 0;
for (var i = 0; i < vocabulary.length; i++) {
n++;
}
-%>
<h1><%= name %></h1>
<p><%= description %></p>
<p>単語数:<%= n %></p>
<ul>
<% for (var i = 0; i < vocabulary.length; i++) { -%>
<%- "<li>" -%>
<%= vocabulary[i].level -%>
<%= " " -%>
<%= vocabulary[i].word -%>
<%= " " -%>
<% for (var j = 0; j < vocabulary[i].meanings.length; j++) { -%>
<% if (j != 0) { -%>
<%= "、 " -%>
<% } -%>
<%= vocabulary[i].meanings[j] -%>
<% } -%>
<%- "</li>" %>
<% } -%>
</ul>
また、下のような内容のvocabulary.json
という名称のJSON形式のデータが存在しています。
{
"name": "単語帳",
"description": "頑張って覚えましょう。",
"vocabulary": [
{
"word": "stale",
"level": "6",
"meanings": ["新鮮でない"]
},
{
"word": "stylist",
"level": "7",
"meanings": ["名文家"]
},
{
"word": "substitution",
"level": "8",
"meanings": ["代用", "代用品", "代入", "置換"]
},
{
"word": "ventilate",
"level": "9",
"meanings": ["~を換気する"]
},
{
"word": "ventilation",
"level": "10",
"meanings": ["換気(装置)"]
}
]
}
これらのEJSテンプレートとデータからレンダリング結果を取得してみます。
C:\work\node>node ejs-render.js template.ejs vocabulary.json html.htm
finished!!
レンダリング結果は下のようになりました。
<h1>単語帳</h1>
<p>頑張って覚えましょう。</p>
<p>単語数:5</p>
<ul>
<li>6 stale 新鮮でない</li>
<li>7 stylist 名文家</li>
<li>8 substitution 代用、 代用品、 代入、 置換</li>
<li>9 ventilate ~を換気する</li>
<li>10 ventilation 換気(装置)</li>
</ul>
関連
