Ruby
haml
middleman

Middleman で link_to_if っぽいことをやる

More than 3 years have passed since last update.

ブログにも書いたのだけど、qiita デビューしてみたかったのでこっちにも書いてみようそうしよう。

<!-- こういうナビゲーションを作りたい時 --> 
<nav class="nav">
  <ul>
    <li class="current">ホーム</li>
    <li><a href="concept.html">コンセプト</a></li>
    <li><a href="products.html">製品情報</a></li>
    <li><a href="contact.html">お問い合わせ</a></li>
  </ul>
</nav>

ナビゲーションで、現在地を表すナビだけリンクをつけないみたいなことをやる時、Railsだと、link_to_if とか link_to_unless とかを使うと便利だが、Middlemanのヘルパーにはそういうのは特にないっぽかったので、どうにかして似たような事をやろうと思ったらこんな感じになった。

source/partials/_nav.html.haml
-# source/partials/_nav.html.haml
%nav.nav
  %ul
    - data.nav.pages.each do |page|
      %li{ class: "#{'current' if page_classes == page.name}" }
        = page_classes == page.name ? page.label : (link_to page.label, "#{page.name}.html")
# data/nav.yml
pages:
  - name: 'index'
    label: 'ホーム'
  - name: 'concept'
    label: 'コンセプト'
  - name: 'products'
    label: '製品情報'
  - name: 'contact'
    label: 'お問い合わせ'

index, concept, product, contact みたいな4つのページが仮にあったとして、それぞれ同じナビゲーション用のパーシャル source/partials/_nav.html.haml を呼び出すとする。

Middlemanのデフォルトのレイアウトは、ページごとにファイル名と同じ名前(index.html だったら "index" という名前)の class が外側の body につくようになってて 、これが "#{page_classes}" という 変数で呼び出されるようになってるので、これを利用して、この page_classes が、データで指定した page.name と一緒だったら、current ページを表すナビゲーションとして処理するという感じにした。三項演算子のところは、もっとシンプルに書けるんでは?という気もするのだけど、これ以外に思いつかなかった。

ナビゲーションの内容は、マークアップとは別の YAML ファイルに data/nav.yml みたいにして置いておく。Frontmatter でもいいんだけど、複数ページで共通の要素なので、外部に置いた方がキレイに共通化できる。コンテンツを外出しするとマークアップがこれだけで済むのがステキですね。Middlemanステキですね。

Rails とまんま一緒のヘルパーを使いたければ、自分で config.rb に追加するという方法もあるらしいが、今回はそれほどという感じでもなく。またこれそういえば、ページが階層構造になったらどうするんだろうなー。まだ考えてない。もっと汎用的ないい方法がありそうな気もする :bird: