[Twisted-web] Re: Good ROM tool ?

Andrea Arcangeli andrea at cpushare.com
Wed Jan 18 09:25:38 MST 2006

On Wed, Jan 18, 2006 at 03:25:03AM -0500, Paul G wrote:
> ah, this appears to be a perfectly valid difference of opinion then. i 
> certainly find that it is reasonable (and expedient) to have presentation 
> logic in a template - cheetah isn't designer friendly enough to let a 
> designer loose on it, but i could definitely get a php monkey to update the 
> template instead of having a dev fudge with it. you seem to want any sort 
> of code out of there, which is a perfectly reasonable preference as well.

I can make an example, to render the CPUShare book I had to write this
code (thanks a lot to Valentino for the help, or I wouldn't even get
this far by myself):

	def render_book_composite(self, ctx, data):
		ptrn_bid = inevow.IQ(ctx).patternGenerator('book_sequence_bid')
		ptrn_ask = inevow.IQ(ctx).patternGenerator('book_sequence_ask')
		return ctx.tag[[ tags.tr(_class="book_outside")
				 [tags.td(_class="book_outside")[ptrn_bid(data=(x[0], x[1], x[2]))],
				  tags.td(_class="book_outside")[ptrn_ask(data=(x[0], x[3], x[4]))]]
				 for x in data ]]
	def render_book_sequence(self, ctx, data): 
		'This is the same as "sequence" but uses data[1] instead of data'
		tag = ctx.tag
		headers = tag.allPatterns('header')
		pattern = tag.patternGenerator('item')
		divider = tag.patternGenerator('divider', default=tags.invisible)
		content = [(pattern(data=element), divider(data=element)) for element in data[2]]
		if not content:
			content = tag.allPatterns('empty')
			## No divider after the last thing.
			content[-1] = content[-1][0]
		footers = tag.allPatterns('footer')

		return tag.clear()[ headers, content, footers ]
	def render_book_header(self, ctx, data):
		currency = data[0]
		nr_orders = data[1]
		ctx.fillSlots('currency', currency)
		nr_orders_str = '%d Order' % nr_orders
		if nr_orders != 1:
			nr_orders_str += 's'
		if nr_orders > BOOK_SIZE:
			nr_orders_str += ' (%d not shown)' % (nr_orders-BOOK_SIZE)
		ctx.fillSlots('nr_orders', nr_orders_str)
		return ctx.tag

If you find the above readable after 1 day, then it means you've a very
good memory and you only work on Nevow, I work on a moltitude of
different projects so there's no way I can know exactly what the
patternGenerator does or other subtle details with allPatterns,
inevow.IQ etc...  Plus the code renders slow (no surprise given all
those inevow.* and tags.pattern*).

As soon as I rewrite the whole thing with Cheetah it'll be like this!!

#for $currency in $currencies
#for $entry in $currency
#end for
#end for

It's obvious what is an order of magnitude more readable... There's no
chance I may not be able to understand the above, with Cheetah one
doesn't need to be a nevow hacker to render two nested tables.

As said yesterday it's a breath of fresh air being able to get full
flexibility with full python control mixed with html, without having to
call into obscure things like nevow.IQ. If you prefer the nevow version
of rendering nested tables, I think you must be a nevow developer, no
mere mortal out there could ever prefer the nevow version if compared to
the Cheetah version.

Also note, I'm recompiling the templates every time, the same way nevow
parses xml every time. There's also the option to precompile them to get
even high perf, but since I can't measure any slowdown in the rendering
anymore (it's already a lot faster than nevow), there's no point for me
to precompile the templates right now.

The most painful thing of porting CPUShare to web2+Cheetah will be the
authentication with secure cookie... I still don't know if others are
working to create a guard on web2.

On the long term techning Cheetah how to handle a deferred would be

BTW, twisted.web2 is working like a charm on klive.cpushare.com, keep up
the great work Twisted developers! ;)

More information about the Twisted-web mailing list