TinyMCE and Related Madness
First of all, I find WYSIWYG editors to be about as exciting as pinching your finger in a door. Personally, I dislike them. I don't like how difficult they can be to set up, I don't like the code they produce on the page, and i don't like the general idea that your CMS backend is being made to look like Microsoft Word. However, they are an inexorable connection to the real world- the real world that consist of people who want to publish on the web but are not developers. (These are the people who pay the developers, so its a good idea to meet them where they are).
So with that in mind, I endeavored to set up one of the more popular and well-known WYSIWYG editors, TinyMCE, on this very blog. Upon getting it to work and documenting how I did it, I intend to remove it and use Markdown going forward, but that is a different story.
First of all, there are few things to acquire- namely, a current version of the TinyMCE code. I used v 3.4.7. Once you download and extract this archive, you'll see there is quite a bit of stuff included. Hold onto it, but all we will need is the tiny_mce
directory inside the /tinymce/jscripts
directory. (All we want is the jelly inside the jelly donut). Place the tiny_mce
directory in a place where your app can access it. In my case, I put it in /static/js/
.
Next, you'll want to install django-tinymce into your virtualenv:
$ pip install django-tinymce
Add tinymce to your INSTALLED_APPS in settings.py:
INSTALLED_APPS = (
...
'tinymce',
)
Your app will need to know where the scripts are, so add these to settings.py:
TINYMCE_JS_URL = os.path.join(STATIC_URL, 'js/tiny_mce/tiny_mce.js')
TINYMCE_JS_ROOT = os.path.join(STATIC_ROOT, 'js/tiny_mce')
I opted for a few more settings as well (these are personal preference based on combing through the TinyMCE Conifguration Page ). Add to settings.py:
TINYMCE_DEFAULT_CONFIG = {
'plugins': "table,paste,searchreplace,advimage",
'theme': "advanced",
'relative_urls': False,
'cleanup_on_startup': True,
'auto_cleanup_word' : True,
'custom_undo_redo_levels': 10,
'paste_auto_cleanup_on_paste' : True,
'extended_valid_elements' : "a[name|href|target=_blank|title|onclick],img[class|src|border=0|alt|title|hspace|vspace|width|height|align|onmouseover|onmouseout|name],hr[class|width|size|noshade],font[face|size|color|style],span[class|align|style]",
'theme_advanced_buttons1' : "bold,italic,underline,|,justifyleft,justifycenter,justifyright,justifyfull,|,link,unlink,image,styleselect,formatselect,removeformat,cleanup,|,bullist,numlist,outdent,indent,hr,blockquote,replace,|,code",
}
TINYMCE_SPELLCHECKER = False
TINYMCE_COMPRESSOR = False
TINYMCE_FILEBROWSER = True
Next, add tinymce.urls to your urls.py:
urlpatterns = patterns('',
...
(r'^tinymce/', include('tinymce.urls')),
)
Now that your configuration is squared up, you will need to tell the Django admin which field to invoke the TinyMCE widget on.
If, for example, your app named "blog" needed some WYSIWYG love on the textfield "Body" in the model "Entry", you would add the following to /blog/admin.py
:
from tinymce.widgets import TinyMCE
...
class EntryAdminForm(forms.ModelForm):
body = forms.CharField(widget=TinyMCE(attrs={'cols': 80, 'rows': 30}), label=u'Body', required=False)
class Meta:
model = Entry
With any luck, you should now see TinyMCE goodness on the "Body" field.
For reference, I am using a virtualenv with the following versions:
Django==1.4.1
Markdown==2.2.0
Pillow==1.7.7
South==0.7.6
disqus==0.0.4
django-debug-toolbar==0.9.4
django-filebrowser==3.5.0
django-grappelli==2.4.2
django-tinymce==1.5.1b2
gunicorn==0.15.0
wsgiref==0.1.2
References
- http://www.tinymce.com/
- https://github.com/aljosa/django-tinymce
- https://code.djangoproject.com/wiki/AddWYSIWYGEditor