« links for 2006-05-24 | Main | Is The Desktop UI Metaphor Dead? »

Using TinyMCE in Django's admin

After a few failed attempts, I managed to get TinyMCE running inside Django's Admin. This is nice for editing html fragments and suchlike. Here's what to do.

First, download TinyMCE and unpack it into the media folder in Django. For example, if the path to your Django Admin is:

   /usr/local/python24/site-packages/django/contrib/admin/media

then put the TinyMCE js folder (in the distro this tinymce/jscripts/tiny_mce) here:

   /usr/local/python24/site-packages/django/contrib/admin/media/tiny_mce

Here's a grab from Windows showing what you should end up with:

tinymce-in-django-admin

Configure the TinyMCE pane. In the django/contrib/admin/media/js folder, add a textareas.js file that will initialize and configure TinyMCE. Here's another grab from Windows showing what you should have:

tinymce-in-django-admin-config


I used the AddWYSIWYGEditor configuration from the Django Wiki for this. It's a minimal setup that grabs all textareas on the page and applies TinyMCE to them. You can download the configuration from here as well: textareas.js.

That's Django Admin set up.

Now let's configure a Model class to use a rich edit area. Here's a model called StaffBio that isn't configured to use TinyMCE:

    class StaffBio(models.Model):
        name = models.CharField("Name", maxlength=128,db_index=True)  
        position =    models.CharField("Position", maxlength=128,db_index=True)  
        bio = models.TextField("Biography")
        fote = ImageField("Photo", null=True, 
               blank=True, upload_to="E:/home/dev/storage/StaffBio/fote")
        pageorder = models.IntegerField("Appearance on bio page",
                  choices=SITEORDER_CHOICES, db_index=True)  
        jobcat = models.CharField(maxlength=1, 
                  choices=JOBCAT_CHOICES, db_index=True, default='P')
        
        def __repr__(self):
            return self.name
    
        class Meta:
            ordering = ['name', 'jobcat', 'status']
            verbose_name = "Staff  Bio"
        
        class Admin:
            fields = (
                ('Content', {'fields': ('name','position','bio','fote', 'jobcat', 'pageorder')}),
                ) 
            list_display = ( 'name', 'jobcat' )
            list_filter = ['status', 'jobcat']
            search_fields = ['name']

In Django's regular admin setup it will look like this:

staffbio-poor

To configure it, we need to add one line to the Admin class - a 'js' array field - like this:

    class StaffBio(models.Model):
        name = models.CharField("Name", maxlength=128,db_index=True)  
        position =    models.CharField("Position", maxlength=128,db_index=True)  
        bio = models.TextField("Biography")
        fote = ImageField("Photo", null=True, 
               blank=True, upload_to="E:/home/dev/storage/StaffBio/fote")
        pageorder = models.IntegerField("Appearance on bio page",
                  choices=SITEORDER_CHOICES, db_index=True)  
        jobcat = models.CharField(maxlength=1, 
                  choices=JOBCAT_CHOICES, db_index=True, default='P')
        
        def __repr__(self):
            return self.name
    
        class Meta:
            ordering = ['name', 'jobcat', 'status']
            verbose_name = "Staff  Bio"
        
        class Admin:
            fields = (
                ('Content', {'fields': ('name','position','bio','fote', 'jobcat', 'pageorder')}),
                ) 
            list_display = ( 'name', 'jobcat' )
            list_filter = ['status', 'jobcat']
            search_fields = ['name']
            js = ['tiny_mce/tiny_mce.js', 'js/textareas.js']

The js field allows you to set javascript for the admin screens. The array itself contains links to the textareas.js file and to the base tiny_mce.js script. One thing to note here is that each link is relative - as of May 2006, Django admin will automatically prepend these links with whatever the value of ADMIN_MEDIA_PREFIX is in your settings.py file (this tripped me up initially).

And that's it. When you go back to your admin and refresh, you'll have a rich text area courtesy of TinyMCE.

staffbio-rich

No doubt the admin is workable with Kupu or FCKEditor if that's your preferred html editor. For me, TinyMCE made sense as it was easy to set up and there was a existing configuration on the Wiki.

The next thing I want to do is install TinyMCE as the default Django Flatpage editor; that will require patching the existing admin module, and probably adding a flag to settings.py to enable/disable it. It would be nice too if the setting was global instead of having to markup each model's Admin class. The only way I've seen to do that to date is to create a new model field called RichTextField that brings in the js editor by default. But that mixes up content authoring concerns with modelling concerns by subclassing forms.TextField, which is why I decided not to go that route. I think hacking the Admin module to be wysiwyg configurable is cleaner, the problem is deciding what js tool to bundle. In the long run I imagine admin will ship with Dojo editor since Dojo is what the Django guys have settled on (and Dojo editor can deal with the back button as well which is *very* cool).


May 24, 2006 04:30 PM

Comments

Scott Mark
(May 24, 2006 06:18 PM #)

We switched to TinyMCE about a year ago for WYSIWYG on admin forms, and have been pretty happy with it. Nice docs and good examples, much more straightforward to config than other things we have used.

However, in implementing TinyMCE and trying to get it right, we discovered that IE was responsible for a lot of the source HTML mangling that we couldn't "turn off" in TinyMCE - works much nicer in Mozilla/Firefox.

Post a comment

(you may use HTML tags for style)




Remember Me?

Trackback Pings

TrackBack URL for this entry:
http://www.dehora.net/mt/mt-tb.cgi/1880