Source code for webapp2_extras.mako

# -*- coding: utf-8 -*-
# Copyright 2011 webapp2 AUTHORS.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""
webapp2_extras.mako
===================

Mako template support for webapp2.

Learn more about Mako: http://www.makotemplates.org/
"""
import importlib

import six
import webapp2


lookup = importlib.import_module('mako.lookup')

#: Default configuration values for this module. Keys are:
#:
#: template_path
#:     Directory for templates. Default is `templates`.
default_config = {
    'template_path': 'templates',
}


[docs]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, six.string_types): directories = [directories] self.environment = lookup.TemplateLookup(directories=directories, output_encoding='utf-8', encoding_errors='replace')
[docs] 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'
[docs]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
[docs]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