User Guide ========== Widget Name ~~~~~~~~~~~ Each attribute in widget corresponds to an appropriate attribute in ``model``. Attribute name becomes ``name`` in the html element. By convention in html ``id`` underscore is replaced with dash. So attribute ``confirm_password`` remains unchanged in html name, however id will be ``confirm-password``. Widget Rendering ~~~~~~~~~~~~~~~~ Once we know the name of the html widget, next we pass control to the appropriate widget for rendering:: credential.username.textbox(autocomplete='off') Let's explain this single line: * ``credential`` - domain object. * ``username`` - attribute name of our domain object. * ``textbox`` - widget we need to render. * ``autocomplete`` - html specific attribute. Once that code is executed we get the following:: Value Formatting ~~~~~~~~~~~~~~~~ You can the format model value before it is passed to widget for rendering. Let's declare our domain model:: from datetime import date class Registration(object): def __init__(self): self.date_of_birth = date.min Here is how you can apply formatting:: registration.date_of_birth.format('%Y/%m/%d') or this way:: registration.date_of_birth.format( format_provider=lambda value, ignore: value.strftime('%m-%d-%y')) Widget formatting can followed by the actual widget that needs to be rendered:: registration.date_of_birth.format('%Y/%m/%d').textbox() ``format_provider`` - a callable of the following form:: def my_format_provider(value, format_string): return value_formatted There are default format providers for built-in types. You can replace and extend them with your own, by altering ``format_providers`` map:: from wheezy.html.utils import format_providers format_providers['my_type'] = my_format_provider Default implementation for date/time types formats its minimal value to an empty string. Model Error ~~~~~~~~~~~ Since ``widget`` is initialized with model and errors, it is capable of decorating html widgets with attributes specific to errors. Let's see this in the following example:: errors = {'username': ['Required field cannot be left blank.']} We get the errors from some sort of validation. The same ``textbox`` is now decorated with class error:: So I can apply appropriate css style to draw a border around input, or what ever else, since in html I have distinguished between input with error and valid input. Now let display error:: credential.username.error() Read above as render error message for username, here is what we get:: Required field cannot be left blank. General Error ~~~~~~~~~~~~~ General error is not related to certain model attribute but is operation related instead. If ``errors`` dictionary contains an element with key __ERROR__ than that one is used as a general error:: errors = {'__ERROR__': 'The username or password provided is incorrect.'} You can display it this way:: credential.error() It renders the following html element only if the __ERROR__ key exists:: The username or password provided is incorrect. Notice class ``error-message``. Your application is able to distinguish field errors from general errors. Integration ~~~~~~~~~~~ :ref:`wheezy.html` integrates with the following template systems: * `Jinja2 Templates `_ * `Mako Templates `_ * `Tenjin Templates `_ * `Wheezy Templates `_ Jinja2 ^^^^^^ :ref:`wheezy.html` integration with ``Jinja2`` is provided via the extension feature. Here is how to add :py:meth:`~wheezy.html.ext.jinja2.WidgetExtension` to your code:: from wheezy.html.ext.jinja2 import WidgetExtension env = Environment( ... extensions=[WidgetExtension]) The only thing :py:meth:`~wheezy.html.ext.jinja2.WidgetExtension` does is translation of widget code to adequate ``Jinja2`` code. Let's demonstrate this with an example:: {{ model.remember_me.checkbox() }} is translated to the following ``Jinja2`` code (during template compilation phase):: which effectively renders the HTML at runtime:: Since widgets also decorate appropriate HTML tags in case of error, the ``errors`` dictionary must be available in the ``Jinja2`` context:: template = env.get_template(template_name) assert 'errors' in kwargs template.render( **kwargs ) See :py:mod:`wheezy.html.ext.jinja2` for more examples. Mako ^^^^ :ref:`wheezy.html` integration with ``Mako`` is provided via the preprocessor feature. Here is how to add :py:meth:`~wheezy.html.ext.mako.widget_preprocessor` to your code:: from wheezy.html.ext.mako import widget_preprocessor template_lookup = TemplateLookup( ... preprocessor=[widget_preprocessor]) The only thing :py:meth:`~wheezy.html.ext.mako.widget_preprocessor` does is translation of widget code to adequate ``Mako`` code. Let's demonstrate this with an example:: ${model.remember_me.checkbox()} is translated to the following ``Mako`` code (during template compilation phase):: which effectively renders the HTML at runtime:: Since widgets also decorate appropriate HTML tags in case of error, the ``errors`` dictionary must be available in the ``Mako`` context:: template = template_lookup.get_template(template_name) assert 'errors' in kwargs template.render( **kwargs ) See :py:mod:`wheezy.html.ext.mako` for more examples. Tenjin ^^^^^^ :ref:`wheezy.html` integration with ``Tenjin`` is provided via the preprocessor feature. Here is how to add :py:meth:`~wheezy.html.ext.tenjin.widget_preprocessor` to your code:: from wheezy.html.ext.tenjin import widget_preprocessor engine = tenjin.Engine( ... pp=[widget_preprocessor]) The only thing :py:meth:`~wheezy.html.ext.mako.widget_preprocessor` does is translation of widget code to adequate ``Tenjin`` code. Let's demonstrate this with an example:: ${model.remember_me.checkbox(class_='i')} is translated to the following ``Tenjin`` code (during template compilation phase):: class="error i" class="i" checked="checked" /> which effectively renders the HTML at runtime:: Since widgets also decorate appropriate HTML tags in case of error, the ``errors`` dictionary must be available in the ``Tenjin`` context:: assert 'errors' in kwargs engine.render('page.html', **kwargs ) See :py:mod:`wheezy.html.ext.tenjin` for more examples. Wheezy Template ^^^^^^^^^^^^^^^ :ref:`wheezy.html` integration with ``wheezy.template`` is provided via the preprocessor feature. Here is how to add :py:meth:`~wheezy.html.ext.template.WidgetExtension` to your code:: from wheezy.html.ext.template import WidgetExtension from wheezy.html.utils import html_escape from wheezy.html.utils import format_value engine = Engine( ... extensions=[ WidgetExtension ]) engine.global_vars.update({ 'format_value': format_value, 'h': html_escape }) The only thing :py:meth:`~wheezy.html.ext.template.WidgetExtension` does is translation of widget code to adequate ``wheezy.template`` code. Let's demonstrate this with an example:: @model.remember_me.checkbox(class_='i') is translated to the following ``wheezy.template`` code (during template compilation phase):: which effectively renders the HTML at runtime:: Since widgets also decorate appropriate HTML tags in case of error, ``errors`` dictionary must be available in ``wheezy.template`` context:: assert 'errors' in kwargs engine.render('page.html', **kwargs ) See :py:mod:`wheezy.html.ext.template` for more examples.