Front Matterでファイルごとに変数を持たせる

ejsnunjucksなどのテンプレートエンジンを使用して、ホームページやブログを作成している場合、共通のテンプレートファイルに変数などを定義しておき、各ファイルではその変数に値をセットして、htmlを作成することになることが多いと思います。

例えば、以下のように各ページのタイトルや概要を変数にするテンプレートがあります。

※言語はnunjucksで説明しますが、他のテンプレートエンジンでも大体考え方は同じだと思います。

_layout.njk(nunjucks)
<!DOCTYPE HTML>
<html>

<head>
  <title>{{title}}</title>
  <description>{{description}}</description>
</head>

<body>
  <!--各ページのコンテンツ-->
  {% block content %}{% endblock %}
</body>
</html>

この時、各ファイルのtitledescriptionはどのように定義しておくか、という問題があります。

私は今まではjsonの別ファイルを作成し、そのファイルに全ページのタイトルや概要など、画面ごとに必要な変数を定義していました。

{
    "index": {
        "title": "トップページ",
        "description": "トップページです"
    },
    "sample1": {
        "title": "サンプルページ1",
        "description": "サンプルページ1です"
    },
    "sample2": {
        "title": "サンプルページ2",
        "description": "サンプルページ2です"
    }
}

しかしこのやり方では、1つのページを作成する際に、2つのファイルを編集しなければならなくなり、手間に感じていたので、別の方法を探すことにしました。

Front Matter

Front MatterとはJekyllという静的サイトジェネレーターで使用されているシステムです。

Front Matterを使えば、各ファイルに変数を定義して簡単に扱えるようになります。

各ページの先頭に以下のように---で囲って情報を定義します。

sample1.njk(nunjucks)
---
title: "サンプルページ1"
description: "Front サンプルページ1です"
---
{% extends '_layout.njk' %}
{% block content %}
サンプルページ1のコンテンツです
{% endblock %}

Front Matterの値を取得する

front-matterというモジュールを使用すれば、簡単にFront Matterで定義した情報を変数として取得できるようになります。

npm install front-matter

具体的には以下のように、取得します。content.attributesFront Matterで定義した値をjson形式で取得できます。

var frontMatter = require('front-matter');

var content = frontMatter(ファイルの内容);
console.log(content.body); //Front Matterで定義した部分以外の内容
console.log(content.attributes); //Front Matterで定義した内容

gulpで使う

nunjucksをコンパイルするときに、Front Matterで定義した値をパラメータとして渡す必要があります。

gulp-nunjucks-renderでNunjucksをgulpでコンパイルする方法で紹介したように、gulp-dataを使えばパラメータとして渡すことができます。

var gulp = require('gulp');
var nunjucksRender = require('gulp-nunjucks-render');
var data = require('gulp-data');
var frontMatter = require('front-matter');

gulp.task('compile', function(){
  gulp.src(['src/**/*.njk',
            '!src/**/_*.njk'])
    .pipe(data(function(file) {
      var content = frontMatter(String(file.contents));
      //Front Matterで定義した部分以外の内容をファイルの内容としてセットします
      file.contents = new Buffer(content.body);
      //Front Matterで定義した内容を返却します
      return content.attributes;
    }))
    .pipe(nunjucksRender())
    .pipe(gulp.dest('dst'));
});

Front Matterというシステム自体あまり知られていないのかもしれませんが、作成日や更新日などの情報も持つようにすれば、いろいろと便利に使えそうです。


関連記事

  • Front Matterでファイルごとに変数を持たせる

    Front Matterを使えば、各ファイルに変数を定義して簡単に扱えるようになります。各ページの先頭に以下のように---で囲って情報を定義します。content.attributesでFront M...


  • Nunjucksの基本的な使い方 -extends,block,include-

    htmlのおすすめテンプレートエンジンNunjucksはとても便利なのです。extendsという機能を使えば、ヘッダやフッタの共通部分を作成しておき(ベースとなるファイル)、各ページではページごとに変...


  • gulp-nunjucks-renderでNunjucksをgulpでコンパイルする方法

    Nunjucksをgulpでコンパイルする方法を紹介します。今回はgulp-nunjucks-renderを使用します。まずは、コマンドラインでgulp-nunjucks-renderをインストールし...


  • Nunjucksで独自のファンクションを実行する

    gulp-dataと組み合わせると、引数のような形で各ファイルにデータ(変数など)を渡すことができます。同じ容量で、変数ではなくファンクション自体をgulp-dataで設定すると、自分で定義したファン...


  • テンプレートエンジンのnunjucksとhighlight.js組み合わせる

    便利なテンプレートエンジンのnunjucksのテンプレートの中で、コードをシンタックスハイライト(色付け)する便利なライブラリのhighlight.jsを組み込む方法を紹介します。nunjucksのテ...


  • gulpの便利なタスク gulpfile.jsの記述例

    gulpの便利なおすすめプラグインで紹介したプラグインなどを利用したgulpの便利なタスクの実装例を紹介します。less,js,htmlのコンパイルや軽量化、watchとlivereload、エラー時...


  • less|cssに変数を使い実装を効率化する方法

    lessには変数を使うだけでなく、変数の色をX%明るくしたり、暗くしたり、透過したり、といった便利な関数も用意されています。また、要素を入れ子にして設定したり、関数を自作できるなど、とても便利な機能が...


  • gulpでディレクトリ構造を維持したままdestにコピーする

    gulpで以下のようなフォルダ構成で、page.html、page2.htmlをそれぞれのフォルダ配下のフォルダにコピーする場合、普通にdestを指定するだけではうまくいかないことがあります。コピーす...


  • gulpの便利なおすすめプラグイン

    gulpを導入するとWEB開発をとても効率よく簡単に行うことができるようになります。私がよく利用している便利なプラグインを紹介します。


  • npmのpackage.jsonを最新のバージョンに更新する

    package.jsonのパッケージを最新のバージョンに更新する方法を紹介します。最新のバージョンに更新するためには、package.jsonに記載されているパッケージのバージョンの記載を最新にする必...