| # -*- coding: utf-8 -*- |
| """ |
| webapp2_extras.mako |
| =================== |
| |
| Mako template support for webapp2. |
| |
| Learn more about Mako: http://www.makotemplates.org/ |
| |
| :copyright: 2011 by tipfy.org. |
| :license: Apache Sotware License, see LICENSE for details. |
| """ |
| from __future__ import absolute_import |
| |
| from mako import lookup |
| |
| import webapp2 |
| |
| #: Default configuration values for this module. Keys are: |
| #: |
| #: template_path |
| #: Directory for templates. Default is `templates`. |
| default_config = { |
| 'template_path': 'templates', |
| } |
| |
| |
| class Mako(object): |
| """Wrapper for configurable and cached Mako environment. |
| |
| To used it, set it as a cached property in a base `RequestHandler`:: |
| |
| import webapp2 |
| |
| from webapp2_extras import mako |
| |
| class BaseHandler(webapp2.RequestHandler): |
| |
| @webapp2.cached_property |
| def mako(self): |
| # Returns a Mako renderer cached in the app registry. |
| return mako.get_mako(app=self.app) |
| |
| def render_response(self, _template, **context): |
| # Renders a template and writes the result to the response. |
| rv = self.mako.render_template(_template, **context) |
| self.response.write(rv) |
| |
| Then extended handlers can render templates directly:: |
| |
| class MyHandler(BaseHandler): |
| def get(self): |
| context = {'message': 'Hello, world!'} |
| self.render_response('my_template.html', **context) |
| """ |
| |
| #: Configuration key. |
| config_key = __name__ |
| |
| #: Loaded configuration. |
| config = None |
| |
| def __init__(self, app, config=None): |
| self.config = config = app.config.load_config(self.config_key, |
| default_values=default_config, user_values=config, |
| required_keys=None) |
| |
| directories = config.get('template_path') |
| if isinstance(directories, basestring): |
| directories = [directories] |
| |
| self.environment = lookup.TemplateLookup(directories=directories, |
| output_encoding='utf-8', |
| encoding_errors='replace') |
| |
| def render_template(self, _filename, **context): |
| """Renders a template and returns a response object. |
| |
| :param _filename: |
| The template filename, related to the templates directory. |
| :param context: |
| Keyword arguments used as variables in the rendered template. |
| These will override values set in the request context. |
| :returns: |
| A rendered template. |
| """ |
| template = self.environment.get_template(_filename) |
| return template.render_unicode(**context) |
| |
| |
| # Factories ------------------------------------------------------------------- |
| |
| |
| #: Key used to store :class:`Mako` in the app registry. |
| _registry_key = 'webapp2_extras.mako.Mako' |
| |
| |
| def get_mako(factory=Mako, key=_registry_key, app=None): |
| """Returns an instance of :class:`Mako` from the app registry. |
| |
| It'll try to get it from the current app registry, and if it is not |
| registered it'll be instantiated and registered. A second call to this |
| function will return the same instance. |
| |
| :param factory: |
| The callable used to build and register the instance if it is not yet |
| registered. The default is the class :class:`Mako` itself. |
| :param key: |
| The key used to store the instance in the registry. A default is used |
| if it is not set. |
| :param app: |
| A :class:`webapp2.WSGIApplication` instance used to store the instance. |
| The active app is used if it is not set. |
| """ |
| app = app or webapp2.get_app() |
| mako = app.registry.get(key) |
| if not mako: |
| mako = app.registry[key] = factory(app) |
| |
| return mako |
| |
| |
| def set_mako(mako, key=_registry_key, app=None): |
| """Sets an instance of :class:`Mako` in the app registry. |
| |
| :param store: |
| An instance of :class:`Mako`. |
| :param key: |
| The key used to retrieve the instance from the registry. A default |
| is used if it is not set. |
| :param request: |
| A :class:`webapp2.WSGIApplication` instance used to retrieve the |
| instance. The active app is used if it is not set. |
| """ |
| app = app or webapp2.get_app() |
| app.registry[key] = mako |