Custom Haml filters in a Sinatra application
I’ve been working on a little ruby/sinatra application which involves displaying content rendered from quite a complex proprietary XML format. I decided to use Haml as my templating engine for rendering the views, and added a custom filter to turn the proprietary content into XML. Here’s how they work.
Haml uses filters to transform foreign markup in a view. For example:
%p
:markdown
Lorem ipsum *dolor* sit amet
renders as
<p>Lorem ipsum <em>dolor</em> sit amet</p>
By default the Haml gem includes filters for dealing with common markup types like markdown or coffee script. But if you’re working with some other type of non-standard markup then you can add your own custom filter to process it.
Imagine that your markup format looks like this - for convenience I’ll call it ‘Pipemark’:
Lorem ipsum |boldface|dolor|end boldface| sit amet,
consectetur |boldface|adipisicing|end boldface| elit
You make a custom filter by building on top of the Haml base filter class. Your filter needs to have a render method for converting the markup into HTML. For ‘Pipemark’ that’s just a simple substitution:
module Haml::Filters::Pipemark
include Haml::Filters::Base
def render(input)
output = input.gsub(/\|boldface\|(.*?)\|end boldface\|/,
'<strong>\1</strong>')
end
end
Pass a bit of ‘Pipemark’ data to your view, e.g. for my Sinatra app:
get '/example' do
data = "Lorem ipsum |boldface|dolor|end boldface| sit amet,
consectetur |boldface|adipisicing|end boldface| elit"
haml :example, :locals => {:quote => data}
end
To render it all you have to do is invoke this filter in your Haml template with a colon:
%div
:pipemark
#{quote}
which produces
<div>Lorem ipsum <strong>dolor</strong> sit amet,
consectetur <strong>adipisicing</strong> elit</div>
The render method in my actual example used some xslt to transform xml into html, but the principle was the same.