Tue, 15 May 2007

turbogears kid to genshi

I've started working on an existing turbogears application recently and we're about to do a pretty major update. From what I've read genshi is taking over from where kid left off and so before I go any further with kid I thought it best to migrate the project to genshi before we get into styling the site and so on. I ran into a few little problems with widgets and some syntax changes between the two which I thought I'd outline after piecing together the following from a few different google searches. I made the following change using turbogears 1.0.2.2:

Set turbogears to use genshi in your dev.cfg (or app.cfg):
tg.defaultview = "genshi"


Rename your kid templates from .kid to .html

Modify your template headers should look similar to this:
< !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" />

notice the use of Xinclude instead of py:extends

Modify your master.html file if your using one close to the stock from tutorial:
old: <head py:match="item.tag=='{http://www.w3.org/1999/xhtml}head'" py:attrs="item.items()">

new: <head py:match="head" py:attrs="select('@*')">

old: <meta py:replace="item[:]"/>
new: <meta py:replace="select('*')" />

old: <body py:match="item.tag=='{http://www.w3.org/1999/xhtml}body'" py:attrs="item.items()">
new: <body py:match="body" py:attrs="select('@*')">

old: <div py:replace="[item.text]+item[:]"/>
new: <div py:replace="select('*|text()')" />


If you are using turbogears widgets they will not work with genshi and it seems the best solution is to use ToscaWidgets (check the site for installation instructions). I was able to get them working by simply importing the widgets from the toscawidgets module and using the FilteringSchema class. Other than that widgets work just the same as they did before. Here are the changes in the controller.py file:
from toscawidgets.core import WidgetsList

from toscawidgets.widgets.forms import TextField, HiddenField, SingleSelectField, TableForm, TextArea, RadioButtonList
from formencode.schema import Schema
...
class FilteringSchema(Schema):
filter_extra_fields = True
allow_extra_fields = True

class ProjectorFields(WidgetsList):
test1 = TextField(validator=validators.NotEmpty(), label="Test 1:")
test2 = TextField(validator=validators.NotEmpty(), label="Test 2:")

form = TableForm("testform", validator=FilteringSchema, fields=TestFormFields(), action="testform", submit_text="Submit")



The one last thing I ran into was the use of py:attrs has changed to using a dictionary of values:
old: py:attrs="selected=tg.selector(id == testid)"

new: py:attrs="{'selected': tg.selector(id == testid)}"


posted at: 01:56 | path: /turbogears | permanent link to this entry


Powered by PyBlosxom | RSS 2.0