tw.api

Public symbols from ToscaWidgets core are exported through this package. It is best to import them from here to ensure portability if TW’s core is refactored.

Core Widgets

These are the building blocks of widgets.

Widget

class tw.api.Widget(*args, **kw)

Base class for all widgets.

Example:

>>> w = Widget('foo')
>>> w.id
'foo'

>>> w = Widget('foo', children=[Widget('c1'), Widget('c2')])
>>> [c.id for c in w.children]
['foo_c1', 'foo_c2']
>>> [c.parent.id for c in w.children]
['foo', 'foo']

It is a must that all initial state is entirely determined by the arguments to this function. This means that two widgets (of the same class) that receive the same parameters must behave in exactly the same way. You should not rely on external sources inside __init__ to set initial state.

If you need to fetch data from external sources, do it at update_params() instead.

Essential pre, and post initialization is done in __new__() and post_init() respectively. post_init() is guaranteed to run after the instance finishes initialization and it’s behavior is rather special as all post_init’s in mro will be called to have a chance to set final state in the instance.

Basic pre-initialization consists of binding all kw arguments to the widget instance, attaching the widget to it’s parent (if given), attaching the children and copying mutable arguments listed at params from the class to the instance to avoid accidental manipulation.

>>> w = Widget('foo', a=1, b=2)
>>> w.id
'foo'
>>> w.a
1
>>> w.b
2

Basic post-initialization consists of caching required CSS and JS resources and setting the widget as initialized preventing further modification of it’s attributes.

>>> w = Widget('foo', a='1', b='2')
>>> w.a = 'bar'
Traceback (most recent call last):
    ...
WidgetLocked: The widget is locked. It's unthread-safe to alter it's attributes after initialization.

Widget attributes can only be modified in this method because widgets should behave in a state-less way as they are shared among threads for multiple requests.

Per request modification of variables sent to the template should be done inside update_params() and all state flowing from parent to children should occur inside that dict.

Widgets should be instantiated at import time and reused among requests, most widgets allow overriding most of their parameters (not neccesarily all of them) at display time to change behavior. You should try avoiding instantiating widgets for every request as their initialization could be quite expensive for heavily nested widgets.

Request-local storage provided by the hosting framework in tw.framework.request can be used to pass state among widgets which don’t share the same root.

id

The calculated id of the widget. This string will provide a unique id for each widget in the tree in a format which allows to re-recreate the nested structure. Example:

>>> A = Widget("A", children=[
...     Widget("B", children=[
...         Widget("C")
...         ])
...     ])
...
>>> C = A.c.B.c.C
>>> C.id
'A_B_C'
is_root
True if the widget doesn’t have a parent
root
The root of this widget tree
displays_on
Where the widget is being displayed on
path
Iterates a walk from this widget to the root of the tree
key

A string that can be used as a key to index the dictionary of parameters sent to the root widget so it reaches this widget when displaying.

Example:

>>> A = Widget("A", children=[
...     Widget("B", children=[
...         Widget("C")
...         ])
...     ])
...
>>> C = A.c.B.c.C
>>> C.key
'.B.C'
params

A set with all the params declared in all the widget’s bases and itself. This set is computed by tw.core.meta.WidgetType from the class attribute.

>>> from tw.api import Widget
>>> class SomeWidget(Widget):
...    params = ["a", "b"]
...
>>> "a" in SomeWidget.params
True

All params from Widget are present in SomeWidget's set too.

>>> "id" in SomeWidget.params
True
javascript
A list of tw.api.JSLink or tw.api.JSSource instances that the widget should register for injection in the page whenever it is displayed
css
A list of tw.api.CSSLink or tw.api.CSSSource instances that the widget should register for injection in the page whenever it is displayed
adapt_value(value)
Adapt object value for rendering in this widget. Should return one of:
  • A list of objects for repeated widgets.
  • A dict for widgets with children, keyed by the children’s ids.
  • Any other object the widget understands.
add_call(call, location='bodybottom')
Adds a tw.api.js_function() call that will be made when the widget is rendered.
display(value=None, **kw)

Renders a widget and adapts the output. This method must be used to display child widgets inside their parent’s template so output is adapted.

