情報アイランド

「情報を制する者は世界を制す」をモットーに様々な情報を提供することを目指すブログです。現在はプログラミング関連情報が多めですが、投資関連情報も取り扱っていきたいです。

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!!');
                    }
                });
            }
        });
    }
});

使用パッケージ

  • strip-bom
    npm install strip-bomでインストールします。
  • EJS
    npm install ejsでインストールします。

実行結果

現在のフォルダには下のような内容の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>

関連

pizyumi
プログラミング歴19年のベテランプログラマー。業務システム全般何でも作れます。現在はWeb系の技術を勉強中。
スポンサーリンク

-Node.js