Posts About

Render Markdown in Jinja Templates

When I started development of this site, the general goal was to generate all the static pages from a few template files. I chose Jinja2 as the templating engine, it was perfect for rendering customized HTML markup with some input parameters. To make writing posts easier, I wanted to write each post as a Markdown file and render it into the page. Jinja2 does not have a built-in Markdown renderer, so I used Mistune instead.

I wanted to render the Markdown through a method in the template. Exposing a method to Jinja2 depends on a nested property inside the Jinja2.Environment object:

jinja_env.globals['render_markdown'] = render_markdown

That globals object is a dictionary of symbols available to Jinja2 templates during rendering. It can refer to variables and methods, the latter of which we use to specify Markdown rendering.

The render_markdown method looked something like the following:

def render_markdown(markdown_string):
    return Markup(mistune.html(markdown_string)

You'll notice that rather than return a raw string, we return a markupsafe.Markup object. I found that when I returned a raw string, Jinja2 would always escape the HTML and dump the escaped text. The browser would not render HTML, but plaintext! Returning Markup signals to Jinja2 that we do in fact want to include this text as HTML and not escape it.