| 1 | = Conversion example |
| 2 | |
| 3 | Here we detail the conversion process of a sample Genshi template ([source:tags/trac-1.0.9/trac/wiki/templates/wiki_view.html wiki_view.html]) into the corresponding Jinja2 template ([source:cboos.git/trac/wiki/templates/jwiki_view.html jwiki_view.html]). |
| 4 | |
| 5 | As will become apparent, we mainly use [http://jinja.pocoo.org/docs/dev/templates/#line-statements line statements] for the Jinja2 control structures. |
| 6 | Note that we have reformatted the Genshi template to use shorter line widths, so that both columns of the table below stay visible (a wide screen also helps). |
| 7 | |
| 8 | {{{#!th style="max-width: 200px" |
| 9 | wiki_view.html (Genshi template) |
| 10 | }}} |
| 11 | {{{#!th style="max-width: 200px" |
| 12 | jwiki_view.html (Jinja2 template) |
| 13 | }}} |
| 14 | |------ |
| 15 | ||= ||= || |
| 16 | {{{#!td |
| 17 | {{{#!html+genshi |
| 18 | <!--! Copyright (C) 2006-2014 Edgewall Software |
| 19 | |
| 20 | This software is licensed as described in the file COPYING, which |
| 21 | you should have received as part of this distribution. The terms |
| 22 | are also available at http://trac.edgewall.com/license.html. |
| 23 | |
| 24 | This software consists of voluntary contributions made by many |
| 25 | individuals. For the exact contribution history, see the revision |
| 26 | history and logs, available at http://trac.edgewall.org/. |
| 27 | --> |
| 28 | }}} |
| 29 | }}} |
| 30 | {{{#!td |
| 31 | {{{#!html+jinja |
| 32 | {# Copyright (C) 2006-2014 Edgewall Software |
| 33 | |
| 34 | This software is licensed as described in the file COPYING, which |
| 35 | you should have received as part of this distribution. The terms |
| 36 | are also available at http://trac.edgewall.com/license.html. |
| 37 | |
| 38 | This software consists of voluntary contributions made by many |
| 39 | individuals. For the exact contribution history, see the revision |
| 40 | history and logs, available at http://trac.edgewall.org/. |
| 41 | #} |
| 42 | }}} |
| 43 | }}} |
| 44 | |----------------------------------------------------------------------------- |
| 45 | |||| Block comments || |
| 46 | |----------------------------------------------------------------------------- |
| 47 | {{{#!td |
| 48 | {{{#!html+genshi |
| 49 | }}} |
| 50 | }}} |
| 51 | {{{#!td |
| 52 | {{{#!html+jinja |
| 53 | # extends "jlayout.html" |
| 54 | }}} |
| 55 | }}} |
| 56 | |----------------------------------------------------------------------------- |
| 57 | |||| This is the equivalent of Genshi's `<py:include href="layout.html" />`. We have to do the extends before outputing any content on our own, otherwise it would show up in the final result. Once we made the `extends`, only the content written within //blocks// will matter. || |
| 58 | |----------------------------------------------------------------------------- |
| 59 | {{{#!td |
| 60 | {{{#!html+genshi |
| 61 | <!DOCTYPE html |
| 62 | PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" |
| 63 | "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> |
| 64 | }}} |
| 65 | }}} |
| 66 | {{{#!td |
| 67 | {{{#!html+jinja |
| 68 | <!DOCTYPE html> |
| 69 | }}} |
| 70 | }}} |
| 71 | |----------------------------------------------------------------------------- |
| 72 | |||| Let's directly make the jump to HTML5, while we're at it (I'm not sure what is the current state of the HTML5 support in Genshi, but it no longer matters) || |
| 73 | |----------------------------------------------------------------------------- |
| 74 | {{{#!td |
| 75 | {{{#!html+genshi |
| 76 | <html xmlns="http://www.w3.org/1999/xhtml" |
| 77 | xmlns:py="http://genshi.edgewall.org/" |
| 78 | xmlns:i18n="http://genshi.edgewall.org/i18n" |
| 79 | xmlns:xi="http://www.w3.org/2001/XInclude" |
| 80 | py:with="modify_perm = 'WIKI_MODIFY' in perm(page.resource); |
| 81 | create_perm = 'WIKI_CREATE' in perm(page.resource); |
| 82 | admin_perm = 'WIKI_ADMIN' in perm(page.resource); |
| 83 | is_not_latest = page.exists and page.version != latest_version"> |
| 84 | }}} |
| 85 | }}} |
| 86 | {{{#!td |
| 87 | {{{#!html+jinja |
| 88 | <html> |
| 89 | |
| 90 | }}} |
| 91 | }}} |
| 92 | |----------------------------------------------------------------------------- |
| 93 | {{{#!td |
| 94 | No need for exotic namespace declarations. |
| 95 | |
| 96 | Note that we can't use a `with` declaration that would encompass the ''head'' and ''content'' blocks we'll define in a moment, as this would force the generation of content twice, once by having the with block present in the template, and a second time because of the extends and the call of the blocks. |
| 97 | }}} |
| 98 | |----------------------------------------------------------------------------- |
| 99 | {{{#!td |
| 100 | {{{#!html+genshi |
| 101 | <xi:include href="layout.html" /> |
| 102 | }}} |
| 103 | }}} |
| 104 | {{{#!td |
| 105 | {{{#!html+jinja |
| 106 | }}} |
| 107 | }}} |
| 108 | |----------------------------------------------------------------------------- |
| 109 | |||| See above, this will be converted to an initial `extends` statement. || |
| 110 | |----------------------------------------------------------------------------- |
| 111 | {{{#!td |
| 112 | {{{#!html+genshi |
| 113 | <head> |
| 114 | <title py:if="title">$title</title> |
| 115 | }}} |
| 116 | }}} |
| 117 | {{{#!td |
| 118 | {{{#!html+jinja |
| 119 | <head> |
| 120 | <title> |
| 121 | # block title |
| 122 | # if title: |
| 123 | ${title} ${ super() } |
| 124 | # endif |
| 125 | # endblock title |
| 126 | </title> |
| 127 | |
| 128 | # block head |
| 129 | # set modify_perm = 'WIKI_MODIFY' in perm(page.resource) |
| 130 | # set is_not_latest = page.exists and page.version != latest_version |
| 131 | |
| 132 | ${ super() } |
| 133 | }}} |
| 134 | }}} |
| 135 | |----------------------------------------------------------------------------- |
| 136 | {{{#!td colspan=2 |
| 137 | The content of the <title> element is placed in the ''title'' block, |
| 138 | followed by the content of the parent ''title'' block (`${ super() }`). |
| 139 | When closing the block, we reuse the name of the block. |
| 140 | |
| 141 | Note that while the only thing that really matters in an extending template |
| 142 | is the content of the blocks, we try hard to keep a correct HTML structure |
| 143 | for the whole template page, so that its HTML content can be validated in a |
| 144 | standalone way (cf. [#jinjachecker]). This is why we add the <html>, <head> and |
| 145 | <title> tags. |
| 146 | |
| 147 | We explained earlier why the title block has to be outside of the ''head'' block: |
| 148 | to avoid appearing twice, once as part of the head block, and the second time |
| 149 | when we call `${ super() }` in order to retrieve the content of the parent ''head'' |
| 150 | block. |
| 151 | |
| 152 | Finally, we define some variables at the beginning of the block (corresponding to |
| 153 | some which were part of the `py:with` attribute in the `<html>` tag, in the Genshi |
| 154 | template). |
| 155 | }}} |
| 156 | |----------------------------------------------------------------------------- |
| 157 | {{{#!td |
| 158 | {{{#!html+genshi |
| 159 | <meta py:if="version or page.author == 'trac'" |
| 160 | name="ROBOTS" content="NOINDEX, NOFOLLOW" /> |
| 161 | <link py:if="modify_perm" rel="alternate" |
| 162 | type="application/x-wiki" |
| 163 | href="${href.wiki(page.name, action='edit', |
| 164 | version=page.version if is_not_latest else None)}" |
| 165 | title="${_('Revert page to this version') if |
| 166 | is_not_latest else _('Edit this page')}"/> |
| 167 | }}} |
| 168 | }}} |
| 169 | {{{#!td |
| 170 | {{{#!html+jinja |
| 171 | # if version or page.author == 'trac': |
| 172 | <meta name="ROBOTS" content="NOINDEX, NOFOLLOW" /> |
| 173 | # endif |
| 174 | # if modify_perm: |
| 175 | <link rel="alternate" type="application/x-wiki" |
| 176 | href="${href.wiki(page.name, action='edit', |
| 177 | version=page.version if is_not_latest)}" |
| 178 | title="${_("Revert page to this version") if is_not_latest else |
| 179 | _("Edit this page")}"/> |
| 180 | # endif |
| 181 | }}} |
| 182 | }}} |
| 183 | |----------------------------------------------------------------------------- |
| 184 | |||| With Jinja2, the logic is now clearly distinct from the content. || |
| 185 | |----------------------------------------------------------------------------- |
| 186 | {{{#!td |
| 187 | {{{#!html+genshi |
| 188 | <script type="text/javascript"> |
| 189 | jQuery(document).ready(function($) { |
| 190 | $("#content").find("h1,h2,h3,h4,h5,h6") |
| 191 | .addAnchor(_("Link to this section")); |
| 192 | $("#content").find(".wikianchor").each(function() { |
| 193 | $(this).addAnchor(babel.format(_("Link to #%(id)s"), |
| 194 | {id: $(this).attr('id')})); |
| 195 | }); |
| 196 | $(".foldable").enableFolding(true, true); |
| 197 | }); |
| 198 | </script> |
| 199 | }}} |
| 200 | }}} |
| 201 | {{{#!td |
| 202 | {{{#!html+jinja |
| 203 | <script type="text/javascript"> |
| 204 | jQuery(document).ready(function($) { |
| 205 | $("#content").find("h1,h2,h3,h4,h5,h6") |
| 206 | .addAnchor(_("Link to this section")); |
| 207 | $("#content").find(".wikianchor").each(function() { |
| 208 | $(this).addAnchor(babel.format(_("Link to #%(id)s"), { |
| 209 | id: $(this).attr('id')})); |
| 210 | }); |
| 211 | $(".foldable").enableFolding(true, true); |
| 212 | }); |
| 213 | </script> |
| 214 | }}} |
| 215 | }}} |
| 216 | |----------------------------------------------------------------------------- |
| 217 | |||| No changes here, except for some reformatting (we try to stay below 80 chars for nicer future side-by-side diffs). || |
| 218 | |----------------------------------------------------------------------------- |
| 219 | {{{#!td |
| 220 | {{{#!html+genshi |
| 221 | </head> |
| 222 | |
| 223 | }}} |
| 224 | }}} |
| 225 | {{{#!td |
| 226 | {{{#!html+jinja |
| 227 | # endblock head |
| 228 | </head> |
| 229 | |
| 230 | }}} |
| 231 | }}} |
| 232 | |----------------------------------------------------------------------------- |
| 233 | |||| We close the ''head'' block. || |
| 234 | |----------------------------------------------------------------------------- |
| 235 | {{{#!td |
| 236 | {{{#!html+genshi |
| 237 | <body> |
| 238 | <div id="content" class="${classes('wiki', create=not page.exists)}"> |
| 239 | |
| 240 | }}} |
| 241 | }}} |
| 242 | {{{#!td |
| 243 | {{{#!html+jinja |
| 244 | <body> |
| 245 | # block content |
| 246 | # set modify_perm = 'WIKI_MODIFY' in perm(page.resource) |
| 247 | # set create_perm = 'WIKI_CREATE' in perm(page.resource) |
| 248 | # set admin_perm = 'WIKI_ADMIN' in perm(page.resource) |
| 249 | # set is_not_latest = page.exists and page.version != latest_version |
| 250 | |
| 251 | <div id="content" class="${classes('wiki', create=not page.exists)}"> |
| 252 | |
| 253 | }}} |
| 254 | }}} |
| 255 | |----------------------------------------------------------------------------- |
| 256 | |||| We start the ''content'' block. As before with the ''header'' block, we define some variables at the beginning of the block. || |
| 257 | |----------------------------------------------------------------------------- |
| 258 | {{{#!td |
| 259 | {{{#!html+genshi |
| 260 | <py:if test="version"> |
| 261 | <br /> |
| 262 | <table id="info" summary="Revision info"> |
| 263 | <tr><th scope="row" i18n:msg="version, author, date"> |
| 264 | Version $page.version (modified by ${authorinfo(page.author)}, |
| 265 | ${pretty_dateinfo(page.time)}) |
| 266 | (<a href="${href.wiki(page.name, action='diff', |
| 267 | version=page.version)}">diff</a>) |
| 268 | </th></tr> |
| 269 | <tr><td class="message" xml:space="preserve"> |
| 270 | ${wiki_to_html(context, page.comment or '--')} |
| 271 | </td></tr> |
| 272 | </table> |
| 273 | </py:if> |
| 274 | }}} |
| 275 | }}} |
| 276 | {{{#!td |
| 277 | {{{#!html+jinja |
| 278 | # if version: |
| 279 | <br /> |
| 280 | <table id="info" summary="${_("Revision info")}"> |
| 281 | <tr><th scope="row"> |
| 282 | # with |
| 283 | # set version = page.version |
| 284 | # set author = authorinfo(page.author) |
| 285 | # set date = pretty_dateinfo(page.time) |
| 286 | # set hef = href.wiki(page.name, action='diff', version=page.version) |
| 287 | # trans version, author, date, href |
| 288 | |
| 289 | Version ${version} (modified by ${author}, ${date}) |
| 290 | (<a href="${href}">diff</a>) |
| 291 | |
| 292 | # endtrans |
| 293 | # endwith |
| 294 | </th></tr> |
| 295 | <tr><td class="message"> |
| 296 | ${wiki_to_html(context, page.comment or '--')} |
| 297 | </td></tr> |
| 298 | </table> |
| 299 | # endif |
| 300 | |
| 301 | }}} |
| 302 | }}} |
| 303 | |----------------------------------------------------------------------------- |
| 304 | {{{#!td colspan=2 |
| 305 | Here we illustrate the i18n changes. |
| 306 | |
| 307 | First, any sentence that corresponds to visible end-user text that should be |
| 308 | translated has to be marked somehow. |
| 309 | |
| 310 | One way is to use the standard i18n calls, |
| 311 | `_`, `ngettext()`, etc. |
| 312 | |
| 313 | The other way is to use `trans` blocks. |
| 314 | There are two big differences with their Genshi i18n equivalent: |
| 315 | - variable substitutions can only be those of direct variables, |
| 316 | no kind of expression is allowed, even as simple as attribute |
| 317 | lookup |
| 318 | - Jinja2, markup neutral as it is, will not do any substitutions |
| 319 | on the markup found in a trans block; what would have ended |
| 320 | in a Genshi bracketed expression `... [1:diff]` in the catalogs |
| 321 | will now remain HTML markup: `... <a href="${href}">diff</a>`. |
| 322 | Note that one can use a `with` statement for breaking up the |
| 323 | assignments needed on multiple separate lines. |
| 324 | Smaller lists of variables can be placed on the `trans` line directly. |
| 325 | }}} |
| 326 | |----------------------------------------------------------------------------- |
| 327 | {{{#!td |
| 328 | {{{#!html+genshi |
| 329 | <div class="wikipage searchable" py:choose="" xml:space="preserve"> |
| 330 | <py:when test="page.exists"> |
| 331 | <div id="wikipage" class="trac-content" |
| 332 | py:content="wiki_to_html(context, text)" /> |
| 333 | <?python |
| 334 | last_modification = (page.comment and |
| 335 | _('Version %(version)s by %(author)s: %(comment)s', |
| 336 | version=page.version, author=format_author(page.author), |
| 337 | comment=page.comment) or |
| 338 | _('Version %(version)s by %(author)s', |
| 339 | version=page.version, author=format_author(page.author))) |
| 340 | ?> |
| 341 | <div py:if="not version" class="trac-modifiedby"> |
| 342 | <span i18n:msg="reldate"> |
| 343 | <a href="${href.wiki(page.name, action='diff', |
| 344 | version=page.version)}" |
| 345 | title="$last_modification">Last modified</a> |
| 346 | ${pretty_dateinfo(page.time)} |
| 347 | </span> |
| 348 | <span class="trac-print" i18n:msg="date">Last modified on |
| 349 | ${format_datetime(page.time)}</span> |
| 350 | </div> |
| 351 | </py:when> |
| 352 | <py:otherwise> |
| 353 | <p i18n:msg="name">The page <strong>${name_of(page.resource)}</strong> |
| 354 | does not exist. You can create it here.</p> |
| 355 | </py:otherwise> |
| 356 | </div> |
| 357 | }}} |
| 358 | }}} |
| 359 | {{{#!td |
| 360 | {{{#!html+jinja |
| 361 | <div class="wikipage searchable"> |
| 362 | # if page.exists: |
| 363 | <div id="wikipage" class="trac-content">${ |
| 364 | wiki_to_html(context, text) |
| 365 | }</div> |
| 366 | # set last_modification = (page.comment and |
| 367 | _('Version %(version)s by %(author)s: %(comment)s', |
| 368 | version=page.version, author=format_author(page.author), |
| 369 | comment=page.comment) or |
| 370 | _('Version %(version)s by %(author)s', |
| 371 | version=page.version, author=format_author(page.author))) |
| 372 | # if not version: |
| 373 | <div class="trac-modifiedby"> |
| 374 | <span> |
| 375 | # with |
| 376 | # set href = href.wiki(page.name, action='diff', |
| 377 | version=page.version), |
| 378 | # set date = pretty_dateinfo(page.time) |
| 379 | # trans href, last_modification, date |
| 380 | |
| 381 | <a href="${href}" |
| 382 | title="${last_modification}">Last modified</a> ${date} |
| 383 | |
| 384 | # endtrans |
| 385 | # endwith |
| 386 | </span> |
| 387 | <span class="trac-print"> |
| 388 | ${_("Last modified on %(date)s", date=format_datetime(page.time))} |
| 389 | </span> |
| 390 | </div> |
| 391 | # endif |
| 392 | # else: |
| 393 | <p> |
| 394 | # trans name = name_of(page.resource) |
| 395 | |
| 396 | The page <strong>${name}</strong> does not exist. |
| 397 | You can create it here. |
| 398 | |
| 399 | # endtrans |
| 400 | </p> |
| 401 | # endif |
| 402 | </div> |
| 403 | }}} |
| 404 | }}} |
| 405 | |----------------------------------------------------------------------------- |
| 406 | |||| || |
| 407 | |----------------------------------------------------------------------------- |
| 408 | {{{#!td |
| 409 | {{{#!html+genshi |
| 410 | <xi:include href="list_of_attachments.html" |
| 411 | py:with="alist = attachments; compact = True; |
| 412 | foldable = True"/> |
| 413 | }}} |
| 414 | }}} |
| 415 | {{{#!td |
| 416 | {{{#!html+jinja |
| 417 | # with |
| 418 | # set alist = attachments |
| 419 | # set compact = True |
| 420 | # set foldable = True |
| 421 | # include "jlist_of_attachments.html" |
| 422 | # endwith |
| 423 | }}} |
| 424 | }}} |
| 425 | |----------------------------------------------------------------------------- |
| 426 | |||| Jinja2 includes also know about their context, so that make them kind of parametric. || |
| 427 | |----------------------------------------------------------------------------- |
| 428 | {{{#!td |
| 429 | {{{#!html+genshi |
| 430 | <py:with vars="delete_perm = 'WIKI_DELETE' in perm(page.resource); |
| 431 | rename_perm = 'WIKI_RENAME' in perm(page.resource)"> |
| 432 | <py:if test="modify_perm or create_perm or delete_perm"> |
| 433 | <div class="buttons"> |
| 434 | <py:if test="modify_perm or create_perm"> |
| 435 | }}} |
| 436 | }}} |
| 437 | {{{#!td |
| 438 | {{{#!html+jinja |
| 439 | # with |
| 440 | # set delete_perm = 'WIKI_DELETE' in perm(page.resource) |
| 441 | # set rename_perm = 'WIKI_RENAME' in perm(page.resource) |
| 442 | # if modify_perm or create_perm or delete_perm: |
| 443 | <div class="buttons"> |
| 444 | # if modify_perm or create_perm: |
| 445 | }}} |
| 446 | }}} |
| 447 | |----------------------------------------------------------------------------- |
| 448 | |||| Again, even when there's a lot of control lines, it's a bit easier to immediately spot the actual content in Jinja2 templates, due to the clearer syntactic difference. || |
| 449 | |----------------------------------------------------------------------------- |
| 450 | {{{#!td |
| 451 | {{{#!html+genshi |
| 452 | <form method="get" action="${href.wiki(page.name)}" id="modifypage"> |
| 453 | <div> |
| 454 | <input type="hidden" name="action" value="edit" /> |
| 455 | <py:choose> |
| 456 | <py:when test="is_not_latest and modify_perm"> |
| 457 | <input type="hidden" name="version" value="${page.version}"/> |
| 458 | <input type="submit" value="${_('Revert to this version')}"/> |
| 459 | </py:when> |
| 460 | <py:when test="page.exists and modify_perm"> |
| 461 | <input type="submit" value="${_('Edit this page')}" |
| 462 | accesskey="e" /> |
| 463 | </py:when> |
| 464 | <py:when test="not page.exists and create_perm"> |
| 465 | <input type="submit" value="${_('Create this page')}" |
| 466 | accesskey="e" /> |
| 467 | <div py:if="templates" id="template"> |
| 468 | <label for="template">using the template:</label> |
| 469 | <select name="template"> |
| 470 | <option selected="${not default_template in templates |
| 471 | or None}" |
| 472 | value="">(blank page)</option> |
| 473 | <option py:for="t in sorted(templates)" value="$t" |
| 474 | selected="${t == default_template or None}" |
| 475 | >$t</option> |
| 476 | </select> |
| 477 | </div> |
| 478 | </py:when> |
| 479 | </py:choose> |
| 480 | </div> |
| 481 | </form> |
| 482 | }}} |
| 483 | }}} |
| 484 | {{{#!td |
| 485 | {{{#!html+jinja |
| 486 | <form method="get" action="${href.wiki(page.name)}" id="modifypage"> |
| 487 | <div> |
| 488 | <input type="hidden" name="action" value="edit" /> |
| 489 | # if is_not_latest and modify_perm: |
| 490 | <input type="hidden" name="version" value="${page.version}"/> |
| 491 | <input type="submit" value="${_('Revert to this version')}"/> |
| 492 | # elif page.exists and modify_perm: |
| 493 | <input type="submit" value="${_('Edit this page')}" |
| 494 | accesskey="e" /> |
| 495 | # elif not page.exists and create_perm: |
| 496 | <input type="submit" value="${_('Create this page')}" |
| 497 | accesskey="e" /> |
| 498 | # if templates: |
| 499 | <div id="template"> |
| 500 | <label for="template">${_("using the template:")}</label> |
| 501 | <select name="template"> |
| 502 | <option ${{'selected': not default_template in templates |
| 503 | }|htmlattr} |
| 504 | value="">${_("(blank page)")}</option> |
| 505 | # for t in sorted(templates): |
| 506 | <option value="${t}" |
| 507 | ${{'selected': t == default_template |
| 508 | }|htmlattr}>${t}</option> |
| 509 | # endfor |
| 510 | </select> |
| 511 | </div> |
| 512 | # endif |
| 513 | # endif |
| 514 | </div> |
| 515 | </form> |
| 516 | |
| 517 | }}} |
| 518 | }}} |
| 519 | |----------------------------------------------------------------------------- |
| 520 | {{{#!td |
| 521 | A `<py:choose>` and its series of `<py:when>` translates very smoothly into a sequence of `if / elif` statements. |
| 522 | |
| 523 | Special care should be taken when producing attributes dynamically, as it's the |
| 524 | case here for `selected`. We use the `htmlattr` filter that takes care of |
| 525 | producing the right value for the attribute depending on its content: with |
| 526 | a truth value, we'll output `selected="selected"` otherwise we'll just omit |
| 527 | the parameter. |
| 528 | }}} |
| 529 | |----------------------------------------------------------------------------- |
| 530 | |||| || |
| 531 | |----------------------------------------------------------------------------- |
| 532 | {{{#!td |
| 533 | {{{#!html+genshi |
| 534 | <py:if test="page.exists"> |
| 535 | <xi:include href="attach_file_form.html" |
| 536 | py:with="alist = attachments"/> |
| 537 | </py:if> |
| 538 | </py:if> |
| 539 | }}} |
| 540 | }}} |
| 541 | {{{#!td |
| 542 | {{{#!html+jinja |
| 543 | # if page.exists: |
| 544 | # with alist = attachments |
| 545 | # include "jattach_file_form.html" |
| 546 | # endwith |
| 547 | # endif |
| 548 | # endif |
| 549 | }}} |
| 550 | }}} |
| 551 | |----------------------------------------------------------------------------- |
| 552 | |||| We pass `attachments` as `alist` to the included template (a `j...` template, obviously). || |
| 553 | |----------------------------------------------------------------------------- |
| 554 | {{{#!td |
| 555 | {{{#!html+genshi |
| 556 | <form method="get" action="${href.wiki(page.name)}" |
| 557 | id="rename" py:if="page.exists and rename_perm"> |
| 558 | <div> |
| 559 | <input type="hidden" name="action" value="rename" /> |
| 560 | <input type="submit" value="${_('Rename page')}" /> |
| 561 | </div> |
| 562 | </form> |
| 563 | <form method="get" action="${href.wiki(page.name)}" |
| 564 | id="delete" py:if="page.exists and delete_perm"> |
| 565 | <div> |
| 566 | <input type="hidden" name="action" value="delete" /> |
| 567 | <input type="hidden" name="version" value="$page.version" /> |
| 568 | <py:if test="page.version == latest_version"> |
| 569 | <input type="submit" name="delete_version" |
| 570 | value="${_('Delete this version')}" /> |
| 571 | </py:if> |
| 572 | <input type="submit" value="${_('Delete page')}" /> |
| 573 | </div> |
| 574 | </form> |
| 575 | </div> |
| 576 | </py:if> |
| 577 | </py:with> |
| 578 | }}} |
| 579 | }}} |
| 580 | {{{#!td |
| 581 | {{{#!html+jinja |
| 582 | # if page.exists and rename_perm: |
| 583 | <form method="get" action="${href.wiki(page.name)}" id="rename"> |
| 584 | <div> |
| 585 | <input type="hidden" name="action" value="rename" /> |
| 586 | <input type="submit" value="${_('Rename page')}" /> |
| 587 | </div> |
| 588 | </form> |
| 589 | # endif |
| 590 | # if page.exists and delete_perm: |
| 591 | <form method="get" action="${href.wiki(page.name)}" id="delete"> |
| 592 | <div> |
| 593 | <input type="hidden" name="action" value="delete" /> |
| 594 | <input type="hidden" name="version" value="${page.version}" /> |
| 595 | # if page.version == latest_version: |
| 596 | <input type="submit" name="delete_version" value="${_('Delete this version')}" /> |
| 597 | # endif |
| 598 | <input type="submit" value="${_('Delete page')}" /> |
| 599 | </div> |
| 600 | </form> |
| 601 | # endif |
| 602 | </div> |
| 603 | # endif |
| 604 | # endwith |
| 605 | |
| 606 | }}} |
| 607 | }}} |
| 608 | |----------------------------------------------------------------------------- |
| 609 | |||| || |
| 610 | |----------------------------------------------------------------------------- |
| 611 | {{{#!td |
| 612 | {{{#!html+genshi |
| 613 | <div class="wikipage searchable" py:if="not page.exists and higher"> |
| 614 | <p>You could also create the same page higher in the hierarchy:</p> |
| 615 | <ul> |
| 616 | <li py:for="markup in higher">${markup}</li> |
| 617 | </ul> |
| 618 | </div> |
| 619 | }}} |
| 620 | }}} |
| 621 | {{{#!td |
| 622 | {{{#!html+jinja |
| 623 | # if not page.exists and higher: |
| 624 | <div class="wikipage searchable"> |
| 625 | <p>You could also create the same page higher in the hierarchy:</p> |
| 626 | <ul> |
| 627 | # for markup in higher: |
| 628 | <li>${markup}</li> |
| 629 | # endfor |
| 630 | </ul> |
| 631 | </div> |
| 632 | # endif |
| 633 | |
| 634 | }}} |
| 635 | }}} |
| 636 | |----------------------------------------------------------------------------- |
| 637 | |||| Here's the first use of the `for` statement. Straightforward. || |
| 638 | |----------------------------------------------------------------------------- |
| 639 | {{{#!td |
| 640 | {{{#!html+genshi |
| 641 | <div class="wikipage searchable" py:if="not page.exists and related"> |
| 642 | <p>The following pages have a name similar to this page, |
| 643 | and may be related:</p> |
| 644 | <ul> |
| 645 | <li py:for="markup in related">${markup}</li> |
| 646 | </ul> |
| 647 | </div> |
| 648 | }}} |
| 649 | }}} |
| 650 | {{{#!td |
| 651 | {{{#!html+jinja |
| 652 | # if not page.exists and related: |
| 653 | <div class="wikipage searchable"> |
| 654 | <p>${_("The following pages have a name similar to this page, and may be related:")}</p> |
| 655 | <ul> |
| 656 | # for markup in related: |
| 657 | <li>${markup}</li> |
| 658 | # endif |
| 659 | </ul> |
| 660 | </div> |
| 661 | # endif |
| 662 | }}} |
| 663 | }}} |
| 664 | |----------------------------------------------------------------------------- |
| 665 | |||| || |
| 666 | |----------------------------------------------------------------------------- |
| 667 | {{{#!td |
| 668 | {{{#!html+genshi |
| 669 | </div> |
| 670 | </body> |
| 671 | </html> |
| 672 | }}} |
| 673 | }}} |
| 674 | {{{#!td |
| 675 | {{{#!html+jinja |
| 676 | </div> |
| 677 | |
| 678 | ${ super() } |
| 679 | |
| 680 | # endblock content |
| 681 | </body> |
| 682 | </html> |
| 683 | }}} |
| 684 | }}} |
| 685 | |----------------------------------------------------------------------------- |
| 686 | |||| Once we're done with the `<div id="content">`, we also call `${ super() }` to re-insert the parent content of the ''content'' block, i.e. the altlinks div and the late_links/late_scripts logic. || |
| 687 | |----------------------------------------------------------------------------- |