Code


Version 9 (modified by seemant+django@…, 7 years ago) (diff)

spelling fix

RichTextField

A attempt at integrating tinymce completely as a own field that has the capability to save a copy as utf-8 in another field for searchability.

Adding the field type

project_dir/local_models.py

from django.utils.html import escape
from django.forms import LargeTextField 
from django.db.models.fields import Field
from django.dispatch import dispatcher
from django.db.models import signals
from django.conf import settings

class TextFieldWithClass(LargeTextField):
    def __init__(self, css_class='', plaintext_field=None, *args, **kwargs):
        self.css_class, self.plaintext_field = css_class, plaintext_field
        LargeTextField.__init__(self, *args, **kwargs)

    def render(self, data):
        if data is None:
            data = ''
        if isinstance(data, unicode):
            data = data.encode(settings.DEFAULT_CHARSET)

        css_class = ''
        if self.css_class != '':
            css_class = ' ' + self.css_class

        return '<textarea id="%s" class="v%s%s%s" name="%s" rows="%s" cols="%s">%s</textarea>' % \
            (self.get_id(), self.__class__.__name__, self.is_required and ' required' or '',
            css_class, self.field_name, self.rows, self.cols, escape(data))

class RichTextFieldWithClass(Field):

    def __init__(self, css_class='', plaintext_field=None, *args, **kwargs):
        self.css_class, self.plaintext_field = css_class, plaintext_field
        Field.__init__(self, *args, **kwargs)

    def set_plaintext_field(self, instance=None):
        from genshi.core import Markup
	plain = Markup(getattr(instance, self.attname)).striptags().stripentities().encode('utf-8')
        setattr(instance, self.plaintext_field, plain) 

    def contribute_to_class(self, cls, name):
        super(RichTextFieldWithClass, self).contribute_to_class(cls, name)
	if self.plaintext_field:
            dispatcher.connect(self.set_plaintext_field, signals.pre_save, sender=cls)

    def prepare_field_objs_and_params(self, manipulator, name_prefix):
        field_objs, params = super(RichTextFieldWithClass, self).prepare_field_objs_and_params(manipulator, name_prefix)
        params['css_class'], params['plaintext_field'] = self.css_class, self.plaintext_field
        return (field_objs, params)

    def get_manipulator_field_objs(self):
        return [TextFieldWithClass]

    def get_internal_type(self):
        return 'TextField'

Adding the neccesary javascript

Unpack tinymce so tiny_mce.js ends up here: /media/js/tinymce/jscripts/tiny_mce/tiny_mce.js

Remember this javascript must be on the same domain as the admin or it won't work.

/media/js/tmce.js

	tinyMCE.init({
		mode : "specific_textareas", // only specific textareas
                editor_selector : "mceEditor", // specified by the mceEditor class
		theme : "advanced",
		plugins : "table,save,advhr,advimage,advlink",
		theme_advanced_buttons1 : "bold,italic,underline,strikethrough,sub,sup,removeformat,charmap,separator,justifyleft,justifycenter,justifyright,bullist,numlist,outdent,indent,separator,formatselect,styleselect,code",
        theme_advanced_buttons2 : "cut,copy,paste,separator,search,replace,image,link,anchor,separator,tablecontrols",
		theme_advanced_buttons3 : "",
		theme_advanced_toolbar_location : "top",
		theme_advanced_toolbar_align : "left",
		theme_advanced_path_location : "bottom",
		theme_advanced_styles : "Left=left;Right=right;", // possible classes
        content_css : "/media/js/tmce.css", // add css styles
	    plugin_insertdate_dateFormat : "%Y-%m-%d",
	    plugin_insertdate_timeFormat : "%H:%M:%S",
		extended_valid_elements : "a[name|href|target|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]",
        width : "640", height : "350" // set size of field
	});

Using the field in the model

project_dir/appdir/models.py

from django.db import models
from local_models import RichTextFieldWithClass

class Page(models.Model):
        
    label = models.CharField(maxlength=255)
    text = RichTextFieldWithClass(css_class='mceEditor', plaintext_field='plaintext')
    plaintext = models.TextField() # optional            optional argument, requires genshi from edgewall

    def __repr__(self):
        return self.label
        
    class Admin:
        js=['../js/tinymce/jscripts/tiny_mce/tiny_mce.js', '../js/tmce.js']