Dear Quixote people,
i prefer form2 over form under many aspects, but because the widgets graphical
look is "hardcoded" into the Widget base class, it's (almost) impossible to
change it by subclassing: you should subclass all the derived widgets.
In my application forms i desired three columns: the labels, the widgets, the
hints and errors. I couldn't overload Widget.render() because it's inherited by
all the widgets. I solved my problem overloading the form's _render_widgets()
method:
class MyForm(Form):
def _render_widgets(self):
r = TemplateIO(html=True)
for widget in self.widgets:
r += self._render_widget(widget)
return r.getvalue()
thus moving the _render_widget from the widget to the form where i can overload
what i need once for all the widget types.
A solution to keep the widgets rendering code apart from the form code would be
to move all Widget.render* methods (except render_content) into a WidgetRenderer
class and compose each form instance with a WidgetRenderer instance. Anyway i
don't think it would be much useful: the widgets rendering is tightly coupled to
the form rendering (a
needs s...) thus each time Form is
subclassed (to alter its graphical look) also WidgetRenderer probably needs to
be, and you would also need stuff like
class Form:
widget_renderer_class = WidgetRenderer
def __init__(self, ...):
self.widget_renderer = self.widget_renderer_class()
...
class MyForm(Form):
widget_renderer_class = MyWidgetRenderer
...
to link each Form subclass to the proper WidgetRenderer)
A different strategy would be to completely decouple the form logic from the
form rendering and use a FormRenderer to render (and subclass) both the form and
the widgets. But does it worth to have this code split into two classes? (the
form base logic is usually thin and application-dependant, just like the
graphical look...)
Anyway i don't think moving the widgets rendering code into their base class was
a great move. What do you think about that?
Regard
Daniele
|