テンプレートエンジンをerbからslimに変えてみました

Tsukasa OISHI

Rubykaigiでのcookpadの人のセッション、 high performance Railsでも出ていましたが、テンプレートエンジンのslimを使ってみました。すでにこのブログはslimを使っています。

使い方は簡単です。Gemfileにslimを追加するだけ。

gem 'slim'

あとはviewファイルの拡張子を.html.slimにすればOKです。erbと混在してても問題ないので、すこしずつ移行することもできます。
書き方はhamlに似ていますが、hamlよりもデザイナさん受けはよさそうな気がします。hamlと同様に、インデントでブロックを定義します。pythonの人は問題ないかもしれませんが、ぼくはこれはやっぱりちょっと不慣れな感じがする。インデントがずれていたりすると全然違う結果になったりします(当たり前だけど)。

基本的に、文の最初の文字によってそれが何を表しているかが決まります。
ハイフンならばレンダリングはされないけどRubyのコードが実行されます。イコールならば、実行したRubyの結果がレンダリングされます。

- if logged_in?
  = link_to "a", a_url
- else
  = link_to "b" b_url

これはerbで書くと

<% if logged_in? %>
  <%= link_to "a", a_url %>
<% else %>
  <%= link_to "b", b_url %>
<% end %>

となります。

| ではじまるとそれは文字として直接レンダリングされます。

- if logged_in?
  | welcome !

erbでは、

<% if logged_in? %>
  welcome !
<% end %>

となります。

他にもいろいろと意味を持つ文字がありますが、大抵はタグとして認識されます。

div [class="special"]
  article
    header
      = @article.title

erbで書くなら

<div class="special">
  <article>
    <header>
      <%= @article.title %>
    </header>
  </article>
</div>

となります。

slimの READMEにわかりやすく書き方について載っているので、見ればすぐにわかると思います。

ちなみにこの画面のベースとなるviewファイルはslimで以下のように書いています。

<article class="col_center" itempscope itemtype="http://schema.org/Article">
  header
    h3 [itemprop="name"]
      = link_to(article.title, article_path(article), rel: :bookmark)
    time [itemprop="datePublished" datetime="#{I18n.l(article.publish_at, format: :publish)}"]
      = I18n.l(article.publish_at, format: :article)
    aside [class="socialButton" data-article-id=article.id]
      - if logged_in?
        span [class="operate"]
          = link_to I18n.t(:edit), edit_article_path(article)
        span [class="operate"]
          = link_to I18n.t(:delete), article, :confirm => I18n.t(:confirm_to_article_delete), :method => :delete
      span [class="accessCount"]
        = article.access_count
  div [itemprop="description"]
    == TextDecorator.replace(article.body)
</article>

_article.html.slim

articleタグを書いていますが、このように < ではじまると、ふつうにHTMLとして扱われます。