wiki:WidgetsBrainStorming
Warning: Can't synchronize with repository "(default)" (Unsupported version control system "svn": No module named svn). Look in the Trac log for more information.

Version 3 (modified by michele, 9 years ago) (diff)

corrections

WidgetsBrainStorming

This page aims to collect opinions regarding TurboGears Widgets.

If you don't know TG widgets take a look at  this message from Kevin.

Feel free to add your own opinions and comments to this page.

Using Widgets

Actually to use a widget you need to do something like this:

  1. Create an instance of the widget from your controller
    ...
    age_field = widgets.TextField("age", default=0, validator=validators.Int())
    ...
    
  2. Insert your widget instance inside your template
    ...
    <div py:replace="age_field.insert(age)"/> 
    ...
    

IMHO for the second point we can use Kid py:match attribute to do something like this:

...
<widget name="age_field" value="age" />
...

it shouldn't be to hard if we add to the sitetemplate a definition like this (I have not tested it):

...
<span py:match="item.tag == 'widget'"
  py:replace="getattribute(self, item.get('name'), None).insert(item.get('value'))">
</span>
...

Customizing Widgets Look&Feel

Look&Feel customization is a quite important aspect for widgets. Actually you have two options:

  1. Providing a custom CSS stylesheet
  2. Providing a custom Kid template

Customization should be an easy task and should happen inside our templates (not the controller).

Widgets should use CSS class and selector to make it straigthforward.

Default attributes

During the 0.9 IRC Chat all have agreed that widgets should use namespaced class names.

For example:

<div class="tg_text_field">...</div>

Ability to set common attributes used for widgets

There is a ticket (#106) regarding this. This is an import requirement that will make customization even more easy. Using the syntax I proposed above customization shouldn't be that hard and inside your template you should be able to do the following:

...
<widget name="age_field" value="age" size="30" id="id_age_field"/>
...

But, how can we make customization as easy also for complex widgets that embeds others widgets? For example the Form widget? Any opinion?

Smart Forms Widgets

In my own visions a Form widget should let me do something along these lines (only a pseudo code to show the concept):

@turbogears.expose(template="...")
def edit_contact(self):
    myform = TableForm(widgets=[
                widgets.TextField("name"),
                widgets.TextField("address"),
                widgets.TextField("age", default=0,
                                validator=validators.Int())]) 
    return dict(form=myform)

@turbogears.expose(template="...")
def save(self, myform):
    if not input_form.valid:
        raise cherrypy.HTTPRedirect(...)
    else:
        contact = Contact.byContactId(...)
        contact.name = myform.name
        contact.address = myform.address
        contact.age = myform.age
        turbogears.flash("Changes saved!")
        raise cherrypy.HTTPRedirect(...)

This way you shouldn't need a special has_error variable, or the need to check against cherrypy.request.form_errors and to take values from cherrypy.request.input_values.

We should be able to access values from the form as normal class attributes, python properties should use to_python and from_python FormEncode methods to ensure attributes values are valid and accessible in a transparent way.

See also