assembleを利用して静的サイトを構築する[yeoman,grunt]
yeomanのgenerator-mobile, generator-webappなどを利用すれば、静的なサイトを実装できる環境は簡単に用意できましたが、assembleを利用することでHTMLの管理・実装に関してさらにすばらしい環境にすることができます。
https://github.com/assemble/assemble/
assemble
assembleは簡単に言うと、静的サイトを構築するためのフレームワークのようなものです。
実現できることとしては下記が挙げられます。
- レイアウトテンプレートの利用
- テンプレートのinclude
- markdown形式でのHTML記述
- モックデータの利用
テンプレートエンジンはhandlebarsまたはswigを選択できます。
今回はhandlebarsを利用したいと思います。
install
$ npm i assemble -D
タスクを設定する
handlebars(.hbs)で記述したテンプレートをコンパイルしてHTMLファイルを生成します。
options 設定内容
options.layoutDir レイアウトテンプレートディレクトリ options.partials include用テンプレートディレクトリ/ファイル options.data モックデータ用ディレクトリ/ファイル
個別の設定内容
コンパイルする単位毎に設定を行います
watch.livereloadタスクと連携することを踏まえ、ページ単位で設定することをお勧めします。
options.layoutでレイアウトテンプレートを指定し、files.srcでメインコンテンツを記述するファイルを指定します。
grunt/assemble.js
'use strict'; module.exports = function(grunt) { grunt.config('assemble', { options: { layoutdir: 'hbs/layouts', partials: ['hbs/includes/**/*.hbs'], data: ['mocks/assemble/**/*.yml'] }, hoge: { options: { layout: 'default.hbs' }, files: [{ expand: true, cwd: 'hbs/pages', src: 'hoge.hbs', dest: '<%= yeoman.app %>' }] }, moge: { options: { layout: 'moge.hbs' }, files: [{ expand: true, cwd: 'hbs/pages', src: 'moge.hbs', dest: '<%= yeoman.app %>' }] } }); grunt.loadNpmTasks('assemble'); };
grunt/contlib-watch.js
ページ単位で、当該ページに関連するファイルを監視対象としてassembleのコンパイルタスクを設定します。
また、livereloadの監視対象ファイルとして、コンパイル後に生成されるHTMLファイルを設定します。
'use strict'; var port = require('../port.json'); module.exports = function(grunt) { grunt.config('watch', { coffee: { files: ['<%= yeoman.app %>/scripts/{,*/}*.coffee'], tasks: ['coffee:dist'] }, coffeeTest: { files: ['test/spec/{,*/}*.coffee'], tasks: ['coffee:test'] }, compass: { files: ['<%= yeoman.app %>/styles/{,*/}*.{scss,sass}'], tasks: ['compass:server'] }, assembleHoge: { files: [ 'hbs/layouts/default.hbs', 'hbs/pages/hoge.hbs', 'hbs/includes/footer.hbs' ], tasks: ['assemble:hoge'] }, assembleMoge: { files: [ 'hbs/layouts/moge.hbs', 'hbs/pages/moge.hbs', 'hbs/includes/footer.hbs' ], tasks: ['assemble:moge'] }, livereload: { options: { livereload: port.livereload }, files: [ '<%= yeoman.app %>/*.html', '{.tmp,<%= yeoman.app %>}/styles/{,*/}*.css', '{.tmp,<%= yeoman.app %>}/scripts/{,*/}*.js', '<%= yeoman.app %>/images/{,*/}*.{png,jpg,jpeg,gif,webp,svg}' ] }, }); };
モックデータとテンプレートを用意する
モックデータ1(mocks/assemble/data.yml)
foo: bar
モックデータ2(mocks/assemble/baz.yml)
qux: quux
レイアウトテンプレート(hbs/layouts/default.hbs)
※{{}}はhandlebarsの記法です
{{> body}}でfiles.srcに設定したメインコンテンツファイルをincludeできます。
<!DOCTYPE HTML> <html lang="en"> <head> <meta charset="UTF-8"> <title>{{title}}</title> </head> <body> This is default layout. {{> body}} </body> </html>
メインコンテンツテンプレート(hbs/pages/hoge.hbs)
1〜3行目はYAML Front Matterを利用してモックデータを定義しています。
hbs/layouts/default.hbsで{{title}}と記述している箇所に、データが代入されます。
{{> footer }}でhbs/includes/footer.hbsをincludeできます。
{{foo}}でmocks/assemble/data.ymlに定義したデータを表示できます。
{{baz.qux}}でmocks/assemble/baz.ymlに定義したデータを表示できます。
※data.yml以外のファイルに定義したデータは、ファイル名を接頭辞として付ける必要があるということです。
--- title: HOGE --- <h1>HOGE</h1> <p>{{foo}}</p> <p>{{baz.qux}}</p> {{> footer }}
include用テンプレート(hbs/includes/footer.hbs)
<footer> </footer>
動作確認
とりあえず、assemble単体で実行し、ファイルのコンパイル処理を確認します。
$ grunt assemble
Running "assemble:hoge" (assemble) task Assembling app/hoge.html OK >> 1 pages assembled. Running "assemble:moge" (assemble) task Assembling app/moge.html OK >> 1 pages assembled. Done, without errors.
$ cat app/hoge.html
<!DOCTYPE HTML> <html lang="en"> <head> <meta charset="UTF-8"> <title>HOGE</title> </head> <body> This is default layout. <h1>HOGE</h1> <p>bar</p> <p>quux</p> <footer> </footer> </body> </html>
期待通りのHTMLが生成されています。
次にlivereloadも試してみましょう。
grunt serverでサーバを起動し、ブラウザからhttp://XXXX:10000/hoge.htmlにアクセスしておきます。
Running "server" task Running "clean:server" (clean) task Cleaning ".tmp"...OK Running "concurrent:server" (concurrent) task Running "coffee:dist" (coffee) task File .tmp/scripts/hello.js created. Done, without errors. Running "compass:server" (compass) task Done, without errors. Running "configureProxies" task Proxy created for: /ajax to 0.0.0.0:8000 Running "connect:livereload" (connect) task Starting connect web server on 0.0.0.0:10000. Running "watch" task Waiting...OK
watchタスクで監視対象に設定したファイル、例えばhbs/pages/hoge.hbsを適当に編集して保存してください。
すると、ブラウザで表示していた画面が自動でリロードされ、変更が反映されると思います。
grunt のログを見てみましょう。
>> File "hbs/pages/hoge.hbs" changed. Running "assemble:hoge" (assemble) task Assembling app/hoge.html OK >> 1 pages assembled. Done, without errors. Completed in 2.412s at Tue Dec 24 2013 14:16:44 GMT+0000 (UTC) - Waiting... OK >> File "app/hoge.html" changed. ... Reload app/hoge.html ... Completed in 0.000s at Tue Dec 24 2013 14:16:44 GMT+0000 (UTC) - Waiting...
下記の順に処理が実行されているのが分かります。
- watch:assembleHogeのタスクで設定したhbs/pages/hoge.hbsの更新を検知
- assemble:hogeのタスクが実行され、app/hoge.htmlが再生成される
- watch:livereloadのタスクで設定した<%= yeoman.app %>/*.htmlにより、app/hoge.htmlの更新が検知されlivereloadが実行される
assembleの動作について、手軽に試したい場合は下記のボイラープレートを試してみてください。