woven-reference.xhtml [plain text]
<?xml version="1.0"?>
<!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"><head><title>Woven Widget Reference</title></head>
<body>
<h1>Woven Widget Reference</h1>
<div class="note">
<p>
This document is a reference guide for Woven builtins and signatures. However, the Woven framework should not be used for new projects. The newer <a href="http://www.divmod.org/Home/Projects/Nevow/">Nevow</a> framework, available as part of the <a href="http://www.divmod.org/Quotient/">Quotient</a> project, is a simpler framework with consistent semantics and better testing and is strongly recommended over Woven.
</p>
<p>
The Woven documentation below is maintained only for users with an existing Woven codebase.
</p>
<p>
If you have feedback on this guide, <a href="mailto:stephen@thorne.id.au">please send it</a>!
</p>
</div>
<h2>Common Factory Signatures</h2>
<pre class="python">
class MyPage(page.Page):
def wchild_foo(self, request):
""" Return the Resource for /mypage/foo/ """
def wmfactory_foo(self, request):
""" Return the Model object for model="/foo" """
def wvfactory_cool(self, request, node, model):
""" Return node for view="cool" """
def wvupdate_thumbnail(self, request, widget, data):
""" Update and Return the widget for view="thumbnail" """
def wcfactory_adjuster(self, request, node, model):
""" Return the controller for controller="adjuster" """
</pre>
<h2>Built-in Widgets</h2>
<h3>Attributes</h3>
<p> For dressing a node with extra attributes from the model. </p>
<pre class="python">
class MyPage(page.Page):
template = """
<a view="Attributes" model="/mylink"> My Link! </a>
"""
MyPage({'mylink': {'href': '/path/to'}})
</pre>
<h3>Text, RawText</h3>
<p>For putting text into a node. This will escape any HTML/XML special
characters turning them into HTML entities, i.e.
<code>&lt;foo&gt;</code>.</p>
<pre class="python">
class MyPage(page.Page):
template = """
<span view="Text" model="/mytext" />
"""
MyPage({'mytext': 'abc'})
</pre>
<h3>ParagraphText</h3>
<p>For taking text, one paragraph per line, and dressing it with
<code><p></code> tags.</p>
<pre class="python">
class MyPage(page.Page):
template = """
<span view="ParagraphText" model="/mytext" />
"""
MyPage({'mytext' : """
This is one Paragraph.
This is a second one. It has two sentences.
"""})
</pre>
<h3>Image</h3>
<p>Displaying Images. Easy.</p>
<pre class="python">
class MyPage(page.Page):
template = """
<img view="Image" alt="MyImage" model="/myimg" />
"""
MyPage({'myimg': '/images/myimage.png'})
</pre>
<h3>Error</h3>
<p>Displaying an error. In red.</p>
<h3>Div</h3>
<p>A Div.</p>
<h3>Span</h3>
<p>A Span.</p>
<h3>Br</h3>
<p>A Br.</p>
<h3>Input</h3>
<p>An Input, it takes <code>value</code>, <code>name</code> and <code>id</code>.
If <code>name</code> isn't supplied, it reverts to the value of <code>id</code>,
if <code>id</code> isn't supplied either, it takes the name of the submodel. The
other input classes extend this one, and give it a proper <code>type</code>.</p>
<h3>CheckBox</h3>
<p>As Input, but... boxy.</p>
<h3>RadioButton</h3>
<p>As Input, but... kinda button like.</p>
<h3>File</h3>
<p>As Input, but... more chance of 1's and 0's. And a dialog on some user-agents.</p>
<h3>Password</h3>
<p>Renders a password text field. no option for maxlength, quite strange.</p>
<h3>Button</h3>
<p>Button</p>
<h3>Select</h3>
<p>This falls under input, but instead of taking a value, you have to fiddle
with options for that. There's no way to specify <code>type="multiple"</code>
either it seems.</p>
<h3>Option</h3>
<p>Option widgets have the methods <code class="API"
base="twisted.web.woven.widgets.Option">setText</code> and <code class="API"
base="twisted.web.woven.widgets.Option">setValue</code>, but if your text
and your value co-incide, they can just be put in the model and it will all be
hunky and/or dory.</p>
<h3>Anchor</h3>
<p>To create an anchor, including safe handling of parameters.</p>
<pre class="python">
class MyPage(page.Page):
template = """
<a view="Anchor" model="/anchorone" />
<a view="myanchor" model="/anchortwo" />
"""
def wvfactory_myanchor(self, request, node, model):
a = Anchor()
a.setText(model['text'])
a.setParameter('thingy', model['thingy'])
a.setLink(model['href'])
MyPage({
'anchorone': '/pages/otherpage',
'anchortwo': {
'href': '/pages/thisotherpage/',
'thingy': 'foobar',
'text': 'The Text Of The Link'
}
})
</pre>
<h3>DirectoryAnchor</h3>
<p>Exactly like Anchor, but given a model which contains
<code>/pages/otherpage</code> it will provide a link to
<code>/pages/otherpage/</code> with a trailing slash.</p>
<h3>List</h3>
<p>List is a nice view for displaying the contents of a list. You can choose
not to specifiy listHeader, listFooter and emptyList. Specifying listItem twice
or more will cause alternation.</p>
<pre class="python">
class MyPage(page.Page):
template = """
<table model="blah" view="List">
<tr pattern="listHeader"><th>A</th><th>B</th></tr>
<tr pattern="emptyList"><td colspan='2'>***None***</td></tr>
<tr pattern="listItem">
<td><span view="Text" model="0" /></td>
<td><span view="Text" model="1" /></td>
</tr>
<tr pattern="listFooter"><td colspan="2">All done!</td></tr>
</table>
"""
MyPage({'blah': [('abc', 'fza'), ('def', 'fdsa'), ('ghi', 'fdas')]})
</pre>
<h3>KeyedList</h3>
<p>KeyedList is similar to List above, works nearly the same way, except the
model is a dictionary, not a list. If you need access to the key in your
listItems, make your listItem use a view that will inspect the
<code>model</code> attribute, as the KeyedList widget will create subwidgets,
respecting <code>view</code> attribute but overriding <code>model</code>.</p>
<pre class="python">
class MyPage(page.Page):
template = """
<table model="blah" view="List">
<tr pattern="listHeader"><th>A</th><th>B</th></tr>
<tr pattern="emptyList"><td colspan='2'>***None***</td></tr>
<tr pattern="listItem">
<td><span view="Text" model="0" /></td>
<td><span view="Text" model="1" /></td>
</tr>
<tr pattern="listFooter"><td colspan="2">All done!</td></tr>
</table>
"""
MyPage({'blah' : [('abc', 'fza'), ('def', 'fdsa'), ('ghi', 'fdas')]})
</pre>
<h3>Bold</h3>
<p>A Bold (b, shouldn't this make a 'strong'?).</p>
<h3>Table</h3>
<p>A Table.</p>
<h3>Row</h3>
<p>A Row (tr).</p>
<h3>Cell</h3>
<p>A Cell (td).</p>
<h3>Link</h3>
<p>A Link (a) tag. Similar to Anchor.</p>
<pre class="python">
class MyPage(page.Page):
template = """
<a view="Link" model="/anchorone"> My Text </a>
<a view="Link" model="/anchortwo" />
"""
MyPage({
'anchorone': '/pages/otherpage',
'anchortwo': {
'href': '/pages/thisotherpage/',
'text': 'The Text Of The Link'
}
})
</pre>
<h3>RootRelativeLink</h3>
<p>Extends Link, and adds the functionality that it will respect this
request.getRootURL, so that we can be deployed in different roots easily.</p>
<pre class="python">
self['href'] = request.getRootURL() + '/' + self['href']
</pre>
<h3>ExpandMacro</h3>
<p>A Macro expansion widget modeled after the METAL expander
in ZPT/TAL/METAL.</p>
<p>In the Page that is being rendered, place the ExpandMacro widget
on the node you want replaced with the Macro, and provide nodes
tagged with <code>fill-slot=</code> attributes which will fill slots in the
Macro:</p>
<pre class="python">
class MyPage(page.Page):
def wvfactory_myMacro(self, request, node, model):
return ExpandMacro(
model,
macroFile="MyMacro.xhtml",
macroName="main")
</pre>
<pre>
<div view="myMacro">
<span fill-slot="greeting">Hello</span>
<span fill-slot="greetee">World</span>
</div>
</pre>
<p>
Then, in your Macro template file (<q>MyMacro.html</q> in the above
example) designate a node as the macro node, and nodes
inside that as the slot nodes:
</p>
<pre>
<div macro="main">
<h3><span slot="greeting" />, <span slot="greetee" />!</h3>
</div>
</pre>
<h3>DeferredWidget</h3>
<p>Wraps around a deferred. Usage unknown.</p>
</body>
</html>