Node.js | EJSテンプレートエンジン
npmでEJSをインストール
以前はHTMLファイルを読み込んで表示しようとしたが、ファイル読み込みに非同期メソッドを使う必要があり、HTML内の値もreplaceで置き換える必要があって面倒だった。もっと簡単な方法がテンプレートエンジンである。Node.jsではさまざまなテンプレートエンジンを利用でき、よく使われるものの1つがEJSである。
EJSはnpmでインストールする。
npm install ejs
npmはNode.jsを利用する場合に必須であり、必要なものの多くはnpm installでインストールできる。EJS自体はGitHubから入手することもできる。
https://github.com/visionmedia/ejs
テンプレートで使える特殊タグ
EJSでは、テンプレートとなるHTMLコードに特殊タグを使って必要な情報を埋め込める。
<%= 値 %>
値をその場所に書き出す。スクリプト側で用意した変数などを表示するために使う。HTMLタグなどはエスケープされる。
<%- 値 %>
同じく値を書き出すが、HTML関連タグはエスケープされずそのまま書き出される。
<% スクリプト %>
スクリプトを書き、レンダリング時に実行する。ブラウザに送られて実行される<script>タグとは異なり、これはサーバー側、つまりNode.js内で実行され、その結果がクライアントへ送られる。
hello.ejsをNode.jsスクリプトと同じ場所に保存する。
<!DOCTYPE html>
<html lang="ko">
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title><%=title %></title>
</head>
<body>
<header>
<h1 id="h1"><%=title %></h1>
</header>
<div role="main">
<p><%-content %></p>
</div>
</body>
</html>
<%=title %>と<%-content %>は、それぞれtitleとcontentという変数を出力する。
EJSでテンプレートを表示する
テンプレートファイルを読み込みWebページを表示するには、ファイル読み込み、テンプレートのレンダリング、生成データのレスポンス書き込みが必要である。
var http = require('http');
var fs = require('fs');
var ejs = require('ejs');
var hello = fs.readFileSync('./hello.ejs', 'utf8');
var server = http.createServer();
server.on('request', doRequest);
server.listen(1234);
console.log('Server running!');
function doRequest(req, res) {
var hello2 = ejs.render(hello, {
title:"タイトルです。",
content:"これはサンプルで作成したテンプレートです。",
});
res.writeHead(200, {'Content-Type': 'text/html'});
res.write(hello2);
res.end();
}
EJSはrequire('ejs')でロードする。テンプレートファイルはfs.readFileSyncで読み込む。同期処理だが、サーバー作成前に読み込むため、テンプレートを最初にグローバル変数へ読み込んでおく用途に向いている。
テンプレートは次のようにレンダリングする。
ejs.render(テンプレートデータ, オプション);
第1引数はテンプレート文字列、第2引数はテンプレートへ渡す変数をまとめた連想配列である。最後にContent-Typeをtext/htmlに設定してレスポンスへ書き込む。
テンプレート部分の結合
テンプレートは別のテンプレートと組み合わせることもできる。たとえば、ページ全体のテンプレートを用意し、その中にコンテンツ用テンプレートを挿入する。
content1.ejsを作成する。
<p>例で作成したテンプレートです。</p>
<p>別ファイルで用意したものを読み込んで使います。</p>
<p><%= message %></p>
内側のテンプレートを先にレンダリングし、その結果を外側のテンプレートに渡す。
var hello2 = ejs.render(hello, {
title: "タイトルです。",
content: ejs.render(content1,{
message:"テキストメッセージ"
})
});
複数のテンプレートを組み合わせる場合の基本は、内側を先にレンダリングし、その結果をオプションとして外側へ渡すことである。
配列データの繰り返し出力
EJSテンプレートでは<% %>タグを使ってJavaScriptを実行できる。サーバー側で実行されるため、ブラウザに表示されるページには処理結果だけが現れる。
注意点は次のとおりである。
<% %>内に書いたものは表示されない。値を出力するには<%= %>を使う。- JavaScriptだが、
alertやdocumentのようなブラウザ依存機能は使えない。 - レンダリング時に渡された変数は
<% %>内でそのまま使用できる。
content1.ejsを次のように変更する。
<p>例で作成したテンプレートです。</p>
<p>配列データを受け取り、リストとして表示します。</p>
<p><ol>
<% data.forEach(function(val){ %>
<li><%= val %></li>
<% }) %>
</ol></p>
スクリプト側から配列データを渡す。
var hello2 = ejs.render(hello, {
title: "タイトルです。",
content: ejs.render(content1, {
data: [
"これは最初のデータです。",
"次のデータです。",
"最後のデータです。"
]
})
});
処理部分は<% %>に書き、値を出力する部分は<%= %>に書く。
<% data.forEach(function(val){ %>
<li><%= val %></li>
<% }) %>
forEachが分かりにくい場合は、通常のfor文でもよい。
<% for (var i = 0;i < data.length;i++){ %>
<li><%= data[i] %></li>
<% } %>
<% %>を使う場合は、処理と出力をきちんと分けて考える必要がある。