A Syntax Coloring Template Filter for Django

08/09/2008

I spent a bit of time this evening putting together a template filter for Django that allows really trivial syntax coloring from within the templates themselves. You can access any of the Pygments lexers, or can attempt to have Pygments detect the appropriate lexer on its own. Here is a quick example:

{% load syntax_color %}
<p> Specifying the lexer for the snippet. </p>
{{ my_code_snippet|colorize:"ruby" }}
<p> Letting Pygments guess the lexer. </p>
{{ my_code_snippet|colorize }}
<p> Adding line numbers as well. </p>
{{ my_code_snippet|colorize_table }}
</p> <code>colorize_table</code> can take an argument as well.</p>
{{ my_code_snippet|colorize_table:"html+django" }}

This may not be tremendously helpful, but I think it's a nice example of how a simple template filter can do something fairly impressive. Read on for the installation details, or you can download the syntax_colorize app here.

Installation and Usage

  1. Install the Pygments library. The easiest way is via easy_install.

    sudo easy_install pygments
    

  2. Download the syntax_colorize app. You can grab it here.

  3. Place the syntax_colorize app in your Python path. For OS X 10.5 it'll be something like this:

    ln -s /Users/will/libraries/syntax_colorize /Library/Python/python2.5/site-packages/syntax_colorize
    
  4. Add it to your INSTALLED_APPS setting.

    INSTALLED_APPS = (
      'django.contrib.sites',
      'syntax_colorize',
      'etc etc',
    )
    

  5. Create the CSS files for Pygments. I created a simple helper function in the syntax_colorize/templatetags/syntax_color.py file, so simply navigate to the directory and fire up Python:

    cd syntax_colorize/templatetags/syntax_color.py
    python
    

    And then run these commands at the interpreter:

    >>> import syntax_color
    >>> syntax_color.generate_pygments_css()
    

    Then copy the created pygments.css file into your media directory.

  6. Update your base template's head tag so that it includes the pygments.css file. That will look something like:

    <head>
    <link rel="stylesheet" href="/media/pygments.css" type="text/css">
    </head>
    
  7. Create a simple view that will pass a template a snippet of code. The simple example I've used for testing looked like this:

    from django.shortcuts import render_to_response
    def index(request):
        code = """def index(request):
        from django.shortcuts import render_to_response
        code = "(define x 10)"
        return render_to_response('index.html',{'code':code})
    """
        return render_to_response('index.html',{'code':code})
    

    In a real use case you might be pulling the code from a database, or perhaps BigTable if you're using the GoogleAppEngine.

  8. Now fire up the Django template where you're interested in using the syntax coloring. Remember that the context contains the variable code which is a string containing some Python code. Coloring the contents of code with the Python lexer will look like this:

    {% load syntax_color %}
    <p> Take a look at this code: </p>
    {{ code|colorize:"python" }}
    <p> Oh. Maybe you wanted it in a table? </p>
    {{ code|colorize_table:"python" }}
    

    Using the colorize_table filter creates the syntax colored snippet inside of a table with line numbering, but is otherwise the same as the colorize filter.

I hope that this snippet is useful, and let me know if you have any suggestions, comments or complaints.

Update 8/12 4:42 PM

I created a GitHub repository for this project. You can access it here. If you don't want to visit the GitHub page, you can use git to clone a local copy:

git clone git://github.com/lethain/django-syntax-colorize.git
mv django-syntax-colorize syntax_colorize

Renaming the directory isn't strictly necessary, but otherwise the above instructions won't work verbatim.

All Rights Reserved, Will Larson 2007 - 2014.