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 }}">&laquo; {{ 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 }} &raquo;</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}&amp;check_keywords=yes&amp;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/