1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256
|
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Template Inheritance — Jinja Documentation</title>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<link rel="stylesheet" href="style.css" type="text/css">
<style type="text/css">
.syntax { background: #ffffff; }
.syntax .c { color: #888888 } /* Comment */
.syntax .err { color: #a61717; background-color: #e3d2d2 } /* Error */
.syntax .k { color: #008800; font-weight: bold } /* Keyword */
.syntax .cm { color: #888888 } /* Comment.Multiline */
.syntax .cp { color: #cc0000; font-weight: bold } /* Comment.Preproc */
.syntax .c1 { color: #888888 } /* Comment.Single */
.syntax .cs { color: #cc0000; font-weight: bold; background-color: #fff0f0 } /* Comment.Special */
.syntax .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */
.syntax .ge { font-style: italic } /* Generic.Emph */
.syntax .gr { color: #aa0000 } /* Generic.Error */
.syntax .gh { color: #303030 } /* Generic.Heading */
.syntax .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
.syntax .go { color: #888888 } /* Generic.Output */
.syntax .gp { color: #555555 } /* Generic.Prompt */
.syntax .gs { font-weight: bold } /* Generic.Strong */
.syntax .gu { color: #606060 } /* Generic.Subheading */
.syntax .gt { color: #aa0000 } /* Generic.Traceback */
.syntax .kc { color: #008800; font-weight: bold } /* Keyword.Constant */
.syntax .kd { color: #008800; font-weight: bold } /* Keyword.Declaration */
.syntax .kp { color: #008800 } /* Keyword.Pseudo */
.syntax .kr { color: #008800; font-weight: bold } /* Keyword.Reserved */
.syntax .kt { color: #888888; font-weight: bold } /* Keyword.Type */
.syntax .m { color: #0000DD; font-weight: bold } /* Literal.Number */
.syntax .s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */
.syntax .na { color: #336699 } /* Name.Attribute */
.syntax .nb { color: #003388 } /* Name.Builtin */
.syntax .nc { color: #bb0066; font-weight: bold } /* Name.Class */
.syntax .no { color: #003366; font-weight: bold } /* Name.Constant */
.syntax .nd { color: #555555 } /* Name.Decorator */
.syntax .ne { color: #bb0066; font-weight: bold } /* Name.Exception */
.syntax .nf { color: #0066bb; font-weight: bold } /* Name.Function */
.syntax .nl { color: #336699; font-style: italic } /* Name.Label */
.syntax .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */
.syntax .py { color: #336699; font-weight: bold } /* Name.Property */
.syntax .nt { color: #bb0066; font-weight: bold } /* Name.Tag */
.syntax .nv { color: #336699 } /* Name.Variable */
.syntax .ow { color: #008800 } /* Operator.Word */
.syntax .w { color: #bbbbbb } /* Text.Whitespace */
.syntax .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */
.syntax .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */
.syntax .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */
.syntax .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */
.syntax .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */
.syntax .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */
.syntax .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */
.syntax .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */
.syntax .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */
.syntax .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */
.syntax .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */
.syntax .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */
.syntax .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */
.syntax .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */
.syntax .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */
.syntax .bp { color: #003388 } /* Name.Builtin.Pseudo */
.syntax .vc { color: #336699 } /* Name.Variable.Class */
.syntax .vg { color: #dd7700 } /* Name.Variable.Global */
.syntax .vi { color: #3333bb } /* Name.Variable.Instance */
.syntax .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */
</style>
</head>
<body>
<div id="content">
<h1 class="heading"><span>Jinja</span></h1>
<h2 class="subheading">Template Inheritance</h2>
<div id="toc">
<h2>Navigation</h2>
<ul>
<li><a href="index.html">back to index</a></li>
</ul>
<h2>Contents</h2>
<ul class="contents">
<li><a href="#base-template">Base Template</a></li>
<li><a href="#child-template">Child Template</a></li>
<li><a href="#how-inheritance-works-internally">How Inheritance Works Internally</a></li>
<li><a href="#super-blocks">Super Blocks</a></li>
<li><a href="#block-shortcuts">Block Shortcuts</a></li>
</ul>
</div>
<div id="contentwrapper">
<p>The most powerful part of Jinja is template inheritance. Template inheritance
allows you to build a base "skeleton" template that contains all the common
elements of your site and defines <strong>blocks</strong> that child templates can override.</p>
<p>Sounds complicated but is very basic. It's easiest to understand it by starting
with an example.</p>
<div class="section">
<h2><a id="base-template" name="base-template">Base Template</a></h2>
<p>This template, which we'll call <tt class="docutils literal"><span class="pre">base.html</span></tt>, defines a simple HTML skeleton
document that you might use for a simple two-column page. It's the job of
"child" templates to fill the empty blocks with content:</p>
<div class="syntax"><pre><span class="cp"><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"</span>
<span class="cp"> "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"></span>
<span class="nt"><html</span> <span class="na">xmlns=</span><span class="s">"http://www.w3.org/1999/xhtml"</span><span class="nt">></span>
<span class="nt"><head></span>
<span class="nt"><link</span> <span class="na">rel=</span><span class="s">"stylesheet"</span> <span class="na">href=</span><span class="s">"style.css"</span> <span class="nt">/></span>
<span class="nt"><title></span><span class="cp">{%</span> <span class="k">block</span> <span class="nv">title</span> <span class="cp">%}{%</span> <span class="k">endblock</span> <span class="cp">%}</span> - My Webpage<span class="nt"></title></span>
<span class="cp">{%</span> <span class="k">block</span> <span class="nv">html_head</span> <span class="cp">%}{%</span> <span class="k">endblock</span> <span class="cp">%}</span>
<span class="nt"></head></span>
<span class="nt"><body></span>
<span class="nt"><div</span> <span class="na">id=</span><span class="s">"content"</span><span class="nt">></span>
<span class="cp">{%</span> <span class="k">block</span> <span class="nv">content</span> <span class="cp">%}{%</span> <span class="k">endblock</span> <span class="cp">%}</span>
<span class="nt"></div></span>
<span class="nt"><div</span> <span class="na">id=</span><span class="s">"footer"</span><span class="nt">></span>
<span class="cp">{%</span> <span class="k">block</span> <span class="nv">footer</span> <span class="cp">%}</span>
<span class="ni">&copy;</span> Copyright 2006 by <span class="nt"><a</span> <span class="na">href=</span><span class="s">"http://mydomain.tld"</span><span class="nt">></span>myself<span class="nt"></a></span>.
<span class="cp">{%</span> <span class="k">endblock</span> <span class="cp">%}</span>
<span class="nt"></div></span>
<span class="nt"></body></span>
</pre></div>
<p>In this example, the <tt class="docutils literal"><span class="pre">{%</span> <span class="pre">block</span> <span class="pre">%}</span></tt> tags define four blocks that child templates
can fill in. All the <cite>block</cite> tag does is to tell the template engine that a
child template may override those portions of the template.</p>
</div>
<div class="section">
<h2><a id="child-template" name="child-template">Child Template</a></h2>
<p>A child template might look like this:</p>
<div class="syntax"><pre><span class="cp">{%</span> <span class="k">extends</span> <span class="s2">"base.html"</span> <span class="cp">%}</span>
<span class="cp">{%</span> <span class="k">block</span> <span class="nv">title</span> <span class="cp">%}</span>Index<span class="cp">{%</span> <span class="k">endblock</span> <span class="cp">%}</span>
<span class="cp">{%</span> <span class="k">block</span> <span class="nv">html_head</span> <span class="cp">%}</span>
<span class="nt"><style </span><span class="na">type=</span><span class="s">"text/css"</span><span class="nt">></span>
<span class="nc">.important</span> <span class="p">{</span>
<span class="k">color</span><span class="o">:</span> <span class="m">#336699</span><span class="p">;</span>
<span class="p">}</span>
<span class="nt"></style></span>
<span class="cp">{%</span> <span class="k">endblock</span> <span class="cp">%}</span>
<span class="cp">{%</span> <span class="k">block</span> <span class="nv">content</span> <span class="cp">%}</span>
<span class="nt"><h1></span>Index<span class="nt"></h1></span>
<span class="nt"><p</span> <span class="na">class=</span><span class="s">"important"</span><span class="nt">></span>
Welcome on my awsome homepage.
<span class="nt"></p></span>
<span class="cp">{%</span> <span class="k">endblock</span> <span class="cp">%}</span>
</pre></div>
<p>The <tt class="docutils literal"><span class="pre">{%</span> <span class="pre">extends</span> <span class="pre">%}</span></tt> tag is the key here. It tells the template engine that
this template "extends" another template. When the template system evaluates
this template, first it locates the parent. It must be always the first tag
in a template but whitespace or a comment is allowed before. This was not
enforced with Jinja 1.0 and 1.1, it does however raise a syntax error with
1.2 or later.</p>
<p>The filename of the template depends on the template loader. For example the
<tt class="docutils literal"><span class="pre">FileSystemLoader</span></tt> allows you to access other templates by giving the
filename. You can access templates in subdirectories with an slash:</p>
<div class="syntax"><pre><span class="cp">{%</span> <span class="k">extends</span> <span class="s2">"layout/default.html"</span> <span class="cp">%}</span><span class="x"></span>
</pre></div>
<p>But this behavior can depend on the application using Jinja.</p>
<p>Note that since the child template didn't define the <tt class="docutils literal"><span class="pre">footer</span></tt> block, the
value from the parent template is used instead.</p>
<div class="admonition-note admonition">
<p class="first admonition-title">Note</p>
<p class="last">You can't define multiple <tt class="docutils literal"><span class="pre">{%</span> <span class="pre">block</span> <span class="pre">%}</span></tt> tags with the same name in the
same template. This limitation exists because a block tag works in "both"
directions. That is, a block tag doesn't just provide a hole to fill - it
also defines the content that fills the hole in the <em>parent</em>. If there were
two similarly-named <tt class="docutils literal"><span class="pre">{%</span> <span class="pre">block</span> <span class="pre">%}</span></tt> tags in a template, that template's
parent wouldn't know which one of the blocks' content to use.</p>
</div>
</div>
<div class="section">
<h2><a id="how-inheritance-works-internally" name="how-inheritance-works-internally">How Inheritance Works Internally</a></h2>
<p>Inheritance in Jinja is straightforward. If a template contains an
<tt class="docutils literal"><span class="pre">{%</span> <span class="pre">extends</span> <span class="pre">%}</span></tt> tag it's considered being a child template, otherwise it's
a layout template. In a layout template you can place blocks basically
everywhere. In a child template blocks can only be located either at the
top level or inside another block.</p>
<p>Data outside of a block in a child template is executed before the layout
template is rendered, thus you can use it to propagate data to the whole
inheritance chain. Having a block in an invalid position you will receive
an syntax error. Here some examples:</p>
<p><strong>impossible</strong>:</p>
<blockquote>
<div class="syntax"><pre><span class="cp">{%</span> <span class="k">extends</span> <span class="s1">'master.html'</span> <span class="cp">%}</span><span class="x"></span>
<span class="cp">{%</span> <span class="k">if</span> <span class="nv">some_condition</span> <span class="cp">%}</span><span class="x"></span>
<span class="x"> </span><span class="cp">{%</span> <span class="k">block</span> <span class="nv">body</span> <span class="cp">%}</span><span class="x"></span>
<span class="x"> ...</span>
<span class="x"> </span><span class="cp">{%</span> <span class="k">endblock</span> <span class="cp">%}</span><span class="x"></span>
<span class="cp">{%</span> <span class="k">endif</span> <span class="cp">%}</span><span class="x"></span>
</pre></div>
<p>This can't work because template inheritance works at translation /
compilation time not at template execution.</p>
</blockquote>
<p><strong>possible</strong>:</p>
<blockquote>
<div class="syntax"><pre><span class="cp">{%</span> <span class="k">extends</span> <span class="s1">'master.html'</span> <span class="cp">%}</span><span class="x"></span>
<span class="cp">{%</span> <span class="k">block</span> <span class="nv">body</span> <span class="cp">%}</span><span class="x"></span>
<span class="x"> </span><span class="cp">{%</span> <span class="k">if</span> <span class="nv">some_condition</span> <span class="cp">%}</span><span class="x"></span>
<span class="x"> </span><span class="cp">{%</span> <span class="k">block</span> <span class="nv">myblock</span> <span class="cp">%}</span><span class="x"></span>
<span class="x"> ...</span>
<span class="x"> </span><span class="cp">{%</span> <span class="k">endblock</span> <span class="cp">%}</span><span class="x"></span>
<span class="x"> </span><span class="cp">{%</span> <span class="k">endif</span> <span class="cp">%}</span><span class="x"></span>
<span class="cp">{%</span> <span class="k">endblock</span> <span class="cp">%}</span><span class="x"></span>
</pre></div>
<p>This can work although it probably makes no sense in this specific case.
However the condition is handled at runtime because it's in a valid block
and defines a new block subtemplates can override.</p>
</blockquote>
<div class="admonition-note admonition">
<p class="first admonition-title">Note</p>
<p class="last">Unlike Python Jinja does not support multiple inheritance. So you can
only have one extends tag with only one constant string argument.</p>
</div>
</div>
<div class="section">
<h2><a id="super-blocks" name="super-blocks">Super Blocks</a></h2>
<p>Starting with <cite>Jinja 1.1</cite> it's possible to render the contents of the parent
block. By calling it you get the results of the parent block back. If you want
to get the data of the parent you can give it an offset:</p>
<div class="syntax"><pre><span class="cp">{{</span> <span class="nv">super</span><span class="o">()</span> <span class="cp">}}</span><span class="x"></span>
<span class="x"> return the parent data</span>
<span class="cp">{{</span> <span class="nv">super</span><span class="o">(</span><span class="m">1</span><span class="o">)</span> <span class="cp">}}</span><span class="x"></span>
<span class="x"> the same as above</span>
<span class="cp">{{</span> <span class="nv">super</span><span class="o">(</span><span class="m">2</span><span class="o">)</span> <span class="cp">}}</span><span class="x"></span>
<span class="x"> return the data of the second parent block</span>
</pre></div>
</div>
<div class="section">
<h2><a id="block-shortcuts" name="block-shortcuts">Block Shortcuts</a></h2>
<p>With Jinja 1.1 onwards it's possible to have a shortcut syntax for blocks
with few content. The following constructs do the same:</p>
<div class="syntax"><pre><span class="cp">{%</span> <span class="k">block</span> <span class="nv">title</span> <span class="cp">%}{{</span> <span class="nv">page_title</span> <span class="cp">}}{%</span> <span class="k">endblock</span> <span class="cp">%}</span><span class="x"></span>
<span class="cp">{%</span> <span class="k">block</span> <span class="nv">title</span> <span class="nv">page_title</span> <span class="cp">%}</span><span class="x"></span>
</pre></div>
<p>Note that as soon as you specify a second argument it's threated as
short block and Jinja won't look for an closing tag.</p>
</div>
</div>
</div>
</body>
<!-- generated on: 2007-11-17 18:18:06.064341
file id: inheritance -->
</html>
|