Haml のpreエスケープフィルタ作り方

こんにちは福山です。突然、「ふじもとさんですよね?」と聞かれました。誰かな。

Hamlのタグをまとめてフィルターにする方法です。いくつか情報がありましたが、それどこに書いてどうやって読み込むの?という感じだったのでメモしておきます。Rubyはまだまだなので、見当違いなことをしているのかもしれません。

まとめたいタグやフィルター

ブログでコードをそのまま表現するのに私の場合、%preからの4行を記述します。エスケープしつつ、改行と半角空白を保持してコードを表示できます。

%pre
  %code
    = preserve do
      :escaped
        <p>
          これは目的の文字列です。
        </p>

設定ファイルの場所

Macに直接Hamlを入れた人はおそらく以下のパス

/Library/Ruby/Gems/1.8/gems/haml-3.1.4/lib/haml

rvm使ってHamlを入れた場合は

/Users/[yourname]/.rvm/gems/ruby-1.9.3-p125/gems/haml-3.1.4/lib

とりあえずHamlの場所をつきとめます。buffer.rbやengine.rbなどのRubyファイルが置いてあると思います。

一つのフィルターにまとめる

先ほどの.rbファイルの階層に、適当にmy.rbという名前のファイルを作り次を書き込みます。

module Codep
  include Haml::Filters::Base

  def render(str)
    str = Haml::Helpers.html_escape(str)
    str = Haml::Helpers.preserve(str)
    "<pre><code>#{str}</code></pre>"
  end
end

同階層のengine.rbをエディタで開くと、最初にrequire..といくつかファイルを読み込んでいる部分があるかと思います。

ここでmy.rbを読み込ませましょう。次を追加します。

require 'haml/my'

結果

定義したCodepで、4行にわたる記述と同じ効果が得られるようになりました。

:codep
  <ul>
    <li>abc</li>
  </ul>

%pre
  %code
    = preserve do
      :escaped
        <ul>
          <li>abc</li>
        </ul>

HTMLへの出力結果
(&#x000A;はブラウザで見ると改行される部分)

<pre><code>&lt;ul&gt;&#x000A;  &lt;li&gt;abc&lt;/li&gt;&#x000A;&lt;/ul&gt;</code></pre>

上記のHTMLをブラウザで見たとき
改行もインデントも保持されます。

<ul>
  <li>abc</li>
</ul>

その他、外部hamlファイルの読み込みを短縮

普通にhreader.hamlというファイルを読み込む場合

= Haml::Engine.new(File.read("header.haml")).render

先ほどと同様に設定ファイルを作り、engine.rbに読み込ませます。

def render_file(filename)
  Haml::Engine.new(File.read(filename)).render
end

すると、短くして次のように出来ます。

= render_file("header.haml")

おわり

:rubyフィルターを使えばhamlファイルの中でもフィルター定義できるみたいですね。

参考