Table of Contents
This page contains miscellaneous recipes for custom widgets and widget usage. Feel free to add your own recipe!
Contributed by: Christopher Arndt
This is a simple widget class that allows to easily create image links which use the Google chart API to display nice diagrams and graphs.
See the docstring for usage information. You can also download an example project built with TurboGears 1.1, which showcases a few simple graphs created with this widget. The example project also contains the the code below in the googlecharts.py module file.
The example code is attached to this page and can be downloaded here:
Here’s a simple example of a chart image link created with this widget:
<img
src="http://chart.apis.google.com/chart?cht=p3&chs=350x150&chl=Python|Perl|PHP&chd=t:60,15,25"
height="150"
class="googlechart"
width="350">
And here is the resulting image delivered by the Google chart web service:
And, finally, here’s the widget code. There are many possibilities for enhancing this widget. Please use this as a base for your own experiments!
from turbogears import widgets
class GoogleChart(widgets.Widget):
"""A simple widget to display Google Chart image links.
Example usage::
widget = GoogleChart(attrs={'class': 'googlechart'},
width=500, height=200)
widget.display((('Python', 60), ('Perl', 15), ('PHP', 25)))
or::
widget.display(dict(Python=60, Perl=15, PHP=25), type='bvs')
or::
widget.display([60, 15, 25], labels=['Python', 'Perl', 'PHP'],
type='bhs')
The widget value is taken as the chart data. It can be either a simple list
or tuple of values, a list or tuple of (label, value) items or a dictionary
with label=value items.
"""
template="""\
<img xmlns:py="http://purl.org/kid/ns#"
src="${api_base_uri}?cht=$type&chs=$size&chl=$labels&chd=$data"
width="$width"
height="$height"
py:attrs="attrs"
/>
"""
params = ['api_base_uri', 'attrs', 'type', 'width', 'height', 'labels']
params_doc = dict(
attrs = 'Dictionary containing extra (X)HTML attributes for the IMG tag',
api_base_uri = 'The base URI of the Google Chart web service',
type = "The code for the chart type (default: 'p3' (a pie chart))",
width = "The width of teh chart image in pixels",
height = "The height of the chart image in pixels",
labels = "The labels for the chart data values. Can be a tuple or list"
" of values or a string of values separated by pipe symbols ('|')"
)
api_base_uri = 'http://chart.apis.google.com/chart'
attrs = {}
height = 150
labels = []
type = 'p3'
width = 250
def update_params(self, params):
super(GoogleChart, self).update_params(params)
value = params.get('value', [])
labels = params.get('labels', [])
if isinstance(value, dict):
# value is a dict of label=value items
value = value.items()
if isinstance(value, (list, tuple)):
if value and isinstance(value[0], (list, tuple)):
# value is a list of (label, value) items
params['labels'] = "|".join([i[0] for i in value])
params['data'] = "t:" + ",".join([str(i[1]) for i in value])
else:
# value is a list of values
params['data'] = "t:" + ",".join([str(i) for i in value])
else:
params['data'] = value
# explicit 'labels' keyword arg overrides labels in data list or dict
if labels and isinstance(labels, (list, tuple)):
params['labels'] = "|".join(list(labels))
params['size'] = "%sx%s" % (params['width'], params['height'])
Contributed by: Christoph Zwerschke
This recipe shows how you can easily embed any Flash Player content on your pages with a TurboGears widget using SWFObject.
This is how a basic FlashWidget class can be defined (modify the template and the parameters as appropriate):
from pkg_resources import resource_filename
from turbogears import url, util, widgets
from turbogears.widgets import Widget, JSLink, JSSource
this_package = util.get_package_name()
static = resource_filename(this_package, 'static')
widgets.register_static_directory(this_package, static)
class FlashWidget(Widget):
"""Embeds Adobe Flash Player content using SWFObject 2.
We assume that you're only using one of these widgets per page.
See http://code.google.com/p/swfobject for info on SWFObject.
"""
params = 'name base title width height flash_vars'.split()
object_id = 'flashwidget'
base = '/static/flash'
width, height = 550, 400
flash_version = '9.0.0'
get_flash_url = 'http://www.adobe.com/go/getflashplayer'
get_flash_button = 'http://www.adobe.com/images/shared/' \
'download_buttons/get_flash_player.gif'
javascript=[JSLink(this_package, 'javascript/swfobject.js'),
JSSource("swfobject.registerObject('flashwidget', '%s', '%s');"
% (flash_version, url(base + '/expressInstall.swf')))]
template = """
<div xmlns:py="http://purl.org/kid/ns#" py:strip="True">
<h2 py:if="title" py:content="title">Title</h2>
<object id="%s"
classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
width="$width" height="$height">
<param name="base" value="$base"/>
<param name="movie" value="$name"/>
<param name="play" value="true"/>
<param name="loop" value="false"/>
<param name="menu" value="true"/>
<param name="quality" value="high"/>
<param name="scale" value="showall"/>
<param name="FlashVars" value="$flash_vars"/>
<!--[if !IE]>-->
<object type="application/x-shockwave-flash"
codebase="$base" data="$name"
width="$width" height="$height">
<param name="base" value="$base"/>
<param name="play" value="true"/>
<param name="loop" value="false"/>
<param name="menu" value="true"/>
<param name="quality" value="high"/>
<param name="scale" value="showall"/>
<param name="FlashVars" value="$flash_vars"/>
<!--<![endif]-->
<p> </p>
<div style="width:${width}px;">
<a href="%s"><img src="%s"
align="right" border="0" hspace="16" vspace="2"
alt="Get Adobe Flash player"/></a>
<p style="text-align:left">You need an up to date version
of the Adobe Flash Player to view this content.</p>
</div>
<p> </p>
<!--[if !IE]>-->
</object>
<!--<![endif]-->
</object>
</div>
""" % (object_id, get_flash_url, get_flash_button)
def __init__(self, name, title=None, flash_vars=None,
width=None, height=None, *args, **kwargs):
Widget.__init__(self, *args, **kwargs)
if not '.' in name:
name += '.swf'
self.base = url(self.base)
self.name = url([self.base, name])
self.title = title
if isinstance(flash_vars, dict):
flash_vars = ['%s=%s' % item for item in flash_vars.items()]
if isinstance(flash_vars, list):
flash_vars = '&'.join(flash_vars)
self.flash_vars = flash_vars or None
if width:
self.width = width
if height:
self.height = height
See the MP3 Player Flash widget below for a demo application using this general Flash widget.
Contributed by: Christoph Zwerschke
This recipe shows how you can easily embed an MP3 player on your pages with a TurboGears widget using the open source MP3 Player and SWFObject.
This is how a basic MP3Widget class can be defined (you can choose a different MP3 player by setting name):
class MP3Widget(FlashWidget):
"""Embeds MP3 content using MP3 Player and SWFObject 2.
See http://flash-mp3-player.net for info on MP3 Player.
"""
object_id = 'mp3widget'
name = 'player_mp3_multi.swf'
width, height = 200, 100
def __init__(self, title=None, flash_vars=None,
width=None, height=None, *args, **kwargs):
if not flash_vars:
flash_vars = {}
if 'width' in flash_vars:
if not width:
width = flash_vars['width']
elif width:
flash_vars['width'] = width
if 'height' in flash_vars:
if not height:
height = flash_vars['height']
elif height:
flash_vars['height'] = width
FlashWidget.__init__(self, self.name, title, flash_vars,
width, height, *args, **kwargs)
An example application using the MP3 player is attached to this page and can be downloaded here:
Here is how the MP3 player embedded on the web page looks like:
Contributed by: Dimitris Glezos
The current implementation of widgets.RepeatingFieldSet creates a set of fieldsets with common attributes; for example, legends are the same for each fieldset. In addition, the variables in each fieldset are automatically numbered – one might want to give them custom names.
Here is an implementation of the widget that accepts lists of the size of repetitions for legends and fields:
class RepeatingFieldSetPlus(RepeatingFormField):
"""
A widget similar to RepeatingFieldSet, but with differentiation
between each field set. Accepts ids and legends as lists.
"""
template="""
<div xmlns:py="http://purl.org/kid/ns#">
<fieldset py:for="repetition, id in enumerate(ids)"
class="${field_class}"
id="${field_id}_${id}"
>
<legend py:if="legends[repetition]"
py:content="legends[repetition]" />
<div py:for="field in hidden_fields"
py:replace="field.display(value_for(field[repetition]),
**params_for(field[repetition]))"
/>
<label class="fieldlabel" for="${field.field_id}"
py:content="field.label" />
<span py:replace="field.display(value_for(field),
**params_for(field))" />
<span py:if="error_for(field)" class="fielderror"
py:content="error_for(field)" />
<span py:if="field.help_text" class="fieldhelp"
py:content="field.help_text" />
</fieldset>
</div>
"""
params = ["legends", "ids", "table_attrs"]
params_doc = {'legend' : _('Text to display as the legend '
'for the fieldset')}
legends = None
ids = None
table_attrs = {}
This widget can be used like this:
RepeatingFieldSetPlus(
ids = [f.id for f in foo.items]
legends = [f.leg for f in foo.items]
fields=[SingleSelectField(":doc:`/foo`%s" % f.id) for f in foo.items]
I hope I’m even somewhat close to something useful/unimplemented here..