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
-~----------~----~----~----~------~----~------~--~---