Middlemanでそこまで頑張らないサイト制作


## はじめに

そこまでコンテンツ量はないけれどもペライチではないWebサイトを作る必要があって、[Middleman](https://middlemanapp.com/jp/) を使ってみたのでそのまとめです。
具体的には、とあるバンドの公式ページを作りました。

### 想定読者

* Rubyが少し分かる (要Ruby, bundler)

### ここでやること

* インストール
* レイアウトとページ作成
* データファイル
* アセット管理
* 設定
* ビルドとデプロイ

### ここでは触れないこと

* 頑張りが必要なこと
  * 外部パイプライン（webpack等)機能
  * ビルドの最適化

## インストール

```shell-session
$ gem install middleman
```

gemがインストールされたらプロジェクトフォルダ内で以下を実行します

```shell-session
$ middleman init
```

プロジェクトの雛形がつくられ、 Gemfileや .gitignore等も生成されます。
以下で開発用のサーバーが立ち上がります。

```shell-session
$ bundle exec middleman
```

(bundlerを経由したいので、以後 middleman コマンドは `bundle exec middleman` で起動します。)

http://localhost:4567 にアクセスするとページが立ち上がっているかと思います

![image.png](https://qiita-image-store.s3.amazonaws.com/0/180624/2bbafa40-0d68-e356-a961-9ae9d6965cb4.png)

## レイアウトとページ作成

Rails等をやっている方にはお馴染みのerbファイルを編集していきます。埋め込みRuby記法が使えるhtmlファイルなので、覚えることは多くありません。

共通で使用されるlayoutファイルを編集してみます。

```diff
--- a/source/layouts/layout.erb
+++ b/source/layouts/layout.erb
@@ -11,6 +11,9 @@
     <%= javascript_include_tag "site" %>
   </head>
   <body>
+    <header>
+      <h1>test website</h1>
+    </header>
     <%= yield %>
   </body>
 </html>
```

`<%= yield %>` 内にページ個別の内容が埋め込まれます。RailsのViewと同じですね。

indexページからAboutページにリンクします。

```diff
--- a/source/index.html.erb
+++ b/source/index.html.erb
@@ -16,8 +16,4 @@ title: Welcome to Middleman
   Middleman is Running
 </h1>

-<%= link_to(
-  "Read Documentation",
-  "https://middlemanapp.com/basics/templating_language/",
-  target: "_blank"
-) %>
+<%= link_to( "About", "about.html") %>
```

source/about.html.erbを作成します。

```diff
--- /dev/null
+++ b/source/about.html.erb
@@ -0,0 +1,6 @@
+---
+title: About
+---
+
+<p>Aboutページです。</p>
```

![image.png](https://qiita-image-store.s3.amazonaws.com/0/180624/20d78a0c-970c-56ea-19f0-febbd92f03f0.png)

これを繰り返せば、共通部分（"test website"の部分）を持つページを作っていけそうですね。

上記3行については Frontmatterと呼ぶらしいです。 https://middlemanapp.com/jp/basics/frontmatter/ 

## データファイル

バンドの公演情報のようなものはある程度構造化されているので、ページ内に直接埋め込むよりも外部ファイルで管理すると楽です。

Middlemanはデータファイルとしてyamlやjsonに対応しています。

```data/live.yml
---
-
  title: タイトル
  date: 2019/1/10
-
  title: タイトル2
  date: 2019/2/22
-
  title: タイトル3
  date: 2019/3/10
```

```diff
--- a/source/about.html.erb
+++ b/source/about.html.erb
@@ -3,4 +3,8 @@ title: About
 ---

 <p>Aboutページです。</p>
+<% data.live.each do |live| %>
+  <h2><%= live.title %></h2>
+  <%= live.date %>
+<% end %>
```

dataディレクトリを作成した直後はサーバの再起動が必要でした。
ページ内で `data` を通じて yamlの内容にアクセス可能です。 `live.each` でlive.ymlの内容をループしています。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/180624/907b533e-48c7-ddbc-1b94-09caa0b8fc12.png)

デザインの差し替え等も楽になりますね。


## アセット管理

リセットcss等を適応したいと思いますよね、stylesheetフォルダ内に追加すれば `<%= stylesheet_link_tag "filename" %>` で直接参照できますが、 あまりイケてないので、npmパッケージから引っ張ってきます。（この章では要Node.jsです）

```shell-session
$ npm init -y
```

リセットcssに normalize.cssを使います。

```shell-session
$ npm i -D normalize.css
```

package.jsonと node_modulesディレクトリが作成されています。 node_modules/ は gitignoreしておきましょう。

また、アセットパイプライン機能としてMiddlemanからsprocketsを使います。公式は外部パイプラインとしてwebpack等を使うことを勧めていますが、~~webpackわからない~~ シンプルに解決したいので…。

Gemfileに以下の記述をして `bundle install` します

```Gemfile
gem "middleman-sprockets"
```

sprocketsを有効にするためにconfig.rbを編集します。

```diff
--- a/config.rb
+++ b/config.rb
@@ -1,6 +1,9 @@
 # Activate and configure extensions
 # https://middlemanapp.com/advanced/configuration/#configuring-extensions

+activate :sprockets
+sprockets.append_path File.join(root, "node_modules")
+
 activate :autoprefixer do |prefix|
   prefix.browsers = "last 2 versions"
 end
```

変更の2行目が肝で、node_modules以下をアセット探索対象に含めます。

サーバーを再起動するとcss上で 以下のような記述が可能になります. (詳細 https://github.com/rails/sprockets#directives )

```diff
--- a/source/stylesheets/site.css.scss
+++ b/source/stylesheets/site.css.scss
@@ -1,3 +1,7 @@
+/*
+*= require 'normalize.css/normalize.css'
+*/
+
 body {
   background-color: #fbc547;
   color: #333;
```

normalize.cssのファイル本体が `node_modules/normalize.css/normalize.css` にあるのでそれを読みに行く記述です。これはパッケージによって異なりそうです。
これでnpmパッケージからcssを参照して使用することができました。

### 余談

normalize.css以外に

* https://github.com/willmcpo/body-scroll-lock (スマホでモーダルを出した時に背景がスクロールできてしまう対策）
* https://github.com/jonsuh/hamburgers (ハンバーガーアイコンのCSS。アニメーションつき)

をぶっ込みました。この程度だったらCDNから直接読んじゃっても良い気がしますが…。


## 設定

config.rbに `activate :directory_indexes` を記述するのがオススメです。
`link_to "About", "about.html"` した時に、
`http://example.com/about.html` ではなく `http://example.com/about/` のようなディレクトリを切った形によしなにビルドしてくれるようになります。 .htmlがないと見栄えがよいですね


## ビルドとデプロイ

```shell-session
$ bundle exec middleman build
```

buildディレクトリに作成されます。
デプロイ先として、Amazon S3の静的ファイルホスティング機能を使うことにしました。(設定等は割愛します)

https://github.com/fredjean/middleman-s3_sync をインストールします.

```ruby
gem 'middleman-s3_sync'
```

```shell-session
$ bundle install
```

```config.rb
activate :s3_sync do |s3_sync|
  s3_sync.bucket                     = 'バケット名をいれる' # The name of the S3 bucket you are targeting. This is globally unique.
  s3_sync.region                     = 'us-west-1などのリージョン'     # The AWS region for your bucket.
  s3_sync.aws_access_key_id          = 'AWS ACCESS KEY IDを入れる'
  s3_sync.aws_secret_access_key      = 'AWS SECRET KEYを入れる'
end
```

ACCESS KEY ID、SECRET KEYはコミットすると危険なので要注意。`.s3_sync` というファイルを作って置いておくとそこから[読み出してくれたりする機能がある](https://github.com/fredjean/middleman-s3_sync#through-s3_sync-file)みたいですね。私は direnvを使って環境変数経由で読み出しました。

あとは

```shell-session
$ bundle exec middleman s3_sync --build
```

でバケットにアップロードされます。


## まとめ

頑張る必要がなく、書き慣れたRubyで書いていけるのでやりやすかったです（一晩でできた）。extensionとしてautoprefixerやminify機能もついていて楽です。
枯れ気味の技術はハマりどころが少なく良かったとも思いました。


制作物: https://nkwors.com/