You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by ma...@apache.org on 2014/09/03 21:35:22 UTC
[10/22] Revert "AMBARI-7138. Ambari RPM deals with jinja2 dependency
incorrectly (aonishuk)"
http://git-wip-us.apache.org/repos/asf/ambari/blob/570de228/ambari-common/src/main/python/jinja2/docs/api.rst
----------------------------------------------------------------------
diff --git a/ambari-common/src/main/python/jinja2/docs/api.rst b/ambari-common/src/main/python/jinja2/docs/api.rst
new file mode 100644
index 0000000..3bf8a94
--- /dev/null
+++ b/ambari-common/src/main/python/jinja2/docs/api.rst
@@ -0,0 +1,787 @@
+API
+===
+
+.. module:: jinja2
+ :synopsis: public Jinja2 API
+
+This document describes the API to Jinja2 and not the template language. It
+will be most useful as reference to those implementing the template interface
+to the application and not those who are creating Jinja2 templates.
+
+Basics
+------
+
+Jinja2 uses a central object called the template :class:`Environment`.
+Instances of this class are used to store the configuration, global objects
+and are used to load templates from the file system or other locations.
+Even if you are creating templates from strings by using the constructor of
+:class:`Template` class, an environment is created automatically for you,
+albeit a shared one.
+
+Most applications will create one :class:`Environment` object on application
+initialization and use that to load templates. In some cases it's however
+useful to have multiple environments side by side, if different configurations
+are in use.
+
+The simplest way to configure Jinja2 to load templates for your application
+looks roughly like this::
+
+ from jinja2 import Environment, PackageLoader
+ env = Environment(loader=PackageLoader('yourapplication', 'templates'))
+
+This will create a template environment with the default settings and a
+loader that looks up the templates in the `templates` folder inside the
+`yourapplication` python package. Different loaders are available
+and you can also write your own if you want to load templates from a
+database or other resources.
+
+To load a template from this environment you just have to call the
+:meth:`get_template` method which then returns the loaded :class:`Template`::
+
+ template = env.get_template('mytemplate.html')
+
+To render it with some variables, just call the :meth:`render` method::
+
+ print template.render(the='variables', go='here')
+
+Using a template loader rather then passing strings to :class:`Template`
+or :meth:`Environment.from_string` has multiple advantages. Besides being
+a lot easier to use it also enables template inheritance.
+
+
+Unicode
+-------
+
+Jinja2 is using Unicode internally which means that you have to pass Unicode
+objects to the render function or bytestrings that only consist of ASCII
+characters. Additionally newlines are normalized to one end of line
+sequence which is per default UNIX style (``\n``).
+
+Python 2.x supports two ways of representing string objects. One is the
+`str` type and the other is the `unicode` type, both of which extend a type
+called `basestring`. Unfortunately the default is `str` which should not
+be used to store text based information unless only ASCII characters are
+used. With Python 2.6 it is possible to make `unicode` the default on a per
+module level and with Python 3 it will be the default.
+
+To explicitly use a Unicode string you have to prefix the string literal
+with a `u`: ``u'Hänsel und Gretel sagen Hallo'``. That way Python will
+store the string as Unicode by decoding the string with the character
+encoding from the current Python module. If no encoding is specified this
+defaults to 'ASCII' which means that you can't use any non ASCII identifier.
+
+To set a better module encoding add the following comment to the first or
+second line of the Python module using the Unicode literal::
+
+ # -*- coding: utf-8 -*-
+
+We recommend utf-8 as Encoding for Python modules and templates as it's
+possible to represent every Unicode character in utf-8 and because it's
+backwards compatible to ASCII. For Jinja2 the default encoding of templates
+is assumed to be utf-8.
+
+It is not possible to use Jinja2 to process non-Unicode data. The reason
+for this is that Jinja2 uses Unicode already on the language level. For
+example Jinja2 treats the non-breaking space as valid whitespace inside
+expressions which requires knowledge of the encoding or operating on an
+Unicode string.
+
+For more details about Unicode in Python have a look at the excellent
+`Unicode documentation`_.
+
+Another important thing is how Jinja2 is handling string literals in
+templates. A naive implementation would be using Unicode strings for
+all string literals but it turned out in the past that this is problematic
+as some libraries are typechecking against `str` explicitly. For example
+`datetime.strftime` does not accept Unicode arguments. To not break it
+completely Jinja2 is returning `str` for strings that fit into ASCII and
+for everything else `unicode`:
+
+>>> m = Template(u"{% set a, b = 'foo', 'föö' %}").module
+>>> m.a
+'foo'
+>>> m.b
+u'f\xf6\xf6'
+
+
+.. _Unicode documentation: http://docs.python.org/dev/howto/unicode.html
+
+High Level API
+--------------
+
+The high-level API is the API you will use in the application to load and
+render Jinja2 templates. The :ref:`low-level-api` on the other side is only
+useful if you want to dig deeper into Jinja2 or :ref:`develop extensions
+<jinja-extensions>`.
+
+.. autoclass:: Environment([options])
+ :members: from_string, get_template, select_template,
+ get_or_select_template, join_path, extend, compile_expression
+
+ .. attribute:: shared
+
+ If a template was created by using the :class:`Template` constructor
+ an environment is created automatically. These environments are
+ created as shared environments which means that multiple templates
+ may have the same anonymous environment. For all shared environments
+ this attribute is `True`, else `False`.
+
+ .. attribute:: sandboxed
+
+ If the environment is sandboxed this attribute is `True`. For the
+ sandbox mode have a look at the documentation for the
+ :class:`~jinja2.sandbox.SandboxedEnvironment`.
+
+ .. attribute:: filters
+
+ A dict of filters for this environment. As long as no template was
+ loaded it's safe to add new filters or remove old. For custom filters
+ see :ref:`writing-filters`. For valid filter names have a look at
+ :ref:`identifier-naming`.
+
+ .. attribute:: tests
+
+ A dict of test functions for this environment. As long as no
+ template was loaded it's safe to modify this dict. For custom tests
+ see :ref:`writing-tests`. For valid test names have a look at
+ :ref:`identifier-naming`.
+
+ .. attribute:: globals
+
+ A dict of global variables. These variables are always available
+ in a template. As long as no template was loaded it's safe
+ to modify this dict. For more details see :ref:`global-namespace`.
+ For valid object names have a look at :ref:`identifier-naming`.
+
+ .. automethod:: overlay([options])
+
+ .. method:: undefined([hint, obj, name, exc])
+
+ Creates a new :class:`Undefined` object for `name`. This is useful
+ for filters or functions that may return undefined objects for
+ some operations. All parameters except of `hint` should be provided
+ as keyword parameters for better readability. The `hint` is used as
+ error message for the exception if provided, otherwise the error
+ message will be generated from `obj` and `name` automatically. The exception
+ provided as `exc` is raised if something with the generated undefined
+ object is done that the undefined object does not allow. The default
+ exception is :exc:`UndefinedError`. If a `hint` is provided the
+ `name` may be ommited.
+
+ The most common way to create an undefined object is by providing
+ a name only::
+
+ return environment.undefined(name='some_name')
+
+ This means that the name `some_name` is not defined. If the name
+ was from an attribute of an object it makes sense to tell the
+ undefined object the holder object to improve the error message::
+
+ if not hasattr(obj, 'attr'):
+ return environment.undefined(obj=obj, name='attr')
+
+ For a more complex example you can provide a hint. For example
+ the :func:`first` filter creates an undefined object that way::
+
+ return environment.undefined('no first item, sequence was empty')
+
+ If it the `name` or `obj` is known (for example because an attribute
+ was accessed) it shold be passed to the undefined object, even if
+ a custom `hint` is provided. This gives undefined objects the
+ possibility to enhance the error message.
+
+.. autoclass:: Template
+ :members: module, make_module
+
+ .. attribute:: globals
+
+ The dict with the globals of that template. It's unsafe to modify
+ this dict as it may be shared with other templates or the environment
+ that loaded the template.
+
+ .. attribute:: name
+
+ The loading name of the template. If the template was loaded from a
+ string this is `None`.
+
+ .. attribute:: filename
+
+ The filename of the template on the file system if it was loaded from
+ there. Otherwise this is `None`.
+
+ .. automethod:: render([context])
+
+ .. automethod:: generate([context])
+
+ .. automethod:: stream([context])
+
+
+.. autoclass:: jinja2.environment.TemplateStream()
+ :members: disable_buffering, enable_buffering, dump
+
+
+Autoescaping
+------------
+
+.. versionadded:: 2.4
+
+As of Jinja 2.4 the preferred way to do autoescaping is to enable the
+:ref:`autoescape-extension` and to configure a sensible default for
+autoescaping. This makes it possible to enable and disable autoescaping
+on a per-template basis (HTML versus text for instance).
+
+Here a recommended setup that enables autoescaping for templates ending
+in ``'.html'``, ``'.htm'`` and ``'.xml'`` and disabling it by default
+for all other extensions::
+
+ def guess_autoescape(template_name):
+ if template_name is None or '.' not in template_name:
+ return False
+ ext = template_name.rsplit('.', 1)[1]
+ return ext in ('html', 'htm', 'xml')
+
+ env = Environment(autoescape=guess_autoescape,
+ loader=PackageLoader('mypackage'),
+ extensions=['jinja2.ext.autoescape'])
+
+When implementing a guessing autoescape function, make sure you also
+accept `None` as valid template name. This will be passed when generating
+templates from strings.
+
+Inside the templates the behaviour can be temporarily changed by using
+the `autoescape` block (see :ref:`autoescape-overrides`).
+
+
+.. _identifier-naming:
+
+Notes on Identifiers
+--------------------
+
+Jinja2 uses the regular Python 2.x naming rules. Valid identifiers have to
+match ``[a-zA-Z_][a-zA-Z0-9_]*``. As a matter of fact non ASCII characters
+are currently not allowed. This limitation will probably go away as soon as
+unicode identifiers are fully specified for Python 3.
+
+Filters and tests are looked up in separate namespaces and have slightly
+modified identifier syntax. Filters and tests may contain dots to group
+filters and tests by topic. For example it's perfectly valid to add a
+function into the filter dict and call it `to.unicode`. The regular
+expression for filter and test identifiers is
+``[a-zA-Z_][a-zA-Z0-9_]*(\.[a-zA-Z_][a-zA-Z0-9_]*)*```.
+
+
+Undefined Types
+---------------
+
+These classes can be used as undefined types. The :class:`Environment`
+constructor takes an `undefined` parameter that can be one of those classes
+or a custom subclass of :class:`Undefined`. Whenever the template engine is
+unable to look up a name or access an attribute one of those objects is
+created and returned. Some operations on undefined values are then allowed,
+others fail.
+
+The closest to regular Python behavior is the `StrictUndefined` which
+disallows all operations beside testing if it's an undefined object.
+
+.. autoclass:: jinja2.Undefined()
+
+ .. attribute:: _undefined_hint
+
+ Either `None` or an unicode string with the error message for
+ the undefined object.
+
+ .. attribute:: _undefined_obj
+
+ Either `None` or the owner object that caused the undefined object
+ to be created (for example because an attribute does not exist).
+
+ .. attribute:: _undefined_name
+
+ The name for the undefined variable / attribute or just `None`
+ if no such information exists.
+
+ .. attribute:: _undefined_exception
+
+ The exception that the undefined object wants to raise. This
+ is usually one of :exc:`UndefinedError` or :exc:`SecurityError`.
+
+ .. method:: _fail_with_undefined_error(\*args, \**kwargs)
+
+ When called with any arguments this method raises
+ :attr:`_undefined_exception` with an error message generated
+ from the undefined hints stored on the undefined object.
+
+.. autoclass:: jinja2.DebugUndefined()
+
+.. autoclass:: jinja2.StrictUndefined()
+
+Undefined objects are created by calling :attr:`undefined`.
+
+.. admonition:: Implementation
+
+ :class:`Undefined` objects are implemented by overriding the special
+ `__underscore__` methods. For example the default :class:`Undefined`
+ class implements `__unicode__` in a way that it returns an empty
+ string, however `__int__` and others still fail with an exception. To
+ allow conversion to int by returning ``0`` you can implement your own::
+
+ class NullUndefined(Undefined):
+ def __int__(self):
+ return 0
+ def __float__(self):
+ return 0.0
+
+ To disallow a method, just override it and raise
+ :attr:`~Undefined._undefined_exception`. Because this is a very common
+ idom in undefined objects there is the helper method
+ :meth:`~Undefined._fail_with_undefined_error` that does the error raising
+ automatically. Here a class that works like the regular :class:`Undefined`
+ but chokes on iteration::
+
+ class NonIterableUndefined(Undefined):
+ __iter__ = Undefined._fail_with_undefined_error
+
+
+The Context
+-----------
+
+.. autoclass:: jinja2.runtime.Context()
+ :members: resolve, get_exported, get_all
+
+ .. attribute:: parent
+
+ A dict of read only, global variables the template looks up. These
+ can either come from another :class:`Context`, from the
+ :attr:`Environment.globals` or :attr:`Template.globals` or points
+ to a dict created by combining the globals with the variables
+ passed to the render function. It must not be altered.
+
+ .. attribute:: vars
+
+ The template local variables. This list contains environment and
+ context functions from the :attr:`parent` scope as well as local
+ modifications and exported variables from the template. The template
+ will modify this dict during template evaluation but filters and
+ context functions are not allowed to modify it.
+
+ .. attribute:: environment
+
+ The environment that loaded the template.
+
+ .. attribute:: exported_vars
+
+ This set contains all the names the template exports. The values for
+ the names are in the :attr:`vars` dict. In order to get a copy of the
+ exported variables as dict, :meth:`get_exported` can be used.
+
+ .. attribute:: name
+
+ The load name of the template owning this context.
+
+ .. attribute:: blocks
+
+ A dict with the current mapping of blocks in the template. The keys
+ in this dict are the names of the blocks, and the values a list of
+ blocks registered. The last item in each list is the current active
+ block (latest in the inheritance chain).
+
+ .. attribute:: eval_ctx
+
+ The current :ref:`eval-context`.
+
+ .. automethod:: jinja2.runtime.Context.call(callable, \*args, \**kwargs)
+
+
+.. admonition:: Implementation
+
+ Context is immutable for the same reason Python's frame locals are
+ immutable inside functions. Both Jinja2 and Python are not using the
+ context / frame locals as data storage for variables but only as primary
+ data source.
+
+ When a template accesses a variable the template does not define, Jinja2
+ looks up the variable in the context, after that the variable is treated
+ as if it was defined in the template.
+
+
+.. _loaders:
+
+Loaders
+-------
+
+Loaders are responsible for loading templates from a resource such as the
+file system. The environment will keep the compiled modules in memory like
+Python's `sys.modules`. Unlike `sys.modules` however this cache is limited in
+size by default and templates are automatically reloaded.
+All loaders are subclasses of :class:`BaseLoader`. If you want to create your
+own loader, subclass :class:`BaseLoader` and override `get_source`.
+
+.. autoclass:: jinja2.BaseLoader
+ :members: get_source, load
+
+Here a list of the builtin loaders Jinja2 provides:
+
+.. autoclass:: jinja2.FileSystemLoader
+
+.. autoclass:: jinja2.PackageLoader
+
+.. autoclass:: jinja2.DictLoader
+
+.. autoclass:: jinja2.FunctionLoader
+
+.. autoclass:: jinja2.PrefixLoader
+
+.. autoclass:: jinja2.ChoiceLoader
+
+
+.. _bytecode-cache:
+
+Bytecode Cache
+--------------
+
+Jinja 2.1 and higher support external bytecode caching. Bytecode caches make
+it possible to store the generated bytecode on the file system or a different
+location to avoid parsing the templates on first use.
+
+This is especially useful if you have a web application that is initialized on
+the first request and Jinja compiles many templates at once which slows down
+the application.
+
+To use a bytecode cache, instanciate it and pass it to the :class:`Environment`.
+
+.. autoclass:: jinja2.BytecodeCache
+ :members: load_bytecode, dump_bytecode, clear
+
+.. autoclass:: jinja2.bccache.Bucket
+ :members: write_bytecode, load_bytecode, bytecode_from_string,
+ bytecode_to_string, reset
+
+ .. attribute:: environment
+
+ The :class:`Environment` that created the bucket.
+
+ .. attribute:: key
+
+ The unique cache key for this bucket
+
+ .. attribute:: code
+
+ The bytecode if it's loaded, otherwise `None`.
+
+
+Builtin bytecode caches:
+
+.. autoclass:: jinja2.FileSystemBytecodeCache
+
+.. autoclass:: jinja2.MemcachedBytecodeCache
+
+
+Utilities
+---------
+
+These helper functions and classes are useful if you add custom filters or
+functions to a Jinja2 environment.
+
+.. autofunction:: jinja2.environmentfilter
+
+.. autofunction:: jinja2.contextfilter
+
+.. autofunction:: jinja2.evalcontextfilter
+
+.. autofunction:: jinja2.environmentfunction
+
+.. autofunction:: jinja2.contextfunction
+
+.. autofunction:: jinja2.evalcontextfunction
+
+.. function:: escape(s)
+
+ Convert the characters ``&``, ``<``, ``>``, ``'``, and ``"`` in string `s`
+ to HTML-safe sequences. Use this if you need to display text that might
+ contain such characters in HTML. This function will not escaped objects
+ that do have an HTML representation such as already escaped data.
+
+ The return value is a :class:`Markup` string.
+
+.. autofunction:: jinja2.clear_caches
+
+.. autofunction:: jinja2.is_undefined
+
+.. autoclass:: jinja2.Markup([string])
+ :members: escape, unescape, striptags
+
+.. admonition:: Note
+
+ The Jinja2 :class:`Markup` class is compatible with at least Pylons and
+ Genshi. It's expected that more template engines and framework will pick
+ up the `__html__` concept soon.
+
+
+Exceptions
+----------
+
+.. autoexception:: jinja2.TemplateError
+
+.. autoexception:: jinja2.UndefinedError
+
+.. autoexception:: jinja2.TemplateNotFound
+
+.. autoexception:: jinja2.TemplatesNotFound
+
+.. autoexception:: jinja2.TemplateSyntaxError
+
+ .. attribute:: message
+
+ The error message as utf-8 bytestring.
+
+ .. attribute:: lineno
+
+ The line number where the error occurred
+
+ .. attribute:: name
+
+ The load name for the template as unicode string.
+
+ .. attribute:: filename
+
+ The filename that loaded the template as bytestring in the encoding
+ of the file system (most likely utf-8 or mbcs on Windows systems).
+
+ The reason why the filename and error message are bytestrings and not
+ unicode strings is that Python 2.x is not using unicode for exceptions
+ and tracebacks as well as the compiler. This will change with Python 3.
+
+.. autoexception:: jinja2.TemplateAssertionError
+
+
+.. _writing-filters:
+
+Custom Filters
+--------------
+
+Custom filters are just regular Python functions that take the left side of
+the filter as first argument and the the arguments passed to the filter as
+extra arguments or keyword arguments.
+
+For example in the filter ``{{ 42|myfilter(23) }}`` the function would be
+called with ``myfilter(42, 23)``. Here for example a simple filter that can
+be applied to datetime objects to format them::
+
+ def datetimeformat(value, format='%H:%M / %d-%m-%Y'):
+ return value.strftime(format)
+
+You can register it on the template environment by updating the
+:attr:`~Environment.filters` dict on the environment::
+
+ environment.filters['datetimeformat'] = datetimeformat
+
+Inside the template it can then be used as follows:
+
+.. sourcecode:: jinja
+
+ written on: {{ article.pub_date|datetimeformat }}
+ publication date: {{ article.pub_date|datetimeformat('%d-%m-%Y') }}
+
+Filters can also be passed the current template context or environment. This
+is useful if a filter wants to return an undefined value or check the current
+:attr:`~Environment.autoescape` setting. For this purpose three decorators
+exist: :func:`environmentfilter`, :func:`contextfilter` and
+:func:`evalcontextfilter`.
+
+Here a small example filter that breaks a text into HTML line breaks and
+paragraphs and marks the return value as safe HTML string if autoescaping is
+enabled::
+
+ import re
+ from jinja2 import environmentfilter, Markup, escape
+
+ _paragraph_re = re.compile(r'(?:\r\n|\r|\n){2,}')
+
+ @evalcontextfilter
+ def nl2br(eval_ctx, value):
+ result = u'\n\n'.join(u'<p>%s</p>' % p.replace('\n', '<br>\n')
+ for p in _paragraph_re.split(escape(value)))
+ if eval_ctx.autoescape:
+ result = Markup(result)
+ return result
+
+Context filters work the same just that the first argument is the current
+active :class:`Context` rather then the environment.
+
+
+.. _eval-context:
+
+Evaluation Context
+------------------
+
+The evaluation context (short eval context or eval ctx) is a new object
+introducted in Jinja 2.4 that makes it possible to activate and deactivate
+compiled features at runtime.
+
+Currently it is only used to enable and disable the automatic escaping but
+can be used for extensions as well.
+
+In previous Jinja versions filters and functions were marked as
+environment callables in order to check for the autoescape status from the
+environment. In new versions it's encouraged to check the setting from the
+evaluation context instead.
+
+Previous versions::
+
+ @environmentfilter
+ def filter(env, value):
+ result = do_something(value)
+ if env.autoescape:
+ result = Markup(result)
+ return result
+
+In new versions you can either use a :func:`contextfilter` and access the
+evaluation context from the actual context, or use a
+:func:`evalcontextfilter` which directly passes the evaluation context to
+the function::
+
+ @contextfilter
+ def filter(context, value):
+ result = do_something(value)
+ if context.eval_ctx.autoescape:
+ result = Markup(result)
+ return result
+
+ @evalcontextfilter
+ def filter(eval_ctx, value):
+ result = do_something(value)
+ if eval_ctx.autoescape:
+ result = Markup(result)
+ return result
+
+The evaluation context must not be modified at runtime. Modifications
+must only happen with a :class:`nodes.EvalContextModifier` and
+:class:`nodes.ScopedEvalContextModifier` from an extension, not on the
+eval context object itself.
+
+.. autoclass:: jinja2.nodes.EvalContext
+
+ .. attribute:: autoescape
+
+ `True` or `False` depending on if autoescaping is active or not.
+
+ .. attribute:: volatile
+
+ `True` if the compiler cannot evaluate some expressions at compile
+ time. At runtime this should always be `False`.
+
+
+.. _writing-tests:
+
+Custom Tests
+------------
+
+Tests work like filters just that there is no way for a test to get access
+to the environment or context and that they can't be chained. The return
+value of a test should be `True` or `False`. The purpose of a test is to
+give the template designers the possibility to perform type and conformability
+checks.
+
+Here a simple test that checks if a variable is a prime number::
+
+ import math
+
+ def is_prime(n):
+ if n == 2:
+ return True
+ for i in xrange(2, int(math.ceil(math.sqrt(n))) + 1):
+ if n % i == 0:
+ return False
+ return True
+
+
+You can register it on the template environment by updating the
+:attr:`~Environment.tests` dict on the environment::
+
+ environment.tests['prime'] = is_prime
+
+A template designer can then use the test like this:
+
+.. sourcecode:: jinja
+
+ {% if 42 is prime %}
+ 42 is a prime number
+ {% else %}
+ 42 is not a prime number
+ {% endif %}
+
+
+.. _global-namespace:
+
+The Global Namespace
+--------------------
+
+Variables stored in the :attr:`Environment.globals` dict are special as they
+are available for imported templates too, even if they are imported without
+context. This is the place where you can put variables and functions
+that should be available all the time. Additionally :attr:`Template.globals`
+exist that are variables available to a specific template that are available
+to all :meth:`~Template.render` calls.
+
+
+.. _low-level-api:
+
+Low Level API
+-------------
+
+The low level API exposes functionality that can be useful to understand some
+implementation details, debugging purposes or advanced :ref:`extension
+<jinja-extensions>` techniques. Unless you know exactly what you are doing we
+don't recommend using any of those.
+
+.. automethod:: Environment.lex
+
+.. automethod:: Environment.parse
+
+.. automethod:: Environment.preprocess
+
+.. automethod:: Template.new_context
+
+.. method:: Template.root_render_func(context)
+
+ This is the low level render function. It's passed a :class:`Context`
+ that has to be created by :meth:`new_context` of the same template or
+ a compatible template. This render function is generated by the
+ compiler from the template code and returns a generator that yields
+ unicode strings.
+
+ If an exception in the template code happens the template engine will
+ not rewrite the exception but pass through the original one. As a
+ matter of fact this function should only be called from within a
+ :meth:`render` / :meth:`generate` / :meth:`stream` call.
+
+.. attribute:: Template.blocks
+
+ A dict of block render functions. Each of these functions works exactly
+ like the :meth:`root_render_func` with the same limitations.
+
+.. attribute:: Template.is_up_to_date
+
+ This attribute is `False` if there is a newer version of the template
+ available, otherwise `True`.
+
+.. admonition:: Note
+
+ The low-level API is fragile. Future Jinja2 versions will try not to
+ change it in a backwards incompatible way but modifications in the Jinja2
+ core may shine through. For example if Jinja2 introduces a new AST node
+ in later versions that may be returned by :meth:`~Environment.parse`.
+
+The Meta API
+------------
+
+.. versionadded:: 2.2
+
+The meta API returns some information about abstract syntax trees that
+could help applications to implement more advanced template concepts. All
+the functions of the meta API operate on an abstract syntax tree as
+returned by the :meth:`Environment.parse` method.
+
+.. autofunction:: jinja2.meta.find_undeclared_variables
+
+.. autofunction:: jinja2.meta.find_referenced_templates
http://git-wip-us.apache.org/repos/asf/ambari/blob/570de228/ambari-common/src/main/python/jinja2/docs/cache_extension.py
----------------------------------------------------------------------
diff --git a/ambari-common/src/main/python/jinja2/docs/cache_extension.py b/ambari-common/src/main/python/jinja2/docs/cache_extension.py
new file mode 100644
index 0000000..8fdefb5
--- /dev/null
+++ b/ambari-common/src/main/python/jinja2/docs/cache_extension.py
@@ -0,0 +1,56 @@
+from jinja2 import nodes
+from jinja2.ext import Extension
+
+
+class FragmentCacheExtension(Extension):
+ # a set of names that trigger the extension.
+ tags = set(['cache'])
+
+ def __init__(self, environment):
+ super(FragmentCacheExtension, self).__init__(environment)
+
+ # add the defaults to the environment
+ environment.extend(
+ fragment_cache_prefix='',
+ fragment_cache=None
+ )
+
+ def parse(self, parser):
+ # the first token is the token that started the tag. In our case
+ # we only listen to ``'cache'`` so this will be a name token with
+ # `cache` as value. We get the line number so that we can give
+ # that line number to the nodes we create by hand.
+ lineno = parser.stream.next().lineno
+
+ # now we parse a single expression that is used as cache key.
+ args = [parser.parse_expression()]
+
+ # if there is a comma, the user provided a timeout. If not use
+ # None as second parameter.
+ if parser.stream.skip_if('comma'):
+ args.append(parser.parse_expression())
+ else:
+ args.append(nodes.Const(None))
+
+ # now we parse the body of the cache block up to `endcache` and
+ # drop the needle (which would always be `endcache` in that case)
+ body = parser.parse_statements(['name:endcache'], drop_needle=True)
+
+ # now return a `CallBlock` node that calls our _cache_support
+ # helper method on this extension.
+ return nodes.CallBlock(self.call_method('_cache_support', args),
+ [], [], body).set_lineno(lineno)
+
+ def _cache_support(self, name, timeout, caller):
+ """Helper callback."""
+ key = self.environment.fragment_cache_prefix + name
+
+ # try to load the block from the cache
+ # if there is no fragment in the cache, render it and store
+ # it in the cache.
+ rv = self.environment.fragment_cache.get(key)
+ if rv is not None:
+ return rv
+ rv = caller()
+ self.environment.fragment_cache.add(key, rv, timeout)
+ return rv
http://git-wip-us.apache.org/repos/asf/ambari/blob/570de228/ambari-common/src/main/python/jinja2/docs/changelog.rst
----------------------------------------------------------------------
diff --git a/ambari-common/src/main/python/jinja2/docs/changelog.rst b/ambari-common/src/main/python/jinja2/docs/changelog.rst
new file mode 100644
index 0000000..9f11484
--- /dev/null
+++ b/ambari-common/src/main/python/jinja2/docs/changelog.rst
@@ -0,0 +1,3 @@
+.. module:: jinja2
+
+.. include:: ../CHANGES
http://git-wip-us.apache.org/repos/asf/ambari/blob/570de228/ambari-common/src/main/python/jinja2/docs/conf.py
----------------------------------------------------------------------
diff --git a/ambari-common/src/main/python/jinja2/docs/conf.py b/ambari-common/src/main/python/jinja2/docs/conf.py
new file mode 100644
index 0000000..ba90c49
--- /dev/null
+++ b/ambari-common/src/main/python/jinja2/docs/conf.py
@@ -0,0 +1,141 @@
+# -*- coding: utf-8 -*-
+#
+# Jinja2 documentation build configuration file, created by
+# sphinx-quickstart on Sun Apr 27 21:42:41 2008.
+#
+# This file is execfile()d with the current directory set to its containing dir.
+#
+# The contents of this file are pickled, so don't put values in the namespace
+# that aren't pickleable (module imports are okay, they're removed automatically).
+#
+# All configuration values have a default value; values that are commented out
+# serve to show the default value.
+
+import sys, os
+
+# If your extensions are in another directory, add it here. If the directory
+# is relative to the documentation root, use os.path.abspath to make it
+# absolute, like shown here.
+sys.path.append(os.path.dirname(os.path.abspath(__file__)))
+
+# General configuration
+# ---------------------
+
+# Add any Sphinx extension module names here, as strings. They can be extensions
+# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
+extensions = ['sphinx.ext.autodoc', 'jinjaext']
+
+# Add any paths that contain templates here, relative to this directory.
+templates_path = ['_templates']
+
+# The suffix of source filenames.
+source_suffix = '.rst'
+
+# The master toctree document.
+master_doc = 'index'
+
+# General substitutions.
+project = 'Jinja2'
+copyright = '2008, Armin Ronacher'
+
+# The default replacements for |version| and |release|, also used in various
+# other places throughout the built documents.
+#
+# The short X.Y version.
+version = '2.0'
+# The full version, including alpha/beta/rc tags.
+release = '2.0'
+
+# There are two options for replacing |today|: either, you set today to some
+# non-false value, then it is used:
+#today = ''
+# Else, today_fmt is used as the format for a strftime call.
+today_fmt = '%B %d, %Y'
+
+# List of documents that shouldn't be included in the build.
+#unused_docs = []
+
+# If true, '()' will be appended to :func: etc. cross-reference text.
+#add_function_parentheses = True
+
+# If true, the current module name will be prepended to all description
+# unit titles (such as .. function::).
+#add_module_names = True
+
+# If true, sectionauthor and moduleauthor directives will be shown in the
+# output. They are ignored by default.
+#show_authors = False
+
+# The name of the Pygments (syntax highlighting) style to use.
+pygments_style = 'jinjaext.JinjaStyle'
+
+
+# Options for HTML output
+# -----------------------
+
+# The style sheet to use for HTML and HTML Help pages. A file of that name
+# must exist either in Sphinx' static/ path, or in one of the custom paths
+# given in html_static_path.
+html_style = 'style.css'
+
+# The name for this set of Sphinx documents. If None, it defaults to
+# "<project> v<release> documentation".
+#html_title = None
+
+# Add any paths that contain custom static files (such as style sheets) here,
+# relative to this directory. They are copied after the builtin static files,
+# so a file named "default.css" will overwrite the builtin "default.css".
+html_static_path = ['_static']
+
+# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
+# using the given strftime format.
+html_last_updated_fmt = '%b %d, %Y'
+
+# If true, SmartyPants will be used to convert quotes and dashes to
+# typographically correct entities.
+#html_use_smartypants = True
+
+# no modindex
+html_use_modindex = False
+
+# If true, the reST sources are included in the HTML build as _sources/<name>.
+#html_copy_source = True
+
+# If true, an OpenSearch description file will be output, and all pages will
+# contain a <link> tag referring to it.
+#html_use_opensearch = False
+
+# Output file base name for HTML help builder.
+htmlhelp_basename = 'Jinja2doc'
+
+
+# Options for LaTeX output
+# ------------------------
+
+# The paper size ('letter' or 'a4').
+latex_paper_size = 'a4'
+
+# The font size ('10pt', '11pt' or '12pt').
+#latex_font_size = '10pt'
+
+# Grouping the document tree into LaTeX files. List of tuples
+# (source start file, target name, title, author, document class [howto/manual]).
+latex_documents = [
+ ('index', 'Jinja2.tex', 'Jinja2 Documentation', 'Armin Ronacher', 'manual', 'toctree_only'),
+]
+
+# Additional stuff for the LaTeX preamble.
+latex_preamble = '''
+\usepackage{palatino}
+\definecolor{TitleColor}{rgb}{0.7,0,0}
+\definecolor{InnerLinkColor}{rgb}{0.7,0,0}
+\definecolor{OuterLinkColor}{rgb}{0.8,0,0}
+\definecolor{VerbatimColor}{rgb}{0.985,0.985,0.985}
+\definecolor{VerbatimBorderColor}{rgb}{0.8,0.8,0.8}
+'''
+
+# Documents to append as an appendix to all manuals.
+#latex_appendices = []
+
+# If false, no module index is generated.
+latex_use_modindex = False
http://git-wip-us.apache.org/repos/asf/ambari/blob/570de228/ambari-common/src/main/python/jinja2/docs/extensions.rst
----------------------------------------------------------------------
diff --git a/ambari-common/src/main/python/jinja2/docs/extensions.rst b/ambari-common/src/main/python/jinja2/docs/extensions.rst
new file mode 100644
index 0000000..c6b6ec9
--- /dev/null
+++ b/ambari-common/src/main/python/jinja2/docs/extensions.rst
@@ -0,0 +1,347 @@
+.. _jinja-extensions:
+
+Extensions
+==========
+
+Jinja2 supports extensions that can add extra filters, tests, globals or even
+extend the parser. The main motivation of extensions is it to move often used
+code into a reusable class like adding support for internationalization.
+
+
+Adding Extensions
+-----------------
+
+Extensions are added to the Jinja2 environment at creation time. Once the
+environment is created additional extensions cannot be added. To add an
+extension pass a list of extension classes or import paths to the
+`environment` parameter of the :class:`Environment` constructor. The following
+example creates a Jinja2 environment with the i18n extension loaded::
+
+ jinja_env = Environment(extensions=['jinja2.ext.i18n'])
+
+
+.. _i18n-extension:
+
+i18n Extension
+--------------
+
+**Import name:** `jinja2.ext.i18n`
+
+Jinja2 currently comes with one extension, the i18n extension. It can be
+used in combination with `gettext`_ or `babel`_. If the i18n extension is
+enabled Jinja2 provides a `trans` statement that marks the wrapped string as
+translatable and calls `gettext`.
+
+After enabling dummy `_` function that forwards calls to `gettext` is added
+to the environment globals. An internationalized application then has to
+provide at least an `gettext` and optoinally a `ngettext` function into the
+namespace. Either globally or for each rendering.
+
+Environment Methods
+~~~~~~~~~~~~~~~~~~~
+
+After enabling of the extension the environment provides the following
+additional methods:
+
+.. method:: jinja2.Environment.install_gettext_translations(translations, newstyle=False)
+
+ Installs a translation globally for that environment. The tranlations
+ object provided must implement at least `ugettext` and `ungettext`.
+ The `gettext.NullTranslations` and `gettext.GNUTranslations` classes
+ as well as `Babel`_\s `Translations` class are supported.
+
+ .. versionchanged:: 2.5 newstyle gettext added
+
+.. method:: jinja2.Environment.install_null_translations(newstyle=False)
+
+ Install dummy gettext functions. This is useful if you want to prepare
+ the application for internationalization but don't want to implement the
+ full internationalization system yet.
+
+ .. versionchanged:: 2.5 newstyle gettext added
+
+.. method:: jinja2.Environment.install_gettext_callables(gettext, ngettext, newstyle=False)
+
+ Installs the given `gettext` and `ngettext` callables into the
+ environment as globals. They are supposed to behave exactly like the
+ standard library's :func:`gettext.ugettext` and
+ :func:`gettext.ungettext` functions.
+
+ If `newstyle` is activated, the callables are wrapped to work like
+ newstyle callables. See :ref:`newstyle-gettext` for more information.
+
+ .. versionadded:: 2.5
+
+.. method:: jinja2.Environment.uninstall_gettext_translations()
+
+ Uninstall the translations again.
+
+.. method:: jinja2.Environment.extract_translations(source)
+
+ Extract localizable strings from the given template node or source.
+
+ For every string found this function yields a ``(lineno, function,
+ message)`` tuple, where:
+
+ * `lineno` is the number of the line on which the string was found,
+ * `function` is the name of the `gettext` function used (if the
+ string was extracted from embedded Python code), and
+ * `message` is the string itself (a `unicode` object, or a tuple
+ of `unicode` objects for functions with multiple string arguments).
+
+ If `Babel`_ is installed :ref:`the babel integration <babel-integration>`
+ can be used to extract strings for babel.
+
+For a web application that is available in multiple languages but gives all
+the users the same language (for example a multilingual forum software
+installed for a French community) may load the translations once and add the
+translation methods to the environment at environment generation time::
+
+ translations = get_gettext_translations()
+ env = Environment(extensions=['jinja2.ext.i18n'])
+ env.install_gettext_translations(translations)
+
+The `get_gettext_translations` function would return the translator for the
+current configuration. (For example by using `gettext.find`)
+
+The usage of the `i18n` extension for template designers is covered as part
+:ref:`of the template documentation <i18n-in-templates>`.
+
+.. _gettext: http://docs.python.org/dev/library/gettext
+.. _Babel: http://babel.edgewall.org/
+
+.. _newstyle-gettext:
+
+Newstyle Gettext
+~~~~~~~~~~~~~~~~
+
+.. versionadded:: 2.5
+
+Starting with version 2.5 you can use newstyle gettext calls. These are
+inspired by trac's internal gettext functions and are fully supported by
+the babel extraction tool. They might not work as expected by other
+extraction tools in case you are not using Babel's.
+
+What's the big difference between standard and newstyle gettext calls? In
+general they are less to type and less error prone. Also if they are used
+in an autoescaping environment they better support automatic escaping.
+Here some common differences between old and new calls:
+
+standard gettext:
+
+.. sourcecode:: html+jinja
+
+ {{ gettext('Hello World!') }}
+ {{ gettext('Hello %(name)s!')|format(name='World') }}
+ {{ ngettext('%(num)d apple', '%(num)d apples', apples|count)|format(
+ num=apples|count
+ )}}
+
+newstyle gettext looks like this instead:
+
+.. sourcecode:: html+jinja
+
+ {{ gettext('Hello World!') }}
+ {{ gettext('Hello %(name)s!', name='World') }}
+ {{ ngettext('%(num)d apple', '%(num)d apples', apples|count) }}
+
+The advantages of newstyle gettext is that you have less to type and that
+named placeholders become mandatory. The latter sounds like a
+disadvantage but solves a lot of troubles translators are often facing
+when they are unable to switch the positions of two placeholder. With
+newstyle gettext, all format strings look the same.
+
+Furthermore with newstyle gettext, string formatting is also used if no
+placeholders are used which makes all strings behave exactly the same.
+Last but not least are newstyle gettext calls able to properly mark
+strings for autoescaping which solves lots of escaping related issues many
+templates are experiencing over time when using autoescaping.
+
+Expression Statement
+--------------------
+
+**Import name:** `jinja2.ext.do`
+
+The "do" aka expression-statement extension adds a simple `do` tag to the
+template engine that works like a variable expression but ignores the
+return value.
+
+.. _loopcontrols-extension:
+
+Loop Controls
+-------------
+
+**Import name:** `jinja2.ext.loopcontrols`
+
+This extension adds support for `break` and `continue` in loops. After
+enabling Jinja2 provides those two keywords which work exactly like in
+Python.
+
+.. _with-extension:
+
+With Statement
+--------------
+
+**Import name:** `jinja2.ext.with_`
+
+.. versionadded:: 2.3
+
+This extension adds support for the with keyword. Using this keyword it
+is possible to enforce a nested scope in a template. Variables can be
+declared directly in the opening block of the with statement or using a
+standard `set` statement directly within.
+
+.. _autoescape-extension:
+
+Autoescape Extension
+--------------------
+
+**Import name:** `jinja2.ext.autoescape`
+
+.. versionadded:: 2.4
+
+The autoescape extension allows you to toggle the autoescape feature from
+within the template. If the environment's :attr:`~Environment.autoescape`
+setting is set to `False` it can be activated, if it's `True` it can be
+deactivated. The setting overriding is scoped.
+
+
+.. _writing-extensions:
+
+Writing Extensions
+------------------
+
+.. module:: jinja2.ext
+
+By writing extensions you can add custom tags to Jinja2. This is a non trival
+task and usually not needed as the default tags and expressions cover all
+common use cases. The i18n extension is a good example of why extensions are
+useful, another one would be fragment caching.
+
+When writing extensions you have to keep in mind that you are working with the
+Jinja2 template compiler which does not validate the node tree you are possing
+to it. If the AST is malformed you will get all kinds of compiler or runtime
+errors that are horrible to debug. Always make sure you are using the nodes
+you create correctly. The API documentation below shows which nodes exist and
+how to use them.
+
+Example Extension
+~~~~~~~~~~~~~~~~~
+
+The following example implements a `cache` tag for Jinja2 by using the
+`Werkzeug`_ caching contrib module:
+
+.. literalinclude:: cache_extension.py
+ :language: python
+
+And here is how you use it in an environment::
+
+ from jinja2 import Environment
+ from werkzeug.contrib.cache import SimpleCache
+
+ env = Environment(extensions=[FragmentCacheExtension])
+ env.fragment_cache = SimpleCache()
+
+Inside the template it's then possible to mark blocks as cacheable. The
+following example caches a sidebar for 300 seconds:
+
+.. sourcecode:: html+jinja
+
+ {% cache 'sidebar', 300 %}
+ <div class="sidebar">
+ ...
+ </div>
+ {% endcache %}
+
+.. _Werkzeug: http://werkzeug.pocoo.org/
+
+Extension API
+~~~~~~~~~~~~~
+
+Extensions always have to extend the :class:`jinja2.ext.Extension` class:
+
+.. autoclass:: Extension
+ :members: preprocess, filter_stream, parse, attr, call_method
+
+ .. attribute:: identifier
+
+ The identifier of the extension. This is always the true import name
+ of the extension class and must not be changed.
+
+ .. attribute:: tags
+
+ If the extension implements custom tags this is a set of tag names
+ the extension is listening for.
+
+Parser API
+~~~~~~~~~~
+
+The parser passed to :meth:`Extension.parse` provides ways to parse
+expressions of different types. The following methods may be used by
+extensions:
+
+.. autoclass:: jinja2.parser.Parser
+ :members: parse_expression, parse_tuple, parse_assign_target,
+ parse_statements, free_identifier, fail
+
+ .. attribute:: filename
+
+ The filename of the template the parser processes. This is **not**
+ the load name of the template. For the load name see :attr:`name`.
+ For templates that were not loaded form the file system this is
+ `None`.
+
+ .. attribute:: name
+
+ The load name of the template.
+
+ .. attribute:: stream
+
+ The current :class:`~jinja2.lexer.TokenStream`
+
+.. autoclass:: jinja2.lexer.TokenStream
+ :members: push, look, eos, skip, next, next_if, skip_if, expect
+
+ .. attribute:: current
+
+ The current :class:`~jinja2.lexer.Token`.
+
+.. autoclass:: jinja2.lexer.Token
+ :members: test, test_any
+
+ .. attribute:: lineno
+
+ The line number of the token
+
+ .. attribute:: type
+
+ The type of the token. This string is interned so you may compare
+ it with arbitrary strings using the `is` operator.
+
+ .. attribute:: value
+
+ The value of the token.
+
+There is also a utility function in the lexer module that can count newline
+characters in strings:
+
+.. autofunction:: jinja2.lexer.count_newlines
+
+AST
+~~~
+
+The AST (Abstract Syntax Tree) is used to represent a template after parsing.
+It's build of nodes that the compiler then converts into executable Python
+code objects. Extensions that provide custom statements can return nodes to
+execute custom Python code.
+
+The list below describes all nodes that are currently available. The AST may
+change between Jinja2 versions but will stay backwards compatible.
+
+For more information have a look at the repr of :meth:`jinja2.Environment.parse`.
+
+.. module:: jinja2.nodes
+
+.. jinjanodes::
+
+.. autoexception:: Impossible
http://git-wip-us.apache.org/repos/asf/ambari/blob/570de228/ambari-common/src/main/python/jinja2/docs/faq.rst
----------------------------------------------------------------------
diff --git a/ambari-common/src/main/python/jinja2/docs/faq.rst b/ambari-common/src/main/python/jinja2/docs/faq.rst
new file mode 100644
index 0000000..89186b1
--- /dev/null
+++ b/ambari-common/src/main/python/jinja2/docs/faq.rst
@@ -0,0 +1,191 @@
+Frequently Asked Questions
+==========================
+
+This page answers some of the often asked questions about Jinja.
+
+.. highlight:: html+jinja
+
+Why is it called Jinja?
+-----------------------
+
+The name Jinja was chosen because it's the name of a Japanese temple and
+temple and template share a similar pronunciation. It is not named after
+the capital city of Uganda.
+
+How fast is it?
+---------------
+
+We really hate benchmarks especially since they don't reflect much. The
+performance of a template depends on many factors and you would have to
+benchmark different engines in different situations. The benchmarks from the
+testsuite show that Jinja2 has a similar performance to `Mako`_ and is between
+10 and 20 times faster than Django's template engine or Genshi. These numbers
+should be taken with tons of salt as the benchmarks that took these numbers
+only test a few performance related situations such as looping. Generally
+speaking the performance of a template engine doesn't matter much as the
+usual bottleneck in a web application is either the database or the application
+code.
+
+.. _Mako: http://www.makotemplates.org/
+
+How Compatible is Jinja2 with Django?
+-------------------------------------
+
+The default syntax of Jinja2 matches Django syntax in many ways. However
+this similarity doesn't mean that you can use a Django template unmodified
+in Jinja2. For example filter arguments use a function call syntax rather
+than a colon to separate filter name and arguments. Additionally the
+extension interface in Jinja is fundamentally different from the Django one
+which means that your custom tags won't work any longer.
+
+Generally speaking you will use much less custom extensions as the Jinja
+template system allows you to use a certain subset of Python expressions
+which can replace most Django extensions. For example instead of using
+something like this::
+
+ {% load comments %}
+ {% get_latest_comments 10 as latest_comments %}
+ {% for comment in latest_comments %}
+ ...
+ {% endfor %}
+
+You will most likely provide an object with attributes to retrieve
+comments from the database::
+
+ {% for comment in models.comments.latest(10) %}
+ ...
+ {% endfor %}
+
+Or directly provide the model for quick testing::
+
+ {% for comment in Comment.objects.order_by('-pub_date')[:10] %}
+ ...
+ {% endfor %}
+
+Please keep in mind that even though you may put such things into templates
+it still isn't a good idea. Queries should go into the view code and not
+the template!
+
+Isn't it a terrible idea to put Logic into Templates?
+-----------------------------------------------------
+
+Without a doubt you should try to remove as much logic from templates as
+possible. But templates without any logic mean that you have to do all
+the processing in the code which is boring and stupid. A template engine
+that does that is shipped with Python and called `string.Template`. Comes
+without loops and if conditions and is by far the fastest template engine
+you can get for Python.
+
+So some amount of logic is required in templates to keep everyone happy.
+And Jinja leaves it pretty much to you how much logic you want to put into
+templates. There are some restrictions in what you can do and what not.
+
+Jinja2 neither allows you to put arbitrary Python code into templates nor
+does it allow all Python expressions. The operators are limited to the
+most common ones and more advanced expressions such as list comprehensions
+and generator expressions are not supported. This keeps the template engine
+easier to maintain and templates more readable.
+
+Why is Autoescaping not the Default?
+------------------------------------
+
+There are multiple reasons why automatic escaping is not the default mode
+and also not the recommended one. While automatic escaping of variables
+means that you will less likely have an XSS problem it also causes a huge
+amount of extra processing in the template engine which can cause serious
+performance problems. As Python doesn't provide a way to mark strings as
+unsafe Jinja has to hack around that limitation by providing a custom
+string class (the :class:`Markup` string) that safely interacts with safe
+and unsafe strings.
+
+With explicit escaping however the template engine doesn't have to perform
+any safety checks on variables. Also a human knows not to escape integers
+or strings that may never contain characters one has to escape or already
+HTML markup. For example when iterating over a list over a table of
+integers and floats for a table of statistics the template designer can
+omit the escaping because he knows that integers or floats don't contain
+any unsafe parameters.
+
+Additionally Jinja2 is a general purpose template engine and not only used
+for HTML/XML generation. For example you may generate LaTeX, emails,
+CSS, JavaScript, or configuration files.
+
+Why is the Context immutable?
+-----------------------------
+
+When writing a :func:`contextfunction` or something similar you may have
+noticed that the context tries to stop you from modifying it. If you have
+managed to modify the context by using an internal context API you may
+have noticed that changes in the context don't seem to be visible in the
+template. The reason for this is that Jinja uses the context only as
+primary data source for template variables for performance reasons.
+
+If you want to modify the context write a function that returns a variable
+instead that one can assign to a variable by using set::
+
+ {% set comments = get_latest_comments() %}
+
+What is the speedups module and why is it missing?
+--------------------------------------------------
+
+To achieve a good performance with automatic escaping enabled, the escaping
+function was also implemented in pure C in older Jinja2 releases and used if
+Jinja2 was installed with the speedups module.
+
+Because this feature itself is very useful for non-template engines as
+well it was moved into a separate project on PyPI called `MarkupSafe`_.
+
+Jinja2 no longer ships with a C implementation of it but only the pure
+Python implementation. It will however check if MarkupSafe is available
+and installed, and if it is, use the Markup class from MarkupSafe.
+
+So if you want the speedups, just import MarkupSafe.
+
+.. _MarkupSafe: http://pypi.python.org/pypi/MarkupSafe
+
+My tracebacks look weird. What's happening?
+--------------------------------------------
+
+If the debugsupport module is not compiled and you are using a Python
+installation without ctypes (Python 2.4 without ctypes, Jython or Google's
+AppEngine) Jinja2 is unable to provide correct debugging information and
+the traceback may be incomplete. There is currently no good workaround
+for Jython or the AppEngine as ctypes is unavailable there and it's not
+possible to use the debugsupport extension.
+
+Why is there no Python 2.3 support?
+-----------------------------------
+
+Python 2.3 is missing a lot of features that are used heavily in Jinja2. This
+decision was made as with the upcoming Python 2.6 and 3.0 versions it becomes
+harder to maintain the code for older Python versions. If you really need
+Python 2.3 support you either have to use `Jinja 1`_ or other templating
+engines that still support 2.3.
+
+My Macros are overriden by something
+------------------------------------
+
+In some situations the Jinja scoping appears arbitrary:
+
+layout.tmpl:
+
+.. sourcecode:: jinja
+
+ {% macro foo() %}LAYOUT{% endmacro %}
+ {% block body %}{% endblock %}
+
+child.tmpl:
+
+.. sourcecode:: jinja
+
+ {% extends 'layout.tmpl' %}
+ {% macro foo() %}CHILD{% endmacro %}
+ {% block body %}{{ foo() }}{% endblock %}
+
+This will print ``LAYOUT`` in Jinja2. This is a side effect of having
+the parent template evaluated after the child one. This allows child
+templates passing information to the parent template. To avoid this
+issue rename the macro or variable in the parent template to have an
+uncommon prefix.
+
+.. _Jinja 1: http://jinja.pocoo.org/1/
http://git-wip-us.apache.org/repos/asf/ambari/blob/570de228/ambari-common/src/main/python/jinja2/docs/index.rst
----------------------------------------------------------------------
diff --git a/ambari-common/src/main/python/jinja2/docs/index.rst b/ambari-common/src/main/python/jinja2/docs/index.rst
new file mode 100644
index 0000000..27bee23
--- /dev/null
+++ b/ambari-common/src/main/python/jinja2/docs/index.rst
@@ -0,0 +1,27 @@
+Jinja2 Documentation
+====================
+
+This is the documentation for the Jinja2 general purpose templating language.
+Jinja2 is a library for Python 2.4 and onwards that is designed to be flexible,
+fast and secure.
+
+.. toctree::
+ :maxdepth: 2
+
+ intro
+ api
+ sandbox
+ templates
+ extensions
+ integration
+ switching
+ tricks
+
+ faq
+ changelog
+
+If you can't find the information you're looking for, have a look at the
+index of try to find it using the search function:
+
+* :ref:`genindex`
+* :ref:`search`
http://git-wip-us.apache.org/repos/asf/ambari/blob/570de228/ambari-common/src/main/python/jinja2/docs/integration.rst
----------------------------------------------------------------------
diff --git a/ambari-common/src/main/python/jinja2/docs/integration.rst b/ambari-common/src/main/python/jinja2/docs/integration.rst
new file mode 100644
index 0000000..1875711
--- /dev/null
+++ b/ambari-common/src/main/python/jinja2/docs/integration.rst
@@ -0,0 +1,88 @@
+Integration
+===========
+
+Jinja2 provides some code for integration into other tools such as frameworks,
+the `Babel`_ library or your favourite editor for fancy code highlighting.
+This is a brief description of whats included.
+
+.. _babel-integration:
+
+Babel Integration
+-----------------
+
+Jinja provides support for extracting gettext messages from templates via a
+`Babel`_ extractor entry point called `jinja2.ext.babel_extract`. The Babel
+support is implemented as part of the :ref:`i18n-extension` extension.
+
+Gettext messages extracted from both `trans` tags and code expressions.
+
+To extract gettext messages from templates, the project needs a Jinja2 section
+in its Babel extraction method `mapping file`_:
+
+.. sourcecode:: ini
+
+ [jinja2: **/templates/**.html]
+ encoding = utf-8
+
+The syntax related options of the :class:`Environment` are also available as
+configuration values in the mapping file. For example to tell the extraction
+that templates use ``%`` as `line_statement_prefix` you can use this code:
+
+.. sourcecode:: ini
+
+ [jinja2: **/templates/**.html]
+ encoding = utf-8
+ line_statement_prefix = %
+
+:ref:`jinja-extensions` may also be defined by passing a comma separated list
+of import paths as `extensions` value. The i18n extension is added
+automatically.
+
+.. _mapping file: http://babel.edgewall.org/wiki/Documentation/messages.html#extraction-method-mapping-and-configuration
+
+Pylons
+------
+
+With `Pylons`_ 0.9.7 onwards it's incredible easy to integrate Jinja into a
+Pylons powered application.
+
+The template engine is configured in `config/environment.py`. The configuration
+for Jinja2 looks something like that::
+
+ from jinja2 import Environment, PackageLoader
+ config['pylons.app_globals'].jinja_env = Environment(
+ loader=PackageLoader('yourapplication', 'templates')
+ )
+
+After that you can render Jinja templates by using the `render_jinja` function
+from the `pylons.templating` module.
+
+Additionally it's a good idea to set the Pylons' `c` object into strict mode.
+Per default any attribute to not existing attributes on the `c` object return
+an empty string and not an undefined object. To change this just use this
+snippet and add it into your `config/environment.py`::
+
+ config['pylons.strict_c'] = True
+
+.. _Pylons: http://www.pylonshq.com/
+
+TextMate
+--------
+
+Inside the `ext` folder of Jinja2 there is a bundle for TextMate that supports
+syntax highlighting for Jinja1 and Jinja2 for text based templates as well as
+HTML. It also contains a few often used snippets.
+
+Vim
+---
+
+A syntax plugin for `Vim`_ exists in the Vim-scripts directory as well as the
+ext folder of Jinja2. `The script <http://www.vim.org/scripts/script.php?script_id=1856>`_
+supports Jinja1 and Jinja2. Once installed two file types are available `jinja`
+and `htmljinja`. The first one for text based templates, the latter for HTML
+templates.
+
+Copy the files into your `syntax` folder.
+
+.. _Babel: http://babel.edgewall.org/
+.. _Vim: http://www.vim.org/
http://git-wip-us.apache.org/repos/asf/ambari/blob/570de228/ambari-common/src/main/python/jinja2/docs/intro.rst
----------------------------------------------------------------------
diff --git a/ambari-common/src/main/python/jinja2/docs/intro.rst b/ambari-common/src/main/python/jinja2/docs/intro.rst
new file mode 100644
index 0000000..0800615
--- /dev/null
+++ b/ambari-common/src/main/python/jinja2/docs/intro.rst
@@ -0,0 +1,168 @@
+Introduction
+============
+
+This is the documentation for the Jinja2 general purpose templating language.
+Jinja2 is a library for Python 2.4 and onwards that is designed to be flexible,
+fast and secure.
+
+If you have any exposure to other text-based template languages, such as Smarty or
+Django, you should feel right at home with Jinja2. It's both designer and
+developer friendly by sticking to Python's principles and adding functionality
+useful for templating environments.
+
+The key-features are...
+
+- ... **configurable syntax**. If you are generating LaTeX or other formats
+ with Jinja2 you can change the delimiters to something that integrates better
+ into the LaTeX markup.
+
+- ... **fast**. While performance is not the primarily target of Jinja2 it's
+ surprisingly fast. The overhead compared to regular Python code was reduced
+ to the very minimum.
+
+- ... **easy to debug**. Jinja2 integrates directly into the python traceback
+ system which allows you to debug Jinja2 templates with regular python
+ debugging helpers.
+
+- ... **secure**. It's possible to evaluate untrusted template code if the
+ optional sandbox is enabled. This allows Jinja2 to be used as templating
+ language for applications where users may modify the template design.
+
+
+Prerequisites
+-------------
+
+Jinja2 needs at least **Python 2.4** to run. Additionally a working C-compiler
+that can create python extensions should be installed for the debugger if you
+are using Python 2.4.
+
+If you don't have a working C-compiler and you are trying to install the source
+release with the debugsupport you will get a compiler error.
+
+.. _ctypes: http://python.net/crew/theller/ctypes/
+
+
+Installation
+------------
+
+You have multiple ways to install Jinja2. If you are unsure what to do, go
+with the Python egg or tarball.
+
+As a Python egg (via easy_install)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can install the most recent Jinja2 version using `easy_install`_ or `pip`_::
+
+ easy_install Jinja2
+ pip install Jinja2
+
+This will install a Jinja2 egg in your Python installation's site-packages
+directory.
+
+(If you are installing from the windows command line omit the `sudo` and make
+sure to run the command as user with administrator rights)
+
+From the tarball release
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+1. Download the most recent tarball from the `download page`_
+2. Unpack the tarball
+3. ``sudo python setup.py install``
+
+Note that you either have to have setuptools or `distribute`_ installed,
+the latter is preferred.
+
+This will install Jinja2 into your Python installation's site-packages directory.
+
+.. _distribute: http://pypi.python.org/pypi/distribute
+
+Installing the development version
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+1. Install `git`_
+2. ``git clone git://github.com/mitsuhiko/jinja2.git``
+3. ``cd jinja2``
+4. ``ln -s jinja2 /usr/lib/python2.X/site-packages``
+
+As an alternative to steps 4 you can also do ``python setup.py develop``
+which will install the package via distribute in development mode. This also
+has the advantage that the C extensions are compiled.
+
+.. _download page: http://pypi.python.org/pypi/Jinja2
+.. _setuptools: http://peak.telecommunity.com/DevCenter/setuptools
+.. _easy_install: http://peak.telecommunity.com/DevCenter/EasyInstall
+.. _pip: http://pypi.python.org/pypi/pip
+.. _git: http://git-scm.org/
+
+
+More Speed with MarkupSafe
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+As of version 2.5.1 Jinja2 will check for an installed `MarkupSafe`_
+module. If it can find it, it will use the Markup class of that module
+instead of the one that comes with Jinja2. `MarkupSafe` replaces the
+older speedups module that came with Jinja2 and has the advantage that is
+has a better setup script and will automatically attempt to install the C
+version and nicely fall back to a pure Python implementation if that is
+not possible.
+
+The C implementation of MarkupSafe is much faster and recommended when
+using Jinja2 with autoescaping.
+
+.. _MarkupSafe: http://pypi.python.org/pypi/MarkupSafe
+
+
+Enable the debug support Module
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+By default Jinja2 will not compile the debug support module. Enabling this
+will fail if you don't have the Python headers or a working compiler. This
+is often the case if you are installing Jinja2 from a windows machine.
+
+Because the debug support is only necessary for Python 2.4 you will not
+have to do this unless you run 2.4::
+
+ sudo python setup.py --with-debugsupport install
+
+
+Basic API Usage
+---------------
+
+This section gives you a brief introduction to the Python API for Jinja2
+templates.
+
+The most basic way to create a template and render it is through
+:class:`~jinja2.Template`. This however is not the recommended way to
+work with it if your templates are not loaded from strings but the file
+system or another data source:
+
+>>> from jinja2 import Template
+>>> template = Template('Hello {{ name }}!')
+>>> template.render(name='John Doe')
+u'Hello John Doe!'
+
+By creating an instance of :class:`~jinja2.Template` you get back a new template
+object that provides a method called :meth:`~jinja2.Template.render` which when
+called with a dict or keyword arguments expands the template. The dict
+or keywords arguments passed to the template are the so-called "context"
+of the template.
+
+What you can see here is that Jinja2 is using unicode internally and the
+return value is an unicode string. So make sure that your application is
+indeed using unicode internally.
+
+
+Experimental Python 3 Support
+-----------------------------
+
+Jinja 2.3 brings experimental support for Python 3. It means that all
+unittests pass on the new version, but there might still be small bugs in
+there and behavior might be inconsistent. If you notice any bugs, please
+provide feedback in the `Jinja bug tracker`_.
+
+Also please keep in mind that the documentation is written with Python 2
+in mind, you will have to adapt the shown code examples to Python 3 syntax
+for yourself.
+
+
+.. _Jinja bug tracker: http://github.com/mitsuhiko/jinja2/issues
http://git-wip-us.apache.org/repos/asf/ambari/blob/570de228/ambari-common/src/main/python/jinja2/docs/jinjaext.py
----------------------------------------------------------------------
diff --git a/ambari-common/src/main/python/jinja2/docs/jinjaext.py b/ambari-common/src/main/python/jinja2/docs/jinjaext.py
new file mode 100644
index 0000000..66f4ba1
--- /dev/null
+++ b/ambari-common/src/main/python/jinja2/docs/jinjaext.py
@@ -0,0 +1,192 @@
+# -*- coding: utf-8 -*-
+"""
+ Jinja Documentation Extensions
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ Support for automatically documenting filters and tests.
+
+ :copyright: Copyright 2008 by Armin Ronacher.
+ :license: BSD.
+"""
+import os
+import re
+import inspect
+import jinja2
+from itertools import islice
+from types import BuiltinFunctionType
+from docutils import nodes
+from docutils.statemachine import ViewList
+from sphinx.ext.autodoc import prepare_docstring
+from sphinx.application import TemplateBridge
+from pygments.style import Style
+from pygments.token import Keyword, Name, Comment, String, Error, \
+ Number, Operator, Generic
+from jinja2 import Environment, FileSystemLoader
+
+
+def parse_rst(state, content_offset, doc):
+ node = nodes.section()
+ # hack around title style bookkeeping
+ surrounding_title_styles = state.memo.title_styles
+ surrounding_section_level = state.memo.section_level
+ state.memo.title_styles = []
+ state.memo.section_level = 0
+ state.nested_parse(doc, content_offset, node, match_titles=1)
+ state.memo.title_styles = surrounding_title_styles
+ state.memo.section_level = surrounding_section_level
+ return node.children
+
+
+class JinjaStyle(Style):
+ title = 'Jinja Style'
+ default_style = ""
+ styles = {
+ Comment: 'italic #aaaaaa',
+ Comment.Preproc: 'noitalic #B11414',
+ Comment.Special: 'italic #505050',
+
+ Keyword: 'bold #B80000',
+ Keyword.Type: '#808080',
+
+ Operator.Word: 'bold #B80000',
+
+ Name.Builtin: '#333333',
+ Name.Function: '#333333',
+ Name.Class: 'bold #333333',
+ Name.Namespace: 'bold #333333',
+ Name.Entity: 'bold #363636',
+ Name.Attribute: '#686868',
+ Name.Tag: 'bold #686868',
+ Name.Decorator: '#686868',
+
+ String: '#AA891C',
+ Number: '#444444',
+
+ Generic.Heading: 'bold #000080',
+ Generic.Subheading: 'bold #800080',
+ Generic.Deleted: '#aa0000',
+ Generic.Inserted: '#00aa00',
+ Generic.Error: '#aa0000',
+ Generic.Emph: 'italic',
+ Generic.Strong: 'bold',
+ Generic.Prompt: '#555555',
+ Generic.Output: '#888888',
+ Generic.Traceback: '#aa0000',
+
+ Error: '#F00 bg:#FAA'
+ }
+
+
+_sig_re = re.compile(r'^[a-zA-Z_][a-zA-Z0-9_]*(\(.*?\))')
+
+
+def format_function(name, aliases, func):
+ lines = inspect.getdoc(func).splitlines()
+ signature = '()'
+ if isinstance(func, BuiltinFunctionType):
+ match = _sig_re.match(lines[0])
+ if match is not None:
+ del lines[:1 + bool(lines and not lines[0])]
+ signature = match.group(1)
+ else:
+ try:
+ argspec = inspect.getargspec(func)
+ if getattr(func, 'environmentfilter', False) or \
+ getattr(func, 'contextfilter', False):
+ del argspec[0][0]
+ signature = inspect.formatargspec(*argspec)
+ except:
+ pass
+ result = ['.. function:: %s%s' % (name, signature), '']
+ result.extend(' ' + line for line in lines)
+ if aliases:
+ result.extend(('', ' :aliases: %s' % ', '.join(
+ '``%s``' % x for x in sorted(aliases))))
+ return result
+
+
+def dump_functions(mapping):
+ def directive(dirname, arguments, options, content, lineno,
+ content_offset, block_text, state, state_machine):
+ reverse_mapping = {}
+ for name, func in mapping.iteritems():
+ reverse_mapping.setdefault(func, []).append(name)
+ filters = []
+ for func, names in reverse_mapping.iteritems():
+ aliases = sorted(names, key=lambda x: len(x))
+ name = aliases.pop()
+ filters.append((name, aliases, func))
+ filters.sort()
+
+ result = ViewList()
+ for name, aliases, func in filters:
+ for item in format_function(name, aliases, func):
+ result.append(item, '<jinjaext>')
+
+ node = nodes.paragraph()
+ state.nested_parse(result, content_offset, node)
+ return node.children
+ return directive
+
+
+from jinja2.defaults import DEFAULT_FILTERS, DEFAULT_TESTS
+jinja_filters = dump_functions(DEFAULT_FILTERS)
+jinja_tests = dump_functions(DEFAULT_TESTS)
+
+
+def jinja_nodes(dirname, arguments, options, content, lineno,
+ content_offset, block_text, state, state_machine):
+ from jinja2.nodes import Node
+ doc = ViewList()
+ def walk(node, indent):
+ p = ' ' * indent
+ sig = ', '.join(node.fields)
+ doc.append(p + '.. autoclass:: %s(%s)' % (node.__name__, sig), '')
+ if node.abstract:
+ members = []
+ for key, name in node.__dict__.iteritems():
+ if not key.startswith('_') and \
+ not hasattr(node.__base__, key) and callable(name):
+ members.append(key)
+ if members:
+ members.sort()
+ doc.append('%s :members: %s' % (p, ', '.join(members)), '')
+ if node.__base__ != object:
+ doc.append('', '')
+ doc.append('%s :Node type: :class:`%s`' %
+ (p, node.__base__.__name__), '')
+ doc.append('', '')
+ children = node.__subclasses__()
+ children.sort(key=lambda x: x.__name__.lower())
+ for child in children:
+ walk(child, indent)
+ walk(Node, 0)
+ return parse_rst(state, content_offset, doc)
+
+
+def inject_toc(app, doctree, docname):
+ titleiter = iter(doctree.traverse(nodes.title))
+ try:
+ # skip first title, we are not interested in that one
+ titleiter.next()
+ title = titleiter.next()
+ # and check if there is at least another title
+ titleiter.next()
+ except StopIteration:
+ return
+ tocnode = nodes.section('')
+ tocnode['classes'].append('toc')
+ toctitle = nodes.section('')
+ toctitle['classes'].append('toctitle')
+ toctitle.append(nodes.title(text='Table Of Contents'))
+ tocnode.append(toctitle)
+ tocnode += doctree.document.settings.env.get_toc_for(docname)[0][1]
+ title.parent.insert(title.parent.children.index(title), tocnode)
+
+
+def setup(app):
+ app.add_directive('jinjafilters', jinja_filters, 0, (0, 0, 0))
+ app.add_directive('jinjatests', jinja_tests, 0, (0, 0, 0))
+ app.add_directive('jinjanodes', jinja_nodes, 0, (0, 0, 0))
+ # uncomment for inline toc. links are broken unfortunately
+ ##app.connect('doctree-resolved', inject_toc)
http://git-wip-us.apache.org/repos/asf/ambari/blob/570de228/ambari-common/src/main/python/jinja2/docs/sandbox.rst
----------------------------------------------------------------------
diff --git a/ambari-common/src/main/python/jinja2/docs/sandbox.rst b/ambari-common/src/main/python/jinja2/docs/sandbox.rst
new file mode 100644
index 0000000..bb0ca9f
--- /dev/null
+++ b/ambari-common/src/main/python/jinja2/docs/sandbox.rst
@@ -0,0 +1,46 @@
+Sandbox
+=======
+
+The Jinja2 sandbox can be used to evaluate untrusted code. Access to unsafe
+attributes and methods is prohibited.
+
+Assuming `env` is a :class:`SandboxedEnvironment` in the default configuration
+the following piece of code shows how it works:
+
+>>> env.from_string("{{ func.func_code }}").render(func=lambda:None)
+u''
+>>> env.from_string("{{ func.func_code.do_something }}").render(func=lambda:None)
+Traceback (most recent call last):
+ ...
+SecurityError: access to attribute 'func_code' of 'function' object is unsafe.
+
+
+.. module:: jinja2.sandbox
+
+.. autoclass:: SandboxedEnvironment([options])
+ :members: is_safe_attribute, is_safe_callable
+
+.. autoclass:: ImmutableSandboxedEnvironment([options])
+
+.. autoexception:: SecurityError
+
+.. autofunction:: unsafe
+
+.. autofunction:: is_internal_attribute
+
+.. autofunction:: modifies_known_mutable
+
+.. admonition:: Note
+
+ The Jinja2 sandbox alone is no solution for perfect security. Especially
+ for web applications you have to keep in mind that users may create
+ templates with arbitrary HTML in so it's crucial to ensure that (if you
+ are running multiple users on the same server) they can't harm each other
+ via JavaScript insertions and much more.
+
+ Also the sandbox is only as good as the configuration. We stronly
+ recommend only passing non-shared resources to the template and use
+ some sort of whitelisting for attributes.
+
+ Also keep in mind that templates may raise runtime or compile time errors,
+ so make sure to catch them.
http://git-wip-us.apache.org/repos/asf/ambari/blob/570de228/ambari-common/src/main/python/jinja2/docs/switching.rst
----------------------------------------------------------------------
diff --git a/ambari-common/src/main/python/jinja2/docs/switching.rst b/ambari-common/src/main/python/jinja2/docs/switching.rst
new file mode 100644
index 0000000..ba3cfb1
--- /dev/null
+++ b/ambari-common/src/main/python/jinja2/docs/switching.rst
@@ -0,0 +1,242 @@
+Switching from other Template Engines
+=====================================
+
+.. highlight:: html+jinja
+
+If you have used a different template engine in the past and want to swtich
+to Jinja2 here is a small guide that shows the basic syntatic and semantic
+changes between some common, similar text template engines for Python.
+
+Jinja1
+------
+
+Jinja2 is mostly compatible with Jinja1 in terms of API usage and template
+syntax. The differences between Jinja1 and 2 are explained in the following
+list.
+
+API
+~~~
+
+Loaders
+ Jinja2 uses a different loader API. Because the internal representation
+ of templates changed there is no longer support for external caching
+ systems such as memcached. The memory consumed by templates is comparable
+ with regular Python modules now and external caching doesn't give any
+ advantage. If you have used a custom loader in the past have a look at
+ the new :ref:`loader API <loaders>`.
+
+Loading templates from strings
+ In the past it was possible to generate templates from a string with the
+ default environment configuration by using `jinja.from_string`. Jinja2
+ provides a :class:`Template` class that can be used to do the same, but
+ with optional additional configuration.
+
+Automatic unicode conversion
+ Jinja1 performed automatic conversion of bytestrings in a given encoding
+ into unicode objects. This conversion is no longer implemented as it
+ was inconsistent as most libraries are using the regular Python ASCII
+ bytestring to Unicode conversion. An application powered by Jinja2
+ *has to* use unicode internally everywhere or make sure that Jinja2 only
+ gets unicode strings passed.
+
+i18n
+ Jinja1 used custom translators for internationalization. i18n is now
+ available as Jinja2 extension and uses a simpler, more gettext friendly
+ interface and has support for babel. For more details see
+ :ref:`i18n-extension`.
+
+Internal methods
+ Jinja1 exposed a few internal methods on the environment object such
+ as `call_function`, `get_attribute` and others. While they were marked
+ as being an internal method it was possible to override them. Jinja2
+ doesn't have equivalent methods.
+
+Sandbox
+ Jinja1 was running sandbox mode by default. Few applications actually
+ used that feature so it became optional in Jinja2. For more details
+ about the sandboxed execution see :class:`SandboxedEnvironment`.
+
+Context
+ Jinja1 had a stacked context as storage for variables passed to the
+ environment. In Jinja2 a similar object exists but it doesn't allow
+ modifications nor is it a singleton. As inheritance is dynamic now
+ multiple context objects may exist during template evaluation.
+
+Filters and Tests
+ Filters and tests are regular functions now. It's no longer necessary
+ and allowed to use factory functions.
+
+
+Templates
+~~~~~~~~~
+
+Jinja2 has mostly the same syntax as Jinja1. What's different is that
+macros require parentheses around the argument list now.
+
+Additionally Jinja2 allows dynamic inheritance now and dynamic includes.
+The old helper function `rendertemplate` is gone now, `include` can be used
+instead. Includes no longer import macros and variable assignments, for
+that the new `import` tag is used. This concept is explained in the
+:ref:`import` documentation.
+
+Another small change happened in the `for`-tag. The special loop variable
+doesn't have a `parent` attribute, instead you have to alias the loop
+yourself. See :ref:`accessing-the-parent-loop` for more details.
+
+
+Django
+------
+
+If you have previously worked with Django templates, you should find
+Jinja2 very familiar. In fact, most of the syntax elements look and
+work the same.
+
+However, Jinja2 provides some more syntax elements covered in the
+documentation and some work a bit different.
+
+This section covers the template changes. As the API is fundamentally
+different we won't cover it here.
+
+Method Calls
+~~~~~~~~~~~~
+
+In Django method calls work implicitly. With Jinja2 you have to specify that
+you want to call an object. Thus this Django code::
+
+ {% for page in user.get_created_pages %}
+ ...
+ {% endfor %}
+
+will look like this in Jinja::
+
+ {% for page in user.get_created_pages() %}
+ ...
+ {% endfor %}
+
+This allows you to pass variables to the function which is also used for macros
+which is not possible in Django.
+
+Conditions
+~~~~~~~~~~
+
+In Django you can use the following constructs to check for equality::
+
+ {% ifequal foo "bar" %}
+ ...
+ {% else %}
+ ...
+ {% endifequal %}
+
+In Jinja2 you can use the normal if statement in combination with operators::
+
+ {% if foo == 'bar' %}
+ ...
+ {% else %}
+ ...
+ {% endif %}
+
+You can also have multiple elif branches in your template::
+
+ {% if something %}
+ ...
+ {% elif otherthing %}
+ ...
+ {% elif foothing %}
+ ...
+ {% else %}
+ ...
+ {% endif %}
+
+Filter Arguments
+~~~~~~~~~~~~~~~~
+
+Jinja2 provides more than one argument for filters. Also the syntax for
+argument passing is different. A template that looks like this in Django::
+
+ {{ items|join:", " }}
+
+looks like this in Jinja2::
+
+ {{ items|join(', ') }}
+
+In fact it's a bit more verbose but it allows different types of arguments -
+including variables - and more than one of them.
+
+Tests
+~~~~~
+
+In addition to filters there also are tests you can perform using the is
+operator. Here are some examples::
+
+ {% if user.user_id is odd %}
+ {{ user.username|e }} is odd
+ {% else %}
+ hmm. {{ user.username|e }} looks pretty normal
+ {% endif %}
+
+Loops
+~~~~~
+
+For loops work very similar to Django, the only incompatibility is that in
+Jinja2 the special variable for the loop context is called `loop` and not
+`forloop` like in Django.
+
+Cycle
+~~~~~
+
+The ``{% cycle %}`` tag does not exist in Jinja because of it's implicit
+nature. However you can achieve mostly the same by using the `cycle`
+method on a loop object.
+
+The following Django template::
+
+ {% for user in users %}
+ <li class="{% cycle 'odd' 'even' %}">{{ user }}</li>
+ {% endfor %}
+
+Would look like this in Jinja::
+
+ {% for user in users %}
+ <li class="{{ loop.cycle('odd', 'even') }}">{{ user }}</li>
+ {% endfor %}
+
+There is no equivalent of ``{% cycle ... as variable %}``.
+
+
+Mako
+----
+
+.. highlight:: html+mako
+
+If you have used Mako so far and want to switch to Jinja2 you can configure
+Jinja2 to look more like Mako:
+
+.. sourcecode:: python
+
+ env = Environment('<%', '%>', '${', '}', '%')
+
+Once the environment is configure like that Jinja2 should be able to interpret
+a small subset of Mako templates. Jinja2 does not support embedded Python code
+so you would have to move that out of the template. The syntax for defs (in
+Jinja2 defs are called macros) and template inheritance is different too. The
+following Mako template::
+
+ <%inherit file="layout.html" />
+ <%def name="title()">Page Title</%def>
+ <ul>
+ % for item in list:
+ <li>${item}</li>
+ % endfor
+ </ul>
+
+Looks like this in Jinja2 with the above configuration::
+
+ <% extends "layout.html" %>
+ <% block title %>Page Title<% endblock %>
+ <% block body %>
+ <ul>
+ % for item in list:
+ <li>${item}</li>
+ % endfor
+ </ul>
+ <% endblock %>