
九保すこひです(フリーランスのITコンサルタント、エンジニア)
さてさて、現在Node.js
の開発が楽しくなってきているところではありますが、(あまり有益ではないとわかっているのですが、)どうしてもメインで使っているLaravel
と比較してしまうことが多々あります。
そして、その度にいかにLaravel
がスピーディーな開発ができるよう設計されているかを実感することになるのですが、今回はNode.js
の高速レスポンスを使うことが目的で、そうも言っていられません。そのため、「この機能は無い・・・なら自前でつくればいい(ぺこぱ風)」ということで前向きに考えるようにしています。
ということで、今回はタイトルにもあるとおり、Node.js
のテンプレート・パッケージ「mustache.js」に継承機能を追加した「grown-mustache」というパッケージをつくってみました。(npmの詳細ページはこちら)
今回はその使い方をご紹介します。
ぜひ皆さんのお役に立てると嬉しいです
開発環境: Node 8.10
テンプレートの継承機能とは?
これもLaravel
由来の話になってしまうのですが、Laravel
が標準で使っているテンプレート・エンジン「Blade」ではある特定のファイルを基本としてセクションごとにコンテンツを振り分けるという機能が備わっています。
例を見てみましょう!
まず、以下のような「ウェブサイトの大枠を決める」レイアウト・テンプレートを作ります。
<html>
<head>
<!-- タイトル・セクション -->
@yield('title')
</head>
<body>
<div id="app">
<!-- コンテンツ・セクション -->
@yield('content')
</div>
</body>
</html>
この中の@yield('*****')
という部分がセクションになります。
そして、メインになるテンプレートはこのようになります。
@extends('layouts/app')
@section('title')
<title>テストタイトル</title>
@stop
@section('content')
<h1>テスト・コンテンツ</h1>
@stop
そうです。
つまり、このファイルの意味としては、「“layouts/app” の中にある、”title” と “content” の中身を入れ替える」という意味になり、結果はこうなります。
<html>
<head>
<title>テストタイトル</title>
</head>
<body>
<div id="app">
<h1>テスト・コンテンツ</h1>
</div>
</body>
</html>
そして「なぜこの継承機能が使えるといいのか?」ですが、
コード量を減らすことが出来る
というメリットが一番ではないでしょうか。
逆に継承機能が使えないと、いちいち <html>〜</html>
などのタグを全ファイルに書くことになります。もしくは、共通ブロックを作って読み込む形でも実装はできますが、そうなるとHTMLタグの開始と終了が別ファイルの中に入ってしまうことになり、wordpress
の改造などのように保守管理が難しくなってしまいます。
※なお、「Node.jsでテンプレートの継承機能を使いたいならPugを使えよ!」という声があるかもしれませんが、実はあのPython
風に書き方があまり好みではないんです・・・ しかも、デザイナーさんにもあの書き方を覚えてもらわないといけないので、保守管理に消極的になると思うんですよね(実際のところはどうでしょう???)
パッケージをインストールする
npm
でパッケージを公開しているので以下のコマンド一発で完了します。
npm i --save grown-mustache
使い方
基本的な使い方
このパッケージはmustache.js
を拡張したものなので、基本的にはmustache.js
と使い方は同じです。
const GrownMustache = require('grown-mustache');
const gm = new GrownMustache({
dir: './views', // (省略可)ビューのディレクトリ
extension: 'mst' // (省略可)テンプレートの拡張子
});
gm.render('index', {
message: 'Message'
});
継承機能の使い方
では、メインの継承機能です。(といってもここはLaravel
のBlade
とほぼ同じです)
まずはレイアウト・テンプレート「layouts/app.mst」を作ります。
<!DOCTYPE html>
<html lang="ja">
<head>
@yield('title')
</head>
<body>
<div id="app">
@yield('content')
</div>
</body>
</html>
そして、メインのテンプレート「index.mst」です。
@extends('layouts/app')
@section('title')
<title>テストタイトル</title>
@stop
@section('content')
<h1>テスト・コンテンツ</h1>
<div class="row">
<div class="col-12">
{{ message }}
</div>
</div>
@stop
※ちなみに、この中の{{ message }}
の部分はパラメータを使って置き換えることになります。
では、実際にindex.mst
を使うコードです。
const content = gm.render('index', {
message: 'テストメッセージ'
});
Expressで使う
「GrownMustache.js」は、Node.js
のフレームワーク「Express」でも使えるようになっています。
こちらも通常のmustache
と同じように設定するだけでOKです。
const GrownMustache = require('grown-mustache');
// Template
app.engine('mst', GrownMustache.express((gm, path, options)=> {
// ここでパラメーターのセットとかができます
gm.set('new_key', 'new_value');
return gm;
}));
app.set('views', './views');
app.set('view engine', 'mst');
【追記:2020.01.21】express
をexpress()
に変更して、render()
の前に実行されるコールバック関数が使えるようにしました
そして、ルート内でres.render()
で呼び出してください。
app.get('/', (req, res) => {
res.render('index', {
message: 'テストメッセージ'
});
});
以上です
おわりに
ということで、今回はmustache.js
を拡張した独自パッケージをご紹介しました。
ちなみにExpress
にはそもそも独自のテンプレートエンジンが使えるように設計されているので、もし今回のパッケージをより良くしたい方はこちらのページ(英語)をご覧ください。
また、より高速表示させるために、当初はパッケージ自体にキャッシュ機能をつけていましたが、Express
にはビューのキャッシュがあるらしい(ただし、デフォルトでは、production
環境だけのようです)ので、あえてそれらのコードは削除しました。
ぜひ皆さんも色々と試してみてくださいね。
ではでは〜!