Search code examples
djangomarkdowndjango-template-filters

Markdown Template does not render HTML Correctly


I have created a Markdown Filter in my Django Website. I have used the library markdown2.

Though the HTML does render, it does not render it entirely. The Code and Syntax Highlights, URLs and Lists do not render properly.

templatetags folder

filename: ttags.py

from django.template import Library
import markdown2

register = Library()

@register.filter('markdown_to_html')
def markdown_to_html(markdown_text):
    htmlversion=markdown2.markdown(markdown_text)
    return htmlversion

templatefile

{% extends "layout.html" %}
{% load ttags %}
{% load static from staticfiles %}

{% block content %}

<div class="content">
{{ step.description | markdown_to_html | safe }}
</div>

{% endblock %}

The Text that was provided to be rendered was as below

##### Usage of Variables

```python
name = "David"
age = 10
```

In the above example name and age are variables that store Text and Numbers respectively.

> Always remember to use Variables in your programs to store information.

The HTML Code of the Rendered Output was as below

<h5>Usage of Variables</h5>

<p><code>python
name = "David"
age = 10
</code></p>

<p>In the above example name and age are variables that store Text and Numbers respectively.</p>

<blockquote>
  <p>Always remember to use Variables in your programs to store information.</p>
</blockquote>

The Code Syntax does not display in two lines


Solution

  • You need to enable the fenced code blocks extension, which is not a standard Markdown feature. In your filter definition do this:

    htmlversion = markdown2.markdown(markdown_text, extras=['fenced-code-blocks'])
    

    Note the addition of the extras keyword argument passed to markdown2.markdown. If you want syntax highlighting to also work you will need to have pygments installed and a copy of the relevant CSS files to define the highlighting styles.

    I have no experience with and have never used the Markdown2 library. So how can I be sure this is correct? Note that the fenced code block:

    ```python
    name = "David"
    age = 10
    ```
    

    Was getting rendered to:

    <p><code>python
    name = "David"
    age = 10
    </code></p>
    

    The entire contents of the fenced code block, including the language identifier are being wrapped in an inline code span (<p><code>), not a code block (<pre><code>). This suggests that the Markdown parser is interpreting the backticks as a code span, not a code block. As fenced code blocks are not part of the original Markdown rules, we can only assume that the parser, like most, does not support fenced code blocks by default. In fact, a quick check of the documentation shows that fenced code blocks need to be enabled via an extension for them to work.