Front Matterでファイルごとに変数を持たせる
ejs
やnunjucks
などのテンプレートエンジンを使用して、ホームページやブログを作成している場合、共通のテンプレートファイルに変数などを定義しておき、各ファイルではその変数に値をセットして、html
を作成することになることが多いと思います。
例えば、以下のように各ページのタイトルや概要を変数にするテンプレートがあります。
※言語はnunjucks
で説明しますが、他のテンプレートエンジンでも大体考え方は同じだと思います。
_layout.njk(nunjucks)
<!DOCTYPE HTML>
<html>
<head>
<title>{{title}}</title>
<description>{{description}}</description>
</head>
<body>
<!--各ページのコンテンツ-->
{% block content %}{% endblock %}
</body>
</html>
この時、各ファイルのtitle
やdescription
はどのように定義しておくか、という問題があります。
私は今までは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.attributes
でFront 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
というシステム自体あまり知られていないのかもしれませんが、作成日や更新日などの情報も持つようにすれば、いろいろと便利に使えそうです。