mahemoff
mahemoff

Reputation: 46419

HAML filters in a helper

Helper functions can receive a block which they yield to render the block. Sometimes I'd want that block to be spec'd with a filter. So for example:

= doc_page title: 'FAQ' do
  :markdown
    # Welcome to the *FAQ*

This is not so DRY as we are always writing doc_page and markdown together. Can I make the helper method accept a block and pass it through a HAML filter. Something like:

= doc_page title: 'FAQ' do
  # Welcome to the *FAQ*

In this fantasy, doc_page is a helper method that does some setup stuff and then passes the content through markdown, saving us the need to declare :markdown everywhere and making the world a DRYer place.

Upvotes: 5

Views: 880

Answers (3)

Vince V.
Vince V.

Reputation: 3143

Currently it is not possible to use filters in helpers. An alternative approach would be to use redcarpet to parse the markdown and then pass the output to a helper.

an example would be:

= doc_page title: 'FAQ', :markdown do
  ### my markdown

= doc_page title: 'FAQ' do
  normal html

The implementation of the doc_page would be something like this:

def doc_page(title, markup=:html)

  content = yield

  if markup == :markdown
    markdown = Redcarpet::Markdown.new(Redcarpet::Render::HTML)
    content = markdown.render(content)
  end

  content
end

This would solve your problem, as you define your markdown filter in the helper. And you don't need an extra indentation level in your haml.

Upvotes: 5

amenzhinsky
amenzhinsky

Reputation: 992

I'm afraid, but it's not possible, because haml is a preprocessor, basicly this piece of code:

= doc_page title: 'FAQ' do
  # Welcome to the *FAQ*
  %a href="/" link

Will be converted in runtime ruby code like:

concat(doc_page title: 'FAQ' do
  # Welcome to the *FAQ*
  concat('<a href="/">link</a>')
end)

Upvotes: 2

smallbutton
smallbutton

Reputation: 3437

You could use tilt (the api haml uses to render markdown) directly instead of through haml. Probably something like this (not tested).

markdown_template = Tilt['md'].new { "# this is markdown code" }
markdown_template.render

You can find a similar example in the Tilt docs. But this is more of an idea than a complete implementation.

Upvotes: 2

Related Questions