レイアウトとパーシャルを使って作業を効率化(slimも少しあり) - middlemanを使ってみよう vol.2

レイアウトとパーシャル

middlemanシリーズの第2弾です。
前回はmiddlemanのインストール、サーバーの起動と終了までを行いました。今回はサイト作成の準備として、middlemanでの開発サイクルとレイアウトやパーシャルなどの機能を紹介していきます。

ディレクトリ構造

testapp/
+-- .gitignore
+-- Gemfile
+-- Gemfile.lock
+-- config.rb
+-- source
    +-- images
    ¦   +-- background.png
    ¦   +-- middleman.png
    +-- index.html.erb
    +-- javascripts
    ¦   +-- all.js
    +-- layouts
    ¦   +-- layout.erb
    +-- stylesheets
        +-- all.css
        +-- normalize.css

ディレクトリ構造

前回のように進んでいると、ディレクトリ構造は上のような感じのはずです。中身のないスケルトンなので、これからが始まりです。

開発サイクルを知ろう

開発の流れはとてもシンプルで

  1. ページを作る
  2. ビルドする -> 開発用ファイルをhtml/css/jsの形式にコンパイルする
  3. デプロイする -> サーバにアップロード

を繰り返すだけ。1の作業時はプレビュー用のローカルサーバーが起動していて、これがかなり優秀です。ERb、Haml、Sass、ScssやCoffeeScriptといった開発用のテンプレート言語をサポートしているので、適宜コンパイルしてプレビューに反映してくれます。

主な作業はSourceディレクトリ内で行います。ここには、html や css、jsなどのデータが格納されていて、開発用のテンプレート言語を使う場合もこのディレクトリ内にファイルを追加し編集していきます。

config.rbで詳細設定

Source内の ディレクトリ名は変更可能で、変更した場合はconfig.rbの情報も書き換えなければいけません。

config.rbはサイトの設定が記載されたファイルのこと。このファイルの記述をもとにmiddlemanはページを生成します。例えば stylesheets を css というディレクトリ名に変更する場合は、50行目付近にあるset :css_dir, 'stylesheets'の記述を以下のように変更します。

set :css_dir, 'css'

config.rbを編集すれば、helperという関数のような設定やビルド時のminify化設定を追加することができます。コメントアウトされている箇所を参考にカスタマイズすると良いですね。

テンプレートと開発言語

デフォルトでERbやHaml、Sass、Scss、CoffeeScriptといった開発用のテンプレート言語がサポートされていますが、自分は html を書くときはslimを使っています。

<div class="welcome">
  <h1>Middleman is Watching</h1>
  <p class="doc">
    <%= link_to "Read Online Documentation", "http://middlemanapp.com/" %>
  </p><!-- .doc -->
</div><!-- .welcome -->

↑ ERb で書かれた初期のindex.html.erbは html にRubyの記述を追加しただけ。

.welcome
  h1 Middleman is Watching
  p.doc
   = link_to "Read Online Documentation", "http://middlemanapp.com/"

↑ slim で書くと閉じタグが要らず、スッキリとした構造になります。(インデントに注意が必要!!)
開発用言語を使う場合はindex.html.slimのように、テンプレート言語の拡張子を各ファイルに追加することで使用可能です。

slimを使おう

自分の周りではslim率が高く、需要高と勝手に思っています。クラス名を.、ID名を#で表現するのが CSS みたいだったので、デザイナーはこちらの方が分かりやすい気がします。ただ、これを覚えてしまうと、高確率で素の html を書く気にならない病にかかります。

slimを使えるようにする

初期の状態であれば、yterajimaさんが作成されたmiddleman-slimというgemを使ってスケルトンを作成するとすぐに始められます。
gemfileに以下を追加し、bundle install --path vendor/bundleを実行。

gem "middleman-slim"

スケルトンの作成は以下を入力するだけです。すごく早い。

$ bundle exec middleman init --template slim

slimのサポート

すでにslimを使って制作を始められるのですが、出力されたソースを見ると html があれなんで、config.rbに下記を追加して見やすい表示になるよう設定します。

set :slim,
    :format => :html5,
    :sort_attrs => false,
    :pretty => true

さらに、divタグを書くときにクラス名だったら.、ID名だったら#から始められるようショートカットを設定しておきます。

Slim::Engine.set_default_options :shortcut => {
  '#' => {:tag => 'div', :attr => 'id'},
  '.' => {:tag => 'div', :attr => 'class'},
  '&' => {:tag => 'input', :attr => 'type'}
}