Unlike tw.api.Widget.render(), tw.api.Widget.display() returns adapted output compatible with the template the widget is being rendered on. For example, this is needed so Genshi doesn’t autoescape string output from mako and to serialize Genshi output on the other way around.

displays_on
Where the widget is being displayed on
get_default()
Returns the default value for the widget. If the default is a funtion that it can be called without arguments it will be called on each render to retrieve a value
id

The calculated id of the widget. This string will provide a unique id for each widget in the tree in a format which allows to re-recreate the nested structure. Example:

>>> A = Widget("A", children=[
...     Widget("B", children=[
...         Widget("C")
...         ])
...     ])
...
>>> C = A.c.B.c.C
>>> C.id
'A_B_C'
ifilter_children(filter)

Returns an iterator for all children applying a filter to them.

>>> class Widgets(WidgetsList):
...     aa = Widget()
...     ab = Widget()
...     ba = Widget()
...     bb = Widget()
...
>>> w = Widget(children=Widgets)
>>> [c.id for c in w.ifilter_children(lambda w: w.id.startswith('a'))]
['aa', 'ab']
is_root
True if the widget doesn’t have a parent
key

A string that can be used as a key to index the dictionary of parameters sent to the root widget so it reaches this widget when displaying.

Example:

>>> A = Widget("A", children=[
...     Widget("B", children=[
...         Widget("C")
...         ])
...     ])
...
>>> C = A.c.B.c.C
>>> C.key
'.B.C'
path
Iterates a walk from this widget to the root of the tree
post_init(*args, **kw)
This method is called for all tw.api.Widget base classes to perform final setup after the widget is initialized but before it is locked.
prepare_dict(value, d, adapt=True)
Prepares the all kw arguments sent to display or render before passing the kw argument’s dict to update_params.
register_resources()

Register the resources required by this Widget with tw.framework for inclusion in the page.

This method is called whenever a Widget is rendered

render(value=None, **kw)
Renders a widget as an unicode string.
root
The root of this widget tree
update_params(d)

Updates the dict sent to the template for the current request.

It is called when displaying or rendering a widget with all keyword arguments passed stuffed inside dict.

Widget subclasses can call super cooperatively to avoid boiler-plate code as Widget.update_params takes care of pre-populating this dict with all attributes from self listed at params (copying them if mutable) and preparing arguments for child widgets.

Any parameter sent to display or render will override those fetched from the instance or the class.

Any function listed at params which can be called without arguments will be automatically called to fetch fresh results on every request. Parameters not found either on the class, the instance or the keyword args to display or render will be set to None.

>>> class MyWidget(Widget):
...     params = ["foo", "bar", "null"]
...     foo = "foo"
...
>>> w = MyWidget('test', bar=lambda: "bar")
>>> d = {}
>>> w.update_params(d)
>>> d['bar']
'bar'
>>> d['foo']
'foo'
>>> d['null'] is None
True
>>> d = {'foo':'overriden'}
>>> w.update_params(d)
>>> d['foo']
'overriden'
walk(filter=None, recur_if_filtered=True)

Does a pre-order walk on widget tree rooted at self optionally applying a filter on them.

Example:

>>> W = Widget
>>> w = W('a', children=[W('b', children=[W('c')]), W('d')])
>>> ''.join(i._id for i in w.walk())
'abcd'
>>> ''.join(i._id for i in w.walk(lambda x: not x.is_root))
'bcd'
>>> ''.join(i._id for i in w.walk(lambda x: x._id == 'c'))
'c'

Recursion can be prevented on children that not match filter.

>>> ''.join(i._id for i in w.walk(lambda x: x._id == 'c', False))
''

WidgetRepeater

class tw.api.WidgetRepeater(*args, **kw)

Static resources

Tosca widgets can bundle their static resources, such as Javascript code, CSS and images in their EGG distributions.

All widgets being used in a page register their resources automatically so TW’s middleware can inject them into the page.

Note

Resources can also be injected manually after the page has been rendered using inject_resources()

These static files can be served by TW’s middleware while developing or moved to a directory where a fast server can serve them in production [1]

Base Widgets and mixins

Resource

class tw.api.Resource(*args, **kw)

A resource for your widget, like a link to external JS/CSS or inline source to include at the page the widget is displayed.

It has the following parameters:

location
Location on the page where the resource should be placed. Available locations can be queried at Resource.valid_locations
inject()
Push this resource into request-local so it is injected to the page

JSMixin

class tw.api.JSMixin

CSSMixin

class tw.api.CSSMixin

Sources

The following widgets are used to inject CSS and JS into the html page widgets are being rendered on.

Note

Injecting links to static files using Link ind its subclasses is recommended over injecting CSS or JS source since the former can be cached by the browser and further optimized for deployment. Besides that, there are third party tools which can help with creating them which won’t work if CSS and JS code is embedded in the python source code

Source

class tw.api.Source(*args, **kw)

An inlined chunk of source code

Examples:

>>> class MySource(Source):
...     template = "$src"
...     src = "foo=$foo"
...     source_vars = ["foo"]
...     foo = "bar"
...
>>> s = MySource()
>>> s.render()
u'foo=bar'

>>> s = MySource(foo='zoo')
>>> s.render()
u'foo=zoo'

>>> s.render(foo='foo')
u'foo=foo'

The whole source can also be overriden

>>> s.render(src='foo')
u'foo'

JSSource

class tw.api.JSSource(*args, **kw)
An inlined chunk of JS source code.

CSSSource

class tw.api.CSSSource(*args, **kw)
An inlined chunk of CSS source code.

Javascript interfacing utilities

The following objects can help interfacing with the Javascript side of the widget from the Python side.

js_function

class tw.api.js_function(name)

A JS function that can be “called” from python and and added to a widget by widget.add_call() so it get’s called every time the widget is rendered.

Used to create a callable object that can be called from your widgets to trigger actions in the browser. It’s used primarily to initialize JS code programatically. Calls can be chained and parameters are automatically json-encoded into something JavaScript undersrtands. Example:

.. sourcecode:: python
>>> jQuery = js_function('jQuery')
>>> call = jQuery('#foo').datePicker({'option1': 'value1'})
>>> str(call)
'jQuery("#foo").datePicker({"option1": "value1"})'

Calls are added to the widget call stack with the add_call method.

If made at Widget initialization those calls will be placed in the template for every request that renders the widget.

>>> from tw.api import Widget
>>> class SomeWidget(Widget):
...     params = ["pickerOptions"]
...     pickerOptions = {}
...     def __init__(self, *args, **kw):
...         super(SomeWidget, self).__init__(*args, **kw)
...         self.add_call(
...             jQuery('#%s' % self.id).datePicker(self.pickerOptions)
...         )

If we want to dynamically make calls on every request, we ca also add_calls inside the update_params method.

>>> class SomeWidget(Widget):
...     params = ["pickerOptions"]
...     pickerOptions = {}
...     def update_params(self, d):
...         super(SomeWidget, self).update_params(d)
...         self.add_call(
...             jQuery('#%s' % d.id).datePicker(d.pickerOptions)
...         )

This would allow to pass different options to the datePicker on every display.

JS calls are rendered by the same mechanisms that render required css and js for a widget and places those calls at bodybottom so DOM elements which we might target are available.

Examples:

>>> call = js_function('jQuery')("a .async")
>>> str(call)
'jQuery("a .async")'

# js_function calls can be chained:

>>> call = js_function('jQuery')("a .async").foo().bar()
>>> str(call)
'jQuery("a .async").foo().bar()'

js_callback

class tw.api.js_callback(cb, *args)

A js function that can be passed as a callback to be called by another JS function

Examples:

>>> str(js_callback("update_div"))
'update_div'

>>> str(js_callback("function (event) { .... }"))
'function (event) { .... }'

# Can also create callbacks for deferred js calls

>>> str(js_callback(js_function('foo')(1,2,3)))
'function(){foo(1, 2, 3)}'

# Or equivalently

>>> str(js_callback(js_function('foo'), 1,2,3))
'function(){foo(1, 2, 3)}'

# A more realistic example
 
>>> jQuery = js_function('jQuery')
>>> my_cb = js_callback('function() { alert(this.text)}')
>>> on_doc_load = jQuery('#foo').bind('click', my_cb)
>>> call = jQuery(js_callback(on_doc_load))
>>> print call
jQuery(function(){jQuery("#foo").bind("click", function() { alert(this.text)})})

