:mod:`formalchemy.templates` -- Template engines
=================================================

.. automodule:: formalchemy.templates

.. Commented imports

   >>> from formalchemy.tests import User
   >>> from formalchemy.forms import FieldSet
   >>> from formalchemy.templates import TemplateEngine
   >>> from formalchemy import config
   >>> old_engine = config.engine

Available engines
-----------------

.. autoclass:: MakoEngine
   :members:

.. autoclass:: GenshiEngine
   :members:

.. autoclass:: TempitaEngine
   :members:

Base class
----------

.. autoclass:: TemplateEngine
   :members:

Customize templates
-------------------

You can override the default template by adding a directory for your project which will contain the templates.
The engine will scan the directory and try to load templates from it. If he can't, the default templates are used.

.. set templates dirs

  >>> import os
  >>> import formalchemy.tests
  >>> from formalchemy. tests import ls, cat
  >>> mako_templates_dir = os.path.join(os.path.dirname(formalchemy.tests.__file__), 'data', 'mako')
  >>> genshi_templates_dir = os.path.join(os.path.dirname(formalchemy.tests.__file__), 'data', 'genshi')

Here is an example::

  >>> ls(mako_templates_dir)
  - fieldset.mako

  >>> cat(mako_templates_dir, 'fieldset.mako')
  <ul>
  %for field in fieldset.render_fields.itervalues():
  <li>${field.name}</li>
  %endfor
  </ul>
  <BLANKLINE>

Then you can override the default mako templates::

  >>> from formalchemy import config
  >>> from formalchemy import templates
  >>> config.engine = templates.MakoEngine(
  ...               directories=[mako_templates_dir],
  ...               input_encoding='utf-8', output_encoding='utf-8')

And see the result::

  >>> print FieldSet(User).render()
  <ul>
  <li>email</li>
  <li>password</li>
  <li>name</li>
  <li>orders</li>
  </ul>
  <BLANKLINE>

Same with genshi except that :mod:`formalchemy` don't provide default templates::  

  >>> cat(genshi_templates_dir, 'fieldset.html')
  <ul xmlns:py="http://genshi.edgewall.org/">
  <li py:for="field in fieldset.render_fields.itervalues()">${field.name}</li>
  </ul>
  <BLANKLINE>

  >>> config.engine = templates.GenshiEngine(directories=[genshi_templates_dir])

And same the result of course::

  >>> print FieldSet(User).render()
  <ul>
  <li>email</li><li>password</li><li>name</li><li>orders</li>
  </ul>

Write your own engine
----------------------

You need to subclass the :class:`~formalchemy.templates.TemplateEngine`::

  >>> class MyEngine(TemplateEngine):
  ...     def render(self, template_name, **kw):
  ...         return 'It works !'

You can use it for a specific :class:`~formalchemy.forms.FieldSet`::

  >>> fs = FieldSet(User)
  >>> fs.engine = MyEngine()
  >>> print fs.render()
  It works !

You can also override the engine in a subclass::

  >>> class MyFieldSet(FieldSet):
  ...     engine = MyEngine()

Or set it as the global engine with :mod:`formalchemy`'s :mod:`~formalchemy.config`::

  >>> from formalchemy import config
  >>> config.engine = MyEngine()

It should be available for all :class:`~formalchemy.forms.FieldSet`::

  >>> print FieldSet(User).render()
  It works !

.. restore config

  >>> config.engine = old_engine
