情報アイランド

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

Node.jsでECTテンプレートエンジンを使う

2016/04/04

ECTテンプレートエンジンはECTパッケージのectモジュールで提供されています。


ECTテンプレートでは下のような記法を使用することができます。

  • <% %>・・・CofeeScriptコードを埋め込みます。埋め込まれたCofeeScriptコードは実行されますが、結果が出力されることはありません。変数を定義すると、以降その変数の値を使用することができます。
  • <%= %>・・・任意のCofeeScript式を埋め込みます。埋め込まれたCofeeScript式の値が出力されます。ただし、値はHTMLエスケープされます
  • <%- %>・・・任意のCofeeScript式を埋め込みます。埋め込まれたCofeeScript式の値が出力されます。ただし、値はHTMLエスケープされません
  • <%%・・・<%のエスケープです。<%を出力したい場合に使用します。
  • %%>・・・%>のエスケープです。%>を出力したい場合に使用します。

ECTテンプレートでは他に継承、パーシャル、ブロックなどの機能が使用できます。これらの機能の詳細に関してはドキュメントを参照してください。


ECTテンプレートエンジンによるレンダリング結果を取得するにはまずect関数を呼び出してECTテンプレートエンジンをインスタンス化します。

第1引数にオプションを指定します。

主なオプションには下のようなものがあります。

  • root・・・テンプレートファイルのルートフォルダです。
  • ext・・・テンプレートファイルの拡張子です。
  • cache・・・キャッシュ機能を有効にするかです。デフォルトはtrueです。
  • watch・・・テンプレートファイルの更新を監視し、更新されたら自動的に再読み込みし、テンプレートを更新するかです。デフォルトはfalseです。
  • open・・・開始タグです。デフォルトは<%です。
  • close・・・終了タグです。デフォルトは%>です。

返り値としてECTテンプレートエンジンのインスタンスが得られます。

次に、ect.render関数を呼び出します。

第1引数にテンプレートファイルのパスを指定します。このパスはテンプレートファイルのルートフォルダ(上のオプションのroot)からの相対パスとしなければなりません。また、テンプレートファイルの拡張子(上のオプションのext)が指定されている場合には拡張子を省略します。

第2引数にデータを指定します。

返り値としてレンダリング結果が得られます。

なお、レンダリング結果の改行コードは\nであるため、場合によっては自分で\r\nに変換しなければならないかもしれません。

サンプルコード1

コマンドライン引数として与えられたECTテンプレートファイルを読み込み、コマンドライン引数として与えられたJSON形式のデータファイルを読み込み、レンダリング結果を取得し、コマンドライン引数として与えられたファイルに書き込みます。

なお、文字コードがUTF-8のテキストファイルを読み込むとテキストの先頭にBOMが付加されていることがあるため、stripBom関数でBOMを取り除いています。

stripBom関数の詳細に関しては下の記事を参照してください。

ect-render.js

var fs = require('fs');
var stripBom = require('strip-bom');
var ect = require('ect');

if (process.argv.length < 5) {
    console.error('lack argument.');
    process.exit(1);
}

fs.readFile(process.argv[3], 'utf-8', function (err, data) {
    if (err) {
        console.error(err);
        process.exit(1);
    }
    else {
        var renderer = ect();
        var result = renderer.render(process.argv[2], JSON.parse(stripBom(data))).replace(new RegExp('\r\n', 'g'), '\n').replace(new RegExp('\n', 'g'), `\r\n`);
        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でインストールします。
  • ECT
    npm install ectでインストールします。

実行結果

現在のフォルダには下のような内容のtemplate.ectという名称のECTテンプレートが存在しています。

このテンプレートでは<% %>の中で変数nを定義し、後で使用しています(なお、このテンプレートではテンプレート中で変数が定義できることを示すために変数nを定義し、変数vocabularyの要素数をカウントしていますが、実際にはvocabulary.lengthを使えば新しく変数を定義する必要はありません)。

<% n = 0 %>
<% for v in @vocabulary : %>
<%   n++ %>
<% end %>
<h1><%= @name %></h1>
<p><%= @description %></p>
<p>単語数:<%= n %></p>
<ul>
<% for v in @vocabulary : %>
<%- "<li>" %>
<%=     v.level %>
<%=     " " %>
<%=     v.word %>
<%=     " " %>
<%      for m, j in v.meanings : %>
<%          if j != 0 : %>
<%=             "、 " %>
<%          end %>
<%=         m %>
<%      end %>
<%- "</li>" %>
<%= "\r\n" %>
<% end %>
</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": ["換気(装置)"]
        }
    ]
}

これらのECTテンプレートとデータからレンダリング結果を取得してみます。

C:\work\node>node ect-render.js template.ect 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