Rich text editor in Django

Many people often want What You See Is What You Get (WYSIWYG) editors when creating content from within their web applications. This can be either in the Django admin control panel or for the end user. One of the most flexible and useful of the WYSIWYG editors currently available is TinyMCE due to its extensive plugin library and robust feature set. Integration with Django is relatively simple given that you extend the functionality of built in classes.

The first thing we will need to do is create a custom widget from forms.Textarea found in the django.forms module. We accomplish this by inheriting the Textarea class and overriding the constructor and render methods. Defining the relative path (on your web server) to the TInyMCE javascript source is also required here. So be aware that you will need to change that path to suite your environment. You may also want to change the content_css variable to include your sites’ main CSS file. The following is the source code for widgets.py which should be place in your projects root directory.

widgets.py

from django import forms
from django.conf import settings
from django.utils.safestring import mark_safe

class AdvancedEditor(forms.Textarea):
class Media:
js = ('/static/tiny_mce/tiny_mce.js',)

def __init__(self, language=None, attrs=None):
self.language = language or settings.LANGUAGE_CODE[:2]
self.attrs = {'class': 'advancededitor'}
if attrs: self.attrs.update(attrs)
super(AdvancedEditor, self).__init__(attrs)

def render(self, name, value, attrs=None):
rendered = super(AdvancedEditor, self).render(name, value, attrs)
return rendered + mark_safe(u'''
<script type="text/javascript">
tinyMCE.init({
mode: "textareas",
theme: "advanced",
plugins: "advhr,table,emotions,media,insertdatetime,directionality",
theme_advanced_toolbar_align: "left",
theme_advanced_toolbar_location: "top",
theme_advanced_buttons1:"bold,italic,underline,strikethrough,sub,sup,separator,justifyleft,justifycenter,justifyright,justifyfull,separator,formatselect,fontselect,fontsizeselect",
theme_advanced_buttons2:"bullist,numlist,outdent,indent,ltr,rtl,separator,link,unlink,anchor,image,separator,table,insertdate,inserttime,advhr,emotions,media,charmap,separator,undo,redo",
theme_advanced_buttons3: "",
content_css: "/static/images/style.css",
height: "350px",
width: "653px"
});
</script>''')

Now we need to create our form which enables us to use the new widget. Just as an example, we will make a form for use in the Django admin control panel: to show how to use the widget in model admin classes. We simply create  a standard ModelForm class as normal, except that the field you wish to use as your WYWISWYG editor must be a CharField. In my example, I create a simple form for use in the Django admin control panel to allow users to write news articles with advanced editing capabilities. You can do this for any class within any of your forms.py files in either the projects’ main directory or within an application directory. The code is as follows:

forms.py

from django import forms
from .widgets import AdvancedEditor
from .models import Product
class ProductModelAdminForm(forms.ModelForm):
class Meta:
model = Product
exclude = ('slug',)
widgets = {
            'description': AdvancedEditor(),
            } 
As you can see, we imported the AdvancedEditor class we created earlier including the Article class which represents the model we wish to associate the form with. Notice the widget for the content field has been set to AdvancedEditor(). Now we can modify our ModelAdmin class to utilize our form and thus allow us to use TinyMCE within the Django admin control panel. In my admin.py file, the code is as follows:

admin.py

from django.contrib import admin
from .models import Product
from .forms import ProductModelAdminForm
class ProductAdmin(admin.ModelAdmin):
list_display = ('short_image', 'name','category','short_description','available','catalogue','created_at','updated_at')
  list_filter = ('category',)
  form = ProductModelAdminForm
admin.site.register(Product, ProductAdmin)
Here we import the model admin form we created in the last code segment. The only difference here from a normal ModelAdmin class is that we define the form field. We set this field to our form class, in this case: ArticleModelAdminForm. When finally run, the result will look something like this:


Remember that we used an example using the Django admin control panel just to show how to do it. But you can take this concept and apply it anywhere in your Django web application where you can utilize forms. Which allows you to make very rich, usable web applications very easily. Hope this helps, comment with any questions or remarks.

Comments

Popular posts from this blog

Python mechanize For Browsing

Django Dynamic Formsets with Jquery

Editor TinyMCE in Django admin