# Migrating from Genshi

Kajiki uses syntax derived from the syntax of Genshi. In particular, the following directives are supported, with semantics intended to be nearly identical to those of Genshi.

> - `py:def`
> - `py:choose` – renamed `py:with`
> - `py:when` – renamed `py:case`
> - `py:otherwise` – renamed `py:else`
> - `py:for`
> - `py:if`
> - `py:with`
> - `py:replace`
> - `py:content`
> - `py:attrs`
> - `py:strip`
> - `xi:include` – renamed `py:include`

Note that, in particular, `py:match` is not supported. But Kajiki supports the following additional directives:

> - `py:extends` - indicates that this is an extension template. The parent template will be read in and used for layout, with any `py:block` directives in the child template overriding the `py:block` directives defined in the parent.
> - `py:block` - used to name a replaceable ‘slot’ in a parent template, or to specify a slot override in a child template. The `py:block` semantics are modeled after the `{% block %}` semantics of Jinja2.

Generally, migration consists of a few steps that can be simple or quite difficult based on your fondness of the `py:match` directive in Genshi. In simple cases where you have one `master.html` template with a few `py:match` directives that is `xi:included` into all your page templates, the following steps should suffice:

> - Rename tags and attributes as indicated above; e.g. `xi:include` becomes `py:include`.
> - Rewrite your include directives to use Kajiki’s module naming system and relative imports.
> - In a simple case where you have only a few `py:match` directives, all of which are in a `master.html` template that is being included from child templates, I recommend that you rewrite the `master.html` as `layout.html`, defining named `py:block` regions that will be overridden in child templates.
> - In your child templates, remove the `<xi:include href="master.html">` that probably lurks near the top. Then add a `py:extends` directive to the top-level tag (usually `<html>`). The tag the parts of the child template that are intended to override parts of the parent template with the `py:block` directive.

Kajiki also provides some helper functions of Genshi:

- `defined('some_variable')` (which returns True if ‘some_variable’ exists in the template context),
- `value_of('name', default_value)`, and
- `Markup(some_string)` (which marks a string so it won’t be escaped in the output), though Kajiki prefers to call this `literal(some_string)`.

## Example Migration

Suppose you have a couple of Genshi templates, one of which called `master.html` and one of which is `index.html`. (TurboGears developers may recognize these files as slightly modified versions of the default templates deposited in a TG quickstarted project.) The contents of `master.html` are:

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
                          "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml"
          xmlns:py="http://genshi.edgewall.org/"
          xmlns:xi="http://www.w3.org/2001/XInclude"
          py:strip="">
        <xi:include href="header.html" />
        <xi:include href="sidebars.html" />
        <xi:include href="footer.html" />
    <head py:match="head" py:attrs="select('@*')">
        <meta content="text/html; charset=UTF-8" http-equiv="content-type" py:replace="''"/>
        <title py:replace="''">Your title goes here</title>
        <meta py:replace="select('*')"/>
        <link rel="stylesheet" type="text/css" media="screen" href="${tg.url('/css/style.css')}" />
        <link rel="stylesheet" type="text/css" media="screen" href="${tg.url('/css/admin.css')}" />
    </head>

    <body py:match="body" py:attrs="select('@*')">
      ${header()}
      <ul id="mainmenu">
        <li class="first"><a href="${tg.url('/')}" class="${('', 'active')[defined('page') and page=='index']}">Welcome</a></li>
            <li><a href="${tg.url('/about')}" class="${('', 'active')[defined('page') and page=='about']}">About</a></li>
            <li py:if="tg.auth_stack_enabled"><a href="${tg.url('/auth')}" class="${('', 'active')[defined('page') and page=='auth']}">Authentication</a></li>
            <li><a href="${tg.url('/environ')}" class="${('', 'active')[defined('page') and page=='environ']}">WSGI Environment</a></li>
            <li><a href="http://groups.google.com/group/turbogears">Contact</a></li>
        <span py:if="tg.auth_stack_enabled" py:strip="True">
            <li py:if="not request.identity" id="login" class="loginlogout"><a href="${tg.url('/login')}">Login</a></li>
            <li py:if="request.identity" id="login" class="loginlogout"><a href="${tg.url('/logout_handler')}">Logout</a></li>
            <li py:if="request.identity" id="admin" class="loginlogout"><a href="${tg.url('/admin')}">Admin</a></li>
        </span>
      </ul>
      <div id="content">
        <py:if test="defined('page')">
        <div class="currentpage">
         Now Viewing: <span py:replace="page"/>
         </div>
        </py:if>
        <py:with vars="flash=tg.flash_obj.render('flash', use_js=False)">
            <div py:if="flash" py:content="XML(flash)" />
        </py:with>
        <div py:replace="select('*|text()')"/>
        <!-- End of main_content -->
        ${footer()}
      </div>
    </body>
    </html>

