mustache.js にExtends機能をつけてパッケージを公開しました!

こんにちは!フリーランス・エンジニアの 九保すこひ です。

さてさて、現在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'
});

継承機能の使い方

では、メインの継承機能です。(といってもここはLaravelBladeとほぼ同じです)

まずはレイアウト・テンプレート「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】expressexpress()に変更して、render()の前に実行されるコールバック関数が使えるようにしました😊

そして、ルート内でres.render()で呼び出してください。

app.get('/', (req, res) => {

  res.render('index', {
    message: 'テストメッセージ'
  });

});

以上です😊✨

おわりに

ということで、今回はmustache.jsを拡張した独自パッケージをご紹介しました。

ちなみにExpressにはそもそも独自のテンプレートエンジンが使えるように設計されているので、もし今回のパッケージをより良くしたい方はこちらのページ(英語)をご覧ください。

また、より高速表示させるために、当初はパッケージ自体にキャッシュ機能をつけていましたが、Expressにはビューのキャッシュがあるらしい(ただし、デフォルトでは、production環境だけのようです)ので、あえてそれらのコードは削除しました。

ぜひ皆さんも色々と試してみてくださいね。

ではでは〜!

この記事が役立ちましたらシェアお願いします😊✨ by 九保すこひ
また、わかりにくい部分がありましたらお問い合わせからお気軽にご連絡ください。
このエントリーをはてなブックマークに追加       follow us in feedly