Render the markdown in django


Problem

We'd like to render the markdown content in Django web site.

Prerequisite

install requirements

$pip3 install django  #install the django
$pip3 install virtualenv # install virtualenv
$pip3 install Markdown # install markdown lib

Let's get started

Before we get stared, we should create the django project with django-admin startproject, we can create the project called blog:

$django-admin startproject blog
$cd blog 
$python3 manage.py startapp md

To render the markdown content, the django have template filter, that take markdown string as input and rendered markdown as HTM. We expected we can use the tag in template like:

{{ blog_content | markdown }}

Setup the templatetags folder

the Django have convention that put all customized tag into folder of templatetags, so we create the templatetags folder:

$mkdir md/templatetags

Create Django filter to render markdown

After that we create the markdown_extras.py module and we will create the django filter that render the markdown content in this module:

markdown_extras.py

from django import template
from django.template.defaultfilters import stringfilter

import markdown as md

register = template.Library()


@register.filter()
@stringfilter
def markdown(value):
    return md.markdown(value, extensions=['markdown.extensions.fenced_code'])

We enabled rendering the code block with markdown.extensions.fenced_code extension. The directory structure now become:

├── blog
│   ├── __init__.py
│   ├── __pycache__
│   │   ├── __init__.cpython-36.pyc
│   │   └── settings.cpython-36.pyc
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
├── manage.py
└── md
    ├── __init__.py
    ├── admin.py
    ├── apps.py
    ├── migrations
    │   └── __init__.py
    ├── models.py
    ├── templatetags
    │   └── markdown_extras.py
    ├── tests.py
    └── views.py

Setup Django project scaffold to render markdown content

setup urls.py

from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('md/', include('md.urls')),
]

setup views.py

from django.shortcuts import render

def content(request, id):
    return render(request, 'md/test.html', {'content': 
        '# this is test title\n' + 
        '- list 1\n' +
        '- list 2\n'
    })

setup templates/md/test.html

{% load markdown_extras %}

{{ content | markdown | safe }}

We already render the markdown content as HTML, so that we should tell Django do not encode it again with safe tag.

register the md module in blog/settings.py

adding the 'md.apps.MdConfig' to your existing INSTALLED_APPS

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'md.apps.MdConfig',
]

Test the output

To test the render result, we can start up the developement server built in django, with command:

$python3 manage.py runserver

Then open your browser, visit: http://127.0.0.1:8000/md/1, you will find the content have been rendered as proper html.

published at May 20, 2018, 9:08 a.m.

Comments:

Sharing your thoughts: