GulpとPugで静的ページを量産できる仕組みを試してみました。
サンプルとしてarticle/カテゴリー別/記事エントリー名/index.html
形式で出力されるようにしてみました。
npmパッケ
$npm install gulp gulp-pug gulp-rename
記事データ
article.json
{
"music": {
"entry-1": {
"name": "バッハ",
"title": "G線上のアリア"
},
"entry-2": {
"name": "ベートーヴェン",
"title": "運命"
}
},
"movie": {
"entry-1": {
"name": "キューブリック",
"title": "2001年宇宙の旅"
},
"entry-2": {
"name": "黒澤明",
"title": "七人の侍"
}
}
}
ウェブページのテンプレート
_article.pug
!DOCTYPE html
html
head
meta(charset="UTF-8")
body
p テスト
Gulp
gulpfile.js
// Gulp
const gulp = require('gulp')
// ファイルリネーム
const rename = require('gulp-rename')
// Pug
const pug = require('gulp-pug')
// テンプレート
const template = './src/_article.pug'
// データファイル
const data = require('./src/article.json')
// ビルドタスク
const build = (callback) => {
// カテゴリーのループ
Object.keys(data).forEach((catKey) => {
// 記事のループ
Object.keys(data[catKey]).forEach((articleKey) => {
// Gulpタスク
gulp.src(template)
.pipe(
pug()
)
// 出力先
.pipe(
rename(`article/${catKey}/${articleKey}/index.html`)
)
.pipe(
gulp.dest('./dist/')
)
})
})
callback()
}
// タスク実行
gulp.task('default', build)
実行結果
dist/
└ article/
├ movie/
│ ├ entry-1/
│ │ └ index.html
│ └ entry-2/
│ └ index.html
└ music/
├ entry-1/
│ └ index.html
└ entry-2/
└ index.html
うまくファイルは出力されたけど、index.htmlの内容が全て同じだ。
各記事のデータが入らなければ意味がない。
調べてみるとPugにはlocalsというオプションでGulpからPugへ文字列を渡せるらしい。
gulpfile.jsをちょっと修正。
gulpfile.js
.pipe(
pug({
// Pugテンプレートファイルに変数を渡す
locals: {
data: data,
category: catKey,
article: articleKey
}
})
)
_article.pug
p #{data}
p #{category}
p #{article}
実行結果
index.html
<p>[object Object]</p>
<p>movie</p>
<p>entry-1</p>
…どうも配列ごとまるっと渡す横着はできないらしい。
あまり美しくないけど小分けで個別の変数として渡すしかないかな?
gulpfile.js
.pipe(
pug({
locals: {
category: catKey,
article: articleKey,
title: articleTitle,
name: articleName,
}
})
)
ページで使いそうなデータを小分けにして送る様子。
JSでも値を使いたい
_article.pug
!DOCTYPE html
html
head
meta(charset="UTF-8")
body
script.
var setting = {
category: '#{category}',
article: '#{article}'
}
こんな風にすればJSのグローバル変数に値を渡せる。あとはJSでお好きに。