Edgewall Software

Changes between Version 13 and Version 14 of GenshiTutorial


Ignore:
Timestamp:
Aug 29, 2007, 2:30:30 PM (17 years ago)
Author:
cmlenz
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • GenshiTutorial

    v13 v14  
    119119  </head>
    120120  <body>
    121     <h1>$title</h1>
     121    <div id="header">
     122      <h1>$title</h1>
     123    </div>
     124
    122125    <p>Welcome!</p>
     126
     127    <div id="footer">
     128      <hr />
     129      <p class="legalese">© 2007 Edgewall Software</p>
     130    </div>
    123131  </body>
    124132</html>
     
    161169  </head>
    162170  <body>
    163     <h1>Geddit</h1>
     171    <div id="header">
     172      <h1>Geddit</h1>
     173    </div>
     174
    164175    <p>Welcome!</p>
     176
     177    <div id="footer">
     178      <hr />
     179      <p class="legalese">© 2007 Edgewall Software</p>
     180    </div>
    165181  </body>
    166182</html>
     
    270286  </head>
    271287  <body>
    272     <h1>Geddit</h1>
     288    <div id="header">
     289      <h1>Geddit</h1>
     290    </div>
    273291
    274292    <p><a href="/submit/">Submit new link</a></p>
     
    282300    </ol>
    283301
     302    <div id="footer">
     303      <hr />
     304      <p class="legalese">© 2007 Edgewall Software</p>
     305    </div>
    284306  </body>
    285307</html>
     
    323345  </head>
    324346  <body>
    325     <h1>Geddit</h1>
     347    <div id="header">
     348      <h1>Geddit</h1>
     349    </div>
    326350
    327351    <h2>Submit new link</h2>
     
    344368    </form>
    345369
     370    <div id="footer">
     371      <hr />
     372      <p class="legalese">© 2007 Edgewall Software</p>
     373    </div>
    346374  </body>
    347375</html>
     
    402430  </head>
    403431  <body>
    404     <h1>Geddit</h1>
     432    <div id="header">
     433      <h1>Geddit</h1>
     434    </div>
    405435
    406436    <h2>Submit new link</h2>
     
    432462    </form>
    433463
     464    <div id="footer">
     465      <hr />
     466      <p class="legalese">© 2007 Edgewall Software</p>
     467    </div>
    434468  </body>
    435469</html>
     
    547581
    548582There's still some duplication of code in the decorators: the need to specify the serialization method and the doctype over and over again is suboptimal, and should ideally be made configurable in a central location.
     583
     584== Adding a Layout Template ==
     585
     586But there's also duplication in the template files themselves: each template has to redefine the complete header and footer, and any other “decoration” markup that we may want to apply to the complete site. Now, we could simply put those commonly used markup snippets into separate HTML files and [wiki:Documentation/xml-templates.html#includes include] them in the templates where they are needed. But Genshi provides a more elegant way to apply a common structure to different templates: [wiki:Documentation/xml-templates.html#match-templates match templates].
     587
     588Most template languages provide an inheritance mechanism to allow different templates to share some kind of common structure, such as a common header, navigation, and footer. Using this mechanism, you create a “master template” in which you declare slots that “derived templates” can fill in. The problem with this approach is that it is fairly rigid: the master needs to now which content the templates will produce, and what kind of slots need to be provided for them to stuff their content in. And derived templates need to know exactly how the master  Also, a derived template is itself not a well-formed or even valid HTML file, and can not be easily previewed or edited in a WYSIWYG authoring tool.
     589
     590Match templates in Genshi turn this up side down. They are conceptually similar to running an XSLT transformation over your template output: you create rules that match elements in the template output stream based on XPath patterns. Whenever there is a match, the matched content is replaced by what the match template produces. This sounds complicated in theory, but is fairly intuitive in practice, so let's look at a concrete example.
     591
     592Let's create a layout template first: in the `geddit/templates/` directory, add a file named `layout.html`, with the following content:
     593
     594{{{
     595#!genshi
     596<html xmlns="http://www.w3.org/1999/xhtml"
     597      xmlns:py="http://genshi.edgewall.org/">
     598
     599  <py:match path="head" once="true">
     600    <head py:attrs="select('@*')">
     601      <title py:with="title = list(select('title/text()'))">
     602        <py:if test="title">${title} –</py:if> geddit
     603      </title>
     604      <link rel="stylesheet" href="/media/layout.css" type="text/css" />
     605      ${select('*[local-name()!="title"]')}
     606    </head>
     607  </py:match>
     608
     609  <py:match path="body" once="true">
     610    <body py:attrs="select('@*')"><div id="wrap">
     611      <div id="header">
     612        <h1>geddit</h1>
     613      </div>
     614      ${select('*|text()')}
     615      <div id="footer">
     616        <hr />
     617        <p class="legalese">© 2007 Edgewall Software</p>
     618      </div>
     619    </div></body>
     620  </py:match>
     621
     622</html>
     623}}}