Friday, May 1, 2009

Extending Admin Forms in Django

So I've decided to start a blog, because well it seems no one will take you seriously if you don't have one these days for some reason. I've been using the basic-apps blog engine as I've used this before to implement a simple news section for a client. I like it because it provides the basic functionality of a blog engine, and leaves you free to implement all the bells and whistles yourself.

One feature I wanted to add was a WYSIWYG editor for the blog posts and flatpages. I found a neat little tutorial on using markItUp! for the textarea inputs. The problem is that this tutorial was written with the purpose of adding this as a core feature to an application, not extending an existing one.

Thankfully, with newforms-admin, this is really easy in Django.
First we need to define the markItUp! widget (as described in the tutorial):

from django import forms

class MarkItUpWidget(forms.Textarea):
    class Media:
        js = (
            'js/jquery.js',
            'js/markitup/jquery.markitup.pack.js',
            'js/markitup/sets/markdown/set.js',
            'js/init_markitup.js',
        )
        css = {
            'screen': (
                'js/markitup/skins/simple/style.css',
                'js/markitup/sets/markdown/style.css',
                )
        }

I use a package in my projects called "local", which I use for local modifications to 3rd part and contrib applications. I added this to local/admin.py

from django.contrib import admin
from django.contrib.flatpages.admin import FlatpageForm, FlatPageAdmin
from django.contrib.flatpages.models import FlatPage

class LocalFlatPageForm(FlatpageForm):
    content = forms.CharField(widget=MarkItUpWidget)

class LocalFlatPageAdmin(FlatPageAdmin):
    form = LocalFlatPageForm

admin.site.unregister(FlatPage)
admin.site.register(FlatPage, LocalFlatPageAdmin)
Then add this to the root urls.py
admin.autodiscover()
import local.admin

It's that simple, my flatpages now use the markItUp! editor.

NOTE: I am using markdown to render flatpages now, if you do the same you will need to rewrite your flatpage templates.