The google group is um... slow <wink>, but still, keeping it in the
public is how it stays alive, so I'm cc'ing the list.
> I'm fairly new to Python, but have been writing code for over 20 years,
> most recently using Ruby and a templating DSL called 'Erector.' I was
> looking for a similar DSL approach to templates for Python, and am very
> impressed with Breve. Nice!
>
> My first exercise was to convert a Google App Engine example to Breve. The
> example iterates over a list of objects which are mapped to rows in their
> database engine.
>
> http://code.google.com/appengine/docs/python/gettingstarted/usingdatastore.html
>
> I successfully converted it to the 'list comprehension' form without
> difficulty, but I'd prefer to use the 'tag multiplication' technique.
> Unfortunately this fails, since the list items are objects instead of
> dictionaries.
>
> I found the code in the 'tags' module which implements the multiply
> operator. I think what I want is an alternative to the 'Template'
> class
> which accepts objects _or_ dictionaries and does the right thing.
The Template class is a bit hairy and not really the right place to
start anyway.
While you could force your way through tag multiplication, I think the
right solution looks more like this:
from breve.tags.html import tags as T
from breve.flatten import flatten
# couple of phony classes to test with
class Author (object):
def __init__ (self, nickname):
self._nick = nickname
def nickname (self):
return self._nick
class Greeting (object):
def __init__ (self, nickname, content):
self.author = Author(nickname)
self.content = content
# some phony data for our phony classes
greetings = [
Greeting ('joe', 'hola'),
Greeting ('ed', 'yo'),
Greeting ('bob', 'hello')
]
def greeting_fragment (greeting):
return (
T.b [ greeting.author.nickname () ] if greeting.author else 'An anonymous person wrote:',
T.blockquote [ greeting.content ]
)
print flatten (
T.html [
T.body [
[ greeting_fragment (g) for g in greetings ]
]
]
)
I'm still using a listcomp, but it's very, very simple, so tag
multiplication buys you nothing. I think the key bit here is that you
have to keep in mind is that one of the goals of Breve is to move easily
between template and code, so you can mix template fragments into your
program and pass functions into templates without it feeling unnatural.
If you still want to use tag multiplication, then what you'll want to
look at is not Template, but rather:
http://github.com/cwells/breve/blob/master/breve/tags/__init__.py
There you'll find the __mul__ method of the Tag class which is where
this is implemented. I'm sure you could probably do some magic to
determine if you're getting a list of dicts or a list of objects (and
keep in mind that Python objects are basically implemented as dicts, so
you've got a foot up) and achieve what you're asking for.
That being said, I'm not convinced it's worth the effort, and I suspect
you'll be creating more corner cases than anyone would be comfortable
with (think composite classes).
> If I can get it going, I'll fork it on Github and let you know, if
> that's
> okay with you.
That's fine with me. If your changes are compatible with the overall
goals of Breve then I'd be happy to accept patches.
Regards,
Cliff
> def greeting_fragment (greeting):
> return (
> T.b [ greeting.author.nickname () ] if greeting.author else 'An anonymous person wrote:',
> T.blockquote [ greeting.content ]
> )
>
>
> print flatten (
> T.html [
> T.body [
> [ greeting_fragment (g) for g in greetings ]
> ]
> ]
> )
I should also point out that you can utilize register_global to make
your function available to all your templates without having to pass it
in your variables:
import breve
breve.register_global ('greeting_fragment', greeting_fragment)
see http://breve.twisty-industries.com/documentation#the-breve-api
where it is somewhat tersely documented.
Regards,
Cliff