diff options
Diffstat (limited to 'nikola/plugins/template/jinja.py')
| -rw-r--r-- | nikola/plugins/template/jinja.py | 102 |
1 files changed, 102 insertions, 0 deletions
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] |
