Edgewall Software

Genshi Recipes: Replacing py:extends with Includes

As noted in GenshiVsKid, Genshi does not support the py:extends directive for template reuse.

This page shows how the example from the Kid language specification translates to a functionally equivalent setup in Genshi.

Assume the following base template, stored as base.html:

<html xmlns:py="http://genshi.edgewall.org/" py:strip="">

  <ul py:def="display_errors(errors)">
    <li py:for="error in errors" py:content="error" />
  </ul>

  <strong py:match="b" py:content="select('text()')" />

</html>

And the following template “extending” that base template, stored as page.html:

<html xmlns:py="http://genshi.edgewall.org/"
      xmlns:xi="http://www.w3.org/2001/XInclude">
  <xi:include href="base.html" />
  <head>
    <title>Errors</title>
  </head>
  <body>
    <p>The following <b>errors</b> were found:</p>
    ${display_errors(["Field is required", "Must be phone number.."])}
  </body>
</html>

The “trick” here is that the base template is included at the top of the page template. This results in the template function display_errors() being available to the page template, and the match template being applied to the output generated by the page template. If you write python code to directly run this example, be sure to use the TemplateLoader? class to load page.html. If you use the MarkupTemplate? class, XInclude processing is silently disabled.

When rendered, these will produce the following output:

<html>
  <head>
    <title>Errors</title>
  </head>
  <body>
    <p>The following <strong>errors</strong> were found:</p>
    <ul>
      <li>Field is required</li><li>Must be phone number..</li>
    </ul>
  </body>
</html>

See also: GenshiRecipes/PyLayoutEquivalent, GenshiRecipes, GenshiVsKid, Genshi XML Template Language

Last modified 14 years ago Last modified on Dec 3, 2009, 2:25:01 AM