On Nov 10, 2006, at 1:14 PM, Christopher Arndt wrote:

>
> JM schrieb:
>> Wow, thanks for that!!! I understand now that this was way out of my
>> reach. I wonder how the code automagically appears in the page,  
>> passing
>> from the dict to the form via templates... and obviously I will  
>> have to
>> spend many hours of research to figure this out.
>
> Look at the source code of <turbogears>/view/templates/ 
> sidetemplate.kid,
> <turbogears>/controllers.py (_process_output function) and
> <turbogears>/widgets/base.py (Resource, CSSLink, JSLink, JSSuurce  
> classes).
>
> But concerning the passing around of arguments/parameters within  
> widget classes
> and instances, it is still not clear to me how it works exactly,  
> even after
> studying the source intensively.
>
> I would be *very* grateful, if somebody could write up a  
> comprehensive summary
> on how data is passed around within widgets and when to pass  
> additional
> parameters to which method (__init__, update_params, display)!

Widget's parameters (those attributes listed at "params") can be set  
in three ways:

1) When subclassing widgets:

class MyFormField(FormField):
        attrs = {.....}

2) When initializing them:

my_form_field = FormField(attrs={....})

3) When displaying them:

my_form_field.display(attrs={....})

Parameters passed at 3 override those at 2 and 1, params. at 2  
override those at 1....

Once a widget is initialized you *should not* modify it's attributes  
because widget instances are shared among requests and it wouldn't be  
thread-safe. Widgets should store no state whatsoever. To modify a  
widget's behavior on a per-request basis (to display different  
values, send different options to a singleselect etc....) you should  
do it at 3 which doesn't modify the instance's attributes in any way.

When displaying a widget, all args sent to display go through the  
dictionary that update_params modifies and then to the template. It's  
in update_params where all data massaging should take place in order  
to reduce logic at the template to a minimum.

In order to reduce bolier-plate code, all params listed at "params"  
are picked up from the **kw args sent to __init__ and bound to the  
widget instance and then picked up from the instance and sent through  
update_params when displaying. I a param is callable, it will be  
automatically called on each request to provide fresh values.

CompoundWidgets are a little bit trickier: In order to send a "value"  
to inner widgets, you shold send them in nested dicts to display:  
value = dict(foo=dict(a=1)) to send a=1 to the 'foo' inner widget.

To send arguments to inner widget's display you should do something  
similar:

form.display(value, options=dict(foo=[1,2,3]))

To send options=[1,2,3] to the 'foo' inner singleselectfield.

In order for these params/values to flow from containers to children,  
you should use "display_field_for" in the containers template to  
display inner widgets:

<form>
        ${display_field_for('address')}
</form>

I must admit this args-passing to CompountWidgets behaviour is  
somewhat clumsy and it's quite hard to do right (specially if you  
want to use a compundwidget to facade a set of inner widgets:  
SelectShuttle comes to mind). Fortunately this is one of the API  
improvements being worked on in TGWidgets (http://tgwidgets.toscat.net)

Well, I hope this clears some things out, at least a little... :)

Alberto

--~--~---------~--~----~------------~-------~--~----~
 You received this message because you are subscribed to the Google Groups 
"TurboGears" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/turbogears?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to