Widgets¶
TranslatableSourceSelectWidget¶
TranslatableSourceSelectWidget
is a SourceSelectWidget
that translates
and sorts the choices.
We will borrow the boring set up code from the SourceSelectWidget test (source.txt in zope.formlib).
>>> import zope.interface
>>> import zope.component
>>> import zope.schema
>>> import zope.schema.interfaces
>>> @zope.interface.implementer(zope.schema.interfaces.IIterableSource)
... class SourceList(list):
... pass
>>> import base64, binascii
>>> import zope.publisher.interfaces.browser
>>> from zope.browser.interfaces import ITerms
>>> from zope.schema.vocabulary import SimpleTerm
>>> @zope.interface.implementer(ITerms)
... class ListTerms:
...
... def __init__(self, source, request):
... pass # We don't actually need the source or the request :)
...
... def getTerm(self, value):
... title = value.decode() if isinstance(value, bytes) else value
... try:
... token = base64.b64encode(title.encode()).strip().decode()
... except binascii.Error:
... raise LookupError(token)
... return SimpleTerm(value, token=token, title=title)
...
... def getValue(self, token):
... return token.decode('base64')
>>> zope.component.provideAdapter(
... ListTerms,
... (SourceList, zope.publisher.interfaces.browser.IBrowserRequest))
>>> dog = zope.schema.Choice(
... __name__ = 'dog',
... title=u"Dogs",
... source=SourceList(['spot', 'bowser', 'prince', 'duchess', 'lassie']),
... )
>>> dog = dog.bind(object())
Now that we have a field and a working source, we can construct and render a widget.
>>> from zope.mimetype.widget import TranslatableSourceSelectWidget
>>> from zope.publisher.browser import TestRequest
>>> request = TestRequest()
>>> widget = TranslatableSourceSelectWidget(
... dog, dog.source, request)
>>> print(widget())
<div>
<div class="value">
<select id="field.dog" name="field.dog" size="5" >
<option value="Ym93c2Vy">bowser</option>
<option value="ZHVjaGVzcw==">duchess</option>
<option value="bGFzc2ll">lassie</option>
<option value="cHJpbmNl">prince</option>
<option value="c3BvdA==">spot</option>
</select>
</div>
<input name="field.dog-empty-marker" type="hidden" value="1" />
</div>
Note that the options are ordered alphabetically.
If the field is not required, we will also see a special choice labeled “(nothing selected)” at the top of the list
>>> dog.required = False
>>> print(widget())
<div>
<div class="value">
<select id="field.dog" name="field.dog" size="5" >
<option selected="selected" value="">(nothing selected)</option>
<option value="Ym93c2Vy">bowser</option>
<option value="ZHVjaGVzcw==">duchess</option>
<option value="bGFzc2ll">lassie</option>
<option value="cHJpbmNl">prince</option>
<option value="c3BvdA==">spot</option>
</select>
</div>
<input name="field.dog-empty-marker" type="hidden" value="1" />
</div>