I'm trying to get Markdown to play nicely with .erb. I'd like to use high_voltage to render markdown pages (or normal .html.erb files with markdown partials) that are parsed with Redcarpet and am struggling to get it to all work together.
At the moment I have an initializer called markdown_template_handler.rb
that contains the following code:
class MarkdownTemplateHandler
def erb
@erb ||= ActionView::Template.registered_template_handler(:erb)
end
def call(template)
compiled_source = erb.call(template)
markdown = Redcarpet::Markdown.new(Redcarpet::Render::HTML)
"#{markdown.render(compiled_source.source).inspect}.html_safe;"
end
end
ActionView::Template.register_template_handler(:md, MarkdownTemplateHandler.new)
However it is failing at line 7, compiled_source = erb.call(template)
with the error code saying "wrong number of arguments (given 1, expected 2)"
I looked at the ERB Ruby documentation but from what I understood, the call method is a derivative of the new method, which only requires 1 argument, the text. However, when I tried to use it just in a quick rails console session, it also required two arguments.
When I remove the requirement to parse erb from the above code, everything works as expected, so I don't think it has anything to do with Redcarpet not working.
I am using Rails v6.0.0.rc1 & Ruby v2.5.3p105
Any help is appreciated.
Edit
Further research has led me to finding the Rails 6.0 ERB ActionView template handler. The call method of this handler does indeed require two arguments, the template and the source. That said, in Rails 5.2.3, the ERB Action View template handler call method only requires one argument, the template.
Could someone please point me in the direction of figuring out what source is in this context? There is no documentation for it that I can find.
The core of the Redcarpet library is the Redcarpet::Markdown class. Each instance of the class is attached to a Renderer object; the Markdown class performs parsing of a document and uses the attached renderer to generate output.
While both Jinja2 and ERB are excellent for generating website markup, the ability to use all of Ruby’s language features in the templates - especially its Perl-like string manipulation features - made it much better-suited to tasks like scraping comments from source code.
And the Ruby code is clean and simple and introduces no serious maintenance burden. I originally intended to use Python and Jinja2, because Python is a popular and easy language, but in the end I found benefits in the ERB templating that outweighed other considerations.
Redcarpet is a Ruby library for Markdown processing that smells like butterflies and popcorn. Redcarpet was written by Vicent Martí. It is maintained by Robin Dupret and Matt Rogers. Redcarpet would not be possible without the Sundown library and its authors (Natacha Porté, Vicent Martí, and its many awesome contributors).
In this case, source would be passed to the call
by ActionView when the handler is called.
You would rewrite your call
function like that:
def call(template, source)
compiled_source = erb.call(template, source)
markdown = Redcarpet::Markdown.new(Redcarpet::Render::HTML)
"#{markdown.render(compiled_source).inspect}.html_safe;"
end
Before Rails 6, the source
value was extracted from template.source
, but it is now passed as a separate parameter.
This approach for rendering markdown with ERB in Rails 6 worked well for me. Thanks to Louis-Michel for pointing me in the right direction, including both parameters in the call.
require 'redcarpet'
class MarkdownTemplateHandler
def erb
@erb ||= ActionView::Template.registered_template_handler(:erb)
end
def call(template, source)
compiled_source = erb.call(template, source)
"Redcarpet::Markdown.new(Redcarpet::Render::HTML.new).render(begin;#{compiled_source};end).html_safe"
end
end
ActionView::Template.register_template_handler(:md, MarkdownTemplateHandler.new)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With