Mode Widget
-----------

I is a very common task to decide if a widget should be rendered as is, should
only be displayed or completly hidden, or even do anything else.

You could solve this in two ways. The first way is to use the custom chain
mechanism.

Define custom renderer::

    >>> def hideordisplay(widget, data):
    ...     if data.request.get('hide'):
    ...         return ''
    ...     if data.request.get('display'):
    ...         return '<div>' + data.value + '</div>'
    ...     return data.rendered

Hook custom to chain on widget generation::

    >>> import yafowil.loader
    >>> from yafowil.base import factory
    >>> widget = factory(
    ...     '*hideordisplay:field:label:text',
    ...     'foo',
    ...     value = 'foo',
    ...     props = {
    ...         'label': 'Foo',
    ...     },
    ...     custom = {
    ...         'hideordisplay': ([], [hideordisplay], [], []),
    ...     })

Check results::

    >>> pxml(widget(request={}))
    <div class="field" id="field-foo">
      <label for="input-foo">Foo</label>
      <input class="text" id="input-foo" name="foo" type="text" value="foo"/>
    </div>
    <BLANKLINE>
    
    >>> widget(request={'display': True})
    '<div>foo</div>'
    
    >>> widget(request={'hide': True})
    ''

So what happend in the above example, is to just break the chain on
inappropriate permissions by ignoring the renderd widget and return anything
else (note the whole chain runs anyway).

It seem a little odd to always rewrite this stub work
elsewhere. The code grows, and the coder gets bored by unnecessary code
repeation and even more debugging by copy and paste errors.

The second way is to use the registered 'mode' widget. Basically its constrolled
by the 'mode' property and tries to render data.value decided on type.

Dummy mode decider function::

    >>> def modedecider(widget, data):
    ...     return data.request.get('mode', 'edit')

Test view widget with single string value::

    >>> widget = factory(
    ...     'mode:field:label:text',
    ...     'foo',
    ...     value = 'foo',
    ...     props = {
    ...         'label': 'Foo',
    ...         'mode': modedecider,
    ...     })
    
    >>> pxml(widget(request={}))
    <div class="field" id="field-foo">
      <label for="input-foo">Foo</label>
      <input class="text" id="input-foo" name="foo" type="text" value="foo"/>
    </div>
    <BLANKLINE>
    
    >>> widget(request={'mode': 'display'})
    u'<div>foo</div>'
    
    >>> widget(request={'mode': 'hidden'})
    u'<input id="input-foo" name="foo" type="hidden" value="foo" />'
    
    >>> widget(request={'mode': 'none'})
    u''

Test view widget with boolean value::

    >>> widget = factory(
    ...     'mode:field:label:text',
    ...     'foo',
    ...     value = True,
    ...     props = {
    ...         'label': 'Foo',
    ...         'mode': modedecider,
    ...     })
    
    >>> widget(request={'mode': 'view'}) 
    u'<div>True</div>'
    
Test view widget with iterable value::

    >>> widget = factory(
    ...     'mode:field:label:select',
    ...     'foo',
    ...     value = ['foo', 'bar'],
    ...     props = {
    ...         'label': 'Foo',
    ...         'mode': modedecider,
    ...         'multivalued': True,
    ...     })
    
    >>> pxml(widget(request={'mode': 'view'}))
    <ul>
      <li>foo</li>
      <li>bar</li>
    </ul>
    <BLANKLINE>

Finally you might want to use your own renderers for mode. You can define this
with the related mode name in props. Just define a callback function doing the 
rendering job::

    >>> def alternative_renderer(widget, data):
    ...     return u'<p>alternative</p>'

    >>> widget = factory(
    ...     'mode:field:label:text',
    ...     'foo',
    ...     value = 'foo',
    ...     props = {
    ...         'label.label': 'Foo',
    ...         'mode': modedecider,
    ...         'mode.display': alternative_renderer,
    ...     })
    
    >>> pxml(widget(request={'mode': 'edit'}))
    <div class="field" id="field-foo">
      <label for="input-foo">Foo</label>
      <input class="text" id="input-foo" name="foo" type="text" value="foo"/>
    </div>
    <BLANKLINE>
    
    >>> widget(request={'mode': 'display'})
    u'<p>alternative</p>'
