Rendering Markdown from json data file

Hi, I’m populating a page with data from a json file. One of the fields in the json is an article and I’m wanting to include some markdown formatting in the json to show thing like paragraph breaks, links, etc. Middleman is currently rendering the markdown literally rather than converting it to html when the page is produced. I’ve tried combinations of index.md.html.erb for my template naming but not working. Can’t find any documentation on the web explaining how to deal with this. Appreciate any pointers.

I wrote a simple helper method to do render Markdown that’s stored in a YAML data file – I imagine it would work when pulling data out of JSON as well.

In config.rb, define a helper method like so:

helpers do
  # other methods...

  def markdown(text)
    Tilt['markdown'].new { text }.render
  end
end

Calling Tilt enables you to use whatever Middleman is already using as the default Markdown engine. This should work automatically.

Then to use this method in your templates, you’d call it like so in HAML:

.markdown_content
  = markdown(data.whatever.foo)

or in ERB:

<div class="markdown_content">
  <%= markdown(data.whatever.foo) %>
</div>

This method is very basic – just call your data from wherever it lives, and pass it to the helper method to get rendered HTML.

This helper works great, as long as there are no markdown links written in data file. For me, if I try to use something like: Just [Google](https://google.com) it! in data/content.yaml and then render it with = markdown (data.content.something) I get following error:

undefined method `link_to' for #<Object:0x000000044f9e18>

Traceback:

/home/myself/.rvm/gems/ruby-2.4.0/gems/middleman-core-4.2.1/lib/middleman-core/renderers/kramdown.rb: in convert_a
    48.		scope.link_to(content, link, attr)	

Does anyone have an idea have to deal with that error? If I use link_to or markdown link directly in my HAML template, all works as expected, without any errors.

Ful example

My data file, data/faq.yaml looks like this:

dog:
  question: I want to know more about a dog.
  answerA: (HTML in data) Just <a href="https://google.com">Google</a> it!
  answerB: (Markdown link in data) Just [Google](https://google.com) it!

Below is my faq.haml template with:

  • Markdown link written directly in HAML, which renders through HAML’s markdown filter
  • Reference to answerA from data with HTML link written directly
  • Reference to answerB from data with same link written with markdown syntax

faq.haml:

.answer
	:markdown
		(HAML) Just [Google](https://google.com) it!
	= markdown(data.faq.dog.answerA)
	= markdown(data.faq.dog.answerB)

First 2 links render propely, but markdown link in answerB throws following error:

undefined method `link_to' for #<Object:0x000000044f9e18>

Traceback:

/home/myself/.rvm/gems/ruby-2.4.0/gems/middleman-core-4.2.1/lib/middleman-core/renderers/kramdown.rb: in convert_a
    48.		scope.link_to(content, link, attr)	

Why is Kramdown unable to convert a markdown link when “asked” to do so via helper from @ecgardner answer, but does it properly when same syntax is used directly in HAML? What can be done, so that markdown link in = markdown(data.faq.dog.answerB) renders properly?

I guess I could use regular expression to convert markdown link to HTML link, prior to passing it to Tilt, but it does not seem to be great solution.

The Tilt template engine was missing the app context. If you change the markdown(text) helper code to the following the error will go away:

def markdown(text)
  Tilt['markdown'].new(context: @app) { text }.render
end
1 Like

Thanks @vvasabi! I made this change and indeed error went away. Links work great now.