Edgewall Software

Changes between Version 15 and Version 16 of GenshiTutorial


Ignore:
Timestamp:
Aug 29, 2007, 4:48:31 PM (17 years ago)
Author:
cmlenz
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • GenshiTutorial

    v15 v16  
    595595#!genshi
    596596<html xmlns="http://www.w3.org/1999/xhtml"
    597       xmlns:py="http://genshi.edgewall.org/">
     597      xmlns:py="http://genshi.edgewall.org/" py:strip="">
    598598
    599599  <py:match path="head" once="true">
     
    623623}}}
    624624
    625 '''TODO: explain'''
     625That contains a whole lot of things, so let's break it up into smaller pieces and go through the various aspects to clarify them.
     626
     627 1. '''The Document Element'''
     628
     629 {{{
     630 #!genshi
     631 <html xmlns="http://www.w3.org/1999/xhtml"
     632       xmlns:py="http://genshi.edgewall.org/" py:strip="">
     633 }}}
     634
     635 First, note that the root element of the template is an `<html>` tag. This is needed because markup templates are XML documents, and XML documents require a single root element (we also use it to attach our namespace declarations, but we just as as well do that on the nested `<py:match>` elements). However, because the page templates that include this file will also have `<html>` root elements, we add the `py:strip=""` directive so that this second `<html>` tag doesn't make it through into the output stream.
     636
     637 2. '''Match Template Definition'''
     638
     639 {{{
     640 #!genshi
     641   <py:match path="head" once="true">
     642 }}}
     643
     644 Here we define the first match template. The `path` attribute contains the XPath pattern the specifies which elements this match template should be applied to. In this case, the XPath is very simple: it matches any element with the local name “head”, so it will be applied to the `<head>...</head>` element (whether it's in the XHTML namespace or not). We also add the `once="true"` attribute to tell Genshi that we only expect a single occurrence of the `<head>` element in the stream. Genshi can perform some optimizations based on this information.
     645
     646 3. '''Selecting Matched Content'''
     647
     648 {{{
     649 #!genshi
     650    <head py:attrs="select('@*')">
     651}}}
     652
     653 Inside match templates, you can use the special function `select(path)` to access the element that matched the pattern. Here we use that function in the `py:attrs` directive, which basically translates to “''get all attributes defined on the matched element, and add them to this element''”. So for example if your page template contained `<head id="foo">`, the element produced by this match template would also have the same `id="foo"` attribute.
     654
     655 {{{
     656 #!genshi
     657      <title py:with="title = list(select('title/text()'))">
     658        geddit<py:if test="title">: ${title}</py:if>
     659      </title>
     660 }}}
     661
     662 This is a more complex example for selecting matched content: it fetches the text contained in the `<title>` element of the original `<head>` and prefixes it with the string “geddit: ”. But as page templates may not even contain a `<title>` element, we first check whether it exists, and only add the colon if it does. Thus, if the page has no title of its own, the result will be “geddit”.
     663
     664 {{{
     665 #!genshi
     666      ${select('*[local-name()!="title"]')}
     667 }}}
     668
     669 Finally, this is an example for using a more complex XPath pattern. This `select()` incantation here returns a stream that contains all child elements of the original `<head>`, except for those elements that have the local name “title”. If we didn't add that predicate, the output stream would contain two `<title>` tags, and we don't want that.
     670
     671If you've done a bit of XSLT, match templates should look familiar. Otherwise, you may want to familiarize yourself with the basics of XPath 1—note though that Genshi only implements a subset of the full spec as explained in [wiki:Documentation/xpath.html Using XPath in Genshi]. And just play around with match templates; at the core, the concept is actually very simple and consistent.
    626672
    627673Now we need to update the page templates: they no longer need the header and footer, and we'll have to include the `layout.html` file. For the inclusion, we add the namespace prefix for XInclude, and an `xi:include` element.