summaryrefslogtreecommitdiffstats
path: root/nikola/plugins/template/mako.py
diff options
context:
space:
mode:
Diffstat (limited to 'nikola/plugins/template/mako.py')
-rw-r--r--nikola/plugins/template/mako.py115
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()