Assembleの使い方(Grunt task)

# Assembleの使い方(Grunt task)

テンプレートエンジンを案件で使用することがあったので、
自分用のメモとしてAssembleの使い方を書いておきます。

## Assembleとは
assemble（アセンブル）とは、node.jsベース(Gruntで動かせる)HTMLテンプレートシステムです。コンパイルすることでHTMLを生成してくれるジェネレータツールになります。

* [Assemble公式サイト](http://assemble.io/)
* [Assembleドキュメント](https://github.com/assemble/assemble/)

## 導入理由
* プログラムを使えないサーバでも、インクルード管理したかったから
* 同じく静的のHTML上でも条件分岐を使用したかったから
* Gruntプラグインで常にタスクで管理したかったから

他にも導入する理由はありましたが、この3つが主な理由になります。
似たようなテンプレートでは、[Jekyll](http://jekyllrb.com/)というものがあります。
どちらも使ったのですが、一番自分にあったのがassembleになります。

## GruntでAssembleをインストール
Gruntのインストールなどに関しては色々と記事が上がっているので、割愛させて頂きます。
コマンド（ターミナル）で該当のプロジェクトディレクトリへ移動します。
Gruntをインストールしassembleをsaveします。

```
cd /User/hogehoge/project/
npm install
assemble --save-dev
```

## Gruntのタスクに作成
自分が設定したタスク内容になります。以下が基本の形で使用しました。
※使用時はSassやCompassや圧縮など色々タスクを使いました。

```js:Gruntfile.js
module.exports = function (grunt) {

  grunt.task.loadNpmTasks('assemble');
  // projectパス 変数
  var projectPath = 'public_html/';

  // assembleパス 変数
  var assembleDATA = 'config.yml',
      assembleLayout = '_develop/layouts/default.hbs',
      assemblePartials = '_develop/partials/**/*.hbs';

  // その他パス 変数
  var cwdPath = '_develop/pages/';
  var hbsPath = '**/*.hbs';

  var destCssPath = 'public_html/common/css',
      destImagePath = 'public_html/common/images';

  var sassPath = '_develop/pages/common/sass/',
      cssPath = '_develop/pages/common/css/',
      imagePath = '_develop/pages/common/images/';

  var pkg = grunt.file.readJSON('package.json');

  grunt.initConfig({
    // assembleの設定
    assemble: {
      build: {
        options: {
          data: [assembleDATA],
          layout: assembleLayout,
          partials: assemblePartials,
          assets: destCssPath
        },
        files: [
          {
            expand: true,
            cwd: cwdPath,
            src: hbsPath,
            dest: projectPath
          }
        ]
      }
    },
    // ファイルの監視
    watch: {
      assemble: {
        files: ['_develop/**'],
        tasks: ['assemble:build']
      }
    }
  });

  // ファイルの監視用(default) コマンド grunt
  grunt.registerTask('default', ['watch']);
  // assemble(a) タスクコマンド grunt a
  grunt.registerTask('a', ['assemble']);

};
```

## 主な使い方
自分が使った主な使い方になります。
まだまだ色々使い方はありますが、抑えておくべきメモしておきます。

### ■インクルードファイル呼び出し
SSIやincludeを使わないで、共通化できる！これが自分にとっては大きなメリットでした。
下記のように{{> header}}で記述した部分がpartials/header.hbsを呼び出しHTMLを生成してくれます。

* {{> header}} → partials/header.hbs
* {{!-- コメントアウトです。 --}}
* {{> body}} → ページごとに呼び出す部分

#### 使用例
```html:default.hbs
<html>
<head>
<title>◯◯案件</title>
</head>
<body>
    <div id="wrapper">
        {{!-- headerを読み込む --}}
        {{> header}} {{!-- header.hbsを読み込みます --}}
        <div id="container">
             {{> body}} {{!-- ページごとに読み込む部分 --}}
        </div>
        {{!-- footerを読み込む --}}
        {{> footer}} {{!-- footer.hbsを読み込みます --}}
    </div>
</body>
</html>
```

```html:partials/header.hbs
<h1>サイトロゴ</h1>
```

```html:partials/footer.hbs
<p>フッターコピーライト</p>
```

### ■条件分岐の仕方
ページごとに条件分岐で分けたいときに使用します。
たとえばページごとにtitleを変更したいときには、このように書いて条件分岐させます。
#### 使用例
```html:default.hbs
{{!-- 共通レイアウトファイル --}}
{{#if is_pageTitle}}
<title>{{pageTitle}} | {{config.siteName}}</title>
{{else}}
<title>{{config.siteName}}</title>
{{/if}}
```

```yaml:config.yml
{{!-- 共通文言呼び出しファイル --}}
# 案件タイトル
siteName: ◯◯案件
```

```html:index.hbs
{{!-- ページファイル --}}
---
pageTitle: ページタイトル
is_pageTitle: true
---
```
is_pageTitleという名前をつけて、条件に当てはまるテンプレートに組み込みます。is_pageTitle: true があるページを判定してHTMLを生成してくれます。

### ■ループ処理
案件では使用しなかったのですが、使用できるようです。
下記のようにconfig.yml（データファイル）を使って呼び出すデータを格納します。
※YAML（ヤムル）で記述するとJSONで記述するよりスマートに書けるようです。
#### 使用例
```yaml:config.yml（データ格納）
navLink:
 - title: HOME
   url: /
 - title: page01
   url: /page01/
 - title: page02
   url: /page02/
 - title: page03
   url: /page03/
```

```html:default.hbs
<div id="globalNav">
    <ul>
        {{#each config.navLink}}
             <li><a href="{{url}}">{{title}}</a></li>
        {{/each}}
    </ul>
</div>
```
最初に{{#each}}にループ処理をさせる対象データを呼び出します。
ループさせたい部分を{{/each}}で括ります。
書き方がすごくMovable Typeっぽいので、わかりやすかったです。

## 最後に
タスクを書くまで1時間ちょっとかかりましたが、次は流用できるので素早く対応できるかなと思います。

#####【導入してよかった点】
* Gruntのプラグインある
* インクルードや条件分岐などプログラム処理をHTMLベースでできる
* 導入が容易だった

何万ページというコーディングには、不向きですが数ページのサイトでは使いやすいツールだと思いました。
今回はやったことをまとめましたが、自分用のメモとして随時更新していきたいと思います。

## 参考サイト
* [assembleの特徴](https://app.codegrid.net/entry/assemble-1)
* [assembleで静的webサイトを作った](http://count0.org/2013/08/03/static-site-generate-assemble.html)
* [assembleを利用して静的サイトを構築する[yeoman,grunt]](http://zkohi.hatenablog.com/entry/2013/12/25/011754)
* [静的サイト開発ツールとしてのMiddlemanとGrunt](http://webtech-walker.com/archive/2013/09/middleman_vs_grunt.html)