[Grunt & Yeoman] grunt-ect テンプレートを使って HTML を生成する

引き続き、テンプレートエンジンについて試してみました。

こちらのエントリーが分かりやすかったので、参考にしながら動かしてみます。

Contents

ect

素の ect。

インストール

% npm install --save-dev grunt-ect

Gruntfile

'use strict'
module.exports = (grunt) ->
  # プラグインの読み込み
  grunt.loadNpmTasks 'grunt-ect'
  # グラントタスクの設定
  grunt.initConfig
    # config
    dir:
      src: 'src'
      dest: 'dist'
    pkg: grunt.file.readJSON "package.json"
    # grunt-ect
    ect:
      options:
        root: '<%= dir.src %>/template'
      index:
        src: 'index.ect'
        dest: '<%= dir.dest %>/index.html'
        variables:
          title: 'タイトル'
          description: 'サイトの説明です。'
      news:
        src: 'news/news.ect'
        dest: '<%= dir.dest %>/news/news.html'
        variables:
          title: 'タイトル'
          description: 'サイトの説明です。'
  # タスクコマンドの設定
  grunt.registerTask 'default', ['ect']

つかいかた

src/template
├── index.ect
└── news
    └── news.ect

src/template/index.ect

<!doctype html>
<html lang="ja">
<head>
  <title><%= @title %></title>
  <meta name="description" content="<%= @description %>" />
</head>
<body>
  <h1><%= @title %></h1>
  <p><%= @description %></p>
</body>
</html>

src/template/news/news.ect

<!doctype html>
<html lang="ja">
<head>
  <title><%= @title %></title>
  <meta name="description" content="<%= @description %>" />
</head>
<body>
  <h1><%= @title %></h1>
  <p><%= @description %></p>
</body>
</html>

実行します。

% grunt ect
Running "ect:index" (ect) task
File dist/index.html created.
Running "ect:news" (ect) task
File dist/news/news.html created.
Done, without errors.
dist
├── index.html
└── news
    └── news.html

分からない点

  • Gruntfile 内に書いた設定を別ファイルにする方法。
  • index, news としたページ毎の設定をせずにまとめて生成できないか。

テンプレートの継承機能をつかって、親レイアウトファイルを用意する

追記:2014/01/09
まとめてコンパイルする方法が分かったので追記します。
Grunfile 内に書いたオブジェクトの渡し方は分からないけれど、Blocks 機能で ect 内からきれいに渡せそう。

Gruntfile

これで /src/template 以下の .html.ect ファイルが、ディレクトリ構造を保ったまま、html として生成されました。

ect:
  options:
    root: '<%= dir.src %>/template'
  dev:
    expand: true,
    flatten: false,
    cwd: '<%= dir.src %>/template'
    src: '**/*.html.ect'
    dest: '<%= dir.dest %>'
    ext: '.html'

※ テンプレートのパスを整えるため、root の設定が必要でした。

継承(Inheritance)とプレースホルダ(Blocks)

こちらを参考に実装していきます。

このようなファイルレイアウトで用意してみます。

src/template
├── index.html.ect
├── news
│   └── news.html.ect
└── partials
    └── layout.ect

layout.ect

<!doctype html>
<html lang="ja">
<head>
  <title><% content 'title' %></title>
  <meta name="description" content="説明" />
</head>
<body>
<% content %>
<!-- Scripts -->
<% content 'scripts' %>
</body>
</html>

index.html.ect

<% block 'title': %>
インデックス<% end %>
<% extend 'partials/layout.ect' %>
<h1>インデックスの見出し</h1>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Placeat, vel eveniet nemo repudiandae dolore consequatur similique dicta voluptates accusamus laboriosam earum sed itaque ex aliquam unde minima illo et obcaecati?</p>
<% block 'scripts': %>
特定のページだけで使うスクリプトとかを呼び出す。
<% end %>

news.html.ect

<% block 'title': %>
ニュース<% end %>
<% extend 'partials/layout.ect' %>
<h1>ニュースの見出し</h1>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Placeat, vel eveniet nemo repudiandae dolore consequatur similique dicta voluptates accusamus laboriosam earum sed itaque ex aliquam unde minima illo et obcaecati?</p>

生成されたファイル

dist
├── index.html
└── news
    └── news.html

index.html

<!doctype html>
<html lang="ja">
<head>
  <title>インデックス</title>
  <meta name="description" content="説明" />
</head>
<body>
<h1>インデックスの見出し</h1>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Placeat, vel eveniet nemo repudiandae dolore consequatur similique dicta voluptates accusamus laboriosam earum sed itaque ex aliquam unde minima illo et obcaecati?</p>
<!-- Scripts -->
特定のページだけで使うスクリプトとかを呼び出す。
</body>
</html>

news.html

<!doctype html>
<html lang="ja">
<head>
  <title>ニュース</title>
  <meta name="description" content="説明" />
</head>
<body>
<h1>ニュースの見出し</h1>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Placeat, vel eveniet nemo repudiandae dolore consequatur similique dicta voluptates accusamus laboriosam earum sed itaque ex aliquam unde minima illo et obcaecati?</p>
<!-- Scripts -->
</body>
</html>

望み通りの出力をすることができました。