Thursday, March 27, 2008

Genshi in Nevow, Revisited

About a year ago, I blogged about using Genshi in Nevow. It was purely an exercise in curiosity on my part: I wanted to know how flexible Nevow's template parsing was. Could I just drop something else in there that was completely different? The answer was yes and no :-)

The "no" part of that was discovered by a kind reader, Karl Bartel, who found that the Genshi templates in Nevow were one-time wonders: after the first render, data was not refreshed. I didn't have time to take a look at why, since Zenoss was occupying so much of my time then. Now that I'm rocking out at Divmod, this sort of thing is more or less my business now :-) What's more, a friend recently made a deeply heart-felt plea to get Genshi working on Nevow, so I took another look tonight.

Here's the "yes" part of that answer :-) This only represents about an hour or so of work, so this hasn't been tested very thoroughly, but there's a trivial way to get last year's old, static code working such that Genshi templates are dynamically rendered in Nevow. Here's what I did to make it work:
  • preserve the original template data in a temp variable
  • reassign to self.template after Nevow's load() method has been called
  • clean Nevow's template cache
That's it :-)

If you want a single template to be able to be processed by both Nevow's templating machinery as well as Genshi's, you're going to have to make some sacrifices in efficiency. However, if you want a pure-Genshi solution for Nevow, you should be able to use this code to get something up in no time.

In addition to the bullet points above, I also did the following:
  • added some "method filters" so that Nevow stuff didn't get called by the Genshi loader
  • checked to see if the python attributes available to the Genshi templates were callable and if so, called them
As usual, leave a comment if you run across any problems.

Technorati Tags: , , , , , , ,

6 comments:

Karl Bartel said...

It's great to get a follow-up on this issue. For people who just want genshi on top of twisted, pylons running on web2 is also quite a nice solution. But that's far less twisty (or whatever the adjective for twisted is), of course.

Duncan McGreggor said...

Hey Karl, I was happy to finally be able to address this... that you are appreciative after a year's silence is a credit to your patience :-)

Twisty's a good adjective for this. For the scary stuff, maybe "twistifying" would be appropriate; "twisterific" for the good stuff; "twisterious" for the impenetrable and stupefying ;-)

It'd' be better if this solution handled deferreds, but it doesn't. If you have any methods that could run for a few seconds, it'd be better to use nevow:render so you didn't block. The example code does allow you to use both in the same template. If there's a need to support deferreds n the future, I'll be back with more ;-)

Tim Parkin said...

We took a look at this recently as we were deciding how to approach a new project. We came to the conclusion that the only thing stopping using Genshi in a way that worked with the reactor (rather than simply blocking) was to change the template streaming method to use a Push rendering (so we could create a potential deferred around each element of the template streaming process). We didn't get much further than a sort of proof of concept but if you are happy to patch the main output.py and change them from generators to push style calls, the rest should be 'straightforward'. I'm presuming this is the sort of thing you mention in the last comment...

Of course I may be talking complete *rs* and have it utterly wrong :-)

Duncan McGreggor said...

Tim,

Synchronicity at work! I was just thinking about this during the drive home two days ago, and what would be needed to implement it. What you have outlined is exactly what I had in mind, but the code was all mental: no prototyping whatsoever.

I would love to see what you guys have done with this. In fact, here's what I'll do: create a txGenshi project on Launchpad where I'll push my tutorial code, arrange it into an installable package, and offer it for general consumption. If you would like, I'll add you (and your team members, if they are so inclined). Feel free to submit a patch or push your code as-is to a branch, etc., and I'll integrate your changes. Maybe we can get this to a production-level Twisted/Nevow add-on with just a little bit of work :-)

Duncan McGreggor said...

Here's the project page on Launchpad:
http://launchpad.net/txgenshi.

Unknown said...

I am intensely curious about this. Did the deferred support that Tim described ever manifest in txGenshi?