js_symbol

class tw.api.js_symbol(name)

encode()

Other

WidgetsList

This object is just syntax sugar to have a DSL-like way to declare a list of widgets. Although it’s subclasses appear to have attributes, there’s some metaclass magic behind the scenes which turns the class into a list factory.

class tw.api.WidgetsList(clones=[])

Syntactic sugar for declaring a list of widgets.

>>> from tw.api import Widget
>>> class Widgets(WidgetsList):
...     a = Widget()
...     b = Widget()
...     c = Widget()
...
>>> widgets = Widgets()
>>> [w.id for w in widgets]
['a', 'b', 'c']

WidgetsLists can be passed to another widget as children by the instance or the class.

>>> w = Widget('foo', children=widgets)
>>> [c.id for c in w.children]
['foo_a', 'foo_b', 'foo_c']
>>> w = Widget('foo', children=Widgets)
>>> [c.id for c in w.children]
['foo_a', 'foo_b', 'foo_c']

WidgetsLists subclasses can also be added to reuse common widgets

>>> class Widgets2(WidgetsList):
...     d = Widget()
...
>>> widgets = Widgets + Widgets2
>>> [w.id for w in widgets]
['a', 'b', 'c', 'd']
>>> widgets = Widgets2 + Widgets
>>> [w.id for w in widgets]
['d', 'a', 'b', 'c']

WidgetBunch

This class is used internally by Widget (in the children and c attribute) and is rarely used standalone anymore.

class tw.api.WidgetBunch(*args)

An ordered collection of widgets.

>>> from tw.core import Widget
>>> wb = WidgetBunch(Widget('foo'), Widget('bar'))
>>> wb[0].id == 'foo'
True
>>> wb[1].id == 'bar'
True

Exposes a mixed dict/list interface which permits indexing both by widget id and position.

>>> wb['foo'] == wb[0]
True
>>> wb['bar'] == wb[1]
True

Also permits attribute access as long as the attribute doesn’t conflict with an internal attribute, in case of conflict the internal attrbute will prevail.

>>> wb.foo.id == 'foo'
True
>>> wb.append(Widget('append'))
>>> wb.append.id
Traceback (most recent call last):
    ...
AttributeError: 'function' object has no attribute 'id'
>>> wb['append'].id == 'append'
True

Iteration is also supported

>>> [w.id for w in wb]
['foo', 'bar', 'append']

Some dict-like iterators too

>>> [id for id in wb.iterkeys()]
['foo', 'bar', 'append']
>>> [id for id in wb.keys()]
['foo', 'bar', 'append']
>>> [w.id for w in wb.itervalues()]
['foo', 'bar', 'append']
>>> [w.id for w in wb.values()]
['foo', 'bar', 'append']

make_middleware()

tw.api.make_middleware(app, config=None, **kw)

Initializes tw.core.middleware.ToscaWidgetsMiddleware and a tw.mods.base.HostFramework and wraps the WSGI application app with it.

Configuration can be passed in a dict as the config parameter.

Available options:

toscawidgets.middleware.*
These parameters will be passed to tw.core.middleware.ToscaWidgetsMiddleware when instatntiating it. See its docstrings for details.
toscawidgets.framework
Name of the toscawidgets.host_frameworks entry point or tw.mods.base.HostFramework subclass which shall interface with the framework. wsgi, pylons are available. Default is wsgi
toscawidgets.framework.*
Parameters for the tw.modes.base.HostFramework. See their respective docstrings for accepted parameters.

This is the ToscaWidgets#middleware paste.filter_app_factory entrypoint.

inject_resources()

tw.api.inject_resources(self, html, resources=None, encoding=None, render_filter=None, environ=None)

Injects resources, if any, into html string when called.

Note

Ignore the self parameter if seeing this as tw.core.resource_injector.inject_resources() docstring since it is an alias for an instance method of a private class.

html must be a encoding encoded string. If encoding is not given it will be tried to be derived from a <meta>.

Resources for current request can be obtained by calling tw.framework.pop_resources(). This will remove resources from request and a further call to pop_resources() will return an empty dict.

Footnotes

[1]See Deploying projects which use ToscaWidgets for more information