この設定をしておけば、<div class="foo">abc</div>

.foo abc

というように書くことができるので、設定しておいて損はないです。

後からslimに乗り換えたい場合

頑張って変換してください。
といってもこれもサポートツールがあって、html2slim を使えば html を slim にしてくれます。ただ、精度が100%ではないので、エラー出るときもあります。

共通の枠組み、レイアウトを理解しよう

レイアウト機能はページ作成の基礎になります。middlemanの公式サイトによると、

レイアウト機能はテンプレート間で共有する個別ページを囲むための共通 HTMLの使用を可能にします。(省略)
最も基本的なレイアウトは共有コンテンツとそのテンプレートの内容を 配置する yield を含みます。
Middleman: レイアウト

この説明の通りです。これは下記のlayout.slimのコードを見た方が早いです。

doctype html
html
  head
    meta charset="utf-8"
    meta content="IE=edge,chrome=1" http-equiv="X-UA-Compatible"
    title = data.page.title || "The Middleman"
    = stylesheet_link_tag "normalize", "all"
    = javascript_include_tag "all"

  body class="#{page_classes}"
    = yield

これから作るページに必要なのはyield部分の記述になります。つまりページごとに、doctypeheadなどを記述する必要ないということです。
現在、index.html.slimには

.welcome
  h1 Middleman is Watching
  p.doc
    = link_to "Read Online Documentation", "http://middlemanapp.com/"

だけがあり、これがyieldの箇所に反映されて html 出力されます。

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta content="IE=edge,chrome=1" http-equiv="X-UA-Compatible">
    <title>Welcome to Middleman</title>
    <link href="/stylesheets/normalize.css" rel="stylesheet" type="text/css" />
    <link href="/stylesheets/all.css" rel="stylesheet" type="text/css" />
    <script src="/javascripts/all.js" type="text/javascript"></script>
  </head>
  <body class="index">
    <div class="welcome">
      <h1>Middleman is Watching</h1>
      <p class="doc"><a href="http://middlemanapp.com/">Read Online Documentation</a></p>
    </div>
  </body>
</html>

body直下のyieldに反映されています。このレイアウト機能が各ページを作っていくときの基礎になります。

知っておくと便利なページ固有変数 Frontmatter

index.html.slimの最上部の記述がFrontmatterです。---で囲われた箇所ですね。

---
title: Welcome to Middleman
---

これ、結構使います。便利です。外部ファイル化することもできますが、まずは基礎的なところから。

frontmatter のデータは current_page.data.titleで取得できます。取得したデータをh1に挿入したいときは、以下のようにします。

h1 = current_page.data.title

title以外にも設定可能で、current_page.dataに設定値をつけて呼び出します。

---
description: 'このページの説明文'
---

/! 下記のように呼び出す
p = current_page.data.description

さらに配列も使えます。

---
menus:
  - menu1
  - menu2
  - menu3
---

menusに格納されたメニューをリストタグで全て出力したいときは、

ul
  - current_page.data.menus.each do |f|
    li = f

とするだけです。これを使えば、項目を増やしたいときでも Frontmatter に値を追加するだけなので作業が楽になります。

パーツを分割、パーシャルを使おう

Wordpressでいうget_template_partのようなもので、共通化できる部分を個別ファイル化して記述の重複を避ける手法です。
同じことを何度も書くことは非効率。共通化できるものはまとめてしまえば、変更が入っても1ファイルの修正ですみます。DIY(Don’t Repeat Yourselef)の考え方ですね。

headerを共通化

header#header.site-header
  ._navbar
    h1._title
      = link_to 'サイト名', '/'
    p._description サイトの説明文

すっごい簡単ですが、上記のような構成の header があったとします。これはレイアウトに読み込ませるためだけのファイルなので、 html としては出力しません。なので、ファイル名を_header.slimとして保存します。先頭の_アンダースコアはパーシャルを意味します。

パーシャルの呼び出しは任意の箇所に= partial "header"とするだけです。例えば、レイアウトのyieldの前に呼び出したいときは以下のようにします。

body class="#{page_classes}"
  = partial "header"
  = yield

今回は、開発の流れを知ってもらい、その中でよく使う機能に焦点を当てました。Frontmatterの外部ファイル化はこのサイトのメニューの部分に採用していたりするので、その辺り興味があればチャレンジしてみてください。

関連記事