| 140 | ==== Jinja2 theme |
| 141 | |
| 142 | Fortunately Jinja2 can do dynamic includes (or extends in this case) as well, |
| 143 | so the same idea can be transposed: have the end user page extend the layout page, |
| 144 | then have the layout page extend whatever has been defined to be the theme page. |
| 145 | |
| 146 | The differences with Genshi are subtle: while in both case the control of the |
| 147 | output is delegated to the more generic page, with Jinja2 the parent only controls |
| 148 | what it puts around //blocks//. It can put some default content in these blocks, |
| 149 | but the end user page has the final say about what to do with this default content, |
| 150 | as it can reuse it inside its block (by calling `super()`) or not. |
| 151 | |
| 152 | So let's transpose the example. |
| 153 | For as long as we have both template engines coexisting, |
| 154 | we prefix the new Jinja2 templates with a `j`, |
| 155 | so we're now discussing: |
| 156 | - jsearch.html, which extends |
| 157 | - jlayout.html, which extends |
| 158 | - jtheme.html (as this is our default theme page) |
| 159 | |
| 160 | In more details, we describe what happens with the |
| 161 | [source:cboos.git/trac/search/templates/jsearch.html jsearch.html] page: |
| 162 | - it starts by //extending// the jlayout.html page: |
| 163 | {{{#!jinja |
| 164 | # extends 'jlayout.html' |
| 165 | }}} |
| 166 | - the [source:cboos.git/trac/templates/jlayout.html jlayout.html] page: |
| 167 | - first **dynamically** //extends// in turn some "theme" page |
| 168 | {{{#!jinja |
| 169 | # extends ('j' + chrome.theme) |
| 170 | }}} |
| 171 | - by default, this will be our |
| 172 | [source:cboos.git/trac/templates/jtheme.html jtheme.html] page: |
| 173 | - it defines a `head` block inside of an otherwise empty `<head>` element; |
| 174 | this means this a "slot" that will be filled by the content |
| 175 | of the `head` block in the extending templates (in this case, |
| 176 | jlayout.html) |
| 177 | - it contains a `<body>` element; |
| 178 | as we want to replicate what the original theme.html did, |
| 179 | what we want to achieve here is to provide a ''slot'' |
| 180 | at the place where we want to substitute in the content |
| 181 | produced by the jlayout.html template: |
| 182 | {{{#!xml (shoud really be jinja+html...) |
| 183 | <body> |
| 184 | # block body |
| 185 | <div id="banner"> |
| 186 | ... |
| 187 | </div> |
| 188 | <div id="main"> |
| 189 | ... |
| 190 | # block content |
| 191 | (here goes the content of the content block produced by layout.html) |
| 192 | # endblock content |
| 193 | </div> |
| 194 | <div id="footer"> |
| 195 | ... |
| 196 | </div> |
| 197 | # block body |
| 198 | </body> |
| 199 | }}} |
| 200 | I didn't name that inner block "body", as this could be confusing: |
| 201 | we're not in control of the `<body>` element there, just of |
| 202 | a fraction of it, the bottom part of the main div. |
| 203 | //If// we want to be in complete control of the body in the extended |
| 204 | template, we could (as opposed to what happens in Genshi), |
| 205 | we would simply have to redefine the `body` block which contains |
| 206 | all of the default structure (possibly reusing the content of that |
| 207 | block by a call to `${ super() }`) |
| 208 | - then the jlayout.html template defines the `head` and `content` blocks; |
| 209 | it doesn't need to redefine the `body` block, as it's happy with what |
| 210 | jtheme does with it; |
| 211 | that `content` block is filled with some predefined, generic content, |
| 212 | mostly the same stuff that could be found in the corresponding |
| 213 | `<py:match>` filters in layout.html; |
| 214 | - the end user template jsearch.html has to redefine the head and content |
| 215 | blocks, and has to place a `${ super() }` expression in order to |
| 216 | insert the default content proposed by the extended template at |
| 217 | the right place |
| 218 | |
| 219 | Depending how one looks at it, it seems this approach is even more flexible than |
| 220 | what we had in Genshi, as the end user template can decide which bits of the |
| 221 | parent template it wants or not ("bottom-up" control), something that was not |
| 222 | readily doable with Genshi ("top-down" control). |
| 223 | |
| 224 | I omitted the discussion of the title block (not even implemented yet) and the |
| 225 | replacement for the `<xi:include href="site.html>` template |
| 226 | (`# include site_head.html` and `# include site_body.html`). |