Edgewall Software
Home
Trac
Trac Hacks
Genshi
Babel
Bitten
Home
Download
Documentation
Mailing Lists
License
FAQ
Search:
Login
Preferences
Help/Guide
About Trac
Wiki
Timeline
Roadmap
Browse Source
View Tickets
New Ticket
Search
Context Navigation
-1
Start Page
Index
History
Editing TracDev/ApiChanges/0.11
Adjust edit area height:
8
12
16
20
24
28
32
36
40
Edit side-by-side
[[PageOutline(2-4)]] = TracDev/ApiChanges/0.11 = '''Note: Development of Trac [milestone:0.11] has not yet "officially" started. However, a good deal of work has already begun on the branches, and the information in this page will mostly be about what is quasi-certain to go in 0.11 at the time of writing. Nevertheless, you should have in mind that the information in this page corresponds to a ''work in progress''.''' == Migrating away from Clearsilver == ClearSilver has proven a bit uncomfortable to work with, and search for better alternatives were done a few months ago. The [http://kid-templating.org/ Kid] templating language was unanimously found appealing, to the point cmlenz did a porting of Trac to Kid, during the DrProject fork. This in turn was found painful, and prompted Christopher to start his own, enhanced, version of Kid currently maturing as [http://genshi.edgewall.org/ Genshi]. Migrating away from ClearSilver to use Genshi is scheduled for early [milestone:0.11], and is mostly complete in the source:sandbox/genshi branch at this point (r3728). The following documentation is by no means a replacement for the excellent documentation you'll find in the Genshi site. You should go there for a more in-depth understanding of how Genshi actually works and should be used. Here we'll focus on the differences with Clearsilver. For migrating your own templates, a good way to start is to learn by example. Compare the Clearsilver templates found in source:trunk/templates and their corresponding Genshi ones in source:sandbox/genshi/templates. Then, in the same way, compare the various web_ui.py controllers you'll find in both branches. === Changes in the template syntax === Most of the time, the porting is a straightforward operation. ==== expand a variable ==== - Clearsilver [[xml(<b><?cs var:the_variable ?></b>)]] - Genshi [[xml(<b>$the_variable</b>)]] ==== expand a simple computation ==== - Clearsilver [[xml(<b><?cs var:the_variable+1 ?></b>)]] - Genshi [[xml(<b>${the_variable+1}</b>)]] ==== include another template ==== - Clearsilver [[xml(<?cs include:the_file.cs ?>)]] - Genshi [[xml(<xi:include href="the_file.html"><xi:fallback/></xi:include>)]] ==== simple if...then (no else) ==== - Clearsilver [[xml(<?cs if:flag ?><b>OK</b><?cs /if ?>)]] - Genshi [[xml(<py:if test="flag"><b>OK</b>)]] or simply [[xml(<b py:if="flag"><b>OK</b>)]] ==== if...then...else ==== - Clearsilver {{{ #!xml <?cs if:flag ?> <b>OK</b> <?cs else ?> <i>!!!</i> <?cs /if ?> }}} - Genshi {{{ #!xml <py:choose test="flag"> <py:when test="True"> <b>OK</b> </py:when> <py:otherwise> <i>!!!</i> </py:otherwise> </py:choose> }}} or simply: {{{ #!xml <py:choose> <b py:when="flag">OK</b> <i py:otherwise="">!!!</i> </py:choose> }}} The <py:choose>/<py:when>/<py:otherwise> is a bit heavy-weight for a simple if/else, but on the other hand, the construct is more general (think switch/case, or the equivalent choose/when/otherwise in XSLT). ==== iterate over a collection ==== - Clearsilver {{{ #!xml <ul><?cs each:element = list ?> <li><?cs var:element ?></li><?cs /each ?> </ul> }}} - Genshi {{{ #!xml <ul> <py:for each="element in list"> <li>$element</li> </py:for> </ul> }}} or simply: {{{ #!xml <ul> <li py:for="element in list">$element</li> </ul> }}} Let's take a full-contained example from the Trac source, the simple index.cs / index.html templates. [source:trunk/templates/index.cs@3725 index.cs]: {{{ #!xml <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"> <head><title>Available Projects</title></head> <body><h1>Available Projects</h1><ul><?cs each:project = projects ?><li><?cs if:project.href ?> <a href="<?cs var:project.href ?>" title="<?cs var:project.description ?>"> <?cs var:project.name ?></a><?cs else ?> <small><?cs var:project.name ?>: <em>Error</em> <br /> (<?cs var:project.description ?>)</small><?cs /if ?> </li><?cs /each ?></ul></body> </html> }}} [source:sandbox/genshi/templates/index.html@3728 index.html]: {{{ #!xml <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:py="http://genshi.edgewall.org/" xmlns:xi="http://www.w3.org/2001/XInclude"> <head><title>Available Projects</title></head> <body> <h1>Available Projects</h1> <ul> <li py:for="project in projects" py:choose=""> <a py:when="project.href" href="$project.href" title="$project.description"> $project.name</a> <py:otherwise> <small>$project.name: <em>Error</em> <br /> ($project.description)</small> </py:otherwise> </li> </ul> </body> </html> }}} Some remarks: - Note the possible use of multiple genshi attributes in the same element (in the above, the <li> element has a py:for and a py:choose attributes). - When there's only one element to output conditionally, one should use a genshi attribute (the py:for=project in projets" and the py:when="project.href" in the above). Otherwise, one should use a genshi element (here, the <py:otherwise>). - In this small example, there's no common Trac layout used (as the index is a bit special). For how a "normal" template looks like, see for example [source:sandbox/genshi/templates/diff_form.html diff_form.html], another small example. Note that a Genshi template can usually be rendered directly to have a taste of how it will look like: ---- {{{ #!html <h1>Available Projects</h1> <ul> <li py:for="project in projects" py:choose=""> <a py:when="project.href" href="$project.href" title="$project.description"> $project.name</a> <py:otherwise> <small>$project.name: <em>Error</em> <br /> ($project.description)</small> </py:otherwise> </li> </ul> }}} ---- This comes from an important property of Genshi templates: '''they must themselves be well-formed XML documents'''. That was not a constraint in Clearsilver, and sometimes the logic in those templates took "advantage" of that, e.g. by conditionally inserting end/start pairs of tags. Such templates are the hardest to port, because you actually have to think a bit... See for example the [source:sandbox/genshi/templates/query.html query.html] template. Of course, the great benefit of this constraint is that you'll end up quite naturally with well-formed content, which was far from being a trivial achievement using Clearsilver templates. Granted, you could still insert directly some non well-formed `Markup` data in your template, but again, if you use the [http://genshi.edgewall.org/wiki/Documentation/builder.html genshi.builder] ''tag'' facility for this, that's hardly a risk. === Changes in the controllers === ==== Implementing the `IRequestHandler` interface ==== Previously, all the data fed to a template had to be placed inside the `req.hdf` HDF wrapper object. With Genshi, the data for the template is basically a `dict`, which has to be returned by `process_request` at the same time as the template name. Check [source:sandbox/genshi/trac/wiki/web_ui.py trac.wiki.web_ui] for an example. ==== Generating content ==== When one wants to directly render a template, the Chrome component facilities should be used. Check the [source:sandbox/genshi/trac/web/chrome.py@3725#L424 Chrome.load_template] and `render_method` methods. Note however that this API is still rapidly evolving. Usage examples: - Implementing [source:sandbox/genshi/trac/ticket/query.py@3725#L740 Ticket Query] macro (''table'' mode) - Sending [source:sandbox/genshi/trac/notification.py@3725#L99 notification] e-mails
Note:
See
WikiFormatting
and
TracWiki
for help on editing wiki content.
Change information
Your email or username:
E-mail address and name can be saved in the
Preferences
Comment about this change (optional):
Note:
See
TracWiki
for help on using the wiki.