You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by ao...@apache.org on 2014/09/03 20:19:59 UTC
[14/22] AMBARI-7138. Ambari RPM deals with jinja2 dependency
incorrectly (aonishuk)
http://git-wip-us.apache.org/repos/asf/ambari/blob/7c3ea59f/ambari-common/src/main/python/ambari_jinja2/custom_fixers/fix_broken_reraising.py
----------------------------------------------------------------------
diff --git a/ambari-common/src/main/python/ambari_jinja2/custom_fixers/fix_broken_reraising.py b/ambari-common/src/main/python/ambari_jinja2/custom_fixers/fix_broken_reraising.py
new file mode 100644
index 0000000..fd0ea68
--- /dev/null
+++ b/ambari-common/src/main/python/ambari_jinja2/custom_fixers/fix_broken_reraising.py
@@ -0,0 +1,21 @@
+from lib2to3 import fixer_base, pytree
+from lib2to3.fixer_util import Name, BlankLine, Name, Attr, ArgList
+
+
+class FixBrokenReraising(fixer_base.BaseFix):
+ PATTERN = """
+ raise_stmt< 'raise' any ',' val=any ',' tb=any >
+ """
+
+ # run before the broken 2to3 checker with the same goal
+ # tries to rewrite it with a rule that does not work out for jinja
+ run_order = 1
+
+ def transform(self, node, results):
+ tb = results['tb'].clone()
+ tb.prefix = ''
+ with_tb = Attr(results['val'].clone(), Name('with_traceback')) + \
+ [ArgList([tb])]
+ new = pytree.Node(self.syms.simple_stmt, [Name("raise")] + with_tb)
+ new.prefix = node.prefix
+ return new
http://git-wip-us.apache.org/repos/asf/ambari/blob/7c3ea59f/ambari-common/src/main/python/ambari_jinja2/custom_fixers/fix_xrange2.py
----------------------------------------------------------------------
diff --git a/ambari-common/src/main/python/ambari_jinja2/custom_fixers/fix_xrange2.py b/ambari-common/src/main/python/ambari_jinja2/custom_fixers/fix_xrange2.py
new file mode 100644
index 0000000..5d35e50
--- /dev/null
+++ b/ambari-common/src/main/python/ambari_jinja2/custom_fixers/fix_xrange2.py
@@ -0,0 +1,11 @@
+from lib2to3 import fixer_base
+from lib2to3.fixer_util import Name, BlankLine
+
+
+# whyever this is necessary..
+
+class FixXrange2(fixer_base.BaseFix):
+ PATTERN = "'xrange'"
+
+ def transform(self, node, results):
+ node.replace(Name('range', prefix=node.prefix))
http://git-wip-us.apache.org/repos/asf/ambari/blob/7c3ea59f/ambari-common/src/main/python/ambari_jinja2/docs/Makefile
----------------------------------------------------------------------
diff --git a/ambari-common/src/main/python/ambari_jinja2/docs/Makefile b/ambari-common/src/main/python/ambari_jinja2/docs/Makefile
new file mode 100644
index 0000000..5e24ec1
--- /dev/null
+++ b/ambari-common/src/main/python/ambari_jinja2/docs/Makefile
@@ -0,0 +1,75 @@
+# Makefile for Sphinx documentation
+#
+
+# You can set these variables from the command line.
+SPHINXOPTS =
+SPHINXBUILD = sphinx-build
+PAPER =
+
+# Internal variables.
+PAPEROPT_a4 = -D latex_paper_size=a4
+PAPEROPT_letter = -D latex_paper_size=letter
+ALLSPHINXOPTS = -d _build/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
+
+.PHONY: help clean html web pickle htmlhelp latex changes linkcheck
+
+help:
+ @echo "Please use \`make <target>' where <target> is one of"
+ @echo " html to make standalone HTML files"
+ @echo " pickle to make pickle files"
+ @echo " json to make JSON files"
+ @echo " htmlhelp to make HTML files and a HTML help project"
+ @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
+ @echo " changes to make an overview over all changed/added/deprecated items"
+ @echo " linkcheck to check all external links for integrity"
+
+clean:
+ -rm -rf _build/*
+
+html:
+ mkdir -p _build/html _build/doctrees
+ $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) _build/html
+ @echo
+ @echo "Build finished. The HTML pages are in _build/html."
+
+pickle:
+ mkdir -p _build/pickle _build/doctrees
+ $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) _build/pickle
+ @echo
+ @echo "Build finished; now you can process the pickle files"
+
+json:
+ mkdir -p _build/json _build/doctrees
+ $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) _build/json
+ @echo
+ @echo "Build finished; now you can process the json files"
+
+web: pickle
+
+htmlhelp:
+ mkdir -p _build/htmlhelp _build/doctrees
+ $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) _build/htmlhelp
+ @echo
+ @echo "Build finished; now you can run HTML Help Workshop with the" \
+ ".hhp project file in _build/htmlhelp."
+
+latex:
+ mkdir -p _build/latex _build/doctrees
+ $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) _build/latex
+ @echo
+ @echo "Build finished; the LaTeX files are in _build/latex."
+ @echo "Run \`make all-pdf' or \`make all-ps' in that directory to" \
+ "run these through (pdf)latex."
+
+changes:
+ mkdir -p _build/changes _build/doctrees
+ $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) _build/changes
+ @echo
+ @echo "The overview file is in _build/changes."
+
+linkcheck:
+ mkdir -p _build/linkcheck _build/doctrees
+ $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) _build/linkcheck
+ @echo
+ @echo "Link check complete; look for any errors in the above output " \
+ "or in _build/linkcheck/output.txt."
http://git-wip-us.apache.org/repos/asf/ambari/blob/7c3ea59f/ambari-common/src/main/python/ambari_jinja2/docs/_static/jinja.js
----------------------------------------------------------------------
diff --git a/ambari-common/src/main/python/ambari_jinja2/docs/_static/jinja.js b/ambari-common/src/main/python/ambari_jinja2/docs/_static/jinja.js
new file mode 100644
index 0000000..1c04218
--- /dev/null
+++ b/ambari-common/src/main/python/ambari_jinja2/docs/_static/jinja.js
@@ -0,0 +1,26 @@
+$(function() {
+
+ var
+ toc = $('#toc').show(),
+ items = $('#toc > ul').hide();
+
+ $('#toc h3')
+ .click(function() {
+ if (items.is(':visible')) {
+ items.animate({
+ height: 'hide',
+ opacity: 'hide'
+ }, 300, function() {
+ toc.removeClass('expandedtoc');
+ });
+ }
+ else {
+ items.animate({
+ height: 'show',
+ opacity: 'show'
+ }, 400);
+ toc.addClass('expandedtoc');
+ }
+ });
+
+});
http://git-wip-us.apache.org/repos/asf/ambari/blob/7c3ea59f/ambari-common/src/main/python/ambari_jinja2/docs/_static/print.css
----------------------------------------------------------------------
diff --git a/ambari-common/src/main/python/ambari_jinja2/docs/_static/print.css b/ambari-common/src/main/python/ambari_jinja2/docs/_static/print.css
new file mode 100644
index 0000000..fb633d8
--- /dev/null
+++ b/ambari-common/src/main/python/ambari_jinja2/docs/_static/print.css
@@ -0,0 +1,5 @@
+div.header, div.relnav, #toc { display: none; }
+#contentwrapper { padding: 0; margin: 0; border: none; }
+body { color: black; background-color: white; }
+div.footer { border-top: 1px solid #888; color: #888; margin-top: 1cm; }
+div.footer a { text-decoration: none; }
http://git-wip-us.apache.org/repos/asf/ambari/blob/7c3ea59f/ambari-common/src/main/python/ambari_jinja2/docs/_static/style.css
----------------------------------------------------------------------
diff --git a/ambari-common/src/main/python/ambari_jinja2/docs/_static/style.css b/ambari-common/src/main/python/ambari_jinja2/docs/_static/style.css
new file mode 100644
index 0000000..a1c4d59
--- /dev/null
+++ b/ambari-common/src/main/python/ambari_jinja2/docs/_static/style.css
@@ -0,0 +1,390 @@
+body {
+ background-color: #222;
+ margin: 0;
+ padding: 0;
+ font-family: 'Georgia', serif;
+ font-size: 15px;
+ color: #eee;
+}
+
+div.footer {
+ border-top: 1px solid #111;
+ padding: 8px;
+ font-size: 11px;
+ text-align: center;
+ letter-spacing: 0.5px;
+}
+
+div.footer a {
+ color: #eee;
+}
+
+div.header {
+ margin: 0 -15px 0 -15px;
+ background: url(headerbg.png) repeat-x;
+ border-top: 6px solid #D20000;
+}
+
+div.relnav {
+ border-bottom: 1px solid #111;
+ background: url(navigation.png);
+ margin: 0 -15px 0 -15px;
+ padding: 2px 20px 0 28px;
+ line-height: 25px;
+ color: #aaa;
+ font-size: 12px;
+ text-align: center;
+}
+
+div.relnav a {
+ color: #eee;
+ font-weight: bold;
+ text-decoration: none;
+}
+
+div.relnav a:hover {
+ text-decoration: underline;
+}
+
+#content {
+ background-color: white;
+ color: #111;
+ border-bottom: 1px solid black;
+ background: url(watermark.png) center 0;
+ padding: 0 15px 0 15px;
+ margin: 0;
+}
+
+h1 {
+ margin: 0;
+ padding: 15px 0 0 0;
+}
+
+h1.heading {
+ margin: 0;
+ padding: 0;
+ height: 80px;
+}
+
+h1.heading:hover {
+ background: #222;
+}
+
+h1.heading a {
+ background: url(jinjabanner.png) no-repeat center 0;
+ display: block;
+ width: 100%;
+ height: 80px;
+}
+
+h1.heading a:focus {
+ -moz-outline: none;
+ outline: none;
+}
+
+h1.heading span {
+ display: none;
+}
+
+#jinjalogo {
+ background-image: url(jinjalogo.png);
+ background-repeat: no-repeat;
+ width: 400px;
+ height: 160px;
+}
+
+#contentwrapper {
+ max-width: 680px;
+ padding: 0 18px 20px 18px;
+ margin: 0 auto 0 auto;
+ border-right: 1px solid #eee;
+ border-left: 1px solid #eee;
+ background: url(watermark_blur.png) center -114px;
+}
+
+#contentwrapper h2,
+#contentwrapper h2 a {
+ color: #222;
+ font-size: 24px;
+ margin: 20px 0 0 0;
+}
+
+#contentwrapper h3,
+#contentwrapper h3 a {
+ color: #b41717;
+ font-size: 20px;
+ margin: 20px 0 0 0;
+}
+
+table.docutils {
+ border-collapse: collapse;
+ border: 2px solid #aaa;
+ margin: 0.5em 1.5em 0.5em 1.5em;
+}
+
+table.docutils td {
+ padding: 2px;
+ border: 1px solid #ddd;
+}
+
+p, li, dd, dt, blockquote {
+ color: #333;
+}
+
+blockquote {
+ margin: 10px 0 10px 20px;
+}
+
+p {
+ line-height: 20px;
+ margin-bottom: 0;
+ margin-top: 10px;
+}
+
+hr {
+ border-top: 1px solid #ccc;
+ border-bottom: 0;
+ border-right: 0;
+ border-left: 0;
+ margin-bottom: 10px;
+ margin-top: 20px;
+}
+
+dl {
+ margin-left: 10px;
+}
+
+li, dt {
+ margin-top: 5px;
+}
+
+dt {
+ font-weight: bold;
+ color: #000;
+}
+
+dd {
+ margin-top: 10px;
+ line-height: 20px;
+}
+
+th {
+ text-align: left;
+ padding: 3px;
+ background-color: #f2f2f2;
+}
+
+a {
+ color: #b41717;
+}
+
+a:hover {
+ color: #444;
+}
+
+pre {
+ background: #ededed url(metal.png);
+ border-top: 1px solid #ccc;
+ border-bottom: 1px solid #ccc;
+ padding: 5px;
+ font-size: 13px;
+ font-family: 'Bitstream Vera Sans Mono', 'Monaco', monospace;
+}
+
+tt {
+ font-size: 13px;
+ font-family: 'Bitstream Vera Sans Mono', 'Monaco', monospace;
+ color: black;
+ padding: 1px 2px 1px 2px;
+ background-color: #fafafa;
+ border-bottom: 1px solid #eee;
+}
+
+a.reference:hover tt {
+ border-bottom-color: #aaa;
+}
+
+cite {
+ /* abusing <cite>, it's generated by ReST for `x` */
+ font-size: 13px;
+ font-family: 'Bitstream Vera Sans Mono', 'Monaco', monospace;
+ font-weight: bold;
+ font-style: normal;
+}
+
+div.admonition {
+ margin: 10px 0 10px 0;
+ padding: 10px 10px 10px 60px;
+ border: 1px solid #ccc;
+}
+
+div.admonition p.admonition-title {
+ background-color: #b41717;
+ color: white;
+ margin: -10px -10px 10px -60px;
+ padding: 4px 10px 4px 10px;
+ font-weight: bold;
+ font-size: 15px;
+}
+
+div.admonition p.admonition-title a {
+ color: white!important;
+}
+
+div.admonition-note {
+ background: url(note.png) no-repeat 10px 40px;
+}
+
+div.admonition-implementation {
+ background: url(implementation.png) no-repeat 10px 40px;
+}
+
+a.headerlink {
+ color: #B4B4B4!important;
+ font-size: 0.8em;
+ padding: 0 4px 0 4px;
+ text-decoration: none!important;
+ visibility: hidden;
+}
+
+h1:hover > a.headerlink,
+h2:hover > a.headerlink,
+h3:hover > a.headerlink,
+h4:hover > a.headerlink,
+h5:hover > a.headerlink,
+h6:hover > a.headerlink,
+dt:hover > a.headerlink,
+dt:hover > a.headerlink {
+ visibility: visible;
+}
+
+a.headerlink:hover {
+ background-color: #B4B4B4;
+ color: #F0F0F0!important;
+}
+
+table.indextable {
+ width: 100%;
+}
+
+table.indextable td {
+ vertical-align: top;
+ width: 50%;
+}
+
+table.indextable dl dd {
+ font-size: 11px;
+}
+
+table.indextable dl dd a {
+ color: #000;
+}
+
+dl.function dt,
+dl.class dt,
+dl.exception dt,
+dl.method dt,
+dl.attribute dt {
+ font-weight: normal;
+}
+
+dt .descname {
+ font-weight: bold;
+ margin-right: 4px;
+}
+
+dt .descname, dt .descclassname {
+ padding: 0;
+ background: transparent;
+ border-bottom: 1px solid #111;
+}
+
+dt .descclassname {
+ margin-left: 2px;
+}
+
+dl dt big {
+ font-size: 100%;
+}
+
+ul.search {
+ margin: 10px 0 0 30px;
+ padding: 0;
+}
+
+ul.search li {
+ margin: 10px 0 0 0;
+ padding: 0;
+}
+
+ul.search div.context {
+ font-size: 12px;
+ padding: 4px 0 0 20px;
+ color: #888;
+}
+
+span.highlight {
+ background-color: #eee;
+ border: 1px solid #ccc;
+}
+
+#toc {
+ margin: 0 -17px 0 -17px;
+ display: none;
+}
+
+#toc h3 {
+ float: right;
+ margin: 5px 5px 0 0;
+ padding: 0;
+ font-size: 12px;
+ color: #777;
+}
+
+#toc h3:hover {
+ color: #333;
+ cursor: pointer;
+}
+
+.expandedtoc {
+ background: #222 url(darkmetal.png);
+ border-bottom: 1px solid #111;
+ outline-bottom: 1px solid #000;
+ padding: 5px;
+}
+
+.expandedtoc h3 {
+ color: #aaa;
+ margin: 0!important;
+}
+
+.expandedtoc h3:hover {
+ color: white!important;
+}
+
+#tod h3:hover {
+ color: white;
+}
+
+#toc a {
+ color: #ddd;
+ text-decoration: none;
+}
+
+#toc a:hover {
+ color: white;
+ text-decoration: underline;
+}
+
+#toc ul {
+ margin: 5px 0 12px 17px;
+ padding: 0 7px 0 7px;
+}
+
+#toc ul ul {
+ margin-bottom: 0;
+}
+
+#toc ul li {
+ margin: 2px 0 0 0;
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/7c3ea59f/ambari-common/src/main/python/ambari_jinja2/docs/_templates/genindex.html
----------------------------------------------------------------------
diff --git a/ambari-common/src/main/python/ambari_jinja2/docs/_templates/genindex.html b/ambari-common/src/main/python/ambari_jinja2/docs/_templates/genindex.html
new file mode 100644
index 0000000..9add6e9
--- /dev/null
+++ b/ambari-common/src/main/python/ambari_jinja2/docs/_templates/genindex.html
@@ -0,0 +1,36 @@
+{% extends "layout.html" %}
+{% set title = 'Index' %}
+{% block body %}
+
+ <h1 id="index">Index</h1>
+
+ {% for key, dummy in genindexentries -%}
+ <a href="#{{ key }}"><strong>{{ key }}</strong></a> {% if not loop.last %}| {% endif %}
+ {%- endfor %}
+ <hr>
+
+ {% for key, entries in genindexentries %}
+ <h2 id="{{ key }}">{{ key }}</h2>
+ <table class="indextable"><tr>
+ {%- for column in entries|slice(2) if column %}
+ <td><dl>
+ {%- for entryname, (links, subitems) in column %}
+ <dt>{% if links %}<a href="{{ links[0] }}">{{ entryname|e }}</a>
+ {% for link in links[1:] %}, <a href="{{ link }}">[Link]</a>{% endfor %}
+ {%- else %}{{ entryname|e }}{% endif %}</dt>
+ {%- if subitems %}
+ <dd><dl>
+ {%- for subentryname, subentrylinks in subitems %}
+ <dt><a href="{{ subentrylinks[0] }}">{{ subentryname|e }}</a>
+ {%- for link in subentrylinks[1:] %}, <a href="{{ link }}">[Link]</a>{% endfor -%}
+ </dt>
+ {%- endfor %}
+ </dl></dd>
+ {%- endif -%}
+ {%- endfor %}
+ </dl></td>
+ {%- endfor %}
+ </tr></table>
+ {% endfor %}
+
+{% endblock %}
http://git-wip-us.apache.org/repos/asf/ambari/blob/7c3ea59f/ambari-common/src/main/python/ambari_jinja2/docs/_templates/layout.html
----------------------------------------------------------------------
diff --git a/ambari-common/src/main/python/ambari_jinja2/docs/_templates/layout.html b/ambari-common/src/main/python/ambari_jinja2/docs/_templates/layout.html
new file mode 100644
index 0000000..f682f90
--- /dev/null
+++ b/ambari-common/src/main/python/ambari_jinja2/docs/_templates/layout.html
@@ -0,0 +1,77 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+ <head>
+ <title>Jinja2 Documentation</title>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+ <link rel="stylesheet" href="{{ pathto('_static/style.css', 1) }}" type="text/css">
+ <link rel="stylesheet" href="{{ pathto('_static/print.css', 1) }}" type="text/css" media="print">
+ <link rel="stylesheet" href="{{ pathto('_static/pygments.css', 1) }}" type="text/css">
+ {%- if builder != 'htmlhelp' %}
+ <script type="text/javascript">
+ var DOCUMENTATION_OPTIONS = {
+ URL_ROOT: '{{ pathto("", 1) }}',
+ VERSION: '{{ release }}'
+ };
+ </script>
+ <script type="text/javascript" src="{{ pathto('_static/jquery.js', 1) }}"></script>
+ <script type="text/javascript" src="{{ pathto('_static/interface.js', 1) }}"></script>
+ <script type="text/javascript" src="{{ pathto('_static/doctools.js', 1) }}"></script>
+ <script type="text/javascript" src="{{ pathto('_static/jinja.js', 1) }}"></script>
+ {%- endif %}
+ {%- if use_opensearch and builder != 'htmlhelp' %}
+ <link rel="search" type="application/opensearchdescription+xml"
+ title="Search within {{ docstitle }}"
+ href="{{ pathto('_static/opensearch.xml', 1) }}">
+ {%- endif %}
+ {%- if hasdoc('about') %}
+ <link rel="author" title="About these documents" href="{{ pathto('about') }}">
+ {%- endif %}
+ <link rel="contents" title="Global table of contents" href="{{ pathto('contents') }}">
+ <link rel="index" title="Global index" href="{{ pathto('genindex') }}">
+ <link rel="search" title="Search" href="{{ pathto('search') }}">
+ {%- if hasdoc('copyright') %}
+ <link rel="copyright" title="Copyright" href="{{ pathto('copyright') }}">
+ {%- endif %}
+ <link rel="top" title="{{ docstitle }}" href="{{ pathto('index') }}">
+ {%- if parents %}
+ <link rel="up" title="{{ parents[-1].title|striptags }}" href="{{ parents[-1].link|e }}">
+ {%- endif %}
+ {%- if next %}
+ <link rel="next" title="{{ next.title|striptags }}" href="{{ next.link|e }}">
+ {%- endif %}
+ {%- if prev %}
+ <link rel="prev" title="{{ prev.title|striptags }}" href="{{ prev.link|e }}">
+ {%- endif %}
+ {% block extrahead %}{% endblock %}
+ </head>
+ <body>
+ <div id="content">
+ <div class="header">
+ <h1 class="heading"><a href="{{ pathto('index') }}"
+ title="back to the documentation overview"><span>Jinja</span></a></h1>
+ </div>
+ <div class="relnav">
+ {%- if prev %}
+ <a href="{{ prev.link|e }}">« {{ prev.title }}</a> |
+ {%- endif %}
+ <a href="{{ pathto(current_page_name) if current_page_name else '#' }}">{{ title }}</a>
+ {%- if next %}
+ | <a href="{{ next.link|e }}">{{ next.title }} »</a>
+ {%- endif %}
+ </div>
+ <div id="contentwrapper">
+ {%- if display_toc %}
+ <div id="toc">
+ <h3>Table Of Contents</h3>
+ {{ toc }}
+ </div>
+ {%- endif %}
+ {% block body %}{% endblock %}
+ </div>
+ </div>
+ <div class="footer">
+ © Copyright 2010 by the <a href="http://pocoo.org/">Pocoo Team</a>,
+ documentation generated by <a href="http://sphinx.pocoo.org/">Sphinx</a>
+ </div>
+ </body>
+</html>
http://git-wip-us.apache.org/repos/asf/ambari/blob/7c3ea59f/ambari-common/src/main/python/ambari_jinja2/docs/_templates/opensearch.xml
----------------------------------------------------------------------
diff --git a/ambari-common/src/main/python/ambari_jinja2/docs/_templates/opensearch.xml b/ambari-common/src/main/python/ambari_jinja2/docs/_templates/opensearch.xml
new file mode 100644
index 0000000..9f2fa42
--- /dev/null
+++ b/ambari-common/src/main/python/ambari_jinja2/docs/_templates/opensearch.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<OpenSearchDescription xmlns="http://a9.com/-/spec/opensearch/1.1/">
+ <ShortName>{{ project }}</ShortName>
+ <Description>Search {{ docstitle }}</Description>
+ <InputEncoding>utf-8</InputEncoding>
+ <Url type="text/html" method="get"
+ template="{{ use_opensearch }}/{{ pathto('search') }}?q={searchTerms}&check_keywords=yes&area=default"/>
+ <LongName>{{ docstitle }}</LongName>
+</OpenSearchDescription>
http://git-wip-us.apache.org/repos/asf/ambari/blob/7c3ea59f/ambari-common/src/main/python/ambari_jinja2/docs/_templates/page.html
----------------------------------------------------------------------
diff --git a/ambari-common/src/main/python/ambari_jinja2/docs/_templates/page.html b/ambari-common/src/main/python/ambari_jinja2/docs/_templates/page.html
new file mode 100644
index 0000000..ee6cad3
--- /dev/null
+++ b/ambari-common/src/main/python/ambari_jinja2/docs/_templates/page.html
@@ -0,0 +1,4 @@
+{% extends 'layout.html' %}
+{% block body %}
+ {{ body }}
+{% endblock %}
http://git-wip-us.apache.org/repos/asf/ambari/blob/7c3ea59f/ambari-common/src/main/python/ambari_jinja2/docs/_templates/search.html
----------------------------------------------------------------------
diff --git a/ambari-common/src/main/python/ambari_jinja2/docs/_templates/search.html b/ambari-common/src/main/python/ambari_jinja2/docs/_templates/search.html
new file mode 100644
index 0000000..0c942b7
--- /dev/null
+++ b/ambari-common/src/main/python/ambari_jinja2/docs/_templates/search.html
@@ -0,0 +1,35 @@
+{% extends "layout.html" %}
+{% set title = 'Search' %}
+{% block extrahead %}
+ <script type="text/javascript" src="{{ pathto('_static/searchtools.js', 1) }}"></script>
+{% endblock %}
+{% block body %}
+ <h1 id="search-documentation">Search</h1>
+ <p>
+ From here you can search these documents. Enter your search
+ words into the box below and click "search". Note that the search
+ function will automatically search for all of the words. Pages
+ containing less words won't appear in the result list.
+ </p>
+ <form action="" method="get"><p>
+ <input type="text" name="q" value="">
+ <input type="submit" value="search">
+ </p></form>
+ {% if search_performed %}
+ <h2>Search Results</h2>
+ {% if not search_results %}
+ <p>Your search did not match any results.</p>
+ {% endif %}
+ {% endif %}
+ <div id="search-results">
+ {% if search_results %}
+ <ul>
+ {% for href, caption, context in search_results %}
+ <li><a href="{{ pathto(item.href) }}">{{ caption }}</a>
+ <div class="context">{{ context|e }}</div>
+ </li>
+ {% endfor %}
+ </ul>
+ {% endif %}
+ </div>
+{% endblock %}
http://git-wip-us.apache.org/repos/asf/ambari/blob/7c3ea59f/ambari-common/src/main/python/ambari_jinja2/docs/api.rst
----------------------------------------------------------------------
diff --git a/ambari-common/src/main/python/ambari_jinja2/docs/api.rst b/ambari-common/src/main/python/ambari_jinja2/docs/api.rst
new file mode 100644
index 0000000..92da04a
--- /dev/null
+++ b/ambari-common/src/main/python/ambari_jinja2/docs/api.rst
@@ -0,0 +1,787 @@
+API
+===
+
+.. module:: ambari_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 ambari_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:`~ambari_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:: ambari_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=['ambari_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:: ambari_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:: ambari_jinja2.DebugUndefined()
+
+.. autoclass:: ambari_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:: ambari_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:: ambari_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:: ambari_jinja2.BaseLoader
+ :members: get_source, load
+
+Here a list of the builtin loaders Jinja2 provides:
+
+.. autoclass:: ambari_jinja2.FileSystemLoader
+
+.. autoclass:: ambari_jinja2.PackageLoader
+
+.. autoclass:: ambari_jinja2.DictLoader
+
+.. autoclass:: ambari_jinja2.FunctionLoader
+
+.. autoclass:: ambari_jinja2.PrefixLoader
+
+.. autoclass:: ambari_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:: ambari_jinja2.BytecodeCache
+ :members: load_bytecode, dump_bytecode, clear
+
+.. autoclass:: ambari_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:: ambari_jinja2.FileSystemBytecodeCache
+
+.. autoclass:: ambari_jinja2.MemcachedBytecodeCache
+
+
+Utilities
+---------
+
+These helper functions and classes are useful if you add custom filters or
+functions to a Jinja2 environment.
+
+.. autofunction:: ambari_jinja2.environmentfilter
+
+.. autofunction:: ambari_jinja2.contextfilter
+
+.. autofunction:: ambari_jinja2.evalcontextfilter
+
+.. autofunction:: ambari_jinja2.environmentfunction
+
+.. autofunction:: ambari_jinja2.contextfunction
+
+.. autofunction:: ambari_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:: ambari_jinja2.clear_caches
+
+.. autofunction:: ambari_jinja2.is_undefined
+
+.. autoclass:: ambari_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:: ambari_jinja2.TemplateError
+
+.. autoexception:: ambari_jinja2.UndefinedError
+
+.. autoexception:: ambari_jinja2.TemplateNotFound
+
+.. autoexception:: ambari_jinja2.TemplatesNotFound
+
+.. autoexception:: ambari_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:: ambari_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 ambari_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:: ambari_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:: ambari_jinja2.meta.find_undeclared_variables
+
+.. autofunction:: ambari_jinja2.meta.find_referenced_templates
http://git-wip-us.apache.org/repos/asf/ambari/blob/7c3ea59f/ambari-common/src/main/python/ambari_jinja2/docs/cache_extension.py
----------------------------------------------------------------------
diff --git a/ambari-common/src/main/python/ambari_jinja2/docs/cache_extension.py b/ambari-common/src/main/python/ambari_jinja2/docs/cache_extension.py
new file mode 100644
index 0000000..d3703e3
--- /dev/null
+++ b/ambari-common/src/main/python/ambari_jinja2/docs/cache_extension.py
@@ -0,0 +1,56 @@
+from ambari_jinja2 import nodes
+from ambari_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/7c3ea59f/ambari-common/src/main/python/ambari_jinja2/docs/changelog.rst
----------------------------------------------------------------------
diff --git a/ambari-common/src/main/python/ambari_jinja2/docs/changelog.rst b/ambari-common/src/main/python/ambari_jinja2/docs/changelog.rst
new file mode 100644
index 0000000..6d6d6ca
--- /dev/null
+++ b/ambari-common/src/main/python/ambari_jinja2/docs/changelog.rst
@@ -0,0 +1,3 @@
+.. module:: ambari_jinja2
+
+.. include:: ../CHANGES
http://git-wip-us.apache.org/repos/asf/ambari/blob/7c3ea59f/ambari-common/src/main/python/ambari_jinja2/docs/conf.py
----------------------------------------------------------------------
diff --git a/ambari-common/src/main/python/ambari_jinja2/docs/conf.py b/ambari-common/src/main/python/ambari_jinja2/docs/conf.py
new file mode 100644
index 0000000..ba90c49
--- /dev/null
+++ b/ambari-common/src/main/python/ambari_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/7c3ea59f/ambari-common/src/main/python/ambari_jinja2/docs/extensions.rst
----------------------------------------------------------------------
diff --git a/ambari-common/src/main/python/ambari_jinja2/docs/extensions.rst b/ambari-common/src/main/python/ambari_jinja2/docs/extensions.rst
new file mode 100644
index 0000000..4d2c458
--- /dev/null
+++ b/ambari-common/src/main/python/ambari_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=['ambari_jinja2.ext.i18n'])
+
+
+.. _i18n-extension:
+
+i18n Extension
+--------------
+
+**Import name:** `ambari_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:: ambari_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:: ambari_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:: ambari_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:: ambari_jinja2.Environment.uninstall_gettext_translations()
+
+ Uninstall the translations again.
+
+.. method:: ambari_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=['ambari_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:** `ambari_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:** `ambari_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:** `ambari_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:** `ambari_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:: ambari_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 ambari_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:`ambari_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:: ambari_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:`~ambari_jinja2.lexer.TokenStream`
+
+.. autoclass:: ambari_jinja2.lexer.TokenStream
+ :members: push, look, eos, skip, next, next_if, skip_if, expect
+
+ .. attribute:: current
+
+ The current :class:`~ambari_jinja2.lexer.Token`.
+
+.. autoclass:: ambari_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:: ambari_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:`ambari_jinja2.Environment.parse`.
+
+.. module:: ambari_jinja2.nodes
+
+.. jinjanodes::
+
+.. autoexception:: Impossible
http://git-wip-us.apache.org/repos/asf/ambari/blob/7c3ea59f/ambari-common/src/main/python/ambari_jinja2/docs/faq.rst
----------------------------------------------------------------------
diff --git a/ambari-common/src/main/python/ambari_jinja2/docs/faq.rst b/ambari-common/src/main/python/ambari_jinja2/docs/faq.rst
new file mode 100644
index 0000000..89186b1
--- /dev/null
+++ b/ambari-common/src/main/python/ambari_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/7c3ea59f/ambari-common/src/main/python/ambari_jinja2/docs/index.rst
----------------------------------------------------------------------
diff --git a/ambari-common/src/main/python/ambari_jinja2/docs/index.rst b/ambari-common/src/main/python/ambari_jinja2/docs/index.rst
new file mode 100644
index 0000000..27bee23
--- /dev/null
+++ b/ambari-common/src/main/python/ambari_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/7c3ea59f/ambari-common/src/main/python/ambari_jinja2/docs/integration.rst
----------------------------------------------------------------------
diff --git a/ambari-common/src/main/python/ambari_jinja2/docs/integration.rst b/ambari-common/src/main/python/ambari_jinja2/docs/integration.rst
new file mode 100644
index 0000000..4f8614a
--- /dev/null
+++ b/ambari-common/src/main/python/ambari_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 `ambari_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
+
+ [ambari_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
+
+ [ambari_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 ambari_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/