bbf6d9b026
Bugfix for feeds - removed categories related and up - load new books now working - category random now working login page is free of non accessible elements boolean custom column is vivible in UI books with only with certain languages can be shown book shelfs can be deleted from UI Anonymous user view is more resticted Added browse of series in sidebar Dependencys in vendor folder are updated to newer versions (licencs files are now present) Bugfix editing Authors names Made upload on windows working
103 lines
4.1 KiB
Python
103 lines
4.1 KiB
Python
# -*- coding: utf-8 -*-
|
|
"""
|
|
jinja2.meta
|
|
~~~~~~~~~~~
|
|
|
|
This module implements various functions that exposes information about
|
|
templates that might be interesting for various kinds of applications.
|
|
|
|
:copyright: (c) 2010 by the Jinja Team, see AUTHORS for more details.
|
|
:license: BSD, see LICENSE for more details.
|
|
"""
|
|
from jinja2 import nodes
|
|
from jinja2.compiler import CodeGenerator
|
|
from jinja2._compat import string_types
|
|
|
|
|
|
class TrackingCodeGenerator(CodeGenerator):
|
|
"""We abuse the code generator for introspection."""
|
|
|
|
def __init__(self, environment):
|
|
CodeGenerator.__init__(self, environment, '<introspection>',
|
|
'<introspection>')
|
|
self.undeclared_identifiers = set()
|
|
|
|
def write(self, x):
|
|
"""Don't write."""
|
|
|
|
def pull_locals(self, frame):
|
|
"""Remember all undeclared identifiers."""
|
|
self.undeclared_identifiers.update(frame.identifiers.undeclared)
|
|
|
|
|
|
def find_undeclared_variables(ast):
|
|
"""Returns a set of all variables in the AST that will be looked up from
|
|
the context at runtime. Because at compile time it's not known which
|
|
variables will be used depending on the path the execution takes at
|
|
runtime, all variables are returned.
|
|
|
|
>>> from jinja2 import Environment, meta
|
|
>>> env = Environment()
|
|
>>> ast = env.parse('{% set foo = 42 %}{{ bar + foo }}')
|
|
>>> meta.find_undeclared_variables(ast) == set(['bar'])
|
|
True
|
|
|
|
.. admonition:: Implementation
|
|
|
|
Internally the code generator is used for finding undeclared variables.
|
|
This is good to know because the code generator might raise a
|
|
:exc:`TemplateAssertionError` during compilation and as a matter of
|
|
fact this function can currently raise that exception as well.
|
|
"""
|
|
codegen = TrackingCodeGenerator(ast.environment)
|
|
codegen.visit(ast)
|
|
return codegen.undeclared_identifiers
|
|
|
|
|
|
def find_referenced_templates(ast):
|
|
"""Finds all the referenced templates from the AST. This will return an
|
|
iterator over all the hardcoded template extensions, inclusions and
|
|
imports. If dynamic inheritance or inclusion is used, `None` will be
|
|
yielded.
|
|
|
|
>>> from jinja2 import Environment, meta
|
|
>>> env = Environment()
|
|
>>> ast = env.parse('{% extends "layout.html" %}{% include helper %}')
|
|
>>> list(meta.find_referenced_templates(ast))
|
|
['layout.html', None]
|
|
|
|
This function is useful for dependency tracking. For example if you want
|
|
to rebuild parts of the website after a layout template has changed.
|
|
"""
|
|
for node in ast.find_all((nodes.Extends, nodes.FromImport, nodes.Import,
|
|
nodes.Include)):
|
|
if not isinstance(node.template, nodes.Const):
|
|
# a tuple with some non consts in there
|
|
if isinstance(node.template, (nodes.Tuple, nodes.List)):
|
|
for template_name in node.template.items:
|
|
# something const, only yield the strings and ignore
|
|
# non-string consts that really just make no sense
|
|
if isinstance(template_name, nodes.Const):
|
|
if isinstance(template_name.value, string_types):
|
|
yield template_name.value
|
|
# something dynamic in there
|
|
else:
|
|
yield None
|
|
# something dynamic we don't know about here
|
|
else:
|
|
yield None
|
|
continue
|
|
# constant is a basestring, direct template name
|
|
if isinstance(node.template.value, string_types):
|
|
yield node.template.value
|
|
# a tuple or list (latter *should* not happen) made of consts,
|
|
# yield the consts that are strings. We could warn here for
|
|
# non string values
|
|
elif isinstance(node, nodes.Include) and \
|
|
isinstance(node.template.value, (tuple, list)):
|
|
for template_name in node.template.value:
|
|
if isinstance(template_name, string_types):
|
|
yield template_name
|
|
# something else we don't care about, we could warn here
|
|
else:
|
|
yield None
|