SinatraでSlimというテンプレートエンジンを利用した場合にPartialする方法について。前からやりたかったんだけど、やり方がわからなくて、過去に自分で作ったWebアプリは結構HTMLコードを重複させていた。今回やっとやり方がわかったので、今後はちょっと重複を減らせるかも。Sinatraのバージョン1.1でパーシャル機能が追加されたようで、結構シンプルな方法で使える模様。昔(ver.1.1より前)はこの機能は無かったので、自分でヘルパーメソッドを定義する必要があったみたい。
Partial(パーシャル)とは
PartialとはRailsにある機能で、通常のテンプレートファイルの中で使うさらに小さい単位のテンプレートファイル(とその展開方法)という感じかな? 似たような機能にlayout.slim
と== yield
を使ったレイアウト機能があって、これは対象のテンプレートの外側を包み込む動作をするけど、パーシャル機能はその逆で、対象のテンプレートの内側(内部)で展開する動作をする。両方の機能をSlimで使った場合のファイル構成としては、
layout.slim
(サイト全体で共通化できそうなレイアウト部分のテンプレート)index.slim
(通常のテンプレート)_partial.slim
(通常テンプレート間で共通化できそうな部分を外部化した部分テンプレート)
という感じになる。
Sinatra+SlimでPartial
例えばパーシャル部分を_fuga.slim
ファイルとして、中身は以下のように記述する。
a href='http://nekostagram.heroku.com' Nekostagram!
パーシャル用のファイル名はアンダースコアで開始するのがRailsの習慣っぽいけど、Sinatraでは特にそういうのは無いみたい。アンダースコアで開始しなくても普通に使えた。ただ、パッと見ですぐパーシャル用ファイルとわかるので、自分はアンダースコアを付けた。あとCSSを書くときのSassのインポート用ファイル名がアンダースコアを付けるので、それと揃えたいってのもあるかな。
それで、通常のテンプレートがhoge.slim
だったとして、その中で先ほど作成したパーシャル用ファイルを使いたい場合は、例えばhoge.slim
の中で以下のように記述する。
h1 My Favorite Links!
ul
li
a href='http://www.google.com' Google!
li == slim :_fuga # これ
li
a href='http://twitter.com' Twitter!
Sinatraが対応しているテンプレートなら、すべて上記のようにテンプレート名のメソッドが用意されてると思う。たぶん。Hamlならhaml :_fuga
、ERBならerb :_fuga
になるんじゃないかな。たぶん。Railsの場合、ファイル名にはアンダースコアをつけて、呼び出すシンボル名にはアンダースコアをつけなかったりするけど、Sinatraはパーシャル用ファイル名にアンダースコアをつけることを義務付けられているわけではないので、ファイル名にアンダースコアを付けたら、呼び出し時のシンボル名にも付ける必要がある。
あとは、いつもどおりにapp.rb
内のどこかで、テンプレートを実行するメソッドを書いて実行する。要は、このいつも使ってたやつと同じ記法でSlimコード内でも書けばパーシャル出来るようになるってわけだったのね。シンプルでいい。
get '/' do
slim :hoge
end
これでSinatraアプリを実行すると、hoge.slim
の中で指定しているパーシャル_fuga.slim
がちゃんと展開された上で、hoge.slim
が表示される。もちろん、この_fuga.slim
はhoge.slim
以外のファイルでも利用可能。というかそれが目的。
注意点
注意点としては、Slimはデフォルトで出力時にHTMLエスケープするので、PartialのときはそのデフォルトのHTMLエスケープをOFFにする記法「==」を使わなければいけない。エスケープする方の「=」を使うと、以下のような出力になってしまうので注意されたし。
My Favorite Links!
Google!
<a href="http://nekostagram.heroku.com">Nekostagram!</a>
Twitter!
これでHTMLもちょっとはDRYにできるかな!