E-Scribe : a programmer’s blog

About Me

PBX I'm Paul Bissex. I build web applications using open source software, especially Django. Started my career doing graphic design for newspapers and magazines in the '90s. Then wrote tech commentary and reviews for Wired, Salon, Chicago Tribune, and others you never heard of. Then I built operations software at a photography school. Then I helped big media serve 40 million pages a day. Then I worked on a translation services API doing millions of dollars of business. Now I'm building the core platform of a global startup accelerator. Feel free to email me.


I co-wrote "Python Web Development with Django". It was the first book to cover the long-awaited Django 1.0. Published by Addison-Wesley and still in print!


Built using Django, served with gunicorn and nginx. The database is SQLite. Hosted on a FreeBSD VPS at Johncompanies.com. Comment-spam protection by Akismet.

Pile o'Tags

Stuff I Use

bitbucket, Django, Emacs, FreeBSD, Git, jQuery, LaunchBar, Markdown, Mercurial, OS X, Python, Review Board, S3, SQLite, Sublime Text, Ubuntu Linux

Spam Report

At least 236428 pieces of comment spam killed since 2008, mostly via Akismet.

A minimal wiki in Django

TheWiki I built a proto-wiki in Django as an exercise for learning how to make a custom template filter. It's absurdly easy, it turns out. Per the docs I added a templatetags module; here's all the code in it -- wikitags.py:

from django.core import template
register = template.Library()

def wikify(value):
    "Makes WikiWords"
    import re
    wikifier = re.compile(r'\b(([A-Z]+[a-z]+){2,})\b')
    return wikifier.sub(r'<a href="/\1/">\1</a>', value)

Then, in my page template:

{% load wikitags %}
<h1>{{ page.title }}</h1>
<div class="body">
    {{ page.content|wikify }}

I wrote about 60 lines of Python code in total. There are much smaller wiki engines, of course, but given the flexibility and expandability offered by Django I think that's pretty good.

The source code is available for anyone who'd like to take a look at it. Consider it MIT licensed if for some reason you actually want to use or extend it.

One thing this highlighted for me is that I don't know the best way to package up a Django app for re-use. Making that process easy, well understood, and perhaps even semi-automated will do a lot for Django as people start accumulating serious components.

Update, 2006-02-13: I've modernized the code to work with the "magic-removal" branch of Django.

Monday, December 12th, 2005
+ +

Comment from Luke Plant , later that day

Re: packaging apps, this page might be helpful:


There is a setup.py example included.

Comment from Paul , later that day

Excellent, thanks. I came across that many months ago and then forgot about it. I think it'll be a while before I have anything substantial worth distributing, though...

Comment from dp_wiz , 2 weeks later

Great one! Very very nice and helpfull.

Comment from Paul K , 12 months later

Great tutorial, very to the point. Minor correction, on my version of Django the template module resides in a different place. Not sure if it has to do with Django versions. If you get errors try: (remove core)

from django import template

Comment from Ankur Sethi , 18 months later

A suggestion that if the site were hosted it would be wonderful, we could see it in action.

Comment from Paul , 18 months later

Hi Ankur,

For now, there's an install here: http://demo.e-scribe.com/wiki/

However, it has absolutely no spam or XSS protection, so I won't be leaving it up forever.

Comment from Tom , 18 months later

Hi Paul,

Thank you for this article and for your site in general.

I have a question about protowiki. Why didn't you use the create/update/delete generic views that come with Django?

Thanks, Tom

Comment from Paul , 18 months later

Hi Tom, I can't actually remember why I didn't use generic views with this app. It was originally written over a year and a half ago, which is like 20 in Django years. I think that some of the wiki-specific behavior, like redirecting to an edit page on a 404, might have been more than I wanted to twist generic views to do at the time. In any case, a version that relied more on generic views (wrapping them where needed for special functionality) would be a nice update.

Comment from Tom , 2 years later

Everything:~ tomsmith$ hg clone static-http://hg.open.e-scribe.com abort: HTTP Error 404: Not Found

Everything:~ tomsmith$ hg clone http://hg.open.e-scribe.com destination directory: hg.open.e-scribe.com abort: 'http://hg.open.e-scribe.com/' does not appear to be an hg repository!

Comment from Paul , 2 years later

Sorry about that, Tom -- fixed now!

Comment from machinehuman , 2 years later

Very nice! Do you have plans for spam protection?

Comment from Paul , 2 years later

Thanks! This is not something I'm maintaining, but if I were to implement spam protection I'd likely base it on Akismet, like I do for my blog, possibly with DNSBLs as a first line of defense.

Comment from Sam Rose , 2 years later

is this code still available?

Comment from Josh , 4 years later

Source code link seems broken. Update?

Comment from Paul , 4 years later

This code has definitely fallen by the wayside. Here's a link to it for those who have asked. Be warned: it was last updated around the time of Django 0.96, so it won't run under 1.x without a little tweaking. http://staticfling.net/_temp/protowiki.zip

Comments are closed for this post. But I welcome questions/comments via email or Twitter.