Middlemanのdirectory_indexesとURLの最後のスラッシュの関係

middleman

directory_indexes(きれなURL)の実際の動き

Middlemanの機能で1つの魅力だと思っていたのは、directory_indexex(きれなURL)です。この機能を使えばURLに無駄がなくシンプルなものにできます。公式マニュアルのこの部分には下のように書いてあります。

このプロジェクトがビルドされた時, about-us.html.erb ファイルは about-us/index.html として出力されます。"index ファイル" 対応の Web サーバに置かれた場合 (Apache や Amazon S3), このページは次の URL でアクセスできます:

1
http://example.com/about-us

これを読むとこのページのURLが最後のスラッシュ(trailing slash)が無しになるのと思ってしまう方もいるのではないでしょうか。

正確には、スラッシュ無しでアクセスしても、ちゃんと表示されますが、通常アクセスした瞬間URLはスラッシュありのものにリダイレクトされます。

これはdirectory_indexesの仕組みが、WEBサーバの下のような動作を利用しているからです。

  1. 上記のURLでアクセスするとまずabout-usという名前のファイル探す。
  2. それがなければその名前のディレクトリのindexを表示する。

という動作です。なので、結果ディレクトリを示すスラッシュが最後につくのが通常の動作になります。そして、スラッシュがあればそのディレクトリのindexというのが明らかなので、index.htmlというファイル名は表示されず、結果URLバーに表示されている値は以下のようにスラッシュで終わっているはずです。

1
http://example.com/about-us/

"set :trailing_slash, true"とは何か

config.rbで設定できる値にtrailing_slashというものがあります。下のようにすると有効にできます。

1
set :trailing_slash, false

directory_indexesと混同してしまいそうな機能なので、説明します。

こちらは、middleman側のテンプレートやレイアウトで使うlink_toなどのヘルパーで生成されるURLに最後のスラッシュをつけるかどうかを決めます。

前述したように、スラッシュありでも無しでも結局スラッシュ有りにリダイレクトされるので、実際はこれがtureでもfalseでも動作は変わりません。

Middleman採用サイトで最後にスラッシュが無いURLを実現できているサイトがあるのはなぜ?

上述したようにdirectory_indexesがスラッシュ無しURLを保証しているわけではありません。なので、以下に挙がっているMiddleman採用サイトも大抵はスラッシュありURLになっています

Middleman採用サイト

ですが、いくつかのサイトでなぜかスラッシュ無しURLになっているのです。たとえば以下のサイトです。いくつかのページを見てみてください。

https://robots.thoughtbot.com

私が推測するに、これはサーバー側の設定で、スラッシュ無しでもディレクトリのURLとして認識するようにしているのだと考えます。ただ、これはサーバー側の設定ファイル、Apacheで言えば.htaccesshttpd.confなどを設定する必要があります。

割り切ってスラッシュ有りにするのがオススメ

.htaccessだけで済めば良いですが、httpd.confはサーバー管理者でないと触れないケースがほとんどです。Middlemanを使うユースケースを考えると、専用のVMなどではなくS3などのストレージサービスを使うと思うので、そのような設定ファイルは触れないことが多いでしょう。

ちなみに当サイトはlolipopのライトプランを使用しています。.htaccessは編集可能ですが、httpd.confは編集することができません。一度.htaccessを編集してスラッシュ無しURLにすることができるか挑戦しましたが、無限ループが発生してしまいできませんでした。やはり大元のhttpd.confを編集できる、専用VM等を使う必要があるようです。

仮に専用のVMを今借りて設定したとしても、後にはストレージサービスに移行したくなるかもしれません。

なので、当サイトはスラッシュ有りで運用することにしました。上述したset :trailing_slash, trueも設定してヘルパーで生成されるURLも全てスラッシュ有りにしました。

trueでもfalseでも動作は変わらないと前述しましたが、SEO的には無駄なリダイレクトが発生しないほうがいいかな、と思ってスラッシュ有りに揃えています。

羊毛や小麦