Code


Version 2 (modified by John D'Agostino <john.dagostino@…>, 7 years ago) (diff)

--

Custom Widgets - TinyMCE

Please Note - django.newforms is a work in progress

With the introduction of the newforms module in revision 3944 came the functionality to create custom widgets for forms. Outlined below is the process of creating a custom reusable TinyMCE widget.

To start the custom widget, create a custom_widgets.py file in your project folder

for the TinyMCE widget i used the code below

from django.newforms import *
from django.newforms.widgets import flatatt
from django.utils.html import escape
from django.utils.simplejson import *
        
class TinyMCE(Textarea):
    """
    TinyMCE widget. requires you include tiny_mce_src.js in your template
    you can customize the mce_settings by overwriting the instance
    mce_settings, or add extra options using update
    """ 
    mce_settings = dict(
        mode = "exact",
        theme = "simple",
        theme_advanced_toolbar_location = "top",
        theme_advanced_toolbar_align = "center",
    )    
             
    def update(self, custom):
        return_dict = self.mce_settings.copy()
        return_dict.update(custom)
        return return_dict
    
    def render(self, name, value, attrs=None):
        if value is None: value = ''
        final_attrs = dict(self.attrs, name=name, id=name)
        if attrs:
            final_attrs.update(attrs)        
            
        self.mce_settings['elements'] = name
        mce_json = JSONEncoder().encode(self.mce_settings)
        
        return u'<textarea %s >%s</textarea> <script type="text/javascript"> \
                 tinyMCE.init(%s)</script>' % (flatatt(final_attrs), escape(value), mce_json)

in the views.py file, replace myproject with your project name

from myproject.custom_widgets import TinyMCE
from django.newforms import Form
from django.newforms.widgets import Textarea
from django.newforms.fields import CharField
from django.shortcuts import render_to_response

modified_settings = { "auto_resize" : True }

class TestForm(Form):
    #test with custom settings
    test_mce = CharField(widget=TinyMCE())
    test_mce.widget.mce_settings = test_mce.widget.update(modified_settings)

    #test with no custom settings    
    another_test = CharField(widget=TinyMCE())

    #plain old textarea
    plain_textarea = CharField(widget=Textarea)

def index(request):
    test_form = TestForm()
    return render_to_response('template.html', {'form': test_form })

in your template file simply add the following, replace http://localhost/ with the location of the tinyMCE source served obviously on your media server.

<html>
<script src="http://localhost/tiny_mce/tiny_mce_src.js"></script>
<head>
    
</head>
<body>

{{ form }}

</body>

<html>

This implementation isn't perfect by all means

  1. It requires the template author to include the javascript file.
  2. tinyMCE.init() is called each time the widget is used, this gives the benefit that you can have multiple tinyMCE text boxes with different settings.
  3. ????

This is as far as I've progressed I haven't yet tested with a Model, validation etc. - if you do please add your experience here.

Any Feedback/Comments please don't hesitate to email me at john.dagostino AT gmail DOT com