summaryrefslogtreecommitdiffstats
path: root/nikola/plugins/template
diff options
context:
space:
mode:
authorLibravatarAgustin Henze <tin@sluc.org.ar>2013-11-20 16:58:50 -0300
committerLibravatarAgustin Henze <tin@sluc.org.ar>2013-11-20 16:58:50 -0300
commitca94afc07df55cb7fc6fe3b4f3011877b7881195 (patch)
treed81e1f275aa77545f33740723f307a83dde2e0b4 /nikola/plugins/template
parentf794eee787e9cde54e6b8f53e45d69c9ddc9936a (diff)
Imported Upstream version 6.2.1upstream/6.2.1
Diffstat (limited to 'nikola/plugins/template')
-rw-r--r--nikola/plugins/template/__init__.py0
-rw-r--r--nikola/plugins/template/jinja.plugin9
-rw-r--r--nikola/plugins/template/jinja.py102
-rw-r--r--nikola/plugins/template/mako.plugin9
-rw-r--r--nikola/plugins/template/mako.py115
5 files changed, 235 insertions, 0 deletions
diff --git a/nikola/plugins/template/__init__.py b/nikola/plugins/template/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/nikola/plugins/template/__init__.py
diff --git a/nikola/plugins/template/jinja.plugin b/nikola/plugins/template/jinja.plugin
new file mode 100644
index 0000000..53b0fec
--- /dev/null
+++ b/nikola/plugins/template/jinja.plugin
@@ -0,0 +1,9 @@
+[Core]
+Name = jinja
+Module = jinja
+
+[Documentation]
+Author = Roberto Alsina
+Version = 0.1
+Website = http://getnikola.com
+Description = Support for Jinja2 templates.
diff --git a/nikola/plugins/template/jinja.py b/nikola/plugins/template/jinja.py
new file mode 100644
index 0000000..a40a476
--- /dev/null
+++ b/nikola/plugins/template/jinja.py
@@ -0,0 +1,102 @@
+# -*- 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.
+
+"""Jinja template handlers"""
+
+import os
+import json
+from collections import deque
+try:
+ import jinja2
+ from jinja2 import meta
+except ImportError:
+ jinja2 = None # NOQA
+
+from nikola.plugin_categories import TemplateSystem
+from nikola.utils import makedirs, req_missing
+
+
+class JinjaTemplates(TemplateSystem):
+ """Wrapper for Jinja2 templates."""
+
+ name = "jinja"
+ lookup = None
+ dependency_cache = {}
+
+ def __init__(self):
+ """ initialize Jinja2 wrapper with extended set of filters"""
+ if jinja2 is None:
+ return
+ self.lookup = jinja2.Environment()
+ self.lookup.filters['tojson'] = json.dumps
+ self.lookup.globals['enumerate'] = enumerate
+
+ def set_directories(self, directories, cache_folder):
+ """Createa template lookup."""
+ if jinja2 is None:
+ req_missing(['jinja2'], 'use this theme')
+ self.lookup.loader = jinja2.FileSystemLoader(directories,
+ encoding='utf-8')
+
+ def render_template(self, template_name, output_name, context):
+ """Render the template into output_name using context."""
+ if jinja2 is None:
+ req_missing(['jinja2'], 'use this theme')
+ template = self.lookup.get_template(template_name)
+ output = template.render(**context)
+ if output_name is not None:
+ makedirs(os.path.dirname(output_name))
+ with open(output_name, 'w+') as output:
+ output.write(output.encode('utf8'))
+ return output
+
+ def render_template_to_string(self, template, context):
+ """ Render template to a string using context. """
+
+ return jinja2.Template(template).render(**context)
+
+ def template_deps(self, template_name):
+ # Cache the lists of dependencies for each template name.
+ if self.dependency_cache.get(template_name) is None:
+ # Use a breadth-first search to find all templates this one
+ # depends on.
+ queue = deque([template_name])
+ visited_templates = set([template_name])
+ deps = []
+ while len(queue) > 0:
+ curr = queue.popleft()
+ source, filename = self.lookup.loader.get_source(self.lookup,
+ curr)[:2]
+ deps.append(filename)
+ ast = self.lookup.parse(source)
+ dep_names = meta.find_referenced_templates(ast)
+ for dep_name in dep_names:
+ if (dep_name not in visited_templates
+ and dep_name is not None):
+ visited_templates.add(dep_name)
+ queue.append(dep_name)
+ self.dependency_cache[template_name] = deps
+ return self.dependency_cache[template_name]
diff --git a/nikola/plugins/template/mako.plugin b/nikola/plugins/template/mako.plugin
new file mode 100644
index 0000000..71f2c71
--- /dev/null
+++ b/nikola/plugins/template/mako.plugin
@@ -0,0 +1,9 @@
+[Core]
+Name = mako
+Module = mako
+
+[Documentation]
+Author = Roberto Alsina
+Version = 0.1
+Website = http://getnikola.com
+Description = Support for Mako templates.
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()