Markdown and smartypants are two tools created to markup “standard” text into XHTML-compliant code. In English, they make it way easier to write HTML, i.e. for a blog.

An Evil Trend is powered by Django (which is no secret), and recently I’ve integrated both markdown and smartypants to make it easier for me to post both articles and blog entries. I’ll document the process that I went through, which is basically from a sterile Django installation to one with markdown and smartypants.

step 1: getting the necessary packages

To begin you’ll need to install python-markdown, usually available via apt-get or your distro’s package repository. You’ll also need to grab smartypants.py, which should be copied into your django project’s main directory (usually where your settings.py and urls.py files are).

step 2: making changes to your settings

The next step is to inform django that you’ll be using markdown in your project. While you might at some point want to check out the official documentation, you can just follow along here.

Add the following line to your settings.py file:

INSTALLED_APPS = (
    ...
    'django.contrib.markup',
    ...
)

step 3: using markdown

At this point you’re ready to go with markdown but not smartypants. I use markdown as a template filter: I upload my blog posts in markdown format, then rely on my server to process the text on each page load. This may or not be an acceptable performance hit to you. In that case, follow this additional documentation on how to have the processing happen only once.

Within each template file that will be rendering markdown text include the following line somewhere near the top:

{% load markup %}

This will give you access to the markdown filter, which you can now use like any other filter in a template. I use it like this:

<div class='postcontent'>
    
</div>

That’s it for markdown. Smartypants is a bit different.

step 4: getting smartypants ready

While using markdown is basically a matter of adding two or three lines, smartypants is a bit more involved. That’s not to say it’s hard. Django doesn’t have a smartypants tag built in, so we need to create that tag ourselves. The django documentation outlines the general process.

The next step will differ for you depending on your setup. I have two different django apps for my blog and articles, so I’ll be taking a longer road here. If you really only have one app that needs smartypants, then you can do something a bit more intuitive. Let me explain the latter approach first.

A django app supports user-defined template tags. To create tags for an app you simply add a templatetags folder to the app folder. Go ahead and create a folder like this for whatever app you need smartypants for. Your app directory should look like this:

../some_django_app/
    models.py
    templatetags/
        __init__.py
        smartypants.py
    views.py

Where __init__.py and smartypants.py are two empty files. Going back to above: if you have two or more apps that need the same smartypants filter, it probably makes more sense to do what I did and create a new django app for your custom tags. If this is what you want, go ahead and create a new app:

$ python manage.py startapp custom_tags

And within this new application replicate the directory structure outlined above by adding a templatetags directory with two empty files: __init__.py and smartypants.py. You’ll also need to add this new app to your INSTALLED_APPS setting in settings.py.

Note that the smartypants.py within the templatetags directory is not the same one you downloaded earlier and put in your project directory. This new file will define our custom tag.

step 5: creating the smartypants filter

It’s now time to edit the empty smartypants.py file you created above. This is the code you’ll want to fill it with:

from django import template

register = template.Library()

@register.filter
def smartypants(value):
    try:
        import your_project.smartypants
        return your_project.smartypants.smartyPants(value)
    except:
        return value

This filter will attempt to load smartypants from the project directory. If it doesn’t find it, or has an error, it’ll pass through the value given to it without modification, otherwise it’ll pass it through smartypants.

At this point you’re ready to use the smartypants filter.

step 6: using the smartypants filter

You get to use the smartypants filter in pretty much exactly the same way you used the markdown filter. Near the top of any template that will use the filter you need to include the line:

{% load smartypants %}

This loads in the custom filter you just wrote above. Now use the filter exactly like markdown. I use it like this:

<div class='postcontent'>
    
</div>

Be sure to send your content through markdown before you send it through smartypants.

That’s it! Not exactly three simple steps, but this guide should help you get the job done. It’s not that hard to add these useful apps to your django website, and they’ve certainly made my life a lot easier.