diff options
Diffstat (limited to 'nikola/plugins/template/mako.py')
| -rw-r--r-- | nikola/plugins/template/mako.py | 115 |
1 files changed, 115 insertions, 0 deletions
diff --git a/nikola/plugins/template/mako.py b/nikola/plugins/template/mako.py new file mode 100644 index 0000000..ae51cac --- /dev/null +++ b/nikola/plugins/template/mako.py @@ -0,0 +1,115 @@ +# -*- coding: utf-8 -*- + +# Copyright © 2012-2013 Roberto Alsina and others. + +# Permission is hereby granted, free of charge, to any +# person obtaining a copy of this software and associated +# documentation files (the "Software"), to deal in the +# Software without restriction, including without limitation +# the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the +# Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice +# shall be included in all copies or substantial portions of +# the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +# PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS +# OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR +# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +"""Mako template handlers""" +from __future__ import unicode_literals, print_function, absolute_import +import os +import shutil +import sys +import tempfile + +from mako import util, lexer +from mako.lookup import TemplateLookup +from mako.template import Template +from markupsafe import Markup # It's ok, Mako requires it + +from nikola.plugin_categories import TemplateSystem +from nikola.utils import makedirs, get_logger, STDERR_HANDLER + +LOGGER = get_logger('mako', STDERR_HANDLER) + + +class MakoTemplates(TemplateSystem): + """Wrapper for Mako templates.""" + + name = "mako" + + lookup = None + cache = {} + + def get_deps(self, filename): + text = util.read_file(filename) + lex = lexer.Lexer(text=text, filename=filename) + lex.parse() + + deps = [] + for n in lex.template.nodes: + keyword = getattr(n, 'keyword', None) + if keyword in ["inherit", "namespace"]: + deps.append(n.attributes['file']) + # TODO: include tags are not handled + return deps + + def set_directories(self, directories, cache_folder): + """Create a template lookup.""" + cache_dir = os.path.join(cache_folder, '.mako.tmp') + # Workaround for a Mako bug, Issue #825 + if sys.version_info[0] == 2: + try: + os.path.abspath(cache_dir).decode('ascii') + except UnicodeEncodeError: + cache_dir = tempfile.mkdtemp() + LOGGER.warning('Because of a Mako bug, setting cache_dir to {0}'.format(cache_dir)) + + if os.path.exists(cache_dir): + shutil.rmtree(cache_dir) + self.lookup = TemplateLookup( + directories=directories, + module_directory=cache_dir, + output_encoding='utf-8') + + def render_template(self, template_name, output_name, context): + """Render the template into output_name using context.""" + context['striphtml'] = striphtml + template = self.lookup.get_template(template_name) + data = template.render_unicode(**context) + if output_name is not None: + makedirs(os.path.dirname(output_name)) + with open(output_name, 'w+') as output: + output.write(data) + return data + + def render_template_to_string(self, template, context): + """ Render template to a string using context. """ + + return Template(template).render(**context) + + def template_deps(self, template_name): + """Returns filenames which are dependencies for a template.""" + # We can cache here because dependencies should + # not change between runs + if self.cache.get(template_name, None) is None: + template = self.lookup.get_template(template_name) + dep_filenames = self.get_deps(template.filename) + deps = [template.filename] + for fname in dep_filenames: + deps += self.template_deps(fname) + self.cache[template_name] = tuple(deps) + return list(self.cache[template_name]) + + +def striphtml(text): + return Markup(text).striptags() |
