Edgewall Software

Changes between Version 9 and Version 10 of TracDev/Proposals/Jinja


Ignore:
Timestamp:
Feb 7, 2016, 11:53:21 PM (8 years ago)
Author:
Christian Boos
Comment:

restructure the #Genshitheme section, also shows what happens with the <title>

Legend:

Unmodified
Added
Removed
Modified
  • TracDev/Proposals/Jinja

    v9 v10  
    6262=== Themeing
    6363==== Genshi theme
    64 I've never really tried the TH:ThemeEnginePlugin plugin, or alternatives, so I can't be sure if I got it right, but from what I can see in Trac's code base itself, the idea with Genshi-based themeing (and page architecture in general) was the following:
     64I've never really tried the TH:ThemeEnginePlugin plugin, or alternatives, so I can't be sure if I got it right, but from what I can see in Trac's code base itself, the idea with Genshi-based themeing (and page architecture in general) was to have a dynamically loaded "theme" template page that would primarily be in charge of the main structure of all HTML pages.
    6565
    6666Let's take the example of a simple "end user" page, the search.html page.
     
    6868 - search.html includes
    6969   - layout.html, which includes
    70      - theme.html (as this is our default theme page)
    71 
    72 In more details, this is what happens with
    73 [source:tags/trac-1.0.9/trac/search/templates/search.html search.html]:
    74  - it starts by including the layout.html page:
    75    {{{#!xml
    76    <xi:include href="layout.html" />
    77    }}}
    78    - the [source:tags/trac-1.0.9/trac/templates/layout.html  layout.html] page:
    79      - defines `<py:match>` filters for transforming the content provided
    80        in `<head>` and `<body>` elements
    81      - then **dynamically** includes some "theme" page:
    82        {{{#!xml
    83        <xi:include href="$chrome.theme"><xi:fallback /></xi:include>
    84        }}}
    85        - by default, this will be our
    86          [source:tags/trac-1.0.9/trac/templates/theme.html theme.html]:
    87          - it defines a `<py:match>` filter on the `<body>` tag
    88            (the one that will be produced by the previously applied filters,
    89            i.e. the output of the `<py:match>` from the layout.html)
    90            and it will **embed** that element into some predefined HTML
    91            structure (inside a div element), and
    92            it will prepend and append other divs around it:
    93            {{{#!xml
    94            <body>
    95              <div id="banner">
    96                ...
    97              </div>
    98              <div id="main">
    99                ...
    100                (here goes the content of the <body></body> produced by layout.html)
    101              </div>
    102              <div id="footer">
    103                ...
    104              </div>
    105            </body>
    106            }}}
    107  - the search.html page then provide the `<head>` and `<body>` elements
    108    specific to that search page; these elements will be processed by the
    109    `<py:match>`es filters defined so far in the order in which
    110    they have been included (so first the ones defined in layout.html,
    111    then the one for the `body` defined in theme.html)
    112 
    113 The scheme can be extended with more intermediate levels,
    114 for example what we have for the admin panels, e.g the
    115 [source:tags/trac-1.0.9/trac/admin/templates/admin_basics.html admin_basics.html] panel:
    116   - it starts by including the admin.html page:
    117     {{{#!xml
    118     <xi:include href="admin.html" />
    119     }}}
    120     - the [source:tags/trac-1.0.9/trac/admin/templates/admin.html admin.html] page
    121       - defines `<py:match>` filters for `<head>` and `<body>`,
    122         which in turn will produce modified `<head>` and `<body>` elements
    123       - it then includes the layout.html page (see above)
    124   - then it provides the `<head>` and `<body>` elements specific to that panel
    125     (they will be process by the `<py:match>` filters in the order seen, so
    126     first those from admin.html, then those from layout.html and finally those
    127     from the dynamically included theme page
     70     - $chrome.theme (typically "theme.html", the default theme page that ships with Trac)
     71
     72In more details, the
     73[source:tags/trac-1.0.9/trac/search/templates/search.html search.html] is structured like this:
     74{{{#!html+genshi
     75<html>
     76  <xi:include href="layout.html" />
     77  <head>
     78    <title>Search</title>
     79    ...
     80  </head>
     81  <body>
     82    <div id="content" class="search">
     83      <h1>Search</h1>
     84      ...
     85    </div>
     86  </body>
     87</html>
     88}}}
     89 - it starts by including the layout.html page (`<xi:include href="layout.html" />`)
     90 - it then provides the `<head>` and `<body>` elements specific to that search page;
     91   these elements will be processed by the `<py:match>`es filters defined so far,
     92   in the order in which they have been included
     93
     94The [source:tags/trac-1.0.9/trac/templates/layout.html  layout.html]
     95page in turn is structure like this:
     96{{{#!html+genshi
     97<html>
     98  <py:match path="head"><head>
     99    <title py:with="title = list(select('title/text()'))">
     100      ${title} – ${project.name or 'Trac'}  <!-- e.g.  "Search - Trac" -->
     101    </title>
     102    ...
     103    ${select("*[local-name() != 'title']|text()|comment()")}
     104  </head></py:match>
     105
     106  <py:match path="body"><body>
     107
     108    ${select('*|text()|comment()')}         <!-- e.g. "<h1>Search</h1>"
     109                                                       ... -->
     110    ...
     111    <div id="altlinks" py:if="'alternate' in chrome.links">
     112      ...
     113    </div>
     114  </body></py:match>
     115
     116  <xi:include href="$chrome.theme"><xi:fallback /></xi:include>
     117</html>     
     118}}}
     119 - it defines `<py:match>` filters for transforming the content provided
     120   in `<head>` and `<body>` elements in the including template (search.html);
     121   the head filter adds some content to the `<title>` and prepends some content
     122   in the <head>, the body filter appends some content in  the <body>
     123 - it then **dynamically** includes some "theme" page, `$chrome.theme`
     124
     125By default, this theme page will be our
     126[source:tags/trac-1.0.9/trac/templates/theme.html theme.html] template:
     127{{{#!xml
     128<html>
     129  <body>
     130    <div id="banner">
     131      ...
     132    </div>
     133    <div id="main">
     134      ...
     135      ${select('*|text()|comment()')}       <!-- e.g. "<h1>Search</h1>"
     136                                                       ...
     137                                                       <div id="altlinks" ... </div> -->
     138    </div>
     139    <div id="footer">
     140      ...
     141    </div>
     142  </body>
     143</html>
     144}}}
     145 - it defines a `<py:match>` filter on the `<body>` tag
     146   (the one that will be produced by the previously applied filters,
     147   i.e. the output of the `<py:match>` from the layout.html)
     148   and it will **embed** that element into some predefined HTML
     149   structure (inside a div element), and
     150   it will prepend and append other divs around it:
     151
     152So this dynamic theme template has the last say, and can theoretically re-order
     153the content generated by the previous filters any way it likes, although in practice
     154it simply inserts the body content produced by previous steps inside a predefined
     155structure (the `<div id="main">`).
     156
     157An example of another theme page: [https://github.com/chevah/trac-bootstrap-theme/blob/master/templates/theme.html trac-bootstrap-theme's theme.html].
     158
     159
     160
     161Note that this scheme can be extended to having more intermediate levels,
     162for example what we have for the admin panels.
     163
     164One such panel is
     165[source:tags/trac-1.0.9/trac/admin/templates/admin_basics.html admin_basics.html]:
     166{{{#!html+genshi
     167<html>
     168  <xi:include href="admin.html" />
     169  <head>
     170    <title>Basics</title>
     171  </head>
     172
     173  <body>
     174    ...
     175  </body>
     176</html>
     177}}}
     178 - it starts by including the admin.html page
     179 - then it provides the `<head>` and `<body>` elements specific to that panel
     180   
     181The [source:tags/trac-1.0.9/trac/admin/templates/admin.html admin.html] page
     182is similar to the search.html page in that it includes the layout.html, but
     183it also first contains its own `<py:match>` templates to organize the content of
     184the admin panel which included it:
     185{{{#!html+genshi
     186<html>
     187  <py:match path="head" once="true"><head>
     188    <title>Administration: ${select('title/text()')}</title>
     189    ${select("*[local-name() != 'title']")}
     190  </head></py:match>
     191
     192  <py:match path="body" once="true" buffer="false"><body>
     193    <div id="content" class="admin">
     194      <h1>Administration</h1>
     195      <div id="tabs">
     196      <div id="tabcontent">
     197        ${select("*|text()")}
     198        <br style="clear: right" />
     199      </div>
     200    </div>
     201
     202  </body></py:match>
     203
     204  <xi:include href="layout.html" />
     205</html>
     206}}}
     207 - defines `<py:match>` filters for `<head>` and `<body>` (of the including panel page),
     208   which in turn will produce modified `<head>` and `<body>` elements
     209 - it then includes the layout.html page (see above)
    128210
    129211Feel free to brush up your Genshi craft by reading ([G:GenshiTutorial#AddingaLayoutTemplate]),
    130212as I just did ;-)
    131213
    132 So this dynamic theme template has the last say, and can theoretically re-order
    133 the content generated by the previous filters any way it likes.
    134 In practice (at least in our default theme.html), it's just a `<py:match once>`
    135 template which appends a footer to the content of the `<body>` element produced
    136 so far.
    137 
    138 An example of another theme page: [https://github.com/chevah/trac-bootstrap-theme/blob/master/templates/theme.html trac-bootstrap-theme's theme.html].
    139214
    140215==== Jinja2 theme
     
    180255           at the place where we want to substitute in the content
    181256           produced by the jlayout.html template:
    182            {{{#!xml (shoud really be jinja+html...)
     257           {{{#!html+jinja
    183258           <body>
    184259             # block body