I am now extensively using Breve as my templating system of choice.
Recently I have been adding in some user login functionality and am
seeking advice on the following:
How to deal with conditional cases involving objects in templates?
Consider the following in a template:
when ('user' in controller.session)
[
controller.session['user'].preferences
]
Where session is a dictionary and user is either a User instance or
None.
Now, because the expression is evaluated fully the template will
generate the error:
AttributeError: 'NoneType' object has no attribute 'preferences' when
User is None.
The solution I am considering is:
* A silent accessor wrapper - e.g.
controller.get('session.user.preferences') that just fails silently on
error
But can anyone suggest a better/cleaner solution?
ta,
Martin
> Consider the following in a template:
> when ('user' in controller.session)
> [
> controller.session['user'].preferences
> ]
>
> Where session is a dictionary and user is either a User instance or
> None.
> Now, because the expression is evaluated fully the template will
> generate the error:
> AttributeError: 'NoneType' object has no attribute 'preferences' when
> User is None.
What I'd *like* to do (but haven't figured out yet) is somehow implement
lazy evaluation for the conditionals in Breve. Another feature that
would help in this case would be a functional equivalent to Python's
exception handling.
Meanwhile, my typical approach to this type of problem is to solve it in
the controller:
def user_preferences ( session ):
try:
return session [ 'user' ].preferences
except KeyError:
return None
register_global ( 'user_preferences', user_preferences )
Then you can simply use this function in your template:
preferences ( controller.session )
Another approach (ugly but I suppose it works in a pinch):
( 'user' in controller.session and controller.session [ 'user' ].preferences ) or None
Regards,
Cliff
html [
body [
(
controller.session['user'].preferences
)
if user in controller.session else
(
"You need to log in first!"
)
]
]
This does lazy evaluation as requested. But it only works in Python
2.5, which may be a problem for you.
With kind regards,
Sven
On Nov 6, 5:47 pm, Martin <martinpengellyphill...@googlemail.com>
wrote:
Sven
On Tue, 2007-11-06 at 08:47 -0800, Martin wrote:
>
The only place I'm aware of in Python 2.4 where lazy evaluation is
available are the "and" and "or" boolean operators. That being the
case, the above can be written as:
'user' in controller.session and (
controller.session['user'].preferences
)
This won't raise an exception as the parenthesized expression is never
evaluated if the condition isn't true.
Of course, in Python 2.5 I suggest using the ternary "if" operator.
Regards,
Cliff
It does evaluate to False, but Breve renders it as an empty string.
Regards,
Cliff
Actually, it appears you are correct. I was basing this idea off of my
usage under TurboGears and Pylons where it turns out the variable used
to determine if someone is logged in is either an empty string or a user
id of some sort, so it works well.
Perhaps I should add a boolean renderer to Breve to support this idea?
I'm not thinking having a boolean render as 'True' or 'False' is going
to be of real use (but perhaps my use-case is too small to say for
sure). Having False render as '' would be of definite utility, although
I'm not sure what True should render as (although in the example above
it wouldn't be rendered at all).
Thoughts?
Cliff
Yet another option would be to simply have a test() function that
performed the equivalent:
def test ( v ):
return v or ''
then you could do
test ( value ) and (
div [ "It's true" ]
)
etc.
Cliff