【爆速テンプレートエンジン】Express3 以降で layout.ejs が使えなくなった代わりに ECT


layout.ejs がレンダリングされない!!

Express2 まではレイアウトを階層化する仕組みが提供されていましたが、Express3 では廃止され、EJS テンプレートエンジンの役割 (ejs-locals) として独立しました。

ejs-locals
※現在はメンテナンスが停止してしまっているようです。

Express2 までは views ディレクトリに layout.ejs という親テンプレートファイルを置き、以下のように記述することでレイアウトテンプレートとして使うことができました。

layout.ejs
<!DOCTYPE html>
<html>
  <head>
    <title><%= title %></title>
    <link rel='stylesheet' href='/stylesheets/style.css' />
  </head>
  <body>
  <%- body %>
  </body>
</html>

しかし Express3 になり、テンプレートエンジン寄りの機能が廃止されました。

the concept of a "layout" (template engine specific now)
partial() (template engine specific)
Migrating from 2.x to 3.x

Hello ECT!

jade を使うという手もありますが、今回は ECT という EJS ライクかつ Smarty に近い機能性を持った高速なテンプレートエンジンを使ってみましょう。
どうやら JS テンプレートエンジン最速 を謳っているようです。

※ express コマンドで生成できるプロジェクト雛形をベースに説明します。 express <フォルダ名> で作成して下さい。

インストール
[user@host project]$ npm install ect

コード:
- ECT の読み込みと設定を行います。

app.js
/**
 * Module 読み込み
 */

var express = require('express');
var routes = require('./routes');
var user = require('./routes/user');
var http = require('http');
var path = require('path');
var ECT = require('ect'); // ECT 読み込み

var app = module.exports = express();
app.set('port', process.env.PORT || 3000);

// ECT 環境設定
app.engine('ect', ECT({ watch: true, root: __dirname + '/views', ext: '.ect' }).render);
app.set('view engine', 'ect');

// その他 環境設定
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.json());
app.use(express.urlencoded());
app.use(express.methodOverride());
app.use(express.cookieParser('your secret here'));
app.use(express.session());
app.use(app.router);
app.use(express.static(path.join(__dirname, 'public')));

app.get('/', routes.index);

http.createServer(app).listen(app.get('port'), function() {
    console.log('Express server listening on port ' + app.get('port'));
});

ハンドラ:
- EJS の時と一緒です。パラメタを渡してあげましょう。

routes/index.js
/*
 * GET home page.
 */
exports.index = function (req, res) {
    res.render('index', { title: 'Hello, ECT!' });
};

レイアウトテンプレート:
- content は値じゃなくて関数ですので、=- を付けないように注意です。

views/layout.ect
<!DOCTYPE html>
<html>
  <head>
    <title>Express3 + ECT</title>
    <link rel='stylesheet' href='/stylesheets/style.css' />
  </head>
  <body>
  <% content %>
  </body>
</html>

Viewテンプレート:
- extend でレイアウトを継承しましょう。
- パラメタには必ず「@」を付けます。CoffeeScript ライクな記法ですね。
- パラメタは継承元テンプレート (layout.ect) でももちろん使えます。

views/index.ect
<% extend 'layout' %>
<h1><%= @title %><h1>

以下のように表示されれば成功です!!

extend による継承以外にも includeblock if による制御も可能です。
Smarty に慣れている人にはお馴染みですね!