Middlemanを使う
- MiddlemanのコーディングはHaml SCSS(Sass) CoffeeScriptといった拡張メタ言語で行い、それをHTML CSS JavaScriptに トランスクリプトしてブラウザ上で確認するという流れをシームレスに実現するための環境です。
- Ruby on Rails といったサーバーサイドアプリケーションだと HTML ファイルを物理的に生成はしません。ということは、サイトを見るためには必ず Web サーバーが必要になります。
- 一方の Middleman は、静的ファイルを物理的に生成することから Web サーバーを必要としないサイトを作ることができます。
- Ruby 関連のプログラム技術を使って効率的に Web サイトを作る。Middleman は正にサーバーサイドを交えた本実装前のプロトタイピングにうってつけの環境というわけです。
1 開発環境
アプリ名 | バージョン |
---|---|
Ruby | 2.0.0-p481 |
Ruby gems | 2.0.14 |
Bundler | 1.11.2 |
2 インストール(Bundlerを用いる場合は、スキップ)
- 後ほど、Bundlerを用いて作業フォルダ内にMiddlemanのgemをインストールするため、今回はスキップします。
- Bundlerを用いない場合は、以下のコードを実行します。
gem install middleman
3 サンプルサイトの構築
3.1 作業ディレクトリの作成と初期化
# try_middleman ディレクトリを作成
mkdir try_middleman
# 作成したディレクトリに移動
cd try_middleman
#Bundlerで作業ディレクトリを初期化
bundle init
3.2 BundlerによるMiddlemanのインストール
作業ディレクトリに生成された
Gemfile
を下記のように変更します。Gemfile
source "https://rubygems.org"
gem "middleman"
- その後、
bundle install
コマンドを使って、Middlemanをインストールします。
bundle install --path vendor/bundle
3.3 Middlemanプロジェクトの作成
- はじめに、Middlemanプロジェクトを作成します。
bundle exec middleman init .
#全部Yを押す
bundle install --path vendor/bundle
3.4 サーバーを起動します。
bundle exec middleman server
3.5 http://localhost:4567にアクセスします。
4 サイトのビルド
-
middleman build
コマンドでサイトをビルドします。
bundle exec middleman build
# create build/stylesheets/site.css
# create build/images/middleman-logo.svg
# create build/javascripts/all.js
# create build/index.html
#Project built successfully.
5 (option)RubyMineでコーディングする設定
- メニューバーの
run
->Edit Configuration
->+マーク
->Gem Command
を選択します。 - 下記の通り設定します。
項目 | 設定値 | 補足 |
---|---|---|
Name | Middleman Development | ※なんでも良い |
Gem name | middleman | |
Executable name | middleman | |
Single instance only | checked | チェックボックスはウィンドウの右上に存在 |
Ruby SDK | Use other SDK and gem: rbenv: 2.0.0-p481 | |
BundlerタブのRun the script in context of the bundle(bundle exec) | checked |
- 以上の設定をしておくと、RubyMineメニューの
run
->Debug Middleman
を押すだけで、Middlemanサーバーが立ち上がり、デバッグできるようになります。
6 Middlemanにおけるテンプレートレイアウト
- テンプレートファイル(コンテンツ) - sample.html.haml
個別ページです。基本的にここには固有のコンテンツだけが記述されており、その他には Frontmatter というレイアウトページ固有の情報したいページ固有の情報群があります。ファイル自体の拡張子はhamlですが、コンパイル後の拡張子をファイル名に含める決まりがあります。
- レイアウトファイル - layout.haml
テンプレートファイルを囲うためのモノです。囲ったテンプレート(コンテンツ)は= yieldと書かれている箇所に出力されます。
- パーシャル - _header.haml_footer.haml 単独で利用されることがなく、他のテンプレートファイルやレイアウトファイルにインクルードされることを前提としたものです。ファイル名に_を接頭辞としてつける決まりがあります。
6.1 カスタムレイアウト
Middleman にはlayout.erb というレイアウトファイルが最初から用意されており、デフォルトで全てのページがこのレイアウトファイルに囲われた状態で出力されます。しかしページによっては異なるレイアウトを使用したいというケースも往々にしてあるでしょう。例として custom_layout.haml というのを作ってみます。
layouts/custom_layout.haml
!!!
%html
%head
%title 初めてのカスタムレイアウト
%body
.wrapper
= yield
- 次に、
custom.html.haml
ファイルを新規作成し、先ほどのカスタムレイアウトを指定します。 ---
で囲まれた部分は、Frontmatterというものです。YAML形式またはJSON形式のどちらでも記述することができます。ただし、RubyMine上ではエラーとして扱われるため、先頭にバックスラッシュをつけ、\---
のようにしておく良いです。(生成されるコードは同じものになります。)custom.html.haml
---
layout: custom_layout
---
%h1 Custom Layout page.
%p カスタムレイアウトのページです。
プロジェクトの規模が大きくなると、Frontmatteによる指定はやや冗長で面倒になります。その場合は config.rb に以下のようなコードを追記して、テンプレートを一括指定します。
config.rb
に下記を追記
page "/custom/*", layout: "custom_layout"
6.2 レイアウトの入れ子
- 複数レイアウトを入れ子にして積み重ねることが出来ます。コードの重複を抑えることができ、複雑なレイアウトを作る上で欠かせません。例として以下の様な二種類のレイアウトがあったとします。
それぞれ、一部の箇所が異なるだけで、それ以外は同じコードです。ならばこの重複している箇所をレイアウトのベースとして切り出し、
layout_a.haml
layout_b.haml
がそれぞれベースレイアウトを入れ子で読みこめばコードの重複を解消することができるわけです。layout_a.haml
!!!
%html
%head
%meta{charset: 'UTF-8'}
%title= current_page.data.title || "Middleman"
%body
%header.global-header
%h1 Page title
.contents
= yield
%footer.global-footer
%small Soushi Yamamoto
layout_b.haml
!!!
%html
%head
%meta{charset: 'UTF-8'}
%title= current_page.data.title || "Middleman"
%body
.wrapper
.contents
= yield
%aside.sidebar
%p hoge
%p fuga
%p foo
%footer.global-foter
%small Soushi Yamamoto
- 先ず、共通部分のみで構成された
layout_base.haml
を作成します。
!!!
%html
%head
%meta{charset: 'UTF-8'}
%title= current_page.data.title || "Middleman"
%body
= yield
%footer.global-footer
%small Soushi Yamamoto
- 次に、
layout_a.haml
とlayout_b.haml
で残りの部分(異なる部分)を記述します。 wrap_layout
という関数を呼び出し、引数に使用するレイアウトを指定します。指定する際はファイル名をそのまま記述するのではなく、上の例にあるように:を冒頭につけてレイアウト名を記述します。これはシンボルというRubyの記法の一つ *1です。呼び出し元はlayout_base.hamlの= yieldの部分に来ます。この機能はオブジェクト指向の継承がイメージとして近いかもしれません。*1 Rubyのシンボルについてはこちら(すぐに忘れる脳みそのためのメモ)layout_a.haml
- wrap_layout :layout_base do
%header.global-header
%h1 Page title
.contents
= yield
layout_b.haml
- wrap_layout :layout_base do
.wrapper
.contents
= yield
%aside.sidebar
%p hoge
%p fuga
%p foo
注意:ここから先(7章「パーシャル」)はバグあり。未検証なので、今後検証すること。
7 パーシャル
外部ファイルをインクルードする機能と基本的には同じです。グローバルヘッダーやグローバルフッター、グローバルナビなど複数ページにわたって共通で使用されるようなコンポーネントは外部ファイル化しておくことでコードの重複を避けることができます。 先の例を続けます。
layout_a.haml
にはグローバルヘッダー要素がありますが、これをパーシャル化してlayout_b.haml
やそれ以外のファイルでも使用できるようにします。パーシャルのファイル名は先頭に_を付けます。 共通するレイアウトの一部ということで、layouts/libというディレクトリを新規に作成してそこに配置します。layouts/lib/_global_header.haml
%header.global-header
%h1 Page title
- 次にpartialメソッドを使って
layout_a.haml
にグローバルヘッダー要素を配置します。 partial という関数の引数として配置したいパーシャルファイルのパスを指定します。ポイントとしてはファイル名にはある 先頭の_と拡張子は記述しない ということです。layout_b.haml にグローバルヘッダーを配置したい場合も上記と同様の手法で実現することができます。
layout_a.haml
- wrap_layout :layout_base do
= partial 'layouts/lib/global_header'
.contents
= yield
パーシャルとして外出しできたのは良いのですが、見出しの文言が Page title と固定になっていては、使い勝手が良い機能とはいえません。呼び出しの際に見出しの文言を引数として渡すことでこの問題を解決することができます。パーシャルファイルを以下のように修正します。
layouts/lib/_global_header.haml
%header.global-header
%h1= title
- titleという変数に書き換えました。この変数に対してパーシャル呼び出し時に値を引数として渡します。
layout_a.haml
を以下のように修正します。 localsというオブジェクトの中にパラメータを指定して値を渡しています。jQuery プラグインにオプションを渡すようなものだと考えておけば問題ないでしょう。
layout_a.haml
- wrap_layout :layout_base do
= partial 'layouts/lib/global_header', locals: {title: "My Title A"}
.contents
= yield