テンプレートエンジンのEJSを使ってみたので、Qiitaにまとめてみました。
公式サイトはこちら。(URLがとても短い!)
https://ejs.co/
テンプレートエンジンとは
SPA(シングルページアプリケーション)でないWebアプリのバックエンドを開発している時に、よく直面する問題として、どうやってHTMLデータを生成するかがあります。
データベースから表示用のデータを引っ張ってきた後に、それをHTMLデータ上に埋め込んで、HTTPSのレスポンスにセットして、クライアントに投げる時ですね。
そのような問題の解決策として、テンプレートエンジンが、昔からよく使われてました。(ビューエンジンと呼ばれることもあります。)
Javaだと、Apache Velocityや、FreeMarkerなどがあります。
.NETだと、Razorが有名です。
FreeMarkerの公式サイトにあった絵がわかりやすいので、ここに貼り付けますが、
左上にテンプレートファイルを定義して、左下のプログラム内で変数をセットしておき、
それらをマージすることで、右のデータを生成します。
EJSの特徴
EJSは、「Embedded JavaScript templating」の略ですが、Eは、Effective, Elegant, Easyでもあるようです。
Javascriptベースで動くので、クライアントサイドで実行できますし、
Node.jsを使っていれば、サーバサイドでも実行することもできます。
Hello, World
クライアントサイドで実行してみましょう。
事前に何かをインストールする必要はありません。
<!DOCTYPE html>
<html>
<head>
<script src="https://github.com/mde/ejs/releases/download/v3.1.9/ejs.min.js"></script>
<script>
window.onload = (() => {
// 表示したいデータを含んだJSONオブジェクト。
let data = {names: ['geddy', 'neil', 'alex']};
// データを表示するテンプレート。namesをループで回して、中身を順番にliタグで出力する。
let str = '<% names.forEach((name) => { %><li><%= name %></li><% }) %>';
// テンプレートとデータを融合させて、HTMLデータを生成。
let html = ejs.render(str, data);
console.log('html : ' + html);
// 大元のHTML内に、生成されたHTMLデータを埋め込む。
document.getElementById('target').innerHTML = html;
});
</script>
</head>
<body>
<ul id="target">target</ul>
</body>
</html>
console.logの出力結果
html : <li>geddy</li><li>neil</li><li>alex</li>
この例だと、Javascriptのループ文とDOM操作を使えば、同じことができるので、あまりありがたみはありませんが、EJSを簡単に試すことができます。
Node.js(Express)内で使う時の例
EJSのテンプレート内容を、拡張子.ejsのファイルに定義しておきます。
事前にejsのインストールが必要なので、公式サイトを見て行ってください。
以下はMVCパターンでフォルダを分けたときの例です。
src
├── controllers
│ ├── routes.ts
├── models
└── views
├── pages(画面ごとのejsファイルを定義します)
│ └── hoge.ejs
└── partials(複数の画面から、共通で使われるUI部品を定義します)
└── header.ejs
/hogeが呼ばれたら、pagesの下においた、hoge.ejsを元に、HTMLデータを生成して、クライアントに返します。
// コードの一部のみ記載している。
// Expressのビューエンジンでejsを使用する。
app.set("view engine", "ejs");
// テンプレートファイルを探しに行くときは、viewsフォルダを基準とする。
app.set("views", path.join(__dirname, '../views'));
app.get("/hoge", function (req, res, next) {
// ビジネスロジック(models)のコードを利用して、データを取得または生成して、param1とparam2にセットする想定。
const data = {'param1': '', 'param2': ''};
res.render("pages/hoge.ejs", data);
});
hoge.ejsの中では、パラメータとして受け取った、param1とparam2を、HTMLデータに埋め込みます。また、共通部品である、partials/header.ejsを呼び出して、埋め込んでいます。
<!DOCTYPE html>
<html>
<head>
<!-- 省略 -->
</head>
<body>
<%# ejsファイルの中から、別のejsファイルを、パラメータ付きで呼び出す。%#から始まるこの行は、出力されないコメントを示す。 %>
<%- include('../partials/header.ejs', {'title': 'hoge'}); %>
<p>param1は、<%= param1 %></p>
<%# 以下のように、出力する際に、javascriptの関数を使って、加工できる。 %>
<p>param2は、<%= param2.substring(0, 4); %></p>
</body>
</html>
以下は共通のUI部品です。以下の内容が、上のincludeと書いてあるところに入ります。
titleには、hogeという文字列が入ります。
<header>
<h1>ここは<%= title %>のページです</h1>
<nav>
<ul>
<li><a href="news.html">News</a></li>
<li><a href="menu.html">Menu</a></li>
<li><a href="contact.html">Contact</a></li>
</ul>
</nav>
</header>
まとめ
EJSを使うことで、スムーズにデータ表示を行うことができました。
htmlにscriptタグを仕込むだけですぐに試せるのは良いですね。
EJS以外に、以下のテンプレートエンジンもあるので、プロジェクトに合ったものを選びましょう!
- Handlebars(タグが<%= %>ではなく、{{ }}になる)
- pug(テンプレートをYAMLっぽく書ける)