diff options
| author | 2013-11-20 16:58:50 -0300 | |
|---|---|---|
| committer | 2013-11-20 16:58:50 -0300 | |
| commit | ca94afc07df55cb7fc6fe3b4f3011877b7881195 (patch) | |
| tree | d81e1f275aa77545f33740723f307a83dde2e0b4 /nikola/plugins/template | |
| parent | f794eee787e9cde54e6b8f53e45d69c9ddc9936a (diff) | |
Imported Upstream version 6.2.1upstream/6.2.1
Diffstat (limited to 'nikola/plugins/template')
| -rw-r--r-- | nikola/plugins/template/__init__.py | 0 | ||||
| -rw-r--r-- | nikola/plugins/template/jinja.plugin | 9 | ||||
| -rw-r--r-- | nikola/plugins/template/jinja.py | 102 | ||||
| -rw-r--r-- | nikola/plugins/template/mako.plugin | 9 | ||||
| -rw-r--r-- | nikola/plugins/template/mako.py | 115 |
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() |
