summaryrefslogtreecommitdiff
path: root/lib/python2.7/site-packages/django/template
diff options
context:
space:
mode:
authorcoderick142017-05-17 15:40:18 +0530
committercoderick142017-05-17 15:41:00 +0530
commita1e0a5502f04da68b6a9ca8508dda3f9d7e1d055 (patch)
tree20181e6b1936f50ad48d8e35720d64a37566f558 /lib/python2.7/site-packages/django/template
parent6f4a84c1e58ff4d54aab94cbee26e995328b05b8 (diff)
downloadSBHS-2018-Rpi-a1e0a5502f04da68b6a9ca8508dda3f9d7e1d055.tar.gz
SBHS-2018-Rpi-a1e0a5502f04da68b6a9ca8508dda3f9d7e1d055.tar.bz2
SBHS-2018-Rpi-a1e0a5502f04da68b6a9ca8508dda3f9d7e1d055.zip
Upgrade to Django 1.11
- Database integration yet to be tested
Diffstat (limited to 'lib/python2.7/site-packages/django/template')
-rw-r--r--lib/python2.7/site-packages/django/template/__init__.py80
-rw-r--r--lib/python2.7/site-packages/django/template/base.py1335
-rw-r--r--lib/python2.7/site-packages/django/template/context.py169
-rw-r--r--lib/python2.7/site-packages/django/template/debug.py101
-rw-r--r--lib/python2.7/site-packages/django/template/defaultfilters.py893
-rw-r--r--lib/python2.7/site-packages/django/template/defaulttags.py1409
-rw-r--r--lib/python2.7/site-packages/django/template/loader.py188
-rw-r--r--lib/python2.7/site-packages/django/template/loader_tags.py265
-rw-r--r--lib/python2.7/site-packages/django/template/loaders/__init__.py0
-rw-r--r--lib/python2.7/site-packages/django/template/loaders/app_directories.py63
-rw-r--r--lib/python2.7/site-packages/django/template/loaders/cached.py64
-rw-r--r--lib/python2.7/site-packages/django/template/loaders/eggs.py33
-rw-r--r--lib/python2.7/site-packages/django/template/loaders/filesystem.py46
-rw-r--r--lib/python2.7/site-packages/django/template/response.py159
-rw-r--r--lib/python2.7/site-packages/django/template/smartif.py205
15 files changed, 0 insertions, 5010 deletions
diff --git a/lib/python2.7/site-packages/django/template/__init__.py b/lib/python2.7/site-packages/django/template/__init__.py
deleted file mode 100644
index ca1bd49..0000000
--- a/lib/python2.7/site-packages/django/template/__init__.py
+++ /dev/null
@@ -1,80 +0,0 @@
-"""
-This is the Django template system.
-
-How it works:
-
-The Lexer.tokenize() function converts a template string (i.e., a string containing
-markup with custom template tags) to tokens, which can be either plain text
-(TOKEN_TEXT), variables (TOKEN_VAR) or block statements (TOKEN_BLOCK).
-
-The Parser() class takes a list of tokens in its constructor, and its parse()
-method returns a compiled template -- which is, under the hood, a list of
-Node objects.
-
-Each Node is responsible for creating some sort of output -- e.g. simple text
-(TextNode), variable values in a given context (VariableNode), results of basic
-logic (IfNode), results of looping (ForNode), or anything else. The core Node
-types are TextNode, VariableNode, IfNode and ForNode, but plugin modules can
-define their own custom node types.
-
-Each Node has a render() method, which takes a Context and returns a string of
-the rendered node. For example, the render() method of a Variable Node returns
-the variable's value as a string. The render() method of an IfNode returns the
-rendered output of whatever was inside the loop, recursively.
-
-The Template class is a convenient wrapper that takes care of template
-compilation and rendering.
-
-Usage:
-
-The only thing you should ever use directly in this file is the Template class.
-Create a compiled template object with a template_string, then call render()
-with a context. In the compilation stage, the TemplateSyntaxError exception
-will be raised if the template doesn't have proper syntax.
-
-Sample code:
-
->>> from django import template
->>> s = u'<html>{% if test %}<h1>{{ varvalue }}</h1>{% endif %}</html>'
->>> t = template.Template(s)
-
-(t is now a compiled template, and its render() method can be called multiple
-times with multiple contexts)
-
->>> c = template.Context({'test':True, 'varvalue': 'Hello'})
->>> t.render(c)
-u'<html><h1>Hello</h1></html>'
->>> c = template.Context({'test':False, 'varvalue': 'Hello'})
->>> t.render(c)
-u'<html></html>'
-"""
-
-# Template lexing symbols
-from django.template.base import (ALLOWED_VARIABLE_CHARS, BLOCK_TAG_END,
- BLOCK_TAG_START, COMMENT_TAG_END, COMMENT_TAG_START,
- FILTER_ARGUMENT_SEPARATOR, FILTER_SEPARATOR, SINGLE_BRACE_END,
- SINGLE_BRACE_START, TOKEN_BLOCK, TOKEN_COMMENT, TOKEN_TEXT, TOKEN_VAR,
- TRANSLATOR_COMMENT_MARK, UNKNOWN_SOURCE, VARIABLE_ATTRIBUTE_SEPARATOR,
- VARIABLE_TAG_END, VARIABLE_TAG_START, filter_re, tag_re)
-
-# Exceptions
-from django.template.base import (ContextPopException, InvalidTemplateLibrary,
- TemplateDoesNotExist, TemplateEncodingError, TemplateSyntaxError,
- VariableDoesNotExist)
-
-# Template parts
-from django.template.base import (Context, FilterExpression, Lexer, Node,
- NodeList, Parser, RequestContext, Origin, StringOrigin, Template,
- TextNode, Token, TokenParser, Variable, VariableNode, constant_string,
- filter_raw_string)
-
-# Compiling templates
-from django.template.base import (compile_string, resolve_variable,
- unescape_string_literal, generic_tag_compiler)
-
-# Library management
-from django.template.base import (Library, add_to_builtins, builtins,
- get_library, get_templatetags_modules, get_text_list, import_library,
- libraries)
-
-__all__ = ('Template', 'Context', 'RequestContext', 'compile_string')
diff --git a/lib/python2.7/site-packages/django/template/base.py b/lib/python2.7/site-packages/django/template/base.py
deleted file mode 100644
index 26f8111..0000000
--- a/lib/python2.7/site-packages/django/template/base.py
+++ /dev/null
@@ -1,1335 +0,0 @@
-from __future__ import absolute_import, unicode_literals
-
-import re
-from functools import partial
-from inspect import getargspec
-
-from django.conf import settings
-from django.template.context import (BaseContext, Context, RequestContext,
- ContextPopException)
-from django.utils.importlib import import_module
-from django.utils.itercompat import is_iterable
-from django.utils.text import (smart_split, unescape_string_literal,
- get_text_list)
-from django.utils.encoding import force_str, force_text
-from django.utils.translation import ugettext_lazy, pgettext_lazy
-from django.utils.safestring import (SafeData, EscapeData, mark_safe,
- mark_for_escaping)
-from django.utils.formats import localize
-from django.utils.html import escape
-from django.utils.module_loading import module_has_submodule
-from django.utils import six
-from django.utils.timezone import template_localtime
-from django.utils.encoding import python_2_unicode_compatible
-
-
-TOKEN_TEXT = 0
-TOKEN_VAR = 1
-TOKEN_BLOCK = 2
-TOKEN_COMMENT = 3
-TOKEN_MAPPING = {
- TOKEN_TEXT: 'Text',
- TOKEN_VAR: 'Var',
- TOKEN_BLOCK: 'Block',
- TOKEN_COMMENT: 'Comment',
-}
-
-# template syntax constants
-FILTER_SEPARATOR = '|'
-FILTER_ARGUMENT_SEPARATOR = ':'
-VARIABLE_ATTRIBUTE_SEPARATOR = '.'
-BLOCK_TAG_START = '{%'
-BLOCK_TAG_END = '%}'
-VARIABLE_TAG_START = '{{'
-VARIABLE_TAG_END = '}}'
-COMMENT_TAG_START = '{#'
-COMMENT_TAG_END = '#}'
-TRANSLATOR_COMMENT_MARK = 'Translators'
-SINGLE_BRACE_START = '{'
-SINGLE_BRACE_END = '}'
-
-ALLOWED_VARIABLE_CHARS = ('abcdefghijklmnopqrstuvwxyz'
- 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_.')
-
-# what to report as the origin for templates that come from non-loader sources
-# (e.g. strings)
-UNKNOWN_SOURCE = '<unknown source>'
-
-# match a variable or block tag and capture the entire tag, including start/end
-# delimiters
-tag_re = (re.compile('(%s.*?%s|%s.*?%s|%s.*?%s)' %
- (re.escape(BLOCK_TAG_START), re.escape(BLOCK_TAG_END),
- re.escape(VARIABLE_TAG_START), re.escape(VARIABLE_TAG_END),
- re.escape(COMMENT_TAG_START), re.escape(COMMENT_TAG_END))))
-
-# global dictionary of libraries that have been loaded using get_library
-libraries = {}
-# global list of libraries to load by default for a new parser
-builtins = []
-
-# True if TEMPLATE_STRING_IF_INVALID contains a format string (%s). None means
-# uninitialised.
-invalid_var_format_string = None
-
-class TemplateSyntaxError(Exception):
- pass
-
-class TemplateDoesNotExist(Exception):
- pass
-
-class TemplateEncodingError(Exception):
- pass
-
-@python_2_unicode_compatible
-class VariableDoesNotExist(Exception):
-
- def __init__(self, msg, params=()):
- self.msg = msg
- self.params = params
-
- def __str__(self):
- return self.msg % tuple([force_text(p, errors='replace')
- for p in self.params])
-
-class InvalidTemplateLibrary(Exception):
- pass
-
-class Origin(object):
- def __init__(self, name):
- self.name = name
-
- def reload(self):
- raise NotImplementedError
-
- def __str__(self):
- return self.name
-
-class StringOrigin(Origin):
- def __init__(self, source):
- super(StringOrigin, self).__init__(UNKNOWN_SOURCE)
- self.source = source
-
- def reload(self):
- return self.source
-
-class Template(object):
- def __init__(self, template_string, origin=None,
- name='<Unknown Template>'):
- try:
- template_string = force_text(template_string)
- except UnicodeDecodeError:
- raise TemplateEncodingError("Templates can only be constructed "
- "from unicode or UTF-8 strings.")
- if settings.TEMPLATE_DEBUG and origin is None:
- origin = StringOrigin(template_string)
- self.nodelist = compile_string(template_string, origin)
- self.name = name
-
- def __iter__(self):
- for node in self.nodelist:
- for subnode in node:
- yield subnode
-
- def _render(self, context):
- return self.nodelist.render(context)
-
- def render(self, context):
- "Display stage -- can be called many times"
- context.render_context.push()
- try:
- return self._render(context)
- finally:
- context.render_context.pop()
-
-def compile_string(template_string, origin):
- "Compiles template_string into NodeList ready for rendering"
- if settings.TEMPLATE_DEBUG:
- from django.template.debug import DebugLexer, DebugParser
- lexer_class, parser_class = DebugLexer, DebugParser
- else:
- lexer_class, parser_class = Lexer, Parser
- lexer = lexer_class(template_string, origin)
- parser = parser_class(lexer.tokenize())
- return parser.parse()
-
-class Token(object):
- def __init__(self, token_type, contents):
- # token_type must be TOKEN_TEXT, TOKEN_VAR, TOKEN_BLOCK or
- # TOKEN_COMMENT.
- self.token_type, self.contents = token_type, contents
- self.lineno = None
-
- def __str__(self):
- token_name = TOKEN_MAPPING[self.token_type]
- return ('<%s token: "%s...">' %
- (token_name, self.contents[:20].replace('\n', '')))
-
- def split_contents(self):
- split = []
- bits = iter(smart_split(self.contents))
- for bit in bits:
- # Handle translation-marked template pieces
- if bit.startswith('_("') or bit.startswith("_('"):
- sentinal = bit[2] + ')'
- trans_bit = [bit]
- while not bit.endswith(sentinal):
- bit = next(bits)
- trans_bit.append(bit)
- bit = ' '.join(trans_bit)
- split.append(bit)
- return split
-
-class Lexer(object):
- def __init__(self, template_string, origin):
- self.template_string = template_string
- self.origin = origin
- self.lineno = 1
- self.verbatim = False
-
- def tokenize(self):
- """
- Return a list of tokens from a given template_string.
- """
- in_tag = False
- result = []
- for bit in tag_re.split(self.template_string):
- if bit:
- result.append(self.create_token(bit, in_tag))
- in_tag = not in_tag
- return result
-
- def create_token(self, token_string, in_tag):
- """
- Convert the given token string into a new Token object and return it.
- If in_tag is True, we are processing something that matched a tag,
- otherwise it should be treated as a literal string.
- """
- if in_tag and token_string.startswith(BLOCK_TAG_START):
- # The [2:-2] ranges below strip off *_TAG_START and *_TAG_END.
- # We could do len(BLOCK_TAG_START) to be more "correct", but we've
- # hard-coded the 2s here for performance. And it's not like
- # the TAG_START values are going to change anytime, anyway.
- block_content = token_string[2:-2].strip()
- if self.verbatim and block_content == self.verbatim:
- self.verbatim = False
- if in_tag and not self.verbatim:
- if token_string.startswith(VARIABLE_TAG_START):
- token = Token(TOKEN_VAR, token_string[2:-2].strip())
- elif token_string.startswith(BLOCK_TAG_START):
- if block_content[:9] in ('verbatim', 'verbatim '):
- self.verbatim = 'end%s' % block_content
- token = Token(TOKEN_BLOCK, block_content)
- elif token_string.startswith(COMMENT_TAG_START):
- content = ''
- if token_string.find(TRANSLATOR_COMMENT_MARK):
- content = token_string[2:-2].strip()
- token = Token(TOKEN_COMMENT, content)
- else:
- token = Token(TOKEN_TEXT, token_string)
- token.lineno = self.lineno
- self.lineno += token_string.count('\n')
- return token
-
-class Parser(object):
- def __init__(self, tokens):
- self.tokens = tokens
- self.tags = {}
- self.filters = {}
- for lib in builtins:
- self.add_library(lib)
-
- def parse(self, parse_until=None):
- if parse_until is None:
- parse_until = []
- nodelist = self.create_nodelist()
- while self.tokens:
- token = self.next_token()
- # Use the raw values here for TOKEN_* for a tiny performance boost.
- if token.token_type == 0: # TOKEN_TEXT
- self.extend_nodelist(nodelist, TextNode(token.contents), token)
- elif token.token_type == 1: # TOKEN_VAR
- if not token.contents:
- self.empty_variable(token)
- try:
- filter_expression = self.compile_filter(token.contents)
- except TemplateSyntaxError as e:
- if not self.compile_filter_error(token, e):
- raise
- var_node = self.create_variable_node(filter_expression)
- self.extend_nodelist(nodelist, var_node, token)
- elif token.token_type == 2: # TOKEN_BLOCK
- try:
- command = token.contents.split()[0]
- except IndexError:
- self.empty_block_tag(token)
- if command in parse_until:
- # put token back on token list so calling
- # code knows why it terminated
- self.prepend_token(token)
- return nodelist
- # execute callback function for this tag and append
- # resulting node
- self.enter_command(command, token)
- try:
- compile_func = self.tags[command]
- except KeyError:
- self.invalid_block_tag(token, command, parse_until)
- try:
- compiled_result = compile_func(self, token)
- except TemplateSyntaxError as e:
- if not self.compile_function_error(token, e):
- raise
- self.extend_nodelist(nodelist, compiled_result, token)
- self.exit_command()
- if parse_until:
- self.unclosed_block_tag(parse_until)
- return nodelist
-
- def skip_past(self, endtag):
- while self.tokens:
- token = self.next_token()
- if token.token_type == TOKEN_BLOCK and token.contents == endtag:
- return
- self.unclosed_block_tag([endtag])
-
- def create_variable_node(self, filter_expression):
- return VariableNode(filter_expression)
-
- def create_nodelist(self):
- return NodeList()
-
- def extend_nodelist(self, nodelist, node, token):
- if node.must_be_first and nodelist:
- try:
- if nodelist.contains_nontext:
- raise AttributeError
- except AttributeError:
- raise TemplateSyntaxError("%r must be the first tag "
- "in the template." % node)
- if isinstance(nodelist, NodeList) and not isinstance(node, TextNode):
- nodelist.contains_nontext = True
- nodelist.append(node)
-
- def enter_command(self, command, token):
- pass
-
- def exit_command(self):
- pass
-
- def error(self, token, msg):
- return TemplateSyntaxError(msg)
-
- def empty_variable(self, token):
- raise self.error(token, "Empty variable tag")
-
- def empty_block_tag(self, token):
- raise self.error(token, "Empty block tag")
-
- def invalid_block_tag(self, token, command, parse_until=None):
- if parse_until:
- raise self.error(token, "Invalid block tag: '%s', expected %s" %
- (command, get_text_list(["'%s'" % p for p in parse_until])))
- raise self.error(token, "Invalid block tag: '%s'" % command)
-
- def unclosed_block_tag(self, parse_until):
- raise self.error(None, "Unclosed tags: %s " % ', '.join(parse_until))
-
- def compile_filter_error(self, token, e):
- pass
-
- def compile_function_error(self, token, e):
- pass
-
- def next_token(self):
- return self.tokens.pop(0)
-
- def prepend_token(self, token):
- self.tokens.insert(0, token)
-
- def delete_first_token(self):
- del self.tokens[0]
-
- def add_library(self, lib):
- self.tags.update(lib.tags)
- self.filters.update(lib.filters)
-
- def compile_filter(self, token):
- """
- Convenient wrapper for FilterExpression
- """
- return FilterExpression(token, self)
-
- def find_filter(self, filter_name):
- if filter_name in self.filters:
- return self.filters[filter_name]
- else:
- raise TemplateSyntaxError("Invalid filter: '%s'" % filter_name)
-
-class TokenParser(object):
- """
- Subclass this and implement the top() method to parse a template line.
- When instantiating the parser, pass in the line from the Django template
- parser.
-
- The parser's "tagname" instance-variable stores the name of the tag that
- the filter was called with.
- """
- def __init__(self, subject):
- self.subject = subject
- self.pointer = 0
- self.backout = []
- self.tagname = self.tag()
-
- def top(self):
- """
- Overload this method to do the actual parsing and return the result.
- """
- raise NotImplementedError()
-
- def more(self):
- """
- Returns True if there is more stuff in the tag.
- """
- return self.pointer < len(self.subject)
-
- def back(self):
- """
- Undoes the last microparser. Use this for lookahead and backtracking.
- """
- if not len(self.backout):
- raise TemplateSyntaxError("back called without some previous "
- "parsing")
- self.pointer = self.backout.pop()
-
- def tag(self):
- """
- A microparser that just returns the next tag from the line.
- """
- subject = self.subject
- i = self.pointer
- if i >= len(subject):
- raise TemplateSyntaxError("expected another tag, found "
- "end of string: %s" % subject)
- p = i
- while i < len(subject) and subject[i] not in (' ', '\t'):
- i += 1
- s = subject[p:i]
- while i < len(subject) and subject[i] in (' ', '\t'):
- i += 1
- self.backout.append(self.pointer)
- self.pointer = i
- return s
-
- def value(self):
- """
- A microparser that parses for a value: some string constant or
- variable name.
- """
- subject = self.subject
- i = self.pointer
-
- def next_space_index(subject, i):
- """
- Increment pointer until a real space (i.e. a space not within
- quotes) is encountered
- """
- while i < len(subject) and subject[i] not in (' ', '\t'):
- if subject[i] in ('"', "'"):
- c = subject[i]
- i += 1
- while i < len(subject) and subject[i] != c:
- i += 1
- if i >= len(subject):
- raise TemplateSyntaxError("Searching for value. "
- "Unexpected end of string in column %d: %s" %
- (i, subject))
- i += 1
- return i
-
- if i >= len(subject):
- raise TemplateSyntaxError("Searching for value. Expected another "
- "value but found end of string: %s" %
- subject)
- if subject[i] in ('"', "'"):
- p = i
- i += 1
- while i < len(subject) and subject[i] != subject[p]:
- i += 1
- if i >= len(subject):
- raise TemplateSyntaxError("Searching for value. Unexpected "
- "end of string in column %d: %s" %
- (i, subject))
- i += 1
-
- # Continue parsing until next "real" space,
- # so that filters are also included
- i = next_space_index(subject, i)
-
- res = subject[p:i]
- while i < len(subject) and subject[i] in (' ', '\t'):
- i += 1
- self.backout.append(self.pointer)
- self.pointer = i
- return res
- else:
- p = i
- i = next_space_index(subject, i)
- s = subject[p:i]
- while i < len(subject) and subject[i] in (' ', '\t'):
- i += 1
- self.backout.append(self.pointer)
- self.pointer = i
- return s
-
-# This only matches constant *strings* (things in quotes or marked for
-# translation). Numbers are treated as variables for implementation reasons
-# (so that they retain their type when passed to filters).
-constant_string = r"""
-(?:%(i18n_open)s%(strdq)s%(i18n_close)s|
-%(i18n_open)s%(strsq)s%(i18n_close)s|
-%(strdq)s|
-%(strsq)s)
-""" % {
- 'strdq': r'"[^"\\]*(?:\\.[^"\\]*)*"', # double-quoted string
- 'strsq': r"'[^'\\]*(?:\\.[^'\\]*)*'", # single-quoted string
- 'i18n_open': re.escape("_("),
- 'i18n_close': re.escape(")"),
- }
-constant_string = constant_string.replace("\n", "")
-
-filter_raw_string = r"""
-^(?P<constant>%(constant)s)|
-^(?P<var>[%(var_chars)s]+|%(num)s)|
- (?:\s*%(filter_sep)s\s*
- (?P<filter_name>\w+)
- (?:%(arg_sep)s
- (?:
- (?P<constant_arg>%(constant)s)|
- (?P<var_arg>[%(var_chars)s]+|%(num)s)
- )
- )?
- )""" % {
- 'constant': constant_string,
- 'num': r'[-+\.]?\d[\d\.e]*',
- 'var_chars': "\w\.",
- 'filter_sep': re.escape(FILTER_SEPARATOR),
- 'arg_sep': re.escape(FILTER_ARGUMENT_SEPARATOR),
- }
-
-filter_re = re.compile(filter_raw_string, re.UNICODE | re.VERBOSE)
-
-class FilterExpression(object):
- """
- Parses a variable token and its optional filters (all as a single string),
- and return a list of tuples of the filter name and arguments.
- Sample::
-
- >>> token = 'variable|default:"Default value"|date:"Y-m-d"'
- >>> p = Parser('')
- >>> fe = FilterExpression(token, p)
- >>> len(fe.filters)
- 2
- >>> fe.var
- <Variable: 'variable'>
-
- This class should never be instantiated outside of the
- get_filters_from_token helper function.
- """
- def __init__(self, token, parser):
- self.token = token
- matches = filter_re.finditer(token)
- var_obj = None
- filters = []
- upto = 0
- for match in matches:
- start = match.start()
- if upto != start:
- raise TemplateSyntaxError("Could not parse some characters: "
- "%s|%s|%s" %
- (token[:upto], token[upto:start],
- token[start:]))
- if var_obj is None:
- var, constant = match.group("var", "constant")
- if constant:
- try:
- var_obj = Variable(constant).resolve({})
- except VariableDoesNotExist:
- var_obj = None
- elif var is None:
- raise TemplateSyntaxError("Could not find variable at "
- "start of %s." % token)
- else:
- var_obj = Variable(var)
- else:
- filter_name = match.group("filter_name")
- args = []
- constant_arg, var_arg = match.group("constant_arg", "var_arg")
- if constant_arg:
- args.append((False, Variable(constant_arg).resolve({})))
- elif var_arg:
- args.append((True, Variable(var_arg)))
- filter_func = parser.find_filter(filter_name)
- self.args_check(filter_name, filter_func, args)
- filters.append((filter_func, args))
- upto = match.end()
- if upto != len(token):
- raise TemplateSyntaxError("Could not parse the remainder: '%s' "
- "from '%s'" % (token[upto:], token))
-
- self.filters = filters
- self.var = var_obj
-
- def resolve(self, context, ignore_failures=False):
- if isinstance(self.var, Variable):
- try:
- obj = self.var.resolve(context)
- except VariableDoesNotExist:
- if ignore_failures:
- obj = None
- else:
- if settings.TEMPLATE_STRING_IF_INVALID:
- global invalid_var_format_string
- if invalid_var_format_string is None:
- invalid_var_format_string = '%s' in settings.TEMPLATE_STRING_IF_INVALID
- if invalid_var_format_string:
- return settings.TEMPLATE_STRING_IF_INVALID % self.var
- return settings.TEMPLATE_STRING_IF_INVALID
- else:
- obj = settings.TEMPLATE_STRING_IF_INVALID
- else:
- obj = self.var
- for func, args in self.filters:
- arg_vals = []
- for lookup, arg in args:
- if not lookup:
- arg_vals.append(mark_safe(arg))
- else:
- arg_vals.append(arg.resolve(context))
- if getattr(func, 'expects_localtime', False):
- obj = template_localtime(obj, context.use_tz)
- if getattr(func, 'needs_autoescape', False):
- new_obj = func(obj, autoescape=context.autoescape, *arg_vals)
- else:
- new_obj = func(obj, *arg_vals)
- if getattr(func, 'is_safe', False) and isinstance(obj, SafeData):
- obj = mark_safe(new_obj)
- elif isinstance(obj, EscapeData):
- obj = mark_for_escaping(new_obj)
- else:
- obj = new_obj
- return obj
-
- def args_check(name, func, provided):
- provided = list(provided)
- plen = len(provided)
- # Check to see if a decorator is providing the real function.
- func = getattr(func, '_decorated_function', func)
- args, varargs, varkw, defaults = getargspec(func)
- # First argument is filter input.
- args.pop(0)
- if defaults:
- nondefs = args[:-len(defaults)]
- else:
- nondefs = args
- # Args without defaults must be provided.
- try:
- for arg in nondefs:
- provided.pop(0)
- except IndexError:
- # Not enough
- raise TemplateSyntaxError("%s requires %d arguments, %d provided" %
- (name, len(nondefs), plen))
-
- # Defaults can be overridden.
- defaults = list(defaults) if defaults else []
- try:
- for parg in provided:
- defaults.pop(0)
- except IndexError:
- # Too many.
- raise TemplateSyntaxError("%s requires %d arguments, %d provided" %
- (name, len(nondefs), plen))
-
- return True
- args_check = staticmethod(args_check)
-
- def __str__(self):
- return self.token
-
-def resolve_variable(path, context):
- """
- Returns the resolved variable, which may contain attribute syntax, within
- the given context.
-
- Deprecated; use the Variable class instead.
- """
- return Variable(path).resolve(context)
-
-class Variable(object):
- """
- A template variable, resolvable against a given context. The variable may
- be a hard-coded string (if it begins and ends with single or double quote
- marks)::
-
- >>> c = {'article': {'section':u'News'}}
- >>> Variable('article.section').resolve(c)
- u'News'
- >>> Variable('article').resolve(c)
- {'section': u'News'}
- >>> class AClass: pass
- >>> c = AClass()
- >>> c.article = AClass()
- >>> c.article.section = u'News'
-
- (The example assumes VARIABLE_ATTRIBUTE_SEPARATOR is '.')
- """
-
- def __init__(self, var):
- self.var = var
- self.literal = None
- self.lookups = None
- self.translate = False
- self.message_context = None
-
- try:
- # First try to treat this variable as a number.
- #
- # Note that this could cause an OverflowError here that we're not
- # catching. Since this should only happen at compile time, that's
- # probably OK.
- self.literal = float(var)
-
- # So it's a float... is it an int? If the original value contained a
- # dot or an "e" then it was a float, not an int.
- if '.' not in var and 'e' not in var.lower():
- self.literal = int(self.literal)
-
- # "2." is invalid
- if var.endswith('.'):
- raise ValueError
-
- except ValueError:
- # A ValueError means that the variable isn't a number.
- if var.startswith('_(') and var.endswith(')'):
- # The result of the lookup should be translated at rendering
- # time.
- self.translate = True
- var = var[2:-1]
- # If it's wrapped with quotes (single or double), then
- # we're also dealing with a literal.
- try:
- self.literal = mark_safe(unescape_string_literal(var))
- except ValueError:
- # Otherwise we'll set self.lookups so that resolve() knows we're
- # dealing with a bonafide variable
- if var.find(VARIABLE_ATTRIBUTE_SEPARATOR + '_') > -1 or var[0] == '_':
- raise TemplateSyntaxError("Variables and attributes may "
- "not begin with underscores: '%s'" %
- var)
- self.lookups = tuple(var.split(VARIABLE_ATTRIBUTE_SEPARATOR))
-
- def resolve(self, context):
- """Resolve this variable against a given context."""
- if self.lookups is not None:
- # We're dealing with a variable that needs to be resolved
- value = self._resolve_lookup(context)
- else:
- # We're dealing with a literal, so it's already been "resolved"
- value = self.literal
- if self.translate:
- if self.message_context:
- return pgettext_lazy(self.message_context, value)
- else:
- return ugettext_lazy(value)
- return value
-
- def __repr__(self):
- return "<%s: %r>" % (self.__class__.__name__, self.var)
-
- def __str__(self):
- return self.var
-
- def _resolve_lookup(self, context):
- """
- Performs resolution of a real variable (i.e. not a literal) against the
- given context.
-
- As indicated by the method's name, this method is an implementation
- detail and shouldn't be called by external code. Use Variable.resolve()
- instead.
- """
- current = context
- try: # catch-all for silent variable failures
- for bit in self.lookups:
- try: # dictionary lookup
- current = current[bit]
- except (TypeError, AttributeError, KeyError, ValueError):
- try: # attribute lookup
- # Don't return class attributes if the class is the context:
- if isinstance(current, BaseContext) and getattr(type(current), bit):
- raise AttributeError
- current = getattr(current, bit)
- except (TypeError, AttributeError):
- try: # list-index lookup
- current = current[int(bit)]
- except (IndexError, # list index out of range
- ValueError, # invalid literal for int()
- KeyError, # current is a dict without `int(bit)` key
- TypeError): # unsubscriptable object
- raise VariableDoesNotExist("Failed lookup for key "
- "[%s] in %r",
- (bit, current)) # missing attribute
- if callable(current):
- if getattr(current, 'do_not_call_in_templates', False):
- pass
- elif getattr(current, 'alters_data', False):
- current = settings.TEMPLATE_STRING_IF_INVALID
- else:
- try: # method call (assuming no args required)
- current = current()
- except TypeError: # arguments *were* required
- # GOTCHA: This will also catch any TypeError
- # raised in the function itself.
- current = settings.TEMPLATE_STRING_IF_INVALID # invalid method call
- except Exception as e:
- if getattr(e, 'silent_variable_failure', False):
- current = settings.TEMPLATE_STRING_IF_INVALID
- else:
- raise
-
- return current
-
-class Node(object):
- # Set this to True for nodes that must be first in the template (although
- # they can be preceded by text nodes.
- must_be_first = False
- child_nodelists = ('nodelist',)
-
- def render(self, context):
- """
- Return the node rendered as a string.
- """
- pass
-
- def __iter__(self):
- yield self
-
- def get_nodes_by_type(self, nodetype):
- """
- Return a list of all nodes (within this node and its nodelist)
- of the given type
- """
- nodes = []
- if isinstance(self, nodetype):
- nodes.append(self)
- for attr in self.child_nodelists:
- nodelist = getattr(self, attr, None)
- if nodelist:
- nodes.extend(nodelist.get_nodes_by_type(nodetype))
- return nodes
-
-class NodeList(list):
- # Set to True the first time a non-TextNode is inserted by
- # extend_nodelist().
- contains_nontext = False
-
- def render(self, context):
- bits = []
- for node in self:
- if isinstance(node, Node):
- bit = self.render_node(node, context)
- else:
- bit = node
- bits.append(force_text(bit))
- return mark_safe(''.join(bits))
-
- def get_nodes_by_type(self, nodetype):
- "Return a list of all nodes of the given type"
- nodes = []
- for node in self:
- nodes.extend(node.get_nodes_by_type(nodetype))
- return nodes
-
- def render_node(self, node, context):
- return node.render(context)
-
-class TextNode(Node):
- def __init__(self, s):
- self.s = s
-
- def __repr__(self):
- return force_str("<Text Node: '%s'>" % self.s[:25], 'ascii',
- errors='replace')
-
- def render(self, context):
- return self.s
-
-def render_value_in_context(value, context):
- """
- Converts any value to a string to become part of a rendered template. This
- means escaping, if required, and conversion to a unicode object. If value
- is a string, it is expected to have already been translated.
- """
- value = template_localtime(value, use_tz=context.use_tz)
- value = localize(value, use_l10n=context.use_l10n)
- value = force_text(value)
- if ((context.autoescape and not isinstance(value, SafeData)) or
- isinstance(value, EscapeData)):
- return escape(value)
- else:
- return value
-
-class VariableNode(Node):
- def __init__(self, filter_expression):
- self.filter_expression = filter_expression
-
- def __repr__(self):
- return "<Variable Node: %s>" % self.filter_expression
-
- def render(self, context):
- try:
- output = self.filter_expression.resolve(context)
- except UnicodeDecodeError:
- # Unicode conversion can fail sometimes for reasons out of our
- # control (e.g. exception rendering). In that case, we fail
- # quietly.
- return ''
- return render_value_in_context(output, context)
-
-# Regex for token keyword arguments
-kwarg_re = re.compile(r"(?:(\w+)=)?(.+)")
-
-def token_kwargs(bits, parser, support_legacy=False):
- """
- A utility method for parsing token keyword arguments.
-
- :param bits: A list containing remainder of the token (split by spaces)
- that is to be checked for arguments. Valid arguments will be removed
- from this list.
-
- :param support_legacy: If set to true ``True``, the legacy format
- ``1 as foo`` will be accepted. Otherwise, only the standard ``foo=1``
- format is allowed.
-
- :returns: A dictionary of the arguments retrieved from the ``bits`` token
- list.
-
- There is no requirement for all remaining token ``bits`` to be keyword
- arguments, so the dictionary will be returned as soon as an invalid
- argument format is reached.
- """
- if not bits:
- return {}
- match = kwarg_re.match(bits[0])
- kwarg_format = match and match.group(1)
- if not kwarg_format:
- if not support_legacy:
- return {}
- if len(bits) < 3 or bits[1] != 'as':
- return {}
-
- kwargs = {}
- while bits:
- if kwarg_format:
- match = kwarg_re.match(bits[0])
- if not match or not match.group(1):
- return kwargs
- key, value = match.groups()
- del bits[:1]
- else:
- if len(bits) < 3 or bits[1] != 'as':
- return kwargs
- key, value = bits[2], bits[0]
- del bits[:3]
- kwargs[key] = parser.compile_filter(value)
- if bits and not kwarg_format:
- if bits[0] != 'and':
- return kwargs
- del bits[:1]
- return kwargs
-
-def parse_bits(parser, bits, params, varargs, varkw, defaults,
- takes_context, name):
- """
- Parses bits for template tag helpers (simple_tag, include_tag and
- assignment_tag), in particular by detecting syntax errors and by
- extracting positional and keyword arguments.
- """
- if takes_context:
- if params[0] == 'context':
- params = params[1:]
- else:
- raise TemplateSyntaxError(
- "'%s' is decorated with takes_context=True so it must "
- "have a first argument of 'context'" % name)
- args = []
- kwargs = {}
- unhandled_params = list(params)
- for bit in bits:
- # First we try to extract a potential kwarg from the bit
- kwarg = token_kwargs([bit], parser)
- if kwarg:
- # The kwarg was successfully extracted
- param, value = list(six.iteritems(kwarg))[0]
- if param not in params and varkw is None:
- # An unexpected keyword argument was supplied
- raise TemplateSyntaxError(
- "'%s' received unexpected keyword argument '%s'" %
- (name, param))
- elif param in kwargs:
- # The keyword argument has already been supplied once
- raise TemplateSyntaxError(
- "'%s' received multiple values for keyword argument '%s'" %
- (name, param))
- else:
- # All good, record the keyword argument
- kwargs[str(param)] = value
- if param in unhandled_params:
- # If using the keyword syntax for a positional arg, then
- # consume it.
- unhandled_params.remove(param)
- else:
- if kwargs:
- raise TemplateSyntaxError(
- "'%s' received some positional argument(s) after some "
- "keyword argument(s)" % name)
- else:
- # Record the positional argument
- args.append(parser.compile_filter(bit))
- try:
- # Consume from the list of expected positional arguments
- unhandled_params.pop(0)
- except IndexError:
- if varargs is None:
- raise TemplateSyntaxError(
- "'%s' received too many positional arguments" %
- name)
- if defaults is not None:
- # Consider the last n params handled, where n is the
- # number of defaults.
- unhandled_params = unhandled_params[:-len(defaults)]
- if unhandled_params:
- # Some positional arguments were not supplied
- raise TemplateSyntaxError(
- "'%s' did not receive value(s) for the argument(s): %s" %
- (name, ", ".join(["'%s'" % p for p in unhandled_params])))
- return args, kwargs
-
-def generic_tag_compiler(parser, token, params, varargs, varkw, defaults,
- name, takes_context, node_class):
- """
- Returns a template.Node subclass.
- """
- bits = token.split_contents()[1:]
- args, kwargs = parse_bits(parser, bits, params, varargs, varkw,
- defaults, takes_context, name)
- return node_class(takes_context, args, kwargs)
-
-class TagHelperNode(Node):
- """
- Base class for tag helper nodes such as SimpleNode, InclusionNode and
- AssignmentNode. Manages the positional and keyword arguments to be passed
- to the decorated function.
- """
-
- def __init__(self, takes_context, args, kwargs):
- self.takes_context = takes_context
- self.args = args
- self.kwargs = kwargs
-
- def get_resolved_arguments(self, context):
- resolved_args = [var.resolve(context) for var in self.args]
- if self.takes_context:
- resolved_args = [context] + resolved_args
- resolved_kwargs = dict((k, v.resolve(context))
- for k, v in self.kwargs.items())
- return resolved_args, resolved_kwargs
-
-class Library(object):
- def __init__(self):
- self.filters = {}
- self.tags = {}
-
- def tag(self, name=None, compile_function=None):
- if name is None and compile_function is None:
- # @register.tag()
- return self.tag_function
- elif name is not None and compile_function is None:
- if callable(name):
- # @register.tag
- return self.tag_function(name)
- else:
- # @register.tag('somename') or @register.tag(name='somename')
- def dec(func):
- return self.tag(name, func)
- return dec
- elif name is not None and compile_function is not None:
- # register.tag('somename', somefunc)
- self.tags[name] = compile_function
- return compile_function
- else:
- raise InvalidTemplateLibrary("Unsupported arguments to "
- "Library.tag: (%r, %r)", (name, compile_function))
-
- def tag_function(self, func):
- self.tags[getattr(func, "_decorated_function", func).__name__] = func
- return func
-
- def filter(self, name=None, filter_func=None, **flags):
- if name is None and filter_func is None:
- # @register.filter()
- def dec(func):
- return self.filter_function(func, **flags)
- return dec
-
- elif name is not None and filter_func is None:
- if callable(name):
- # @register.filter
- return self.filter_function(name, **flags)
- else:
- # @register.filter('somename') or @register.filter(name='somename')
- def dec(func):
- return self.filter(name, func, **flags)
- return dec
-
- elif name is not None and filter_func is not None:
- # register.filter('somename', somefunc)
- self.filters[name] = filter_func
- for attr in ('expects_localtime', 'is_safe', 'needs_autoescape'):
- if attr in flags:
- value = flags[attr]
- # set the flag on the filter for FilterExpression.resolve
- setattr(filter_func, attr, value)
- # set the flag on the innermost decorated function
- # for decorators that need it e.g. stringfilter
- if hasattr(filter_func, "_decorated_function"):
- setattr(filter_func._decorated_function, attr, value)
- filter_func._filter_name = name
- return filter_func
- else:
- raise InvalidTemplateLibrary("Unsupported arguments to "
- "Library.filter: (%r, %r)", (name, filter_func))
-
- def filter_function(self, func, **flags):
- name = getattr(func, "_decorated_function", func).__name__
- return self.filter(name, func, **flags)
-
- def simple_tag(self, func=None, takes_context=None, name=None):
- def dec(func):
- params, varargs, varkw, defaults = getargspec(func)
-
- class SimpleNode(TagHelperNode):
-
- def render(self, context):
- resolved_args, resolved_kwargs = self.get_resolved_arguments(context)
- return func(*resolved_args, **resolved_kwargs)
-
- function_name = (name or
- getattr(func, '_decorated_function', func).__name__)
- compile_func = partial(generic_tag_compiler,
- params=params, varargs=varargs, varkw=varkw,
- defaults=defaults, name=function_name,
- takes_context=takes_context, node_class=SimpleNode)
- compile_func.__doc__ = func.__doc__
- self.tag(function_name, compile_func)
- return func
-
- if func is None:
- # @register.simple_tag(...)
- return dec
- elif callable(func):
- # @register.simple_tag
- return dec(func)
- else:
- raise TemplateSyntaxError("Invalid arguments provided to simple_tag")
-
- def assignment_tag(self, func=None, takes_context=None, name=None):
- def dec(func):
- params, varargs, varkw, defaults = getargspec(func)
-
- class AssignmentNode(TagHelperNode):
- def __init__(self, takes_context, args, kwargs, target_var):
- super(AssignmentNode, self).__init__(takes_context, args, kwargs)
- self.target_var = target_var
-
- def render(self, context):
- resolved_args, resolved_kwargs = self.get_resolved_arguments(context)
- context[self.target_var] = func(*resolved_args, **resolved_kwargs)
- return ''
-
- function_name = (name or
- getattr(func, '_decorated_function', func).__name__)
-
- def compile_func(parser, token):
- bits = token.split_contents()[1:]
- if len(bits) < 2 or bits[-2] != 'as':
- raise TemplateSyntaxError(
- "'%s' tag takes at least 2 arguments and the "
- "second last argument must be 'as'" % function_name)
- target_var = bits[-1]
- bits = bits[:-2]
- args, kwargs = parse_bits(parser, bits, params,
- varargs, varkw, defaults, takes_context, function_name)
- return AssignmentNode(takes_context, args, kwargs, target_var)
-
- compile_func.__doc__ = func.__doc__
- self.tag(function_name, compile_func)
- return func
-
- if func is None:
- # @register.assignment_tag(...)
- return dec
- elif callable(func):
- # @register.assignment_tag
- return dec(func)
- else:
- raise TemplateSyntaxError("Invalid arguments provided to assignment_tag")
-
- def inclusion_tag(self, file_name, context_class=Context, takes_context=False, name=None):
- def dec(func):
- params, varargs, varkw, defaults = getargspec(func)
-
- class InclusionNode(TagHelperNode):
-
- def render(self, context):
- resolved_args, resolved_kwargs = self.get_resolved_arguments(context)
- _dict = func(*resolved_args, **resolved_kwargs)
-
- if not getattr(self, 'nodelist', False):
- from django.template.loader import get_template, select_template
- if isinstance(file_name, Template):
- t = file_name
- elif not isinstance(file_name, six.string_types) and is_iterable(file_name):
- t = select_template(file_name)
- else:
- t = get_template(file_name)
- self.nodelist = t.nodelist
- new_context = context_class(_dict, **{
- 'autoescape': context.autoescape,
- 'current_app': context.current_app,
- 'use_l10n': context.use_l10n,
- 'use_tz': context.use_tz,
- })
- # Copy across the CSRF token, if present, because
- # inclusion tags are often used for forms, and we need
- # instructions for using CSRF protection to be as simple
- # as possible.
- csrf_token = context.get('csrf_token', None)
- if csrf_token is not None:
- new_context['csrf_token'] = csrf_token
- return self.nodelist.render(new_context)
-
- function_name = (name or
- getattr(func, '_decorated_function', func).__name__)
- compile_func = partial(generic_tag_compiler,
- params=params, varargs=varargs, varkw=varkw,
- defaults=defaults, name=function_name,
- takes_context=takes_context, node_class=InclusionNode)
- compile_func.__doc__ = func.__doc__
- self.tag(function_name, compile_func)
- return func
- return dec
-
-def is_library_missing(name):
- """Check if library that failed to load cannot be found under any
- templatetags directory or does exist but fails to import.
-
- Non-existing condition is checked recursively for each subpackage in cases
- like <appdir>/templatetags/subpackage/package/module.py.
- """
- # Don't bother to check if '.' is in name since any name will be prefixed
- # with some template root.
- path, module = name.rsplit('.', 1)
- try:
- package = import_module(path)
- return not module_has_submodule(package, module)
- except ImportError:
- return is_library_missing(path)
-
-def import_library(taglib_module):
- """
- Load a template tag library module.
-
- Verifies that the library contains a 'register' attribute, and
- returns that attribute as the representation of the library
- """
- try:
- mod = import_module(taglib_module)
- except ImportError as e:
- # If the ImportError is because the taglib submodule does not exist,
- # that's not an error that should be raised. If the submodule exists
- # and raised an ImportError on the attempt to load it, that we want
- # to raise.
- if is_library_missing(taglib_module):
- return None
- else:
- raise InvalidTemplateLibrary("ImportError raised loading %s: %s" %
- (taglib_module, e))
- try:
- return mod.register
- except AttributeError:
- raise InvalidTemplateLibrary("Template library %s does not have "
- "a variable named 'register'" %
- taglib_module)
-
-templatetags_modules = []
-
-def get_templatetags_modules():
- """
- Return the list of all available template tag modules.
-
- Caches the result for faster access.
- """
- global templatetags_modules
- if not templatetags_modules:
- _templatetags_modules = []
- # Populate list once per process. Mutate the local list first, and
- # then assign it to the global name to ensure there are no cases where
- # two threads try to populate it simultaneously.
- for app_module in ['django'] + list(settings.INSTALLED_APPS):
- try:
- templatetag_module = '%s.templatetags' % app_module
- import_module(templatetag_module)
- _templatetags_modules.append(templatetag_module)
- except ImportError:
- continue
- templatetags_modules = _templatetags_modules
- return templatetags_modules
-
-def get_library(library_name):
- """
- Load the template library module with the given name.
-
- If library is not already loaded loop over all templatetags modules
- to locate it.
-
- {% load somelib %} and {% load someotherlib %} loops twice.
-
- Subsequent loads eg. {% load somelib %} in the same process will grab
- the cached module from libraries.
- """
- lib = libraries.get(library_name, None)
- if not lib:
- templatetags_modules = get_templatetags_modules()
- tried_modules = []
- for module in templatetags_modules:
- taglib_module = '%s.%s' % (module, library_name)
- tried_modules.append(taglib_module)
- lib = import_library(taglib_module)
- if lib:
- libraries[library_name] = lib
- break
- if not lib:
- raise InvalidTemplateLibrary("Template library %s not found, "
- "tried %s" %
- (library_name,
- ','.join(tried_modules)))
- return lib
-
-
-def add_to_builtins(module):
- builtins.append(import_library(module))
-
-
-add_to_builtins('django.template.defaulttags')
-add_to_builtins('django.template.defaultfilters')
diff --git a/lib/python2.7/site-packages/django/template/context.py b/lib/python2.7/site-packages/django/template/context.py
deleted file mode 100644
index 1ef7e88..0000000
--- a/lib/python2.7/site-packages/django/template/context.py
+++ /dev/null
@@ -1,169 +0,0 @@
-from copy import copy
-from django.utils.module_loading import import_by_path
-
-# Cache of actual callables.
-_standard_context_processors = None
-# We need the CSRF processor no matter what the user has in their settings,
-# because otherwise it is a security vulnerability, and we can't afford to leave
-# this to human error or failure to read migration instructions.
-_builtin_context_processors = ('django.core.context_processors.csrf',)
-
-class ContextPopException(Exception):
- "pop() has been called more times than push()"
- pass
-
-class BaseContext(object):
- def __init__(self, dict_=None):
- self._reset_dicts(dict_)
-
- def _reset_dicts(self, value=None):
- builtins = {'True': True, 'False': False, 'None': None}
- self.dicts = [builtins]
- if value is not None:
- self.dicts.append(value)
-
- def __copy__(self):
- duplicate = copy(super(BaseContext, self))
- duplicate.dicts = self.dicts[:]
- return duplicate
-
- def __repr__(self):
- return repr(self.dicts)
-
- def __iter__(self):
- for d in reversed(self.dicts):
- yield d
-
- def push(self):
- d = {}
- self.dicts.append(d)
- return d
-
- def pop(self):
- if len(self.dicts) == 1:
- raise ContextPopException
- return self.dicts.pop()
-
- def __setitem__(self, key, value):
- "Set a variable in the current context"
- self.dicts[-1][key] = value
-
- def __getitem__(self, key):
- "Get a variable's value, starting at the current context and going upward"
- for d in reversed(self.dicts):
- if key in d:
- return d[key]
- raise KeyError(key)
-
- def __delitem__(self, key):
- "Delete a variable from the current context"
- del self.dicts[-1][key]
-
- def has_key(self, key):
- for d in self.dicts:
- if key in d:
- return True
- return False
-
- def __contains__(self, key):
- return self.has_key(key)
-
- def get(self, key, otherwise=None):
- for d in reversed(self.dicts):
- if key in d:
- return d[key]
- return otherwise
-
- def new(self, values=None):
- """
- Returns a new context with the same properties, but with only the
- values given in 'values' stored.
- """
- new_context = copy(self)
- new_context._reset_dicts(values)
- return new_context
-
-class Context(BaseContext):
- "A stack container for variable context"
- def __init__(self, dict_=None, autoescape=True, current_app=None,
- use_l10n=None, use_tz=None):
- self.autoescape = autoescape
- self.current_app = current_app
- self.use_l10n = use_l10n
- self.use_tz = use_tz
- self.render_context = RenderContext()
- super(Context, self).__init__(dict_)
-
- def __copy__(self):
- duplicate = super(Context, self).__copy__()
- duplicate.render_context = copy(self.render_context)
- return duplicate
-
- def update(self, other_dict):
- "Pushes other_dict to the stack of dictionaries in the Context"
- if not hasattr(other_dict, '__getitem__'):
- raise TypeError('other_dict must be a mapping (dictionary-like) object.')
- self.dicts.append(other_dict)
- return other_dict
-
-class RenderContext(BaseContext):
- """
- A stack container for storing Template state.
-
- RenderContext simplifies the implementation of template Nodes by providing a
- safe place to store state between invocations of a node's `render` method.
-
- The RenderContext also provides scoping rules that are more sensible for
- 'template local' variables. The render context stack is pushed before each
- template is rendered, creating a fresh scope with nothing in it. Name
- resolution fails if a variable is not found at the top of the RequestContext
- stack. Thus, variables are local to a specific template and don't affect the
- rendering of other templates as they would if they were stored in the normal
- template context.
- """
- def __iter__(self):
- for d in self.dicts[-1]:
- yield d
-
- def has_key(self, key):
- return key in self.dicts[-1]
-
- def get(self, key, otherwise=None):
- d = self.dicts[-1]
- if key in d:
- return d[key]
- return otherwise
-
-# This is a function rather than module-level procedural code because we only
-# want it to execute if somebody uses RequestContext.
-def get_standard_processors():
- from django.conf import settings
- global _standard_context_processors
- if _standard_context_processors is None:
- processors = []
- collect = []
- collect.extend(_builtin_context_processors)
- collect.extend(settings.TEMPLATE_CONTEXT_PROCESSORS)
- for path in collect:
- func = import_by_path(path)
- processors.append(func)
- _standard_context_processors = tuple(processors)
- return _standard_context_processors
-
-class RequestContext(Context):
- """
- This subclass of template.Context automatically populates itself using
- the processors defined in TEMPLATE_CONTEXT_PROCESSORS.
- Additional processors can be specified as a list of callables
- using the "processors" keyword argument.
- """
- def __init__(self, request, dict_=None, processors=None, current_app=None,
- use_l10n=None, use_tz=None):
- Context.__init__(self, dict_, current_app=current_app,
- use_l10n=use_l10n, use_tz=use_tz)
- if processors is None:
- processors = ()
- else:
- processors = tuple(processors)
- for processor in get_standard_processors() + processors:
- self.update(processor(request))
diff --git a/lib/python2.7/site-packages/django/template/debug.py b/lib/python2.7/site-packages/django/template/debug.py
deleted file mode 100644
index 043dd91..0000000
--- a/lib/python2.7/site-packages/django/template/debug.py
+++ /dev/null
@@ -1,101 +0,0 @@
-from django.template.base import Lexer, Parser, tag_re, NodeList, VariableNode, TemplateSyntaxError
-from django.utils.encoding import force_text
-from django.utils.html import escape
-from django.utils.safestring import SafeData, EscapeData
-from django.utils.formats import localize
-from django.utils.timezone import template_localtime
-
-
-class DebugLexer(Lexer):
- def __init__(self, template_string, origin):
- super(DebugLexer, self).__init__(template_string, origin)
-
- def tokenize(self):
- "Return a list of tokens from a given template_string"
- result, upto = [], 0
- for match in tag_re.finditer(self.template_string):
- start, end = match.span()
- if start > upto:
- result.append(self.create_token(self.template_string[upto:start], (upto, start), False))
- upto = start
- result.append(self.create_token(self.template_string[start:end], (start, end), True))
- upto = end
- last_bit = self.template_string[upto:]
- if last_bit:
- result.append(self.create_token(last_bit, (upto, upto + len(last_bit)), False))
- return result
-
- def create_token(self, token_string, source, in_tag):
- token = super(DebugLexer, self).create_token(token_string, in_tag)
- token.source = self.origin, source
- return token
-
-class DebugParser(Parser):
- def __init__(self, lexer):
- super(DebugParser, self).__init__(lexer)
- self.command_stack = []
-
- def enter_command(self, command, token):
- self.command_stack.append( (command, token.source) )
-
- def exit_command(self):
- self.command_stack.pop()
-
- def error(self, token, msg):
- return self.source_error(token.source, msg)
-
- def source_error(self, source, msg):
- e = TemplateSyntaxError(msg)
- e.django_template_source = source
- return e
-
- def create_nodelist(self):
- return DebugNodeList()
-
- def create_variable_node(self, contents):
- return DebugVariableNode(contents)
-
- def extend_nodelist(self, nodelist, node, token):
- node.source = token.source
- super(DebugParser, self).extend_nodelist(nodelist, node, token)
-
- def unclosed_block_tag(self, parse_until):
- command, source = self.command_stack.pop()
- msg = "Unclosed tag '%s'. Looking for one of: %s " % (command, ', '.join(parse_until))
- raise self.source_error(source, msg)
-
- def compile_filter_error(self, token, e):
- if not hasattr(e, 'django_template_source'):
- e.django_template_source = token.source
-
- def compile_function_error(self, token, e):
- if not hasattr(e, 'django_template_source'):
- e.django_template_source = token.source
-
-class DebugNodeList(NodeList):
- def render_node(self, node, context):
- try:
- return node.render(context)
- except Exception as e:
- if not hasattr(e, 'django_template_source'):
- e.django_template_source = node.source
- raise
-
-
-class DebugVariableNode(VariableNode):
- def render(self, context):
- try:
- output = self.filter_expression.resolve(context)
- output = template_localtime(output, use_tz=context.use_tz)
- output = localize(output, use_l10n=context.use_l10n)
- output = force_text(output)
- except UnicodeDecodeError:
- return ''
- except Exception as e:
- if not hasattr(e, 'django_template_source'):
- e.django_template_source = self.source
- raise
- if (context.autoescape and not isinstance(output, SafeData)) or isinstance(output, EscapeData):
- return escape(output)
- else:
- return output
diff --git a/lib/python2.7/site-packages/django/template/defaultfilters.py b/lib/python2.7/site-packages/django/template/defaultfilters.py
deleted file mode 100644
index 76c0121..0000000
--- a/lib/python2.7/site-packages/django/template/defaultfilters.py
+++ /dev/null
@@ -1,893 +0,0 @@
-"""Default variable filters."""
-from __future__ import unicode_literals
-
-import re
-import random as random_module
-from decimal import Decimal, InvalidOperation, Context, ROUND_HALF_UP
-from functools import wraps
-from pprint import pformat
-
-from django.template.base import Variable, Library, VariableDoesNotExist
-from django.conf import settings
-from django.utils import formats
-from django.utils.dateformat import format, time_format
-from django.utils.encoding import force_text, iri_to_uri
-from django.utils.html import (conditional_escape, escapejs, fix_ampersands,
- escape, urlize as urlize_impl, linebreaks, strip_tags, avoid_wrapping)
-from django.utils.http import urlquote
-from django.utils.text import Truncator, wrap, phone2numeric
-from django.utils.safestring import mark_safe, SafeData, mark_for_escaping
-from django.utils import six
-from django.utils.timesince import timesince, timeuntil
-from django.utils.translation import ugettext, ungettext
-from django.utils.text import normalize_newlines
-
-register = Library()
-
-#######################
-# STRING DECORATOR #
-#######################
-
-def stringfilter(func):
- """
- Decorator for filters which should only receive unicode objects. The object
- passed as the first positional argument will be converted to a unicode
- object.
- """
- def _dec(*args, **kwargs):
- if args:
- args = list(args)
- args[0] = force_text(args[0])
- if (isinstance(args[0], SafeData) and
- getattr(_dec._decorated_function, 'is_safe', False)):
- return mark_safe(func(*args, **kwargs))
- return func(*args, **kwargs)
-
- # Include a reference to the real function (used to check original
- # arguments by the template parser, and to bear the 'is_safe' attribute
- # when multiple decorators are applied).
- _dec._decorated_function = getattr(func, '_decorated_function', func)
-
- return wraps(func)(_dec)
-
-
-###################
-# STRINGS #
-###################
-
-@register.filter(is_safe=True)
-@stringfilter
-def addslashes(value):
- """
- Adds slashes before quotes. Useful for escaping strings in CSV, for
- example. Less useful for escaping JavaScript; use the ``escapejs``
- filter instead.
- """
- return value.replace('\\', '\\\\').replace('"', '\\"').replace("'", "\\'")
-
-@register.filter(is_safe=True)
-@stringfilter
-def capfirst(value):
- """Capitalizes the first character of the value."""
- return value and value[0].upper() + value[1:]
-
-@register.filter("escapejs")
-@stringfilter
-def escapejs_filter(value):
- """Hex encodes characters for use in JavaScript strings."""
- return escapejs(value)
-
-@register.filter("fix_ampersands", is_safe=True)
-@stringfilter
-def fix_ampersands_filter(value):
- """Replaces ampersands with ``&amp;`` entities."""
- return fix_ampersands(value)
-
-# Values for testing floatformat input against infinity and NaN representations,
-# which differ across platforms and Python versions. Some (i.e. old Windows
-# ones) are not recognized by Decimal but we want to return them unchanged vs.
-# returning an empty string as we do for completely invalid input. Note these
-# need to be built up from values that are not inf/nan, since inf/nan values do
-# not reload properly from .pyc files on Windows prior to some level of Python 2.5
-# (see Python Issue757815 and Issue1080440).
-pos_inf = 1e200 * 1e200
-neg_inf = -1e200 * 1e200
-nan = (1e200 * 1e200) // (1e200 * 1e200)
-special_floats = [str(pos_inf), str(neg_inf), str(nan)]
-
-@register.filter(is_safe=True)
-def floatformat(text, arg=-1):
- """
- Displays a float to a specified number of decimal places.
-
- If called without an argument, it displays the floating point number with
- one decimal place -- but only if there's a decimal place to be displayed:
-
- * num1 = 34.23234
- * num2 = 34.00000
- * num3 = 34.26000
- * {{ num1|floatformat }} displays "34.2"
- * {{ num2|floatformat }} displays "34"
- * {{ num3|floatformat }} displays "34.3"
-
- If arg is positive, it will always display exactly arg number of decimal
- places:
-
- * {{ num1|floatformat:3 }} displays "34.232"
- * {{ num2|floatformat:3 }} displays "34.000"
- * {{ num3|floatformat:3 }} displays "34.260"
-
- If arg is negative, it will display arg number of decimal places -- but
- only if there are places to be displayed:
-
- * {{ num1|floatformat:"-3" }} displays "34.232"
- * {{ num2|floatformat:"-3" }} displays "34"
- * {{ num3|floatformat:"-3" }} displays "34.260"
-
- If the input float is infinity or NaN, the (platform-dependent) string
- representation of that value will be displayed.
- """
-
- try:
- input_val = force_text(text)
- d = Decimal(input_val)
- except UnicodeEncodeError:
- return ''
- except InvalidOperation:
- if input_val in special_floats:
- return input_val
- try:
- d = Decimal(force_text(float(text)))
- except (ValueError, InvalidOperation, TypeError, UnicodeEncodeError):
- return ''
- try:
- p = int(arg)
- except ValueError:
- return input_val
-
- try:
- m = int(d) - d
- except (ValueError, OverflowError, InvalidOperation):
- return input_val
-
- if not m and p < 0:
- return mark_safe(formats.number_format('%d' % (int(d)), 0))
-
- if p == 0:
- exp = Decimal(1)
- else:
- exp = Decimal('1.0') / (Decimal(10) ** abs(p))
- try:
- # Set the precision high enough to avoid an exception, see #15789.
- tupl = d.as_tuple()
- units = len(tupl[1]) - tupl[2]
- prec = abs(p) + units + 1
-
- # Avoid conversion to scientific notation by accessing `sign`, `digits`
- # and `exponent` from `Decimal.as_tuple()` directly.
- sign, digits, exponent = d.quantize(exp, ROUND_HALF_UP,
- Context(prec=prec)).as_tuple()
- digits = [six.text_type(digit) for digit in reversed(digits)]
- while len(digits) <= abs(exponent):
- digits.append('0')
- digits.insert(-exponent, '.')
- if sign:
- digits.append('-')
- number = ''.join(reversed(digits))
- return mark_safe(formats.number_format(number, abs(p)))
- except InvalidOperation:
- return input_val
-
-@register.filter(is_safe=True)
-@stringfilter
-def iriencode(value):
- """Escapes an IRI value for use in a URL."""
- return force_text(iri_to_uri(value))
-
-@register.filter(is_safe=True, needs_autoescape=True)
-@stringfilter
-def linenumbers(value, autoescape=None):
- """Displays text with line numbers."""
- lines = value.split('\n')
- # Find the maximum width of the line count, for use with zero padding
- # string format command
- width = six.text_type(len(six.text_type(len(lines))))
- if not autoescape or isinstance(value, SafeData):
- for i, line in enumerate(lines):
- lines[i] = ("%0" + width + "d. %s") % (i + 1, line)
- else:
- for i, line in enumerate(lines):
- lines[i] = ("%0" + width + "d. %s") % (i + 1, escape(line))
- return mark_safe('\n'.join(lines))
-
-@register.filter(is_safe=True)
-@stringfilter
-def lower(value):
- """Converts a string into all lowercase."""
- return value.lower()
-
-@register.filter(is_safe=False)
-@stringfilter
-def make_list(value):
- """
- Returns the value turned into a list.
-
- For an integer, it's a list of digits.
- For a string, it's a list of characters.
- """
- return list(value)
-
-@register.filter(is_safe=True)
-@stringfilter
-def slugify(value):
- """
- Converts to lowercase, removes non-word characters (alphanumerics and
- underscores) and converts spaces to hyphens. Also strips leading and
- trailing whitespace.
- """
- from django.utils.text import slugify
- return slugify(value)
-
-@register.filter(is_safe=True)
-def stringformat(value, arg):
- """
- Formats the variable according to the arg, a string formatting specifier.
-
- This specifier uses Python string formating syntax, with the exception that
- the leading "%" is dropped.
-
- See http://docs.python.org/lib/typesseq-strings.html for documentation
- of Python string formatting
- """
- try:
- return ("%" + six.text_type(arg)) % value
- except (ValueError, TypeError):
- return ""
-
-@register.filter(is_safe=True)
-@stringfilter
-def title(value):
- """Converts a string into titlecase."""
- t = re.sub("([a-z])'([A-Z])", lambda m: m.group(0).lower(), value.title())
- return re.sub("\d([A-Z])", lambda m: m.group(0).lower(), t)
-
-@register.filter(is_safe=True)
-@stringfilter
-def truncatechars(value, arg):
- """
- Truncates a string after a certain number of characters.
-
- Argument: Number of characters to truncate after.
- """
- try:
- length = int(arg)
- except ValueError: # Invalid literal for int().
- return value # Fail silently.
- return Truncator(value).chars(length)
-
-@register.filter(is_safe=True)
-@stringfilter
-def truncatewords(value, arg):
- """
- Truncates a string after a certain number of words.
-
- Argument: Number of words to truncate after.
-
- Newlines within the string are removed.
- """
- try:
- length = int(arg)
- except ValueError: # Invalid literal for int().
- return value # Fail silently.
- return Truncator(value).words(length, truncate=' ...')
-
-@register.filter(is_safe=True)
-@stringfilter
-def truncatewords_html(value, arg):
- """
- Truncates HTML after a certain number of words.
-
- Argument: Number of words to truncate after.
-
- Newlines in the HTML are preserved.
- """
- try:
- length = int(arg)
- except ValueError: # invalid literal for int()
- return value # Fail silently.
- return Truncator(value).words(length, html=True, truncate=' ...')
-
-@register.filter(is_safe=False)
-@stringfilter
-def upper(value):
- """Converts a string into all uppercase."""
- return value.upper()
-
-@register.filter(is_safe=False)
-@stringfilter
-def urlencode(value, safe=None):
- """
- Escapes a value for use in a URL.
-
- Takes an optional ``safe`` parameter used to determine the characters which
- should not be escaped by Django's ``urlquote`` method. If not provided, the
- default safe characters will be used (but an empty string can be provided
- when *all* characters should be escaped).
- """
- kwargs = {}
- if safe is not None:
- kwargs['safe'] = safe
- return urlquote(value, **kwargs)
-
-@register.filter(is_safe=True, needs_autoescape=True)
-@stringfilter
-def urlize(value, autoescape=None):
- """Converts URLs in plain text into clickable links."""
- return mark_safe(urlize_impl(value, nofollow=True, autoescape=autoescape))
-
-@register.filter(is_safe=True, needs_autoescape=True)
-@stringfilter
-def urlizetrunc(value, limit, autoescape=None):
- """
- Converts URLs into clickable links, truncating URLs to the given character
- limit, and adding 'rel=nofollow' attribute to discourage spamming.
-
- Argument: Length to truncate URLs to.
- """
- return mark_safe(urlize_impl(value, trim_url_limit=int(limit), nofollow=True,
- autoescape=autoescape))
-
-@register.filter(is_safe=False)
-@stringfilter
-def wordcount(value):
- """Returns the number of words."""
- return len(value.split())
-
-@register.filter(is_safe=True)
-@stringfilter
-def wordwrap(value, arg):
- """
- Wraps words at specified line length.
-
- Argument: number of characters to wrap the text at.
- """
- return wrap(value, int(arg))
-
-@register.filter(is_safe=True)
-@stringfilter
-def ljust(value, arg):
- """
- Left-aligns the value in a field of a given width.
-
- Argument: field size.
- """
- return value.ljust(int(arg))
-
-@register.filter(is_safe=True)
-@stringfilter
-def rjust(value, arg):
- """
- Right-aligns the value in a field of a given width.
-
- Argument: field size.
- """
- return value.rjust(int(arg))
-
-@register.filter(is_safe=True)
-@stringfilter
-def center(value, arg):
- """Centers the value in a field of a given width."""
- return value.center(int(arg))
-
-@register.filter
-@stringfilter
-def cut(value, arg):
- """
- Removes all values of arg from the given string.
- """
- safe = isinstance(value, SafeData)
- value = value.replace(arg, '')
- if safe and arg != ';':
- return mark_safe(value)
- return value
-
-###################
-# HTML STRINGS #
-###################
-
-@register.filter("escape", is_safe=True)
-@stringfilter
-def escape_filter(value):
- """
- Marks the value as a string that should not be auto-escaped.
- """
- return mark_for_escaping(value)
-
-@register.filter(is_safe=True)
-@stringfilter
-def force_escape(value):
- """
- Escapes a string's HTML. This returns a new string containing the escaped
- characters (as opposed to "escape", which marks the content for later
- possible escaping).
- """
- return escape(value)
-
-@register.filter("linebreaks", is_safe=True, needs_autoescape=True)
-@stringfilter
-def linebreaks_filter(value, autoescape=None):
- """
- Replaces line breaks in plain text with appropriate HTML; a single
- newline becomes an HTML line break (``<br />``) and a new line
- followed by a blank line becomes a paragraph break (``</p>``).
- """
- autoescape = autoescape and not isinstance(value, SafeData)
- return mark_safe(linebreaks(value, autoescape))
-
-@register.filter(is_safe=True, needs_autoescape=True)
-@stringfilter
-def linebreaksbr(value, autoescape=None):
- """
- Converts all newlines in a piece of plain text to HTML line breaks
- (``<br />``).
- """
- autoescape = autoescape and not isinstance(value, SafeData)
- value = normalize_newlines(value)
- if autoescape:
- value = escape(value)
- return mark_safe(value.replace('\n', '<br />'))
-
-@register.filter(is_safe=True)
-@stringfilter
-def safe(value):
- """
- Marks the value as a string that should not be auto-escaped.
- """
- return mark_safe(value)
-
-@register.filter(is_safe=True)
-def safeseq(value):
- """
- A "safe" filter for sequences. Marks each element in the sequence,
- individually, as safe, after converting them to unicode. Returns a list
- with the results.
- """
- return [mark_safe(force_text(obj)) for obj in value]
-
-@register.filter(is_safe=True)
-@stringfilter
-def removetags(value, tags):
- """Removes a space separated list of [X]HTML tags from the output."""
- from django.utils.html import remove_tags
- return remove_tags(value, tags)
-
-@register.filter(is_safe=True)
-@stringfilter
-def striptags(value):
- """Strips all [X]HTML tags."""
- return strip_tags(value)
-
-###################
-# LISTS #
-###################
-
-@register.filter(is_safe=False)
-def dictsort(value, arg):
- """
- Takes a list of dicts, returns that list sorted by the property given in
- the argument.
- """
- try:
- return sorted(value, key=Variable(arg).resolve)
- except (TypeError, VariableDoesNotExist):
- return ''
-
-@register.filter(is_safe=False)
-def dictsortreversed(value, arg):
- """
- Takes a list of dicts, returns that list sorted in reverse order by the
- property given in the argument.
- """
- try:
- return sorted(value, key=Variable(arg).resolve, reverse=True)
- except (TypeError, VariableDoesNotExist):
- return ''
-
-@register.filter(is_safe=False)
-def first(value):
- """Returns the first item in a list."""
- try:
- return value[0]
- except IndexError:
- return ''
-
-@register.filter(is_safe=True, needs_autoescape=True)
-def join(value, arg, autoescape=None):
- """
- Joins a list with a string, like Python's ``str.join(list)``.
- """
- value = map(force_text, value)
- if autoescape:
- value = [conditional_escape(v) for v in value]
- try:
- data = conditional_escape(arg).join(value)
- except AttributeError: # fail silently but nicely
- return value
- return mark_safe(data)
-
-@register.filter(is_safe=True)
-def last(value):
- "Returns the last item in a list"
- try:
- return value[-1]
- except IndexError:
- return ''
-
-@register.filter(is_safe=True)
-def length(value):
- """Returns the length of the value - useful for lists."""
- try:
- return len(value)
- except (ValueError, TypeError):
- return ''
-
-@register.filter(is_safe=False)
-def length_is(value, arg):
- """Returns a boolean of whether the value's length is the argument."""
- try:
- return len(value) == int(arg)
- except (ValueError, TypeError):
- return ''
-
-@register.filter(is_safe=True)
-def random(value):
- """Returns a random item from the list."""
- return random_module.choice(value)
-
-@register.filter("slice", is_safe=True)
-def slice_filter(value, arg):
- """
- Returns a slice of the list.
-
- Uses the same syntax as Python's list slicing; see
- http://www.diveintopython3.net/native-datatypes.html#slicinglists
- for an introduction.
- """
- try:
- bits = []
- for x in arg.split(':'):
- if len(x) == 0:
- bits.append(None)
- else:
- bits.append(int(x))
- return value[slice(*bits)]
-
- except (ValueError, TypeError):
- return value # Fail silently.
-
-@register.filter(is_safe=True, needs_autoescape=True)
-def unordered_list(value, autoescape=None):
- """
- Recursively takes a self-nested list and returns an HTML unordered list --
- WITHOUT opening and closing <ul> tags.
-
- The list is assumed to be in the proper format. For example, if ``var``
- contains: ``['States', ['Kansas', ['Lawrence', 'Topeka'], 'Illinois']]``,
- then ``{{ var|unordered_list }}`` would return::
-
- <li>States
- <ul>
- <li>Kansas
- <ul>
- <li>Lawrence</li>
- <li>Topeka</li>
- </ul>
- </li>
- <li>Illinois</li>
- </ul>
- </li>
- """
- if autoescape:
- escaper = conditional_escape
- else:
- escaper = lambda x: x
- def convert_old_style_list(list_):
- """
- Converts old style lists to the new easier to understand format.
-
- The old list format looked like:
- ['Item 1', [['Item 1.1', []], ['Item 1.2', []]]
-
- And it is converted to:
- ['Item 1', ['Item 1.1', 'Item 1.2]]
- """
- if not isinstance(list_, (tuple, list)) or len(list_) != 2:
- return list_, False
- first_item, second_item = list_
- if second_item == []:
- return [first_item], True
- try:
- # see if second item is iterable
- iter(second_item)
- except TypeError:
- return list_, False
- old_style_list = True
- new_second_item = []
- for sublist in second_item:
- item, old_style_list = convert_old_style_list(sublist)
- if not old_style_list:
- break
- new_second_item.extend(item)
- if old_style_list:
- second_item = new_second_item
- return [first_item, second_item], old_style_list
- def _helper(list_, tabs=1):
- indent = '\t' * tabs
- output = []
-
- list_length = len(list_)
- i = 0
- while i < list_length:
- title = list_[i]
- sublist = ''
- sublist_item = None
- if isinstance(title, (list, tuple)):
- sublist_item = title
- title = ''
- elif i < list_length - 1:
- next_item = list_[i+1]
- if next_item and isinstance(next_item, (list, tuple)):
- # The next item is a sub-list.
- sublist_item = next_item
- # We've processed the next item now too.
- i += 1
- if sublist_item:
- sublist = _helper(sublist_item, tabs+1)
- sublist = '\n%s<ul>\n%s\n%s</ul>\n%s' % (indent, sublist,
- indent, indent)
- output.append('%s<li>%s%s</li>' % (indent,
- escaper(force_text(title)), sublist))
- i += 1
- return '\n'.join(output)
- value, converted = convert_old_style_list(value)
- return mark_safe(_helper(value))
-
-###################
-# INTEGERS #
-###################
-
-@register.filter(is_safe=False)
-def add(value, arg):
- """Adds the arg to the value."""
- try:
- return int(value) + int(arg)
- except (ValueError, TypeError):
- try:
- return value + arg
- except Exception:
- return ''
-
-@register.filter(is_safe=False)
-def get_digit(value, arg):
- """
- Given a whole number, returns the requested digit of it, where 1 is the
- right-most digit, 2 is the second-right-most digit, etc. Returns the
- original value for invalid input (if input or argument is not an integer,
- or if argument is less than 1). Otherwise, output is always an integer.
- """
- try:
- arg = int(arg)
- value = int(value)
- except ValueError:
- return value # Fail silently for an invalid argument
- if arg < 1:
- return value
- try:
- return int(str(value)[-arg])
- except IndexError:
- return 0
-
-###################
-# DATES #
-###################
-
-@register.filter(expects_localtime=True, is_safe=False)
-def date(value, arg=None):
- """Formats a date according to the given format."""
- if value in (None, ''):
- return ''
- if arg is None:
- arg = settings.DATE_FORMAT
- try:
- return formats.date_format(value, arg)
- except AttributeError:
- try:
- return format(value, arg)
- except AttributeError:
- return ''
-
-@register.filter(expects_localtime=True, is_safe=False)
-def time(value, arg=None):
- """Formats a time according to the given format."""
- if value in (None, ''):
- return ''
- if arg is None:
- arg = settings.TIME_FORMAT
- try:
- return formats.time_format(value, arg)
- except AttributeError:
- try:
- return time_format(value, arg)
- except AttributeError:
- return ''
-
-@register.filter("timesince", is_safe=False)
-def timesince_filter(value, arg=None):
- """Formats a date as the time since that date (i.e. "4 days, 6 hours")."""
- if not value:
- return ''
- try:
- if arg:
- return timesince(value, arg)
- return timesince(value)
- except (ValueError, TypeError):
- return ''
-
-@register.filter("timeuntil", is_safe=False)
-def timeuntil_filter(value, arg=None):
- """Formats a date as the time until that date (i.e. "4 days, 6 hours")."""
- if not value:
- return ''
- try:
- return timeuntil(value, arg)
- except (ValueError, TypeError):
- return ''
-
-###################
-# LOGIC #
-###################
-
-@register.filter(is_safe=False)
-def default(value, arg):
- """If value is unavailable, use given default."""
- return value or arg
-
-@register.filter(is_safe=False)
-def default_if_none(value, arg):
- """If value is None, use given default."""
- if value is None:
- return arg
- return value
-
-@register.filter(is_safe=False)
-def divisibleby(value, arg):
- """Returns True if the value is devisible by the argument."""
- return int(value) % int(arg) == 0
-
-@register.filter(is_safe=False)
-def yesno(value, arg=None):
- """
- Given a string mapping values for true, false and (optionally) None,
- returns one of those strings according to the value:
-
- ========== ====================== ==================================
- Value Argument Outputs
- ========== ====================== ==================================
- ``True`` ``"yeah,no,maybe"`` ``yeah``
- ``False`` ``"yeah,no,maybe"`` ``no``
- ``None`` ``"yeah,no,maybe"`` ``maybe``
- ``None`` ``"yeah,no"`` ``"no"`` (converts None to False
- if no mapping for None is given.
- ========== ====================== ==================================
- """
- if arg is None:
- arg = ugettext('yes,no,maybe')
- bits = arg.split(',')
- if len(bits) < 2:
- return value # Invalid arg.
- try:
- yes, no, maybe = bits
- except ValueError:
- # Unpack list of wrong size (no "maybe" value provided).
- yes, no, maybe = bits[0], bits[1], bits[1]
- if value is None:
- return maybe
- if value:
- return yes
- return no
-
-###################
-# MISC #
-###################
-
-@register.filter(is_safe=True)
-def filesizeformat(bytes):
- """
- Formats the value like a 'human-readable' file size (i.e. 13 KB, 4.1 MB,
- 102 bytes, etc).
- """
- try:
- bytes = float(bytes)
- except (TypeError,ValueError,UnicodeDecodeError):
- value = ungettext("%(size)d byte", "%(size)d bytes", 0) % {'size': 0}
- return avoid_wrapping(value)
-
- filesize_number_format = lambda value: formats.number_format(round(value, 1), 1)
-
- KB = 1<<10
- MB = 1<<20
- GB = 1<<30
- TB = 1<<40
- PB = 1<<50
-
- if bytes < KB:
- value = ungettext("%(size)d byte", "%(size)d bytes", bytes) % {'size': bytes}
- elif bytes < MB:
- value = ugettext("%s KB") % filesize_number_format(bytes / KB)
- elif bytes < GB:
- value = ugettext("%s MB") % filesize_number_format(bytes / MB)
- elif bytes < TB:
- value = ugettext("%s GB") % filesize_number_format(bytes / GB)
- elif bytes < PB:
- value = ugettext("%s TB") % filesize_number_format(bytes / TB)
- else:
- value = ugettext("%s PB") % filesize_number_format(bytes / PB)
-
- return avoid_wrapping(value)
-
-@register.filter(is_safe=False)
-def pluralize(value, arg='s'):
- """
- Returns a plural suffix if the value is not 1. By default, 's' is used as
- the suffix:
-
- * If value is 0, vote{{ value|pluralize }} displays "0 votes".
- * If value is 1, vote{{ value|pluralize }} displays "1 vote".
- * If value is 2, vote{{ value|pluralize }} displays "2 votes".
-
- If an argument is provided, that string is used instead:
-
- * If value is 0, class{{ value|pluralize:"es" }} displays "0 classes".
- * If value is 1, class{{ value|pluralize:"es" }} displays "1 class".
- * If value is 2, class{{ value|pluralize:"es" }} displays "2 classes".
-
- If the provided argument contains a comma, the text before the comma is
- used for the singular case and the text after the comma is used for the
- plural case:
-
- * If value is 0, cand{{ value|pluralize:"y,ies" }} displays "0 candies".
- * If value is 1, cand{{ value|pluralize:"y,ies" }} displays "1 candy".
- * If value is 2, cand{{ value|pluralize:"y,ies" }} displays "2 candies".
- """
- if not ',' in arg:
- arg = ',' + arg
- bits = arg.split(',')
- if len(bits) > 2:
- return ''
- singular_suffix, plural_suffix = bits[:2]
-
- try:
- if int(value) != 1:
- return plural_suffix
- except ValueError: # Invalid string that's not a number.
- pass
- except TypeError: # Value isn't a string or a number; maybe it's a list?
- try:
- if len(value) != 1:
- return plural_suffix
- except TypeError: # len() of unsized object.
- pass
- return singular_suffix
-
-@register.filter("phone2numeric", is_safe=True)
-def phone2numeric_filter(value):
- """Takes a phone number and converts it in to its numerical equivalent."""
- return phone2numeric(value)
-
-@register.filter(is_safe=True)
-def pprint(value):
- """A wrapper around pprint.pprint -- for debugging, really."""
- try:
- return pformat(value)
- except Exception as e:
- return "Error in formatting: %s" % force_text(e, errors="replace")
diff --git a/lib/python2.7/site-packages/django/template/defaulttags.py b/lib/python2.7/site-packages/django/template/defaulttags.py
deleted file mode 100644
index 554c7bc..0000000
--- a/lib/python2.7/site-packages/django/template/defaulttags.py
+++ /dev/null
@@ -1,1409 +0,0 @@
-"""Default tags used by the template system, available to all templates."""
-from __future__ import unicode_literals
-
-import os
-import sys
-import re
-from datetime import datetime
-from itertools import groupby, cycle as itertools_cycle
-import warnings
-
-from django.conf import settings
-from django.template.base import (Node, NodeList, Template, Context, Library,
- TemplateSyntaxError, VariableDoesNotExist, InvalidTemplateLibrary,
- BLOCK_TAG_START, BLOCK_TAG_END, VARIABLE_TAG_START, VARIABLE_TAG_END,
- SINGLE_BRACE_START, SINGLE_BRACE_END, COMMENT_TAG_START, COMMENT_TAG_END,
- VARIABLE_ATTRIBUTE_SEPARATOR, get_library, token_kwargs, kwarg_re,
- render_value_in_context)
-from django.template.smartif import IfParser, Literal
-from django.template.defaultfilters import date
-from django.utils.encoding import smart_text
-from django.utils.safestring import mark_safe
-from django.utils.html import format_html
-from django.utils import six
-from django.utils import timezone
-
-register = Library()
-
-class AutoEscapeControlNode(Node):
- """Implements the actions of the autoescape tag."""
- def __init__(self, setting, nodelist):
- self.setting, self.nodelist = setting, nodelist
-
- def render(self, context):
- old_setting = context.autoescape
- context.autoescape = self.setting
- output = self.nodelist.render(context)
- context.autoescape = old_setting
- if self.setting:
- return mark_safe(output)
- else:
- return output
-
-class CommentNode(Node):
- def render(self, context):
- return ''
-
-class CsrfTokenNode(Node):
- def render(self, context):
- csrf_token = context.get('csrf_token', None)
- if csrf_token:
- if csrf_token == 'NOTPROVIDED':
- return format_html("")
- else:
- return format_html("<input type='hidden' name='csrfmiddlewaretoken' value='{0}' />", csrf_token)
- else:
- # It's very probable that the token is missing because of
- # misconfiguration, so we raise a warning
- from django.conf import settings
- if settings.DEBUG:
- warnings.warn("A {% csrf_token %} was used in a template, but the context did not provide the value. This is usually caused by not using RequestContext.")
- return ''
-
-class CycleNode(Node):
- def __init__(self, cyclevars, variable_name=None, silent=False, escape=False):
- self.cyclevars = cyclevars
- self.variable_name = variable_name
- self.silent = silent
- self.escape = escape # only while the "future" version exists
-
- def render(self, context):
- if self not in context.render_context:
- # First time the node is rendered in template
- context.render_context[self] = itertools_cycle(self.cyclevars)
- cycle_iter = context.render_context[self]
- value = next(cycle_iter).resolve(context)
- if self.variable_name:
- context[self.variable_name] = value
- if self.silent:
- return ''
- if not self.escape:
- value = mark_safe(value)
- return render_value_in_context(value, context)
-
-class DebugNode(Node):
- def render(self, context):
- from pprint import pformat
- output = [pformat(val) for val in context]
- output.append('\n\n')
- output.append(pformat(sys.modules))
- return ''.join(output)
-
-class FilterNode(Node):
- def __init__(self, filter_expr, nodelist):
- self.filter_expr, self.nodelist = filter_expr, nodelist
-
- def render(self, context):
- output = self.nodelist.render(context)
- # Apply filters.
- context.update({'var': output})
- filtered = self.filter_expr.resolve(context)
- context.pop()
- return filtered
-
-class FirstOfNode(Node):
- def __init__(self, variables, escape=False):
- self.vars = variables
- self.escape = escape # only while the "future" version exists
-
- def render(self, context):
- for var in self.vars:
- value = var.resolve(context, True)
- if value:
- if not self.escape:
- value = mark_safe(value)
- return render_value_in_context(value, context)
- return ''
-
-class ForNode(Node):
- child_nodelists = ('nodelist_loop', 'nodelist_empty')
-
- def __init__(self, loopvars, sequence, is_reversed, nodelist_loop, nodelist_empty=None):
- self.loopvars, self.sequence = loopvars, sequence
- self.is_reversed = is_reversed
- self.nodelist_loop = nodelist_loop
- if nodelist_empty is None:
- self.nodelist_empty = NodeList()
- else:
- self.nodelist_empty = nodelist_empty
-
- def __repr__(self):
- reversed_text = ' reversed' if self.is_reversed else ''
- return "<For Node: for %s in %s, tail_len: %d%s>" % \
- (', '.join(self.loopvars), self.sequence, len(self.nodelist_loop),
- reversed_text)
-
- def __iter__(self):
- for node in self.nodelist_loop:
- yield node
- for node in self.nodelist_empty:
- yield node
-
- def render(self, context):
- if 'forloop' in context:
- parentloop = context['forloop']
- else:
- parentloop = {}
- context.push()
- try:
- values = self.sequence.resolve(context, True)
- except VariableDoesNotExist:
- values = []
- if values is None:
- values = []
- if not hasattr(values, '__len__'):
- values = list(values)
- len_values = len(values)
- if len_values < 1:
- context.pop()
- return self.nodelist_empty.render(context)
- nodelist = NodeList()
- if self.is_reversed:
- values = reversed(values)
- unpack = len(self.loopvars) > 1
- # Create a forloop value in the context. We'll update counters on each
- # iteration just below.
- loop_dict = context['forloop'] = {'parentloop': parentloop}
- for i, item in enumerate(values):
- # Shortcuts for current loop iteration number.
- loop_dict['counter0'] = i
- loop_dict['counter'] = i+1
- # Reverse counter iteration numbers.
- loop_dict['revcounter'] = len_values - i
- loop_dict['revcounter0'] = len_values - i - 1
- # Boolean values designating first and last times through loop.
- loop_dict['first'] = (i == 0)
- loop_dict['last'] = (i == len_values - 1)
-
- pop_context = False
- if unpack:
- # If there are multiple loop variables, unpack the item into
- # them.
- try:
- unpacked_vars = dict(zip(self.loopvars, item))
- except TypeError:
- pass
- else:
- pop_context = True
- context.update(unpacked_vars)
- else:
- context[self.loopvars[0]] = item
- # In TEMPLATE_DEBUG mode provide source of the node which
- # actually raised the exception
- if settings.TEMPLATE_DEBUG:
- for node in self.nodelist_loop:
- try:
- nodelist.append(node.render(context))
- except Exception as e:
- if not hasattr(e, 'django_template_source'):
- e.django_template_source = node.source
- raise
- else:
- for node in self.nodelist_loop:
- nodelist.append(node.render(context))
- if pop_context:
- # The loop variables were pushed on to the context so pop them
- # off again. This is necessary because the tag lets the length
- # of loopvars differ to the length of each set of items and we
- # don't want to leave any vars from the previous loop on the
- # context.
- context.pop()
- context.pop()
- return nodelist.render(context)
-
-class IfChangedNode(Node):
- child_nodelists = ('nodelist_true', 'nodelist_false')
-
- def __init__(self, nodelist_true, nodelist_false, *varlist):
- self.nodelist_true, self.nodelist_false = nodelist_true, nodelist_false
- self._varlist = varlist
-
- def render(self, context):
- # Init state storage
- state_frame = self._get_context_stack_frame(context)
- if self not in state_frame:
- state_frame[self] = None
-
- nodelist_true_output = None
- try:
- if self._varlist:
- # Consider multiple parameters. This automatically behaves
- # like an OR evaluation of the multiple variables.
- compare_to = [var.resolve(context, True) for var in self._varlist]
- else:
- # The "{% ifchanged %}" syntax (without any variables) compares the rendered output.
- compare_to = nodelist_true_output = self.nodelist_true.render(context)
- except VariableDoesNotExist:
- compare_to = None
-
- if compare_to != state_frame[self]:
- state_frame[self] = compare_to
- return nodelist_true_output or self.nodelist_true.render(context) # render true block if not already rendered
- elif self.nodelist_false:
- return self.nodelist_false.render(context)
- return ''
-
- def _get_context_stack_frame(self, context):
- # The Context object behaves like a stack where each template tag can create a new scope.
- # Find the place where to store the state to detect changes.
- if 'forloop' in context:
- # Ifchanged is bound to the local for loop.
- # When there is a loop-in-loop, the state is bound to the inner loop,
- # so it resets when the outer loop continues.
- return context['forloop']
- else:
- # Using ifchanged outside loops. Effectively this is a no-op because the state is associated with 'self'.
- return context.render_context
-
-class IfEqualNode(Node):
- child_nodelists = ('nodelist_true', 'nodelist_false')
-
- def __init__(self, var1, var2, nodelist_true, nodelist_false, negate):
- self.var1, self.var2 = var1, var2
- self.nodelist_true, self.nodelist_false = nodelist_true, nodelist_false
- self.negate = negate
-
- def __repr__(self):
- return "<IfEqualNode>"
-
- def render(self, context):
- val1 = self.var1.resolve(context, True)
- val2 = self.var2.resolve(context, True)
- if (self.negate and val1 != val2) or (not self.negate and val1 == val2):
- return self.nodelist_true.render(context)
- return self.nodelist_false.render(context)
-
-class IfNode(Node):
-
- def __init__(self, conditions_nodelists):
- self.conditions_nodelists = conditions_nodelists
-
- def __repr__(self):
- return "<IfNode>"
-
- def __iter__(self):
- for _, nodelist in self.conditions_nodelists:
- for node in nodelist:
- yield node
-
- @property
- def nodelist(self):
- return NodeList(node for _, nodelist in self.conditions_nodelists for node in nodelist)
-
- def render(self, context):
- for condition, nodelist in self.conditions_nodelists:
-
- if condition is not None: # if / elif clause
- try:
- match = condition.eval(context)
- except VariableDoesNotExist:
- match = None
- else: # else clause
- match = True
-
- if match:
- return nodelist.render(context)
-
- return ''
-
-class RegroupNode(Node):
- def __init__(self, target, expression, var_name):
- self.target, self.expression = target, expression
- self.var_name = var_name
-
- def resolve_expression(self, obj, context):
- # This method is called for each object in self.target. See regroup()
- # for the reason why we temporarily put the object in the context.
- context[self.var_name] = obj
- return self.expression.resolve(context, True)
-
- def render(self, context):
- obj_list = self.target.resolve(context, True)
- if obj_list == None:
- # target variable wasn't found in context; fail silently.
- context[self.var_name] = []
- return ''
- # List of dictionaries in the format:
- # {'grouper': 'key', 'list': [list of contents]}.
- context[self.var_name] = [
- {'grouper': key, 'list': list(val)}
- for key, val in
- groupby(obj_list, lambda obj: self.resolve_expression(obj, context))
- ]
- return ''
-
-def include_is_allowed(filepath):
- filepath = os.path.abspath(filepath)
- for root in settings.ALLOWED_INCLUDE_ROOTS:
- if filepath.startswith(root):
- return True
- return False
-
-class SsiNode(Node):
- def __init__(self, filepath, parsed):
- self.filepath = filepath
- self.parsed = parsed
-
- def render(self, context):
- filepath = self.filepath.resolve(context)
-
- if not include_is_allowed(filepath):
- if settings.DEBUG:
- return "[Didn't have permission to include file]"
- else:
- return '' # Fail silently for invalid includes.
- try:
- with open(filepath, 'r') as fp:
- output = fp.read()
- except IOError:
- output = ''
- if self.parsed:
- try:
- t = Template(output, name=filepath)
- return t.render(context)
- except TemplateSyntaxError as e:
- if settings.DEBUG:
- return "[Included template had syntax error: %s]" % e
- else:
- return '' # Fail silently for invalid included templates.
- return output
-
-class LoadNode(Node):
- def render(self, context):
- return ''
-
-class NowNode(Node):
- def __init__(self, format_string):
- self.format_string = format_string
-
- def render(self, context):
- tzinfo = timezone.get_current_timezone() if settings.USE_TZ else None
- return date(datetime.now(tz=tzinfo), self.format_string)
-
-class SpacelessNode(Node):
- def __init__(self, nodelist):
- self.nodelist = nodelist
-
- def render(self, context):
- from django.utils.html import strip_spaces_between_tags
- return strip_spaces_between_tags(self.nodelist.render(context).strip())
-
-class TemplateTagNode(Node):
- mapping = {'openblock': BLOCK_TAG_START,
- 'closeblock': BLOCK_TAG_END,
- 'openvariable': VARIABLE_TAG_START,
- 'closevariable': VARIABLE_TAG_END,
- 'openbrace': SINGLE_BRACE_START,
- 'closebrace': SINGLE_BRACE_END,
- 'opencomment': COMMENT_TAG_START,
- 'closecomment': COMMENT_TAG_END,
- }
-
- def __init__(self, tagtype):
- self.tagtype = tagtype
-
- def render(self, context):
- return self.mapping.get(self.tagtype, '')
-
-class URLNode(Node):
- def __init__(self, view_name, args, kwargs, asvar):
- self.view_name = view_name
- self.args = args
- self.kwargs = kwargs
- self.asvar = asvar
-
- def render(self, context):
- from django.core.urlresolvers import reverse, NoReverseMatch
- args = [arg.resolve(context) for arg in self.args]
- kwargs = dict([(smart_text(k, 'ascii'), v.resolve(context))
- for k, v in self.kwargs.items()])
-
- view_name = self.view_name.resolve(context)
-
- if not view_name:
- raise NoReverseMatch("'url' requires a non-empty first argument. "
- "The syntax changed in Django 1.5, see the docs.")
-
- # Try to look up the URL twice: once given the view name, and again
- # relative to what we guess is the "main" app. If they both fail,
- # re-raise the NoReverseMatch unless we're using the
- # {% url ... as var %} construct in which case return nothing.
- url = ''
- try:
- url = reverse(view_name, args=args, kwargs=kwargs, current_app=context.current_app)
- except NoReverseMatch:
- exc_info = sys.exc_info()
- if settings.SETTINGS_MODULE:
- project_name = settings.SETTINGS_MODULE.split('.')[0]
- try:
- url = reverse(project_name + '.' + view_name,
- args=args, kwargs=kwargs,
- current_app=context.current_app)
- except NoReverseMatch:
- if self.asvar is None:
- # Re-raise the original exception, not the one with
- # the path relative to the project. This makes a
- # better error message.
- six.reraise(*exc_info)
- else:
- if self.asvar is None:
- raise
-
- if self.asvar:
- context[self.asvar] = url
- return ''
- else:
- return url
-
-class VerbatimNode(Node):
- def __init__(self, content):
- self.content = content
-
- def render(self, context):
- return self.content
-
-class WidthRatioNode(Node):
- def __init__(self, val_expr, max_expr, max_width):
- self.val_expr = val_expr
- self.max_expr = max_expr
- self.max_width = max_width
-
- def render(self, context):
- try:
- value = self.val_expr.resolve(context)
- max_value = self.max_expr.resolve(context)
- max_width = int(self.max_width.resolve(context))
- except VariableDoesNotExist:
- return ''
- except (ValueError, TypeError):
- raise TemplateSyntaxError("widthratio final argument must be a number")
- try:
- value = float(value)
- max_value = float(max_value)
- ratio = (value / max_value) * max_width
- except ZeroDivisionError:
- return '0'
- except (ValueError, TypeError):
- return ''
- return str(int(round(ratio)))
-
-class WithNode(Node):
- def __init__(self, var, name, nodelist, extra_context=None):
- self.nodelist = nodelist
- # var and name are legacy attributes, being left in case they are used
- # by third-party subclasses of this Node.
- self.extra_context = extra_context or {}
- if name:
- self.extra_context[name] = var
-
- def __repr__(self):
- return "<WithNode>"
-
- def render(self, context):
- values = dict([(key, val.resolve(context)) for key, val in
- six.iteritems(self.extra_context)])
- context.update(values)
- output = self.nodelist.render(context)
- context.pop()
- return output
-
-@register.tag
-def autoescape(parser, token):
- """
- Force autoescape behavior for this block.
- """
- # token.split_contents() isn't useful here because this tag doesn't accept variable as arguments
- args = token.contents.split()
- if len(args) != 2:
- raise TemplateSyntaxError("'autoescape' tag requires exactly one argument.")
- arg = args[1]
- if arg not in ('on', 'off'):
- raise TemplateSyntaxError("'autoescape' argument should be 'on' or 'off'")
- nodelist = parser.parse(('endautoescape',))
- parser.delete_first_token()
- return AutoEscapeControlNode((arg == 'on'), nodelist)
-
-@register.tag
-def comment(parser, token):
- """
- Ignores everything between ``{% comment %}`` and ``{% endcomment %}``.
- """
- parser.skip_past('endcomment')
- return CommentNode()
-
-@register.tag
-def cycle(parser, token, escape=False):
- """
- Cycles among the given strings each time this tag is encountered.
-
- Within a loop, cycles among the given strings each time through
- the loop::
-
- {% for o in some_list %}
- <tr class="{% cycle 'row1' 'row2' %}">
- ...
- </tr>
- {% endfor %}
-
- Outside of a loop, give the values a unique name the first time you call
- it, then use that name each sucessive time through::
-
- <tr class="{% cycle 'row1' 'row2' 'row3' as rowcolors %}">...</tr>
- <tr class="{% cycle rowcolors %}">...</tr>
- <tr class="{% cycle rowcolors %}">...</tr>
-
- You can use any number of values, separated by spaces. Commas can also
- be used to separate values; if a comma is used, the cycle values are
- interpreted as literal strings.
-
- The optional flag "silent" can be used to prevent the cycle declaration
- from returning any value::
-
- {% for o in some_list %}
- {% cycle 'row1' 'row2' as rowcolors silent %}
- <tr class="{{ rowcolors }}">{% include "subtemplate.html " %}</tr>
- {% endfor %}
-
- """
- if not escape:
- warnings.warn(
- "'The `cycle` template tag is changing to escape its arguments; "
- "the non-autoescaping version is deprecated. Load it "
- "from the `future` tag library to start using the new behavior.",
- PendingDeprecationWarning, stacklevel=2)
-
- # Note: This returns the exact same node on each {% cycle name %} call;
- # that is, the node object returned from {% cycle a b c as name %} and the
- # one returned from {% cycle name %} are the exact same object. This
- # shouldn't cause problems (heh), but if it does, now you know.
- #
- # Ugly hack warning: This stuffs the named template dict into parser so
- # that names are only unique within each template (as opposed to using
- # a global variable, which would make cycle names have to be unique across
- # *all* templates.
-
- args = token.split_contents()
-
- if len(args) < 2:
- raise TemplateSyntaxError("'cycle' tag requires at least two arguments")
-
- if ',' in args[1]:
- # Backwards compatibility: {% cycle a,b %} or {% cycle a,b as foo %}
- # case.
- args[1:2] = ['"%s"' % arg for arg in args[1].split(",")]
-
- if len(args) == 2:
- # {% cycle foo %} case.
- name = args[1]
- if not hasattr(parser, '_namedCycleNodes'):
- raise TemplateSyntaxError("No named cycles in template. '%s' is not defined" % name)
- if not name in parser._namedCycleNodes:
- raise TemplateSyntaxError("Named cycle '%s' does not exist" % name)
- return parser._namedCycleNodes[name]
-
- as_form = False
-
- if len(args) > 4:
- # {% cycle ... as foo [silent] %} case.
- if args[-3] == "as":
- if args[-1] != "silent":
- raise TemplateSyntaxError("Only 'silent' flag is allowed after cycle's name, not '%s'." % args[-1])
- as_form = True
- silent = True
- args = args[:-1]
- elif args[-2] == "as":
- as_form = True
- silent = False
-
- if as_form:
- name = args[-1]
- values = [parser.compile_filter(arg) for arg in args[1:-2]]
- node = CycleNode(values, name, silent=silent, escape=escape)
- if not hasattr(parser, '_namedCycleNodes'):
- parser._namedCycleNodes = {}
- parser._namedCycleNodes[name] = node
- else:
- values = [parser.compile_filter(arg) for arg in args[1:]]
- node = CycleNode(values, escape=escape)
- return node
-
-@register.tag
-def csrf_token(parser, token):
- return CsrfTokenNode()
-
-@register.tag
-def debug(parser, token):
- """
- Outputs a whole load of debugging information, including the current
- context and imported modules.
-
- Sample usage::
-
- <pre>
- {% debug %}
- </pre>
- """
- return DebugNode()
-
-@register.tag('filter')
-def do_filter(parser, token):
- """
- Filters the contents of the block through variable filters.
-
- Filters can also be piped through each other, and they can have
- arguments -- just like in variable syntax.
-
- Sample usage::
-
- {% filter force_escape|lower %}
- This text will be HTML-escaped, and will appear in lowercase.
- {% endfilter %}
-
- Note that the ``escape`` and ``safe`` filters are not acceptable arguments.
- Instead, use the ``autoescape`` tag to manage autoescaping for blocks of
- template code.
- """
- # token.split_contents() isn't useful here because this tag doesn't accept variable as arguments
- _, rest = token.contents.split(None, 1)
- filter_expr = parser.compile_filter("var|%s" % (rest))
- for func, unused in filter_expr.filters:
- filter_name = getattr(func, '_filter_name', None)
- if filter_name in ('escape', 'safe'):
- raise TemplateSyntaxError('"filter %s" is not permitted. Use the "autoescape" tag instead.' % filter_name)
- nodelist = parser.parse(('endfilter',))
- parser.delete_first_token()
- return FilterNode(filter_expr, nodelist)
-
-@register.tag
-def firstof(parser, token, escape=False):
- """
- Outputs the first variable passed that is not False, without escaping.
-
- Outputs nothing if all the passed variables are False.
-
- Sample usage::
-
- {% firstof var1 var2 var3 %}
-
- This is equivalent to::
-
- {% if var1 %}
- {{ var1|safe }}
- {% elif var2 %}
- {{ var2|safe }}
- {% elif var3 %}
- {{ var3|safe }}
- {% endif %}
-
- but obviously much cleaner!
-
- You can also use a literal string as a fallback value in case all
- passed variables are False::
-
- {% firstof var1 var2 var3 "fallback value" %}
-
- If you want to escape the output, use a filter tag::
-
- {% filter force_escape %}
- {% firstof var1 var2 var3 "fallback value" %}
- {% endfilter %}
-
- """
- if not escape:
- warnings.warn(
- "'The `firstof` template tag is changing to escape its arguments; "
- "the non-autoescaping version is deprecated. Load it "
- "from the `future` tag library to start using the new behavior.",
- PendingDeprecationWarning, stacklevel=2)
-
- bits = token.split_contents()[1:]
- if len(bits) < 1:
- raise TemplateSyntaxError("'firstof' statement requires at least one argument")
- return FirstOfNode([parser.compile_filter(bit) for bit in bits], escape=escape)
-
-@register.tag('for')
-def do_for(parser, token):
- """
- Loops over each item in an array.
-
- For example, to display a list of athletes given ``athlete_list``::
-
- <ul>
- {% for athlete in athlete_list %}
- <li>{{ athlete.name }}</li>
- {% endfor %}
- </ul>
-
- You can loop over a list in reverse by using
- ``{% for obj in list reversed %}``.
-
- You can also unpack multiple values from a two-dimensional array::
-
- {% for key,value in dict.items %}
- {{ key }}: {{ value }}
- {% endfor %}
-
- The ``for`` tag can take an optional ``{% empty %}`` clause that will
- be displayed if the given array is empty or could not be found::
-
- <ul>
- {% for athlete in athlete_list %}
- <li>{{ athlete.name }}</li>
- {% empty %}
- <li>Sorry, no athletes in this list.</li>
- {% endfor %}
- <ul>
-
- The above is equivalent to -- but shorter, cleaner, and possibly faster
- than -- the following::
-
- <ul>
- {% if althete_list %}
- {% for athlete in athlete_list %}
- <li>{{ athlete.name }}</li>
- {% endfor %}
- {% else %}
- <li>Sorry, no athletes in this list.</li>
- {% endif %}
- </ul>
-
- The for loop sets a number of variables available within the loop:
-
- ========================== ================================================
- Variable Description
- ========================== ================================================
- ``forloop.counter`` The current iteration of the loop (1-indexed)
- ``forloop.counter0`` The current iteration of the loop (0-indexed)
- ``forloop.revcounter`` The number of iterations from the end of the
- loop (1-indexed)
- ``forloop.revcounter0`` The number of iterations from the end of the
- loop (0-indexed)
- ``forloop.first`` True if this is the first time through the loop
- ``forloop.last`` True if this is the last time through the loop
- ``forloop.parentloop`` For nested loops, this is the loop "above" the
- current one
- ========================== ================================================
-
- """
- bits = token.split_contents()
- if len(bits) < 4:
- raise TemplateSyntaxError("'for' statements should have at least four"
- " words: %s" % token.contents)
-
- is_reversed = bits[-1] == 'reversed'
- in_index = -3 if is_reversed else -2
- if bits[in_index] != 'in':
- raise TemplateSyntaxError("'for' statements should use the format"
- " 'for x in y': %s" % token.contents)
-
- loopvars = re.split(r' *, *', ' '.join(bits[1:in_index]))
- for var in loopvars:
- if not var or ' ' in var:
- raise TemplateSyntaxError("'for' tag received an invalid argument:"
- " %s" % token.contents)
-
- sequence = parser.compile_filter(bits[in_index+1])
- nodelist_loop = parser.parse(('empty', 'endfor',))
- token = parser.next_token()
- if token.contents == 'empty':
- nodelist_empty = parser.parse(('endfor',))
- parser.delete_first_token()
- else:
- nodelist_empty = None
- return ForNode(loopvars, sequence, is_reversed, nodelist_loop, nodelist_empty)
-
-def do_ifequal(parser, token, negate):
- bits = list(token.split_contents())
- if len(bits) != 3:
- raise TemplateSyntaxError("%r takes two arguments" % bits[0])
- end_tag = 'end' + bits[0]
- nodelist_true = parser.parse(('else', end_tag))
- token = parser.next_token()
- if token.contents == 'else':
- nodelist_false = parser.parse((end_tag,))
- parser.delete_first_token()
- else:
- nodelist_false = NodeList()
- val1 = parser.compile_filter(bits[1])
- val2 = parser.compile_filter(bits[2])
- return IfEqualNode(val1, val2, nodelist_true, nodelist_false, negate)
-
-@register.tag
-def ifequal(parser, token):
- """
- Outputs the contents of the block if the two arguments equal each other.
-
- Examples::
-
- {% ifequal user.id comment.user_id %}
- ...
- {% endifequal %}
-
- {% ifnotequal user.id comment.user_id %}
- ...
- {% else %}
- ...
- {% endifnotequal %}
- """
- return do_ifequal(parser, token, False)
-
-@register.tag
-def ifnotequal(parser, token):
- """
- Outputs the contents of the block if the two arguments are not equal.
- See ifequal.
- """
- return do_ifequal(parser, token, True)
-
-class TemplateLiteral(Literal):
- def __init__(self, value, text):
- self.value = value
- self.text = text # for better error messages
-
- def display(self):
- return self.text
-
- def eval(self, context):
- return self.value.resolve(context, ignore_failures=True)
-
-class TemplateIfParser(IfParser):
- error_class = TemplateSyntaxError
-
- def __init__(self, parser, *args, **kwargs):
- self.template_parser = parser
- super(TemplateIfParser, self).__init__(*args, **kwargs)
-
- def create_var(self, value):
- return TemplateLiteral(self.template_parser.compile_filter(value), value)
-
-@register.tag('if')
-def do_if(parser, token):
- """
- The ``{% if %}`` tag evaluates a variable, and if that variable is "true"
- (i.e., exists, is not empty, and is not a false boolean value), the
- contents of the block are output:
-
- ::
-
- {% if athlete_list %}
- Number of athletes: {{ athlete_list|count }}
- {% elif athlete_in_locker_room_list %}
- Athletes should be out of the locker room soon!
- {% else %}
- No athletes.
- {% endif %}
-
- In the above, if ``athlete_list`` is not empty, the number of athletes will
- be displayed by the ``{{ athlete_list|count }}`` variable.
-
- As you can see, the ``if`` tag may take one or several `` {% elif %}``
- clauses, as well as an ``{% else %}`` clause that will be displayed if all
- previous conditions fail. These clauses are optional.
-
- ``if`` tags may use ``or``, ``and`` or ``not`` to test a number of
- variables or to negate a given variable::
-
- {% if not athlete_list %}
- There are no athletes.
- {% endif %}
-
- {% if athlete_list or coach_list %}
- There are some athletes or some coaches.
- {% endif %}
-
- {% if athlete_list and coach_list %}
- Both atheletes and coaches are available.
- {% endif %}
-
- {% if not athlete_list or coach_list %}
- There are no athletes, or there are some coaches.
- {% endif %}
-
- {% if athlete_list and not coach_list %}
- There are some athletes and absolutely no coaches.
- {% endif %}
-
- Comparison operators are also available, and the use of filters is also
- allowed, for example::
-
- {% if articles|length >= 5 %}...{% endif %}
-
- Arguments and operators _must_ have a space between them, so
- ``{% if 1>2 %}`` is not a valid if tag.
-
- All supported operators are: ``or``, ``and``, ``in``, ``not in``
- ``==`` (or ``=``), ``!=``, ``>``, ``>=``, ``<`` and ``<=``.
-
- Operator precedence follows Python.
- """
- # {% if ... %}
- bits = token.split_contents()[1:]
- condition = TemplateIfParser(parser, bits).parse()
- nodelist = parser.parse(('elif', 'else', 'endif'))
- conditions_nodelists = [(condition, nodelist)]
- token = parser.next_token()
-
- # {% elif ... %} (repeatable)
- while token.contents.startswith('elif'):
- bits = token.split_contents()[1:]
- condition = TemplateIfParser(parser, bits).parse()
- nodelist = parser.parse(('elif', 'else', 'endif'))
- conditions_nodelists.append((condition, nodelist))
- token = parser.next_token()
-
- # {% else %} (optional)
- if token.contents == 'else':
- nodelist = parser.parse(('endif',))
- conditions_nodelists.append((None, nodelist))
- token = parser.next_token()
-
- # {% endif %}
- assert token.contents == 'endif'
-
- return IfNode(conditions_nodelists)
-
-
-@register.tag
-def ifchanged(parser, token):
- """
- Checks if a value has changed from the last iteration of a loop.
-
- The ``{% ifchanged %}`` block tag is used within a loop. It has two
- possible uses.
-
- 1. Checks its own rendered contents against its previous state and only
- displays the content if it has changed. For example, this displays a
- list of days, only displaying the month if it changes::
-
- <h1>Archive for {{ year }}</h1>
-
- {% for date in days %}
- {% ifchanged %}<h3>{{ date|date:"F" }}</h3>{% endifchanged %}
- <a href="{{ date|date:"M/d"|lower }}/">{{ date|date:"j" }}</a>
- {% endfor %}
-
- 2. If given one or more variables, check whether any variable has changed.
- For example, the following shows the date every time it changes, while
- showing the hour if either the hour or the date has changed::
-
- {% for date in days %}
- {% ifchanged date.date %} {{ date.date }} {% endifchanged %}
- {% ifchanged date.hour date.date %}
- {{ date.hour }}
- {% endifchanged %}
- {% endfor %}
- """
- bits = token.split_contents()
- nodelist_true = parser.parse(('else', 'endifchanged'))
- token = parser.next_token()
- if token.contents == 'else':
- nodelist_false = parser.parse(('endifchanged',))
- parser.delete_first_token()
- else:
- nodelist_false = NodeList()
- values = [parser.compile_filter(bit) for bit in bits[1:]]
- return IfChangedNode(nodelist_true, nodelist_false, *values)
-
-@register.tag
-def ssi(parser, token):
- """
- Outputs the contents of a given file into the page.
-
- Like a simple "include" tag, the ``ssi`` tag includes the contents
- of another file -- which must be specified using an absolute path --
- in the current page::
-
- {% ssi "/home/html/ljworld.com/includes/right_generic.html" %}
-
- If the optional "parsed" parameter is given, the contents of the included
- file are evaluated as template code, with the current context::
-
- {% ssi "/home/html/ljworld.com/includes/right_generic.html" parsed %}
- """
- bits = token.split_contents()
- parsed = False
- if len(bits) not in (2, 3):
- raise TemplateSyntaxError("'ssi' tag takes one argument: the path to"
- " the file to be included")
- if len(bits) == 3:
- if bits[2] == 'parsed':
- parsed = True
- else:
- raise TemplateSyntaxError("Second (optional) argument to %s tag"
- " must be 'parsed'" % bits[0])
- filepath = parser.compile_filter(bits[1])
- return SsiNode(filepath, parsed)
-
-@register.tag
-def load(parser, token):
- """
- Loads a custom template tag set.
-
- For example, to load the template tags in
- ``django/templatetags/news/photos.py``::
-
- {% load news.photos %}
-
- Can also be used to load an individual tag/filter from
- a library::
-
- {% load byline from news %}
-
- """
- # token.split_contents() isn't useful here because this tag doesn't accept variable as arguments
- bits = token.contents.split()
- if len(bits) >= 4 and bits[-2] == "from":
- try:
- taglib = bits[-1]
- lib = get_library(taglib)
- except InvalidTemplateLibrary as e:
- raise TemplateSyntaxError("'%s' is not a valid tag library: %s" %
- (taglib, e))
- else:
- temp_lib = Library()
- for name in bits[1:-2]:
- if name in lib.tags:
- temp_lib.tags[name] = lib.tags[name]
- # a name could be a tag *and* a filter, so check for both
- if name in lib.filters:
- temp_lib.filters[name] = lib.filters[name]
- elif name in lib.filters:
- temp_lib.filters[name] = lib.filters[name]
- else:
- raise TemplateSyntaxError("'%s' is not a valid tag or filter in tag library '%s'" %
- (name, taglib))
- parser.add_library(temp_lib)
- else:
- for taglib in bits[1:]:
- # add the library to the parser
- try:
- lib = get_library(taglib)
- parser.add_library(lib)
- except InvalidTemplateLibrary as e:
- raise TemplateSyntaxError("'%s' is not a valid tag library: %s" %
- (taglib, e))
- return LoadNode()
-
-@register.tag
-def now(parser, token):
- """
- Displays the date, formatted according to the given string.
-
- Uses the same format as PHP's ``date()`` function; see http://php.net/date
- for all the possible values.
-
- Sample usage::
-
- It is {% now "jS F Y H:i" %}
- """
- bits = token.split_contents()
- if len(bits) != 2:
- raise TemplateSyntaxError("'now' statement takes one argument")
- format_string = bits[1][1:-1]
- return NowNode(format_string)
-
-@register.tag
-def regroup(parser, token):
- """
- Regroups a list of alike objects by a common attribute.
-
- This complex tag is best illustrated by use of an example: say that
- ``people`` is a list of ``Person`` objects that have ``first_name``,
- ``last_name``, and ``gender`` attributes, and you'd like to display a list
- that looks like:
-
- * Male:
- * George Bush
- * Bill Clinton
- * Female:
- * Margaret Thatcher
- * Colendeeza Rice
- * Unknown:
- * Pat Smith
-
- The following snippet of template code would accomplish this dubious task::
-
- {% regroup people by gender as grouped %}
- <ul>
- {% for group in grouped %}
- <li>{{ group.grouper }}
- <ul>
- {% for item in group.list %}
- <li>{{ item }}</li>
- {% endfor %}
- </ul>
- {% endfor %}
- </ul>
-
- As you can see, ``{% regroup %}`` populates a variable with a list of
- objects with ``grouper`` and ``list`` attributes. ``grouper`` contains the
- item that was grouped by; ``list`` contains the list of objects that share
- that ``grouper``. In this case, ``grouper`` would be ``Male``, ``Female``
- and ``Unknown``, and ``list`` is the list of people with those genders.
-
- Note that ``{% regroup %}`` does not work when the list to be grouped is not
- sorted by the key you are grouping by! This means that if your list of
- people was not sorted by gender, you'd need to make sure it is sorted
- before using it, i.e.::
-
- {% regroup people|dictsort:"gender" by gender as grouped %}
-
- """
- bits = token.split_contents()
- if len(bits) != 6:
- raise TemplateSyntaxError("'regroup' tag takes five arguments")
- target = parser.compile_filter(bits[1])
- if bits[2] != 'by':
- raise TemplateSyntaxError("second argument to 'regroup' tag must be 'by'")
- if bits[4] != 'as':
- raise TemplateSyntaxError("next-to-last argument to 'regroup' tag must"
- " be 'as'")
- var_name = bits[5]
- # RegroupNode will take each item in 'target', put it in the context under
- # 'var_name', evaluate 'var_name'.'expression' in the current context, and
- # group by the resulting value. After all items are processed, it will
- # save the final result in the context under 'var_name', thus clearing the
- # temporary values. This hack is necessary because the template engine
- # doesn't provide a context-aware equivalent of Python's getattr.
- expression = parser.compile_filter(var_name +
- VARIABLE_ATTRIBUTE_SEPARATOR +
- bits[3])
- return RegroupNode(target, expression, var_name)
-
-@register.tag
-def spaceless(parser, token):
- """
- Removes whitespace between HTML tags, including tab and newline characters.
-
- Example usage::
-
- {% spaceless %}
- <p>
- <a href="foo/">Foo</a>
- </p>
- {% endspaceless %}
-
- This example would return this HTML::
-
- <p><a href="foo/">Foo</a></p>
-
- Only space between *tags* is normalized -- not space between tags and text.
- In this example, the space around ``Hello`` won't be stripped::
-
- {% spaceless %}
- <strong>
- Hello
- </strong>
- {% endspaceless %}
- """
- nodelist = parser.parse(('endspaceless',))
- parser.delete_first_token()
- return SpacelessNode(nodelist)
-
-@register.tag
-def templatetag(parser, token):
- """
- Outputs one of the bits used to compose template tags.
-
- Since the template system has no concept of "escaping", to display one of
- the bits used in template tags, you must use the ``{% templatetag %}`` tag.
-
- The argument tells which template bit to output:
-
- ================== =======
- Argument Outputs
- ================== =======
- ``openblock`` ``{%``
- ``closeblock`` ``%}``
- ``openvariable`` ``{{``
- ``closevariable`` ``}}``
- ``openbrace`` ``{``
- ``closebrace`` ``}``
- ``opencomment`` ``{#``
- ``closecomment`` ``#}``
- ================== =======
- """
- # token.split_contents() isn't useful here because this tag doesn't accept variable as arguments
- bits = token.contents.split()
- if len(bits) != 2:
- raise TemplateSyntaxError("'templatetag' statement takes one argument")
- tag = bits[1]
- if tag not in TemplateTagNode.mapping:
- raise TemplateSyntaxError("Invalid templatetag argument: '%s'."
- " Must be one of: %s" %
- (tag, list(TemplateTagNode.mapping)))
- return TemplateTagNode(tag)
-
-@register.tag
-def url(parser, token):
- """
- Returns an absolute URL matching given view with its parameters.
-
- This is a way to define links that aren't tied to a particular URL
- configuration::
-
- {% url "path.to.some_view" arg1 arg2 %}
-
- or
-
- {% url "path.to.some_view" name1=value1 name2=value2 %}
-
- The first argument is a path to a view. It can be an absolute Python path
- or just ``app_name.view_name`` without the project name if the view is
- located inside the project.
-
- Other arguments are space-separated values that will be filled in place of
- positional and keyword arguments in the URL. Don't mix positional and
- keyword arguments.
-
- All arguments for the URL should be present.
-
- For example if you have a view ``app_name.client`` taking client's id and
- the corresponding line in a URLconf looks like this::
-
- ('^client/(\d+)/$', 'app_name.client')
-
- and this app's URLconf is included into the project's URLconf under some
- path::
-
- ('^clients/', include('project_name.app_name.urls'))
-
- then in a template you can create a link for a certain client like this::
-
- {% url "app_name.client" client.id %}
-
- The URL will look like ``/clients/client/123/``.
-
- The first argument can also be a named URL instead of the Python path to
- the view callable. For example if the URLconf entry looks like this::
-
- url('^client/(\d+)/$', name='client-detail-view')
-
- then in the template you can use::
-
- {% url "client-detail-view" client.id %}
-
- There is even another possible value type for the first argument. It can be
- the name of a template variable that will be evaluated to obtain the view
- name or the URL name, e.g.::
-
- {% with view_path="app_name.client" %}
- {% url view_path client.id %}
- {% endwith %}
-
- or,
-
- {% with url_name="client-detail-view" %}
- {% url url_name client.id %}
- {% endwith %}
-
- """
- bits = token.split_contents()
- if len(bits) < 2:
- raise TemplateSyntaxError("'%s' takes at least one argument"
- " (path to a view)" % bits[0])
- try:
- viewname = parser.compile_filter(bits[1])
- except TemplateSyntaxError as exc:
- exc.args = (exc.args[0] + ". "
- "The syntax of 'url' changed in Django 1.5, see the docs."),
- raise
- args = []
- kwargs = {}
- asvar = None
- bits = bits[2:]
- if len(bits) >= 2 and bits[-2] == 'as':
- asvar = bits[-1]
- bits = bits[:-2]
-
- if len(bits):
- for bit in bits:
- match = kwarg_re.match(bit)
- if not match:
- raise TemplateSyntaxError("Malformed arguments to url tag")
- name, value = match.groups()
- if name:
- kwargs[name] = parser.compile_filter(value)
- else:
- args.append(parser.compile_filter(value))
-
- return URLNode(viewname, args, kwargs, asvar)
-
-@register.tag
-def verbatim(parser, token):
- """
- Stops the template engine from rendering the contents of this block tag.
-
- Usage::
-
- {% verbatim %}
- {% don't process this %}
- {% endverbatim %}
-
- You can also designate a specific closing tag block (allowing the
- unrendered use of ``{% endverbatim %}``)::
-
- {% verbatim myblock %}
- ...
- {% endverbatim myblock %}
- """
- nodelist = parser.parse(('endverbatim',))
- parser.delete_first_token()
- return VerbatimNode(nodelist.render(Context()))
-
-@register.tag
-def widthratio(parser, token):
- """
- For creating bar charts and such, this tag calculates the ratio of a given
- value to a maximum value, and then applies that ratio to a constant.
-
- For example::
-
- <img src='bar.gif' height='10' width='{% widthratio this_value max_value max_width %}' />
-
- If ``this_value`` is 175, ``max_value`` is 200, and ``max_width`` is 100,
- the image in the above example will be 88 pixels wide
- (because 175/200 = .875; .875 * 100 = 87.5 which is rounded up to 88).
- """
- bits = token.split_contents()
- if len(bits) != 4:
- raise TemplateSyntaxError("widthratio takes three arguments")
- tag, this_value_expr, max_value_expr, max_width = bits
-
- return WidthRatioNode(parser.compile_filter(this_value_expr),
- parser.compile_filter(max_value_expr),
- parser.compile_filter(max_width))
-
-@register.tag('with')
-def do_with(parser, token):
- """
- Adds one or more values to the context (inside of this block) for caching
- and easy access.
-
- For example::
-
- {% with total=person.some_sql_method %}
- {{ total }} object{{ total|pluralize }}
- {% endwith %}
-
- Multiple values can be added to the context::
-
- {% with foo=1 bar=2 %}
- ...
- {% endwith %}
-
- The legacy format of ``{% with person.some_sql_method as total %}`` is
- still accepted.
- """
- bits = token.split_contents()
- remaining_bits = bits[1:]
- extra_context = token_kwargs(remaining_bits, parser, support_legacy=True)
- if not extra_context:
- raise TemplateSyntaxError("%r expected at least one variable "
- "assignment" % bits[0])
- if remaining_bits:
- raise TemplateSyntaxError("%r received an invalid token: %r" %
- (bits[0], remaining_bits[0]))
- nodelist = parser.parse(('endwith',))
- parser.delete_first_token()
- return WithNode(None, None, nodelist, extra_context=extra_context)
diff --git a/lib/python2.7/site-packages/django/template/loader.py b/lib/python2.7/site-packages/django/template/loader.py
deleted file mode 100644
index 6df4e43..0000000
--- a/lib/python2.7/site-packages/django/template/loader.py
+++ /dev/null
@@ -1,188 +0,0 @@
-# Wrapper for loading templates from storage of some sort (e.g. filesystem, database).
-#
-# This uses the TEMPLATE_LOADERS setting, which is a list of loaders to use.
-# Each loader is expected to have this interface:
-#
-# callable(name, dirs=[])
-#
-# name is the template name.
-# dirs is an optional list of directories to search instead of TEMPLATE_DIRS.
-#
-# The loader should return a tuple of (template_source, path). The path returned
-# might be shown to the user for debugging purposes, so it should identify where
-# the template was loaded from.
-#
-# A loader may return an already-compiled template instead of the actual
-# template source. In that case the path returned should be None, since the
-# path information is associated with the template during the compilation,
-# which has already been done.
-#
-# Each loader should have an "is_usable" attribute set. This is a boolean that
-# specifies whether the loader can be used in this Python installation. Each
-# loader is responsible for setting this when it's initialized.
-#
-# For example, the eggs loader (which is capable of loading templates from
-# Python eggs) sets is_usable to False if the "pkg_resources" module isn't
-# installed, because pkg_resources is necessary to read eggs.
-
-from django.core.exceptions import ImproperlyConfigured
-from django.template.base import Origin, Template, Context, TemplateDoesNotExist, add_to_builtins
-from django.conf import settings
-from django.utils.module_loading import import_by_path
-from django.utils import six
-
-template_source_loaders = None
-
-class BaseLoader(object):
- is_usable = False
-
- def __init__(self, *args, **kwargs):
- pass
-
- def __call__(self, template_name, template_dirs=None):
- return self.load_template(template_name, template_dirs)
-
- def load_template(self, template_name, template_dirs=None):
- source, display_name = self.load_template_source(template_name, template_dirs)
- origin = make_origin(display_name, self.load_template_source, template_name, template_dirs)
- try:
- template = get_template_from_string(source, origin, template_name)
- return template, None
- except TemplateDoesNotExist:
- # If compiling the template we found raises TemplateDoesNotExist, back off to
- # returning the source and display name for the template we were asked to load.
- # This allows for correct identification (later) of the actual template that does
- # not exist.
- return source, display_name
-
- def load_template_source(self, template_name, template_dirs=None):
- """
- Returns a tuple containing the source and origin for the given template
- name.
-
- """
- raise NotImplementedError
-
- def reset(self):
- """
- Resets any state maintained by the loader instance (e.g., cached
- templates or cached loader modules).
-
- """
- pass
-
-class LoaderOrigin(Origin):
- def __init__(self, display_name, loader, name, dirs):
- super(LoaderOrigin, self).__init__(display_name)
- self.loader, self.loadname, self.dirs = loader, name, dirs
-
- def reload(self):
- return self.loader(self.loadname, self.dirs)[0]
-
-def make_origin(display_name, loader, name, dirs):
- if settings.TEMPLATE_DEBUG and display_name:
- return LoaderOrigin(display_name, loader, name, dirs)
- else:
- return None
-
-def find_template_loader(loader):
- if isinstance(loader, (tuple, list)):
- loader, args = loader[0], loader[1:]
- else:
- args = []
- if isinstance(loader, six.string_types):
- TemplateLoader = import_by_path(loader)
-
- if hasattr(TemplateLoader, 'load_template_source'):
- func = TemplateLoader(*args)
- else:
- # Try loading module the old way - string is full path to callable
- if args:
- raise ImproperlyConfigured("Error importing template source loader %s - can't pass arguments to function-based loader." % loader)
- func = TemplateLoader
-
- if not func.is_usable:
- import warnings
- warnings.warn("Your TEMPLATE_LOADERS setting includes %r, but your Python installation doesn't support that type of template loading. Consider removing that line from TEMPLATE_LOADERS." % loader)
- return None
- else:
- return func
- else:
- raise ImproperlyConfigured('Loader does not define a "load_template" callable template source loader')
-
-def find_template(name, dirs=None):
- # Calculate template_source_loaders the first time the function is executed
- # because putting this logic in the module-level namespace may cause
- # circular import errors. See Django ticket #1292.
- global template_source_loaders
- if template_source_loaders is None:
- loaders = []
- for loader_name in settings.TEMPLATE_LOADERS:
- loader = find_template_loader(loader_name)
- if loader is not None:
- loaders.append(loader)
- template_source_loaders = tuple(loaders)
- for loader in template_source_loaders:
- try:
- source, display_name = loader(name, dirs)
- return (source, make_origin(display_name, loader, name, dirs))
- except TemplateDoesNotExist:
- pass
- raise TemplateDoesNotExist(name)
-
-def get_template(template_name):
- """
- Returns a compiled Template object for the given template name,
- handling template inheritance recursively.
- """
- template, origin = find_template(template_name)
- if not hasattr(template, 'render'):
- # template needs to be compiled
- template = get_template_from_string(template, origin, template_name)
- return template
-
-def get_template_from_string(source, origin=None, name=None):
- """
- Returns a compiled Template object for the given template code,
- handling template inheritance recursively.
- """
- return Template(source, origin, name)
-
-def render_to_string(template_name, dictionary=None, context_instance=None):
- """
- Loads the given template_name and renders it with the given dictionary as
- context. The template_name may be a string to load a single template using
- get_template, or it may be a tuple to use select_template to find one of
- the templates in the list. Returns a string.
- """
- dictionary = dictionary or {}
- if isinstance(template_name, (list, tuple)):
- t = select_template(template_name)
- else:
- t = get_template(template_name)
- if not context_instance:
- return t.render(Context(dictionary))
- # Add the dictionary to the context stack, ensuring it gets removed again
- # to keep the context_instance in the same state it started in.
- context_instance.update(dictionary)
- try:
- return t.render(context_instance)
- finally:
- context_instance.pop()
-
-def select_template(template_name_list):
- "Given a list of template names, returns the first that can be loaded."
- if not template_name_list:
- raise TemplateDoesNotExist("No template names provided")
- not_found = []
- for template_name in template_name_list:
- try:
- return get_template(template_name)
- except TemplateDoesNotExist as e:
- if e.args[0] not in not_found:
- not_found.append(e.args[0])
- continue
- # If we get here, none of the templates could be loaded
- raise TemplateDoesNotExist(', '.join(not_found))
-
-add_to_builtins('django.template.loader_tags')
diff --git a/lib/python2.7/site-packages/django/template/loader_tags.py b/lib/python2.7/site-packages/django/template/loader_tags.py
deleted file mode 100644
index 85ffcf1..0000000
--- a/lib/python2.7/site-packages/django/template/loader_tags.py
+++ /dev/null
@@ -1,265 +0,0 @@
-from collections import defaultdict
-
-from django.conf import settings
-from django.template.base import TemplateSyntaxError, Library, Node, TextNode,\
- token_kwargs, Variable
-from django.template.loader import get_template
-from django.utils.safestring import mark_safe
-from django.utils import six
-
-register = Library()
-
-BLOCK_CONTEXT_KEY = 'block_context'
-
-class ExtendsError(Exception):
- pass
-
-class BlockContext(object):
- def __init__(self):
- # Dictionary of FIFO queues.
- self.blocks = defaultdict(list)
-
- def add_blocks(self, blocks):
- for name, block in six.iteritems(blocks):
- self.blocks[name].insert(0, block)
-
- def pop(self, name):
- try:
- return self.blocks[name].pop()
- except IndexError:
- return None
-
- def push(self, name, block):
- self.blocks[name].append(block)
-
- def get_block(self, name):
- try:
- return self.blocks[name][-1]
- except IndexError:
- return None
-
-class BlockNode(Node):
- def __init__(self, name, nodelist, parent=None):
- self.name, self.nodelist, self.parent = name, nodelist, parent
-
- def __repr__(self):
- return "<Block Node: %s. Contents: %r>" % (self.name, self.nodelist)
-
- def render(self, context):
- block_context = context.render_context.get(BLOCK_CONTEXT_KEY)
- context.push()
- if block_context is None:
- context['block'] = self
- result = self.nodelist.render(context)
- else:
- push = block = block_context.pop(self.name)
- if block is None:
- block = self
- # Create new block so we can store context without thread-safety issues.
- block = BlockNode(block.name, block.nodelist)
- block.context = context
- context['block'] = block
- result = block.nodelist.render(context)
- if push is not None:
- block_context.push(self.name, push)
- context.pop()
- return result
-
- def super(self):
- render_context = self.context.render_context
- if (BLOCK_CONTEXT_KEY in render_context and
- render_context[BLOCK_CONTEXT_KEY].get_block(self.name) is not None):
- return mark_safe(self.render(self.context))
- return ''
-
-class ExtendsNode(Node):
- must_be_first = True
-
- def __init__(self, nodelist, parent_name, template_dirs=None):
- self.nodelist = nodelist
- self.parent_name = parent_name
- self.template_dirs = template_dirs
- self.blocks = dict([(n.name, n) for n in nodelist.get_nodes_by_type(BlockNode)])
-
- def __repr__(self):
- return '<ExtendsNode: extends %s>' % self.parent_name.token
-
- def get_parent(self, context):
- parent = self.parent_name.resolve(context)
- if not parent:
- error_msg = "Invalid template name in 'extends' tag: %r." % parent
- if self.parent_name.filters or\
- isinstance(self.parent_name.var, Variable):
- error_msg += " Got this from the '%s' variable." %\
- self.parent_name.token
- raise TemplateSyntaxError(error_msg)
- if hasattr(parent, 'render'):
- return parent # parent is a Template object
- return get_template(parent)
-
- def render(self, context):
- compiled_parent = self.get_parent(context)
-
- if BLOCK_CONTEXT_KEY not in context.render_context:
- context.render_context[BLOCK_CONTEXT_KEY] = BlockContext()
- block_context = context.render_context[BLOCK_CONTEXT_KEY]
-
- # Add the block nodes from this node to the block context
- block_context.add_blocks(self.blocks)
-
- # If this block's parent doesn't have an extends node it is the root,
- # and its block nodes also need to be added to the block context.
- for node in compiled_parent.nodelist:
- # The ExtendsNode has to be the first non-text node.
- if not isinstance(node, TextNode):
- if not isinstance(node, ExtendsNode):
- blocks = dict([(n.name, n) for n in
- compiled_parent.nodelist.get_nodes_by_type(BlockNode)])
- block_context.add_blocks(blocks)
- break
-
- # Call Template._render explicitly so the parser context stays
- # the same.
- return compiled_parent._render(context)
-
-class BaseIncludeNode(Node):
- def __init__(self, *args, **kwargs):
- self.extra_context = kwargs.pop('extra_context', {})
- self.isolated_context = kwargs.pop('isolated_context', False)
- super(BaseIncludeNode, self).__init__(*args, **kwargs)
-
- def render_template(self, template, context):
- values = dict([(name, var.resolve(context)) for name, var
- in six.iteritems(self.extra_context)])
- if self.isolated_context:
- return template.render(context.new(values))
- context.update(values)
- output = template.render(context)
- context.pop()
- return output
-
-class ConstantIncludeNode(BaseIncludeNode):
- def __init__(self, template_path, *args, **kwargs):
- super(ConstantIncludeNode, self).__init__(*args, **kwargs)
- try:
- t = get_template(template_path)
- self.template = t
- except:
- if settings.TEMPLATE_DEBUG:
- raise
- self.template = None
-
- def render(self, context):
- if not self.template:
- return ''
- return self.render_template(self.template, context)
-
-class IncludeNode(BaseIncludeNode):
- def __init__(self, template_name, *args, **kwargs):
- super(IncludeNode, self).__init__(*args, **kwargs)
- self.template_name = template_name
-
- def render(self, context):
- try:
- template_name = self.template_name.resolve(context)
- template = get_template(template_name)
- return self.render_template(template, context)
- except:
- if settings.TEMPLATE_DEBUG:
- raise
- return ''
-
-@register.tag('block')
-def do_block(parser, token):
- """
- Define a block that can be overridden by child templates.
- """
- # token.split_contents() isn't useful here because this tag doesn't accept variable as arguments
- bits = token.contents.split()
- if len(bits) != 2:
- raise TemplateSyntaxError("'%s' tag takes only one argument" % bits[0])
- block_name = bits[1]
- # Keep track of the names of BlockNodes found in this template, so we can
- # check for duplication.
- try:
- if block_name in parser.__loaded_blocks:
- raise TemplateSyntaxError("'%s' tag with name '%s' appears more than once" % (bits[0], block_name))
- parser.__loaded_blocks.append(block_name)
- except AttributeError: # parser.__loaded_blocks isn't a list yet
- parser.__loaded_blocks = [block_name]
- nodelist = parser.parse(('endblock',))
-
- # This check is kept for backwards-compatibility. See #3100.
- endblock = parser.next_token()
- acceptable_endblocks = ('endblock', 'endblock %s' % block_name)
- if endblock.contents not in acceptable_endblocks:
- parser.invalid_block_tag(endblock, 'endblock', acceptable_endblocks)
-
- return BlockNode(block_name, nodelist)
-
-@register.tag('extends')
-def do_extends(parser, token):
- """
- Signal that this template extends a parent template.
-
- This tag may be used in two ways: ``{% extends "base" %}`` (with quotes)
- uses the literal value "base" as the name of the parent template to extend,
- or ``{% extends variable %}`` uses the value of ``variable`` as either the
- name of the parent template to extend (if it evaluates to a string) or as
- the parent template itself (if it evaluates to a Template object).
- """
- bits = token.split_contents()
- if len(bits) != 2:
- raise TemplateSyntaxError("'%s' takes one argument" % bits[0])
- parent_name = parser.compile_filter(bits[1])
- nodelist = parser.parse()
- if nodelist.get_nodes_by_type(ExtendsNode):
- raise TemplateSyntaxError("'%s' cannot appear more than once in the same template" % bits[0])
- return ExtendsNode(nodelist, parent_name)
-
-@register.tag('include')
-def do_include(parser, token):
- """
- Loads a template and renders it with the current context. You can pass
- additional context using keyword arguments.
-
- Example::
-
- {% include "foo/some_include" %}
- {% include "foo/some_include" with bar="BAZZ!" baz="BING!" %}
-
- Use the ``only`` argument to exclude the current context when rendering
- the included template::
-
- {% include "foo/some_include" only %}
- {% include "foo/some_include" with bar="1" only %}
- """
- bits = token.split_contents()
- if len(bits) < 2:
- raise TemplateSyntaxError("%r tag takes at least one argument: the name of the template to be included." % bits[0])
- options = {}
- remaining_bits = bits[2:]
- while remaining_bits:
- option = remaining_bits.pop(0)
- if option in options:
- raise TemplateSyntaxError('The %r option was specified more '
- 'than once.' % option)
- if option == 'with':
- value = token_kwargs(remaining_bits, parser, support_legacy=False)
- if not value:
- raise TemplateSyntaxError('"with" in %r tag needs at least '
- 'one keyword argument.' % bits[0])
- elif option == 'only':
- value = True
- else:
- raise TemplateSyntaxError('Unknown argument for %r tag: %r.' %
- (bits[0], option))
- options[option] = value
- isolated_context = options.get('only', False)
- namemap = options.get('with', {})
- path = bits[1]
- if path[0] in ('"', "'") and path[-1] == path[0]:
- return ConstantIncludeNode(path[1:-1], extra_context=namemap,
- isolated_context=isolated_context)
- return IncludeNode(parser.compile_filter(bits[1]), extra_context=namemap,
- isolated_context=isolated_context)
diff --git a/lib/python2.7/site-packages/django/template/loaders/__init__.py b/lib/python2.7/site-packages/django/template/loaders/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/lib/python2.7/site-packages/django/template/loaders/__init__.py
+++ /dev/null
diff --git a/lib/python2.7/site-packages/django/template/loaders/app_directories.py b/lib/python2.7/site-packages/django/template/loaders/app_directories.py
deleted file mode 100644
index c82817a..0000000
--- a/lib/python2.7/site-packages/django/template/loaders/app_directories.py
+++ /dev/null
@@ -1,63 +0,0 @@
-"""
-Wrapper for loading templates from "templates" directories in INSTALLED_APPS
-packages.
-"""
-
-import os
-import sys
-
-from django.conf import settings
-from django.core.exceptions import ImproperlyConfigured
-from django.template.base import TemplateDoesNotExist
-from django.template.loader import BaseLoader
-from django.utils._os import safe_join
-from django.utils.importlib import import_module
-from django.utils import six
-
-# At compile time, cache the directories to search.
-if six.PY2:
- fs_encoding = sys.getfilesystemencoding() or sys.getdefaultencoding()
-app_template_dirs = []
-for app in settings.INSTALLED_APPS:
- try:
- mod = import_module(app)
- except ImportError as e:
- raise ImproperlyConfigured('ImportError %s: %s' % (app, e.args[0]))
- template_dir = os.path.join(os.path.dirname(mod.__file__), 'templates')
- if os.path.isdir(template_dir):
- if six.PY2:
- template_dir = template_dir.decode(fs_encoding)
- app_template_dirs.append(template_dir)
-
-# It won't change, so convert it to a tuple to save memory.
-app_template_dirs = tuple(app_template_dirs)
-
-class Loader(BaseLoader):
- is_usable = True
-
- def get_template_sources(self, template_name, template_dirs=None):
- """
- Returns the absolute paths to "template_name", when appended to each
- directory in "template_dirs". Any paths that don't lie inside one of the
- template dirs are excluded from the result set, for security reasons.
- """
- if not template_dirs:
- template_dirs = app_template_dirs
- for template_dir in template_dirs:
- try:
- yield safe_join(template_dir, template_name)
- except UnicodeDecodeError:
- # The template dir name was a bytestring that wasn't valid UTF-8.
- raise
- except ValueError:
- # The joined path was located outside of template_dir.
- pass
-
- def load_template_source(self, template_name, template_dirs=None):
- for filepath in self.get_template_sources(template_name, template_dirs):
- try:
- with open(filepath, 'rb') as fp:
- return (fp.read().decode(settings.FILE_CHARSET), filepath)
- except IOError:
- pass
- raise TemplateDoesNotExist(template_name)
diff --git a/lib/python2.7/site-packages/django/template/loaders/cached.py b/lib/python2.7/site-packages/django/template/loaders/cached.py
deleted file mode 100644
index c61045d..0000000
--- a/lib/python2.7/site-packages/django/template/loaders/cached.py
+++ /dev/null
@@ -1,64 +0,0 @@
-"""
-Wrapper class that takes a list of template loaders as an argument and attempts
-to load templates from them in order, caching the result.
-"""
-
-import hashlib
-from django.template.base import TemplateDoesNotExist
-from django.template.loader import BaseLoader, get_template_from_string, find_template_loader, make_origin
-from django.utils.encoding import force_bytes
-
-class Loader(BaseLoader):
- is_usable = True
-
- def __init__(self, loaders):
- self.template_cache = {}
- self._loaders = loaders
- self._cached_loaders = []
-
- @property
- def loaders(self):
- # Resolve loaders on demand to avoid circular imports
- if not self._cached_loaders:
- # Set self._cached_loaders atomically. Otherwise, another thread
- # could see an incomplete list. See #17303.
- cached_loaders = []
- for loader in self._loaders:
- cached_loaders.append(find_template_loader(loader))
- self._cached_loaders = cached_loaders
- return self._cached_loaders
-
- def find_template(self, name, dirs=None):
- for loader in self.loaders:
- try:
- template, display_name = loader(name, dirs)
- return (template, make_origin(display_name, loader, name, dirs))
- except TemplateDoesNotExist:
- pass
- raise TemplateDoesNotExist(name)
-
- def load_template(self, template_name, template_dirs=None):
- key = template_name
- if template_dirs:
- # If template directories were specified, use a hash to differentiate
- key = '-'.join([template_name, hashlib.sha1(force_bytes('|'.join(template_dirs))).hexdigest()])
-
- try:
- template = self.template_cache[key]
- except KeyError:
- template, origin = self.find_template(template_name, template_dirs)
- if not hasattr(template, 'render'):
- try:
- template = get_template_from_string(template, origin, template_name)
- except TemplateDoesNotExist:
- # If compiling the template we found raises TemplateDoesNotExist,
- # back off to returning the source and display name for the template
- # we were asked to load. This allows for correct identification (later)
- # of the actual template that does not exist.
- return template, origin
- self.template_cache[key] = template
- return template, None
-
- def reset(self):
- "Empty the template cache."
- self.template_cache.clear()
diff --git a/lib/python2.7/site-packages/django/template/loaders/eggs.py b/lib/python2.7/site-packages/django/template/loaders/eggs.py
deleted file mode 100644
index 7da1803..0000000
--- a/lib/python2.7/site-packages/django/template/loaders/eggs.py
+++ /dev/null
@@ -1,33 +0,0 @@
-# Wrapper for loading templates from eggs via pkg_resources.resource_string.
-from __future__ import unicode_literals
-
-try:
- from pkg_resources import resource_string
-except ImportError:
- resource_string = None
-
-from django.conf import settings
-from django.template.base import TemplateDoesNotExist
-from django.template.loader import BaseLoader
-from django.utils import six
-
-class Loader(BaseLoader):
- is_usable = resource_string is not None
-
- def load_template_source(self, template_name, template_dirs=None):
- """
- Loads templates from Python eggs via pkg_resource.resource_string.
-
- For every installed app, it tries to get the resource (app, template_name).
- """
- if resource_string is not None:
- pkg_name = 'templates/' + template_name
- for app in settings.INSTALLED_APPS:
- try:
- resource = resource_string(app, pkg_name)
- except Exception:
- continue
- if six.PY2:
- resource = resource.decode(settings.FILE_CHARSET)
- return (resource, 'egg:%s:%s' % (app, pkg_name))
- raise TemplateDoesNotExist(template_name)
diff --git a/lib/python2.7/site-packages/django/template/loaders/filesystem.py b/lib/python2.7/site-packages/django/template/loaders/filesystem.py
deleted file mode 100644
index 1a7f0d2..0000000
--- a/lib/python2.7/site-packages/django/template/loaders/filesystem.py
+++ /dev/null
@@ -1,46 +0,0 @@
-"""
-Wrapper for loading templates from the filesystem.
-"""
-
-from django.conf import settings
-from django.template.base import TemplateDoesNotExist
-from django.template.loader import BaseLoader
-from django.utils._os import safe_join
-
-class Loader(BaseLoader):
- is_usable = True
-
- def get_template_sources(self, template_name, template_dirs=None):
- """
- Returns the absolute paths to "template_name", when appended to each
- directory in "template_dirs". Any paths that don't lie inside one of the
- template dirs are excluded from the result set, for security reasons.
- """
- if not template_dirs:
- template_dirs = settings.TEMPLATE_DIRS
- for template_dir in template_dirs:
- try:
- yield safe_join(template_dir, template_name)
- except UnicodeDecodeError:
- # The template dir name was a bytestring that wasn't valid UTF-8.
- raise
- except ValueError:
- # The joined path was located outside of this particular
- # template_dir (it might be inside another one, so this isn't
- # fatal).
- pass
-
- def load_template_source(self, template_name, template_dirs=None):
- tried = []
- for filepath in self.get_template_sources(template_name, template_dirs):
- try:
- with open(filepath, 'rb') as fp:
- return (fp.read().decode(settings.FILE_CHARSET), filepath)
- except IOError:
- tried.append(filepath)
- if tried:
- error_msg = "Tried %s" % tried
- else:
- error_msg = "Your TEMPLATE_DIRS setting is empty. Change it to point to at least one template directory."
- raise TemplateDoesNotExist(error_msg)
- load_template_source.is_usable = True
diff --git a/lib/python2.7/site-packages/django/template/response.py b/lib/python2.7/site-packages/django/template/response.py
deleted file mode 100644
index 3b3b413..0000000
--- a/lib/python2.7/site-packages/django/template/response.py
+++ /dev/null
@@ -1,159 +0,0 @@
-from django.http import HttpResponse
-from django.template import loader, Context, RequestContext
-from django.utils import six
-
-
-class ContentNotRenderedError(Exception):
- pass
-
-
-class SimpleTemplateResponse(HttpResponse):
- rendering_attrs = ['template_name', 'context_data', '_post_render_callbacks']
-
- def __init__(self, template, context=None, content_type=None, status=None,
- mimetype=None):
- # It would seem obvious to call these next two members 'template' and
- # 'context', but those names are reserved as part of the test Client
- # API. To avoid the name collision, we use tricky-to-debug problems
- self.template_name = template
- self.context_data = context
-
- self._post_render_callbacks = []
-
- # content argument doesn't make sense here because it will be replaced
- # with rendered template so we always pass empty string in order to
- # prevent errors and provide shorter signature.
- super(SimpleTemplateResponse, self).__init__('', content_type, status,
- mimetype)
-
- # _is_rendered tracks whether the template and context has been baked
- # into a final response.
- # Super __init__ doesn't know any better than to set self.content to
- # the empty string we just gave it, which wrongly sets _is_rendered
- # True, so we initialize it to False after the call to super __init__.
- self._is_rendered = False
-
- def __getstate__(self):
- """Pickling support function.
-
- Ensures that the object can't be pickled before it has been
- rendered, and that the pickled state only includes rendered
- data, not the data used to construct the response.
- """
- obj_dict = super(SimpleTemplateResponse, self).__getstate__()
- if not self._is_rendered:
- raise ContentNotRenderedError('The response content must be '
- 'rendered before it can be pickled.')
- for attr in self.rendering_attrs:
- if attr in obj_dict:
- del obj_dict[attr]
-
- return obj_dict
-
- def resolve_template(self, template):
- "Accepts a template object, path-to-template or list of paths"
- if isinstance(template, (list, tuple)):
- return loader.select_template(template)
- elif isinstance(template, six.string_types):
- return loader.get_template(template)
- else:
- return template
-
- def resolve_context(self, context):
- """Converts context data into a full Context object
- (assuming it isn't already a Context object).
- """
- if isinstance(context, Context):
- return context
- else:
- return Context(context)
-
- @property
- def rendered_content(self):
- """Returns the freshly rendered content for the template and context
- described by the TemplateResponse.
-
- This *does not* set the final content of the response. To set the
- response content, you must either call render(), or set the
- content explicitly using the value of this property.
- """
- template = self.resolve_template(self.template_name)
- context = self.resolve_context(self.context_data)
- content = template.render(context)
- return content
-
- def add_post_render_callback(self, callback):
- """Adds a new post-rendering callback.
-
- If the response has already been rendered,
- invoke the callback immediately.
- """
- if self._is_rendered:
- callback(self)
- else:
- self._post_render_callbacks.append(callback)
-
- def render(self):
- """Renders (thereby finalizing) the content of the response.
-
- If the content has already been rendered, this is a no-op.
-
- Returns the baked response instance.
- """
- retval = self
- if not self._is_rendered:
- self.content = self.rendered_content
- for post_callback in self._post_render_callbacks:
- newretval = post_callback(retval)
- if newretval is not None:
- retval = newretval
- return retval
-
- @property
- def is_rendered(self):
- return self._is_rendered
-
- def __iter__(self):
- if not self._is_rendered:
- raise ContentNotRenderedError('The response content must be '
- 'rendered before it can be iterated over.')
- return super(SimpleTemplateResponse, self).__iter__()
-
- @property
- def content(self):
- if not self._is_rendered:
- raise ContentNotRenderedError('The response content must be '
- 'rendered before it can be accessed.')
- return super(SimpleTemplateResponse, self).content
-
- @content.setter
- def content(self, value):
- """Sets the content for the response
- """
- HttpResponse.content.fset(self, value)
- self._is_rendered = True
-
-
-class TemplateResponse(SimpleTemplateResponse):
- rendering_attrs = SimpleTemplateResponse.rendering_attrs + \
- ['_request', '_current_app']
-
- def __init__(self, request, template, context=None, content_type=None,
- status=None, mimetype=None, current_app=None):
- # self.request gets over-written by django.test.client.Client - and
- # unlike context_data and template_name the _request should not
- # be considered part of the public API.
- self._request = request
- # As a convenience we'll allow callers to provide current_app without
- # having to avoid needing to create the RequestContext directly
- self._current_app = current_app
- super(TemplateResponse, self).__init__(
- template, context, content_type, status, mimetype)
-
- def resolve_context(self, context):
- """Convert context data into a full RequestContext object
- (assuming it isn't already a Context object).
- """
- if isinstance(context, Context):
- return context
- return RequestContext(self._request, context, current_app=self._current_app)
diff --git a/lib/python2.7/site-packages/django/template/smartif.py b/lib/python2.7/site-packages/django/template/smartif.py
deleted file mode 100644
index e2ca395..0000000
--- a/lib/python2.7/site-packages/django/template/smartif.py
+++ /dev/null
@@ -1,205 +0,0 @@
-"""
-Parser and utilities for the smart 'if' tag
-"""
-
-# Using a simple top down parser, as described here:
-# http://effbot.org/zone/simple-top-down-parsing.htm.
-# 'led' = left denotation
-# 'nud' = null denotation
-# 'bp' = binding power (left = lbp, right = rbp)
-
-class TokenBase(object):
- """
- Base class for operators and literals, mainly for debugging and for throwing
- syntax errors.
- """
- id = None # node/token type name
- value = None # used by literals
- first = second = None # used by tree nodes
-
- def nud(self, parser):
- # Null denotation - called in prefix context
- raise parser.error_class(
- "Not expecting '%s' in this position in if tag." % self.id
- )
-
- def led(self, left, parser):
- # Left denotation - called in infix context
- raise parser.error_class(
- "Not expecting '%s' as infix operator in if tag." % self.id
- )
-
- def display(self):
- """
- Returns what to display in error messages for this node
- """
- return self.id
-
- def __repr__(self):
- out = [str(x) for x in [self.id, self.first, self.second] if x is not None]
- return "(" + " ".join(out) + ")"
-
-
-def infix(bp, func):
- """
- Creates an infix operator, given a binding power and a function that
- evaluates the node
- """
- class Operator(TokenBase):
- lbp = bp
-
- def led(self, left, parser):
- self.first = left
- self.second = parser.expression(bp)
- return self
-
- def eval(self, context):
- try:
- return func(context, self.first, self.second)
- except Exception:
- # Templates shouldn't throw exceptions when rendering. We are
- # most likely to get exceptions for things like {% if foo in bar
- # %} where 'bar' does not support 'in', so default to False
- return False
-
- return Operator
-
-
-def prefix(bp, func):
- """
- Creates a prefix operator, given a binding power and a function that
- evaluates the node.
- """
- class Operator(TokenBase):
- lbp = bp
-
- def nud(self, parser):
- self.first = parser.expression(bp)
- self.second = None
- return self
-
- def eval(self, context):
- try:
- return func(context, self.first)
- except Exception:
- return False
-
- return Operator
-
-
-# Operator precedence follows Python.
-# NB - we can get slightly more accurate syntax error messages by not using the
-# same object for '==' and '='.
-# We defer variable evaluation to the lambda to ensure that terms are
-# lazily evaluated using Python's boolean parsing logic.
-OPERATORS = {
- 'or': infix(6, lambda context, x, y: x.eval(context) or y.eval(context)),
- 'and': infix(7, lambda context, x, y: x.eval(context) and y.eval(context)),
- 'not': prefix(8, lambda context, x: not x.eval(context)),
- 'in': infix(9, lambda context, x, y: x.eval(context) in y.eval(context)),
- 'not in': infix(9, lambda context, x, y: x.eval(context) not in y.eval(context)),
- '=': infix(10, lambda context, x, y: x.eval(context) == y.eval(context)),
- '==': infix(10, lambda context, x, y: x.eval(context) == y.eval(context)),
- '!=': infix(10, lambda context, x, y: x.eval(context) != y.eval(context)),
- '>': infix(10, lambda context, x, y: x.eval(context) > y.eval(context)),
- '>=': infix(10, lambda context, x, y: x.eval(context) >= y.eval(context)),
- '<': infix(10, lambda context, x, y: x.eval(context) < y.eval(context)),
- '<=': infix(10, lambda context, x, y: x.eval(context) <= y.eval(context)),
-}
-
-# Assign 'id' to each:
-for key, op in OPERATORS.items():
- op.id = key
-
-
-class Literal(TokenBase):
- """
- A basic self-resolvable object similar to a Django template variable.
- """
- # IfParser uses Literal in create_var, but TemplateIfParser overrides
- # create_var so that a proper implementation that actually resolves
- # variables, filters etc is used.
- id = "literal"
- lbp = 0
-
- def __init__(self, value):
- self.value = value
-
- def display(self):
- return repr(self.value)
-
- def nud(self, parser):
- return self
-
- def eval(self, context):
- return self.value
-
- def __repr__(self):
- return "(%s %r)" % (self.id, self.value)
-
-
-class EndToken(TokenBase):
- lbp = 0
-
- def nud(self, parser):
- raise parser.error_class("Unexpected end of expression in if tag.")
-
-EndToken = EndToken()
-
-
-class IfParser(object):
- error_class = ValueError
-
- def __init__(self, tokens):
- # pre-pass necessary to turn 'not','in' into single token
- l = len(tokens)
- mapped_tokens = []
- i = 0
- while i < l:
- token = tokens[i]
- if token == "not" and i + 1 < l and tokens[i+1] == "in":
- token = "not in"
- i += 1 # skip 'in'
- mapped_tokens.append(self.translate_token(token))
- i += 1
-
- self.tokens = mapped_tokens
- self.pos = 0
- self.current_token = self.next_token()
-
- def translate_token(self, token):
- try:
- op = OPERATORS[token]
- except (KeyError, TypeError):
- return self.create_var(token)
- else:
- return op()
-
- def next_token(self):
- if self.pos >= len(self.tokens):
- return EndToken
- else:
- retval = self.tokens[self.pos]
- self.pos += 1
- return retval
-
- def parse(self):
- retval = self.expression()
- # Check that we have exhausted all the tokens
- if self.current_token is not EndToken:
- raise self.error_class("Unused '%s' at end of if expression." %
- self.current_token.display())
- return retval
-
- def expression(self, rbp=0):
- t = self.current_token
- self.current_token = self.next_token()
- left = t.nud(self)
- while rbp < self.current_token.lbp:
- t = self.current_token
- self.current_token = self.next_token()
- left = t.led(left, self)
- return left
-
- def create_var(self, value):
- return Literal(value)