ToscaWidgets JQuery and TinyMCE (Tutorialish-ly)

So you've browsed the ToscaWidgets web-site and know that there's a JQuery Plugin and a TinyMCE (Rich-text-editor control) plugin... now how the heck do you use them?  Not a lot of documentation for these two pieces, so I've tried to cobble together a minimal example.  Fair warning, I'm piecing this together basically without any documentation or examples, so I may be using the widget horribly wrong :) .  Step 1, create the environment:

virtualenv --no-site-packages adminhack
cd adminhack
source bin/activate
easy_install tg.devtools tw.jquery tw.tinymce
paster quickstart adminhack # (choose defaults)
cd adminhack
python setup.py develop
paster setup-app development.ini # create the db

All basically boilerplate stuff, at this point you've got a reasonably-blank TurboGears 2.x application that you could run with:

paster serve development.ini
firefox http://localhost:8080

Okay, now to create a simple TinyMCE editor on your site.  Edit the adminhack/controllers/root.py file (we'll use the root because it's simple and obvious).  We'll import our required packages:

from tg.decorators import validate

from tw.tinymce import TinyMCE, MarkupConverter
from tw.jquery import JQueryCompressed,JQuery

def jquery():
"""Get the appropriate jquery for this configuration

At the moment the non-compressed version of jquery doesn't
appear to be distributed with tw.jquery, so we always return
a JQueryCompressed() instance.
"""
return JQueryCompressed()

We're going to use the tw.tinymce "MarkupConverter" validator so that the value we get back from the control will be cleaned up (as suggested by the tw.tinymce docstrings).  The widgets we want to use are the TinyMCE and the JQueryCompressed objects.  We'd actually *also* like to be able to use the JQuery object, but tw.jquery doesn't seem to install an uncompressed JQuery version when installed, so we'll leave that for later.

We'll create a view (at http://localhost:8080/mcetest) which will create a TinyMCE instance and a JQueryCompressed() instance and pass them into a page template for rendering.  We're going to configure the TinyMCE instance a bit, as the default of using an "exact" mode (whatever that means) doesn't catch our TextArea properly.

    @expose('adminhack.templates.tinymcetest' )
def mcetest( self ):
return dict(
page = 'mcetest',
jquery = jquery(),
long_text_value = """<div>Some testing text</div><div>With two divs</div>""",
mce = TinyMCE(
mce_options = dict(
mode = 'textareas',
width = '100%',
height = '10em',
),
name = 'long_text',
),
)

We also pass in some formatting options for height and width, as the defaults seem to be a bit too aggressive to display properly (at least, on my machines).  The name parameter is the HTML form name for the widget's underlying text-area.

The template we use to render this form is fairly trivial (intentionally).  I'm guessing that "real" ToscaWidgets people would have a ToscaWidgets form object instead of individual widgets, but I want something minimalist for this exploration/example (this file is saved into adminhack/templates/tinymcetest.html):

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:py="http://genshi.edgewall.org/"
xmlns:xi="http://www.w3.org/2001/XInclude">

<xi:include href="master.html" />
${ jquery() }
<head>
<meta content="text/html; charset=UTF-8" http-equiv="content-type" py:replace="''"/>
<title>TinyMCE Test</title>
</head>

<body>
<div id="mce-test">
<form action="mceupdate" id="mainform">
<h2>Example TinyMCE Editor</h2>
${ mce( value = long_text_value ) }
<input type="submit" name="submit" value="Update" />
</form>
</div>
<div class="clearingdiv" />
</body>
</html>

The widgets both have "javascript" attributes which are being converted to simple javascript links which reference the automatically exposed ToscaWidgets "/toscawidgets/resources/" resource tree on your TurboGears server.  The TinyMCE widget also adds a script to the page which does the TinyMCE.init() call with its options (as a json option dictionary).

Lastly, we'll create a method which validates/converts the edited value from the TinyMCE control into a clean, un-escaped Unicode value (i.e. we'll validate it with the provided MarkupConverter), (in the adminhack/controllers/root.py file, again):

    @validate( validators = {
'long_text': MarkupConverter(),
}, error_handler = mcetest )
@expose()
def mceupdate( self, long_text, **named ):
"""Perform update of long text (does nothing)"""
assert long_text
flash( """Received: %r"""%( long_text, ))
redirect( 'mcetest' )

There are apparently lots of TinyMCE options, which you can see in their wiki.  As mentioned earlier, these are just my notes on trying to hack my way through getting TW.TinyMCE working, it's quite likely there are easier ways to go about doing all of this.

Comments

  1. alexbodn

    alexbodn on 09/29/2009 7:03 p.m. #

    hello,

    thanks for the tutorial.
    first, you may wish to use more modern tw.tinymce3 that uses (and hence depends on and imports) tw.jquery by itself.
    second, tw provides an even stronger and shorter way to define and display forms: tw.forms.
    but if you wish to use a standalone widget, you may use it's save feature, that will invoke a controller like mceupdate by ajax.

    hth,
    alex

Comments are closed.

Pingbacks

Pingbacks are closed.