# Woven Widget Reference

This document is a reference guide for Woven builtins and signatures. However, the Woven framework should not be used for new projects. The newer Nevow framework, available as part of the Quotient project, is a simpler framework with consistent semantics and better testing and is strongly recommended over Woven.

The Woven documentation below is maintained only for users with an existing Woven codebase.

If you have feedback on this guide, please send it!

## Common Factory Signatures

    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" """

## Built-in Widgets

### Attributes

For dressing a node with extra attributes from the model.

    class MyPage(page.Page):
        template = """
        <a view="Attributes" model="/mylink"> My Link! </a>
        """

    MyPage({'mylink': {'href': '/path/to'}})

### Text, RawText

For putting text into a node. This will escape any HTML/XML special characters turning them into HTML entities, i.e. `&lt;foo&gt;`.

    class MyPage(page.Page):
        template = """
        <span view="Text" model="/mytext" />
        """

    MyPage({'mytext': 'abc'})

### ParagraphText

For taking text, one paragraph per line, and dressing it with `<p>` tags.

    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.
    """})

### Image

Displaying Images. Easy.

    class MyPage(page.Page):
        template = """
        <img view="Image" alt="MyImage" model="/myimg" />
        """

    MyPage({'myimg': '/images/myimage.png'})

### Error

Displaying an error. In red.

### Div

A Div.

### Span

A Span.

### Br

A Br.

### Input

An Input, it takes `value`, `name` and `id`. If `name` isn't supplied, it reverts to the value of `id`, if `id` isn't supplied either, it takes the name of the submodel. The other input classes extend this one, and give it a proper `type`.

### CheckBox

As Input, but... boxy.

### RadioButton

As Input, but... kinda button like.

### File

As Input, but... more chance of 1's and 0's. And a dialog on some user-agents.

### Password

Renders a password text field. no option for maxlength, quite strange.

### Button

Button

### Select

This falls under input, but instead of taking a value, you have to fiddle with options for that. There's no way to specify `type="multiple"` either it seems.

### Option

Option widgets have the methods `setText` and `setValue`, 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.

### Anchor

To create an anchor, including safe handling of parameters.

    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'
        }
    })

### DirectoryAnchor

Exactly like Anchor, but given a model which contains `/pages/otherpage` it will provide a link to `/pages/otherpage/` with a trailing slash.

### List

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.

    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')]})

### KeyedList

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 `model` attribute, as the KeyedList widget will create subwidgets, respecting `view` attribute but overriding `model`.

    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')]})

### Bold

A Bold (b, shouldn't this make a 'strong'?).

### Table

A Table.

### Row

A Row (tr).

### Cell

A Cell (td).

### Link

A Link (a) tag. Similar to Anchor.

    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'
        }
    })

### RootRelativeLink

Extends Link, and adds the functionality that it will respect this request.getRootURL, so that we can be deployed in different roots easily.

    self['href'] = request.getRootURL() + '/' + self['href']

### ExpandMacro

A Macro expansion widget modeled after the METAL expander in ZPT/TAL/METAL.

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 `fill-slot=` attributes which will fill slots in the Macro:

    class MyPage(page.Page):
        def wvfactory_myMacro(self, request, node, model):
            return ExpandMacro(
                model,
                macroFile="MyMacro.xhtml",
                macroName="main")

    <div view="myMacro">
        <span fill-slot="greeting">Hello</span>
        <span fill-slot="greetee">World</span>
    </div>

Then, in your Macro template file (MyMacro.html in the above example) designate a node as the macro node, and nodes inside that as the slot nodes:

    <div macro="main">
        <h3><span slot="greeting" />, <span slot="greetee" />!</h3>
    </div>

### DeferredWidget

Wraps around a deferred. Usage unknown.