`).
An example of another theme page: [https://github.com/chevah/trac-bootstrap-theme/blob/master/templates/theme.html trac-bootstrap-theme's theme.html].
=== The admin.html template as container for other templates
Note that this scheme can be extended to additional intermediate levels,
for example see what we do with the admin panels.
One such panel is
[source:tags/trac-1.0.9/trac/admin/templates/admin_basics.html admin_basics.html]:
{{{#!html+genshi
Basics
...
}}}
- it starts by including the admin.html page
- then it provides the `` and `` elements specific to that panel
The [source:tags/trac-1.0.9/trac/admin/templates/admin.html admin.html] page
is similar to the search.html page in that it includes the layout.html, but
it also first contains its own `
` templates to organize the content of
the admin panel which included it:
{{{#!html+genshi
Administration: ${select('title/text()')}
${select("*[local-name() != 'title']")}
Administration
}}}
- defines `
` filters for `` and `` (of the including panel page),
which in turn will produce modified `` and `` elements
- it then includes the layout.html page (see above)
Feel free to brush up your Genshi craft by reading ([G:GenshiTutorial#AddingaLayoutTemplate]),
as I just did ;-)
== Jinja2 architecture
Jinja2 can do dynamic includes as well, or more precisely, dynamic ''extends''.
Therefore the Genshi approach can be transposed to Jinja: have the end user page extend the layout page,
then have the layout page extend whatever has been defined to be the theme page.
The differences with Genshi are subtle: while in both case the control of the
output is delegated to the more generic page, with Jinja2 the parent only controls
what it puts around //blocks//. It can put some default content in these blocks,
but the end user page has the final say about what to do with this default content,
as it can reuse it inside its block (by calling `super()`) or not.
=== The search.html template
Let's transpose the previous example of the search.html template.
So we're now discussing:
- [source:cboos.git/trac/search/templates/search.html@jinja2-trunk-r15341 search.html], which extends
- [source:cboos.git/trac/templates/layout.html@jinja2-trunk-r15341 layout.html], which extends
- [source:cboos.git/trac/templates/theme.html@jinja2-trunk-r15341 theme.html] (as this is our default theme page)
A template which extends another can redefine the content of the //named blocks// defined in the extended template. This redefinition may or may not include the original content of the block in the extended template (`${ super() }`).
We first give an overview of the three templates and how their content will be combined in the generated output.
|--------------------------------------------------------------------------
|| __theme.html__ || \
|| __layout.html__ \\ //# extends theme.html// || \
|| __search.html__ \\ //# extends layout.html// ||
|--------------------------------------------------------------------------
{{{#!td style="vertical-align:top"
{{{#!html
<html>
<head>
# block head
# endblock head
</head>
<body>
# block body
… banner + metanav + mainnav + contextnav + warnings + notices …
# block content
# endblock content
… footer …
# endblock body
</body>
</html>
}}}
\\
(//head// and //content// blocks \\
have no default content)
}}}
{{{#!td style="vertical-align:top"
{{{#!html
<html>
<head>
# block head
<title>
# block title
- Trac
# endblock title
</title>
… meta + link + script …
# endblock head
</head>
<body>
# block content
… alternate formats …
# endblock content
</body>
</html>
}}}
\\
(//head// and //content// blocks \\
have default content)
}}}
{{{#!td style="vertical-align:top"
{{{#!html
<html>
<head>
<title>
# block title
Search
${ super() }
# endblock title
</title>
# block head
${ super() }
… meta …
# endblock head
</head>
<body>
# block content
<div class="content">
… Search Results …
</div>
${ super() }
# endblock content
</body>
</html>
}}}
}}}
|--------------------------------------------------------------------------
{{{#!td colspan=3 style="vertical-align:top"
generated output:
{{{#!html
<html>
<head>
<title>
Search
- Trac
</title>
… meta + link + script …
… meta …
</head>
<body>
… banner + metanav + mainnav + contextnav + warnings + notices …
<div class="content">
… Search Results …
</div>
… alternate formats …
… footer …
</body>
</html>
}}}
}}}
Let's have a closer look at the content of each template, starting with the
most specific template, in our example the [source:cboos.git/trac/search/templates/search.html@jinja2-trunk-r15341 search.html] page:
{{{#!html+jinja
# extends 'layout.html'
# block title
${_("Search")} ${ super() }
# endblock title
# block head
${ super() }
...
# endblock head
# block content
${_("Search")}
...
}}}
- it starts by //extending// the layout.html page (`# extends 'layout.html')
- then it redefines the ''title'', ''head'' and ''content'' blocks,
and has to place a `${ super() }` expression in order to insert the default
content proposed by the extended template at the right place;
note that the presence of the ``, `` and `` tags here
is strictly "decorative", they will be ignored in the final output. As we're
in a template extending another, **only what's in the redefined blocks matters**.
This is especially important to remember, as this can be a source of error:
for example, no matter that you added your `