Table of Contents
TurboGears uses Genshi, an XML-based template engine, as default template engine. Check http://genshi.edgewall.org/wiki/Documentation/0.4.x/index.html for detail.
py:if
py:for
py:content
py:strip
TurboGears help you to facilitate the use of different template engines.
For example, you could handle some of your method with the specific template engine:
@expose(template="genshi:tutorial.templates.welcome")
def index(self):
records = ['iterable', 'items']
return dict(records = records)
If you have a simple template like this:
<body>
${message} <br>
</body>
....
You start the server but met error with it. The error message buffs you that your template has some errors in.
If you are not sure if the error is about syntax or about the arguments passed from the controller, You could isolate the template problem from controllers by directly setting up the return value in the template. such as:
<?python message = “Hello, world!” ?>
In this case you’ll see the template still fail, it because the ‘<br>’ tag is not valid in xhtml. you should use ‘<br/>’ instead.
>>> now.strftime('%Y-%m-%d %H:%M')
'2007-02-27 17:14'
Now it’s time to modify the markup in your templates.
All the templates used by the resources we exposed inherit from a master template called master.html. If every page on your site has common elements like headers, navigation links, and footers, then these pieces belong in master.html. This is also the best place to insert CSS and JavaScript that will be used by every page on your site.
Open tutorial/templates/master.html. There are some pieces of the welcome screen you saw when you first started up the server, as well as some advanced elements I won’t use in this tutorial.
You only need two elements in the <body> of your master template:
<div py:if="tg_flash" class="flash" py:content="tg_flash"></div>
<div py:replace="item[:]"/>
The first element is for messages that you can show on the page after the user has performed some action. The second element is a placeholder for any elements that appear in the body of the template that inherits from this one.
For example, if you were to return dict(tg_flash="Test message.") from a controller, and the only element in that controller’s template <body> is <p>Hello, world!</p>, this is what would be rendered:
<body>
<div class="flash">Test message.</div>
<p>Hello, world!</p>
</body>
Or use the build-in function flash("Test message.") could do the same thing for you.
For help with building your templates using Genshi, see the reference manual:
There are two more things to add to the master template before closing it.
First, add any CSS or JavaScript files you want your pages to load. At the top of the <head> in your master template, add:
<link rel="stylesheet" type="text/css" href="/static/css/style.css"/>
<script type="text/javascript" src="/tg_js/MochiKit.js"></script>
Why should these lines be added to the top? More specifically, they should be added before <meta py:replace="item[:]"/> because this is where any child template’s stylesheets or scripts will be loaded, and those might depend on the master template’s scripts already being loaded.
The second addition to master.html is any page layout markup. You could just going to add links to several sections of your site on every page.
To do this, add the following code to the top of the <body> in master.html:
<h1>My Navigator Bar</h1>
<ul id="nav">
<li><a href="/">Home</a></li>
<li><a href="/about">About</a></li>
<li><a href="/users/">Users</a></li>
</ul>
Save your templates, restart the server, and browse to http://localhost:8080. You should see the three section links at the top of the page and the “Hello, world!” message.
Now you can add functionality to your page templates.
The about method passes an author argument to its template. To reproduce the plaintext string substitution we had before, change the contents of <body> in about.html to the following:
<p>This tutorial was written by ${author}.</p>
Browse to http://localhost:8080/about to ensure that the changes worked.
Recall that on the Users page, we want to print a list of users in the database. Now that we have templates, we should add a link to each user’s to-do lists as well. Change the contents of <body> in users.html to the following:
<h2>Users</h2>
<ol>
<li py:for="user in users">
${user.email} (<a href="${user.id}">View lists</a>)
</li>
</ol>
Now on each user’s page, print each of their lists. Change the contents of <body> in user.html to the following:
<h2>${user.email}'s Lists</h2>
<div py:for="userList in user.lists">
<h3>${userList.title}</h3>
<ol>
<li py:for="item in userList.items">${item.value}</li>
</ol>
</div>
If you added users to the database using the interactive shell, you should be able to browse around to see the output of the above template code. This should give you a good starting point for writing templates with Genshi.