[PW-dev] Widget design
Status: Alpha
Brought to you by:
spadkins
|
From: James G S. <JG...@TA...> - 2001-06-11 14:54:11
|
The Internet is being a bit flaky right now with all the water in Houston.
TAMU is routing through Austin for now, so we can get email there. My ISP at
home is a different matter -- two of the connections that still need to be
checked by the phone co. are underwater at the moment in Houston.
Over the weekend I threw together a Widget library (there had been some
mention that we should do an implementation based on some of our ideas and see
what happens...) to see how some things might work out. As soon as I get my
machine at home on the network I'll make it available for people to look at.
I use render() here, but it really doesn't enter the picture since "" is
overloaded.
The basic classes (actual documentation is written for most of them):
Widget::Controller -- makes widgets and manages which environment is being used
Widget::Base -- base class for widgets - handles rendering/displaying and
other basic functions
Widget::Array -- an array of widgets - rendering the array renders all the
component widgets
Widget::Form -- derived from Widget::Array - provides a wrapper for forms
Widget::Selector -- basic single- or multi- selection
Widget::Selector::Month -- offers a single- or multi- selection for months
with validation
Widget::Date -- derived from Widget::Array - provides a set of selections for
selecting a date
Widget::Text -- static text widget with hooks for translation
Widget::State -- a widget (derived from Widget::Base) for handling state -
rendering this widget saves state in an appropriate manner
Widget::Dictionary -- base abstract class for defining a translation mechanism
Still need to write: Widget::Selector::{Day,Year}.
Basic features:
Rendering is either done with a <class>->render_<env> method
(Widget::Selector -> render_html, for example) or with <class>::<env>->render
method (Widget::Selector::HTML -> render, for example). <class>::<env> is a
lot easier to do than trying to put <env> in the middle of the class name.
AUTOLOAD is used to handle widget attributes. This allows for default
values to come from the state object, if one is present, without additional
code in the actual widget (handled in Widget::Base). Only attributes
requiring special handling and/or validation need explicit code.
String escaping is handled similar to rendering. The widget need not know
which environment it is in in order to escape a string correctly. This allows
for greater reuse of rendering code if two environments are very similar.
The state object handles saving state. If it's by putting a lot of hidden
fields in a form, then so be it. It might also be through a session with only
a session id being put in a form somewhere. It's up to the state object to
figure all that out -- it's the state of the script. This takes away the
burden of saving values from the widgets.
An example:
my $controller = new Widget::Controller;
$form = $controller -> widget("Form");
# get the reference to the tied array
$array = $form -> ARRAY;
@{$array} = (
"Some text without translation.<br>",
$controller -> widget("Text", (
value => "Text with translation."
)
),
"<br>",
$controller -> widget("Selector", (
name => "entree",
value => "a",
values => (
a => "apple",
b => "banana",
c => "calamari"
),
)
)
);
print $form;
__END__
Results:
<form action="/scriptname" method="POST">
Some text without translation<br>
Text with translation
<br>
<select name="entree">
<option value="a" SELECTED>apple</option>
<option value="b">banana</option>
<option value="c">clamari</option>
</select>
</form>
--
James Smith <JG...@TA...>, 979-862-3725
Texas A&M CIS Operating Systems Group, Unix
|