Likewise, the contents of `index.html` are as follows:

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
                          "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml"
          xmlns:py="http://genshi.edgewall.org/"
          xmlns:xi="http://www.w3.org/2001/XInclude">

      <xi:include href="master.html" />

    <head>
      <meta content="text/html; charset=UTF-8" http-equiv="content-type" py:replace="''"/>
      <title>Welcome to TurboGears 2.0, standing on the
      shoulders of giants, since 2007</title>
    </head>

    <body>
        ${sidebar_top()}
      <div id="getting_started">
        <h2>Presentation</h2>
        <p>TurboGears 2 is rapid web application development toolkit designed to make your life easier.</p>
        <ol id="getting_started_steps">
          <li class="getting_started">
            <h3>Code your data model</h3>
            <p> Design your data model, Create the database, and Add some bootstrap data.</p>
          </li>
          <li class="getting_started">
            <h3>Design your URL architecture</h3>
            <p> Decide your URLs, Program your controller methods, Design your
                templates, and place some static files (CSS and/or JavaScript). </p>
          </li>
          <li class="getting_started">
            <h3>Distribute your app</h3>
            <p> Test your source, Generate project documents, Build a distribution.</p>
          </li>
        </ol>
      </div>
      <div class="clearingdiv" />
      <div class="notice"> Thank you for choosing TurboGears.
      </div>
    </body>
    </html>

In order to perform our kajiki migration, we begin by creating two empty templates. The first one will replace our `master.html`, and we will call it `layout.html`:

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
                          "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html>
        <py:include href="header" />
        <py:include href="footer" />

        <head>
          <title py:block="title">Your title goes here</title>
          <py:block name="head_content">
            <link rel="stylesheet" type="text/css" media="screen" href="${tg.url('/css/style.css')}" />
            <link rel="stylesheet" type="text/css" media="screen" href="${tg.url('/css/admin.css')}" />
          </py:block>
        </head>

        <body>
          <py:block name="body_header"><h1>My Header</h1></py:block>
          <ul py:block="mainmenu" id="mainmenu">
            <li class="first"><a href="${tg.url('/')}" class="${('', 'active')[defined('page') and page=='index']}">Welcome</a></li>
            <li><a href="${tg.url('/about')}" class="${('', 'active')[defined('page') and page=='about']}">About</a></li>
            <li py:if="tg.auth_stack_enabled"><a href="${tg.url('/auth')}" class="${('', 'active')[defined('page') and page=='auth']}">Authentication</a></li>
            <li><a href="${tg.url('/environ')}" class="${('', 'active')[defined('page') and page=='environ']}">WSGI Environment</a></li>
            <li><a href="http://groups.google.com/group/turbogears">Contact</a></li>
          </ul>
          <div id="content">
            <py:if test="defined('page')">
              <div class="currentpage">
                Now Viewing: <span py:replace="page"/>
              </div>
            </py:if>
            <py:with vars="flash=tg.flash_obj.render('flash', use_js=False)">
              <div py:if="flash" py:content="XML(flash)" />
            </py:with>
            <py:block name="body_text">Your body text goes here</py:block>
            <py:block name="bodyfooter">${footer()}</py:block>
          </div>
        </body>
    </html>

Note the introduction of the `py:block` directive, and the disappearance of the `py:match` directives from `master.html`. `py:block` mimics the behavior of Jinja2 “blocks”, providing a name to a construct in a parent template which can be replaced by the contents of `py:block` -named constructs in child templates. For instance, the “title” slot in `layout.html`:

    1

          <title py:block="title">Your title goes here</title>

can be replaced by a similarly-named slot in the child document `index_kajiki.html`:

    1
    2
    3
    4
    5
    6
    7

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
                          "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html py:extends="layout">
        <py:include href="sidebars" />

        <title py:block="title">Welcome to TurboGears 2.0, standing on the
          shoulders of giants, since 2007</title>

We also provide a way of including the contents of the parent template’s slot in a child template’s slot using `${parent_block()}`. The following slot in `layout.html`:

    1

          <py:block name="body_header"><h1>My Header</h1></py:block>

can be replaced in `include/index_kajiki.html` with:

    1
    2
    3
    4

        <py:block name="body_header">
          ${parent_block()}
          <h1>Some extra header data</h1>
        </py:block>

Yielding the following html once rendered:

    1
    2

     <h1>My Header</h1>
     <h1>Some extra header data</h1>