== Templates ==

modu has pretty much standardized on using the Cheetah template system for it's preferred templating engine, so much of the documentation in this section is going to be rather Cheetah-specific.

=== Other Engines ===

Technically, modu supports two alternate template engines in addition to Cheetah, but they have not been very thoroughly tested, and may lack features compared to the preferred Cheetah engine. These alternate template engines include CherryTemplate and ZPTPages, but it should be trivial to implement support for any template engine that can function with a namespace backed by a Python dictionary.

=== Standard Variables ===

The default TemplateContent superclass inserts a number of variables into the template dictionary as part of get_content(). Template engines that wish to use these variables must make sure to call the superclass get_content() from their own overridden version of the method.

The variables include:
    req
        The current request object.
    
    header_content
        During content generation, req.content.report('header', 'text') will accumulate a list of strings to be concatenated and inserted into this variable. It is currently used to allow code to insert STYLE, LINK, SCRIPT, or other tags into the HTML HEAD section. Since it uses the MessageQueue class to hold these items, duplicate calls to report() will be collapsed into a single entry. Unlike the usual req.messages queue, the content queue is not backed by the session, so data is not saved across requests.

These variables are set *after* prepare_content() is called, so it's important not to use these names for your own variables, since they will be clobbered.

=== Cheetah Revisions ===

First of all, it's important to understand Cheetah's origins, and that we are only using a subset of Cheetah's features. Cheetah integrates tightly with the Python web development toolkit Webware, and has a number of features that make sense in that environment, but that aren't terribly useful in the modu environment. It may be that some of these things *are*, in fact, useful to modu developers, but at this time they are unused.

Consequently, a few assumptions are made about how templates are used and organized in modu that may not be obvious to existing Cheetah users. The goal in this section is to outline some of these changes and development standards that have been adopted during use of Cheetah in the modu environment.

 * String Templates vs. Files
    As described in the Resource API section, templates can either be specified by returning a string template from get_template(), or by returning a filename (the interpretation of which is which is based on the result of get_template_type()).

 * Compiled templates
    When a template is new, it gets compiled to Python code, and that code gets saved in a file in the compiled_template_root directory. If the modified date of the template is newer than the compiled version, it is recompiled. One unfortunate implementation detail is that the compiled templates aren't loaded via the usual Python import mechanism, instead being read in and exec()ed. This will hopefully be addressed in the future.

 * Thread-safety
    Cheetah isn't entirely threadsafe, and we add some customizations that can potentially be an issue for threads, so the entire template compilation process is locked by semaphore. This could potentially have performance ramifications, but so far it seems to be relatively efficient.

 * Include files
    Include files are such a common template organization technique, some time was spent implementing these inside the modu environment. It's assumed that the location of the include files is the same as the calling template, but get_template_root() is still called for each. This allows particularly clever Resources (such as the AdminResource, which provides default templates for any that aren't overridden by the user) to alter the behavior of includes and template lookup in general.

 * Unicode support
    Release 2.2.0 of the Cheetah template software modified the template generation code to use entirely unicode strings. It then forced all strings in the template dictionary to be unicode as well. Since a large amount of modu code exists that depends on the ability to embed regular strings into templates, a monkeypatch exists to override the default behavior. This patch assumes that all bytestrings are encoded using UTF-8, and then decodes them to unicode objects before output. Finally, the get_content() method on a CheetahTemplateContent instance will convert back to UTF-8 before returning it to the user. At some point this code must be revised so that other encodings can be used.
