perl-widget-developer Mailing List for Perl Widget Library (Page 9)
Status: Alpha
Brought to you by:
spadkins
You can subscribe to this list here.
2001 |
Jan
|
Feb
|
Mar
|
Apr
|
May
(8) |
Jun
(132) |
Jul
(3) |
Aug
(6) |
Sep
|
Oct
(6) |
Nov
|
Dec
|
---|---|---|---|---|---|---|---|---|---|---|---|---|
2002 |
Jan
|
Feb
|
Mar
(1) |
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
2005 |
Jan
|
Feb
(2) |
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
2006 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
(2) |
Nov
|
Dec
(9) |
2007 |
Jan
(2) |
Feb
(2) |
Mar
(1) |
Apr
(1) |
May
|
Jun
|
Jul
|
Aug
(19) |
Sep
(6) |
Oct
(5) |
Nov
(5) |
Dec
(3) |
2008 |
Jan
|
Feb
(7) |
Mar
(34) |
Apr
(13) |
May
(15) |
Jun
(5) |
Jul
(14) |
Aug
(6) |
Sep
(6) |
Oct
(3) |
Nov
(1) |
Dec
|
From: Jay L. <Ja...@La...> - 2001-06-06 15:05:25
|
The purpose? Ah, good question. More variety of configuration options. I expect that I'll want to configure my widgets separate from my code. (At least the types of widgets I'm thinking about) So this gives me the option to configure them elsewhere, save them (freeze), and have my code thaw all the widgets that it cares about. FURTHERMORE, if I want to give others the chance to configure some or all widgets - I can allow them to modify the saved definition and resave it as I deem appropriate. The widget has to know how to freeze and thaw itsself because of course that is implementation dependant to some degree. IE/ Data::Dumper would dump out the hash that holds all of the widget properties - which in itsself is an implementation detail. Jay > At 10:05 AM 6/6/2001 -0400, Jay Lawrence wrote: > >One other thing I really wanna see is thaw/freeze support. Scary? Not > >really. Obviously if you don't wanna thaw and freeze widgets ever this will > >be no skin off your nose - it is optional to use. > > > >I belive that one thing needs to happen in the thaw phase - that is a "use" > >for the widget's class. There is no guarantee that you've "use"d that widget > >class already. > > > > Interesting idea. > What is the purpose of freezing and thawing widgets? > > Stephen > > > |
From: Stephen A. <ste...@of...> - 2001-06-06 15:03:26
|
At 09:53 AM 6/6/2001 -0400, Jay Lawrence wrote: > >Widgets in Template Toolkit - QED > >Here is something that I prototyped on my own system... > - Just to show exactly how simple I'd like the widgets to appear to the >template user ... > >General ideas: > - Create hash of widgets: name => Widget::Object > - Register this with Template::Toolkit somehow > - two places come to mind - in the vars (as I have shown here) > - At Template instantiation > my $tt=Template->new ( { WIDGETS=>$widgetHashRef } ); > - Reference widgets solely by name > - I do find the "wc." - "wc.widget" - a bit redundant but understand >its purpose > - instead we can beef up the _dotop sub of Stash to give us what we >want! > - Trained Stash to look for widgets by name and if found call their >"display" method with any parameters supplied in the template > > >testprg.pl >------------- >use Template; >use Widget::Test; > >my $tt=Template->new( { INCLUDE_PATH=>"." } ); > ># Ya get yer vermin whereever u want - XML, SQL, FooBar >$vars= { > 'widgets' => { > 'test1' => Widget::Test->new( maximum=>100, current=>10 ) > }, > 'lots' => 'o', > 'more' => 'variables', >}; > >$tt->process("test.html", $vars) || > die "Failed: ".$tt->error()."\n"; Hmmm. So the "widgets" entry in the stash becomes magic. Seems unattractive because you need to modify the Template Toolkit itself. But I every solution I can think of requires more steps in the Templates page than I'd like to see as well. >-------------- >test.html >-------------- >This is a test. <p> >[% test1 %] What do you see as the desirability of making the call program know about the widgets vs. making the template know about the widgets? I had envisioned some usage like... [% USE wc = Widget %] This is a test. <p> [% wc.test1 %] This would need some sort of Template Toolkit driver or a special controller for Template Toolkit to make the syntax work out this way. >-------------- >Patch to Template Toolkit 2.02 - Template/Stash.pm >-------------- > if (defined($value = $root->{ $item })) { > return $value unless ref $value eq 'CODE'; ## RETURN > @result = &$value(@$args); ## @result > } ># Whacked in widget handler > if (defined $root->{ 'widgets' } && defined >$root->{'widgets'}{$item}) { > return $root->{'widgets'}{$item}->display(@$args); > } ># /Whack > > elsif ($lvalue) { > # we create an intermediate hash if this is an lvalue > return $root->{ $item } = { }; ## RETURN > } > This is an interesting option. Please see if you can come up with a way which does not require us to modify the Template Toolkit to specifically recognize a "magic" variable in the stash. Stephen |
From: Stephen A. <ste...@of...> - 2001-06-06 14:47:03
|
At 10:05 AM 6/6/2001 -0400, Jay Lawrence wrote: >One other thing I really wanna see is thaw/freeze support. Scary? Not >really. Obviously if you don't wanna thaw and freeze widgets ever this will >be no skin off your nose - it is optional to use. > >I belive that one thing needs to happen in the thaw phase - that is a "use" >for the widget's class. There is no guarantee that you've "use"d that widget >class already. > Interesting idea. What is the purpose of freezing and thawing widgets? Stephen |
From: Jay L. <Ja...@La...> - 2001-06-06 14:04:19
|
One other thing I really wanna see is thaw/freeze support. Scary? Not really. Obviously if you don't wanna thaw and freeze widgets ever this will be no skin off your nose - it is optional to use. I belive that one thing needs to happen in the thaw phase - that is a "use" for the widget's class. There is no guarantee that you've "use"d that widget class already. ie/ use Widget; open DAT, "widget.dat"; undef $/; $widget_dat=<DAT>; close DAT; my $widget=Widget->thaw($widget_dat); print $widget->whizbang; $widget->whizbang( rand ); open DAT, ">widget.dat"; print DAT $widget->freeze; close DAT; -------- Base class would support serialization of widget properties through Storable, Data::Dumper and XML. You might be able to test what format is being thaw'ed but it might be desirable to pass that info along explicitly: $widget->freeze('XML', (params for XML generation) ); $widget->freeze('dumper'); $widget->freeze('storable'); $Widget::freezer="storable"; # Over ride default Cheers, Jay |
From: Jay L. <Ja...@La...> - 2001-06-06 13:52:19
|
Widgets in Template Toolkit - QED Here is something that I prototyped on my own system... - Just to show exactly how simple I'd like the widgets to appear to the template user ... General ideas: - Create hash of widgets: name => Widget::Object - Register this with Template::Toolkit somehow - two places come to mind - in the vars (as I have shown here) - At Template instantiation my $tt=Template->new ( { WIDGETS=>$widgetHashRef } ); - Reference widgets solely by name - I do find the "wc." - "wc.widget" - a bit redundant but understand its purpose - instead we can beef up the _dotop sub of Stash to give us what we want! - Trained Stash to look for widgets by name and if found call their "display" method with any parameters supplied in the template testprg.pl ------------- use Template; use Widget::Test; my $tt=Template->new( { INCLUDE_PATH=>"." } ); # Ya get yer vermin whereever u want - XML, SQL, FooBar $vars= { 'widgets' => { 'test1' => Widget::Test->new( maximum=>100, current=>10 ) }, 'lots' => 'o', 'more' => 'variables', }; $tt->process("test.html", $vars) || die "Failed: ".$tt->error()."\n"; -------------- test.html -------------- This is a test. <p> [% test1 %] -------------- Patch to Template Toolkit 2.02 - Template/Stash.pm -------------- if (defined($value = $root->{ $item })) { return $value unless ref $value eq 'CODE'; ## RETURN @result = &$value(@$args); ## @result } # Whacked in widget handler if (defined $root->{ 'widgets' } && defined $root->{'widgets'}{$item}) { return $root->{'widgets'}{$item}->display(@$args); } # /Whack elsif ($lvalue) { # we create an intermediate hash if this is an lvalue return $root->{ $item } = { }; ## RETURN } |
From: Cees H. <ce...@si...> - 2001-06-06 13:15:54
|
On Tue, 5 Jun 2001, Stephen Adkins wrote: > Several people have commented on this topic. > > Is it 1. Widget::HTML::Select ? > ....or 2. Widget::Select::HTML ? > > I believe that "all of the HTML widgets" have more in common > than "all of the Select widgets". That's why I chose #1 rather > than #2. I don't think you can easily make that generalization about all widgets. I agree with you that for simple widgets, most of the package will be about how to render the widget. But when you look at a widget like the Databound Select widget you mentioned in an other email, then I can see a lot of code that can be shared between all those databound select widgets. And if we look back at the DateDropDowns widget, It doesn't need to know anything at all about how to render itself, since it uses three sub-widgets to do all the rendering work. All DateDropDowns really does is figure out how the user wants the sub-widgets configured, and handles splitting and joining the date values (in other words all of it could be shared across the HTML, WML or Gtk interfaces). However, I can also see your point about keeping the HTML stuff together and the Gtk stuff together. So I would be happy using the multiple inheritance model, where Widget::HTML::DateDropDowns would inherit from Widget::HTML::Base and Widget::Base::DateDropDowns. -- Cees Hek ce...@si... |
From: Cees H. <ce...@si...> - 2001-06-06 12:48:17
|
On Tue, 5 Jun 2001, Stephen Adkins wrote: > I originally thought that every attribute should be required to be > configured from the config file. > Now I think that every configurable attribute should be *able* to be > configured from the config file, but that it should also be *able* to > be overridden by the constructor parameters. Excellent. That's exactly how I see it. > I actually would like to create data-bound controls as well, > where the SQL to populate the controls can be configured into the > config file and the values are populated at run time. I really like the sounds of that -- Cees Hek ce...@si... |
From: Stephen A. <ste...@of...> - 2001-06-05 20:20:38
|
Hi, Several people have commented on this topic. Is it 1. Widget::HTML::Select ? ...or 2. Widget::Select::HTML ? I believe that "all of the HTML widgets" have more in common than "all of the Select widgets". That's why I chose #1 rather than #2. Remember that a package structure is a logical grouping which says *nothing* about the inheritance structure. It has more to do with code organization, distribution, and dependencies. I would much rather delegate the entire package of Widget::Curses to someone who is really good with Curses, and delegate Widget::Gtk to someone who is really good with Gtk. Each one of them could develop their packages and release them independently on CPAN. I really think there will be very little code in common between "Widget::HTML::Button" and "Widget::WML::Button". In fact, there is no reason to expect that every user interface technology will even *have* a Widget::*::Button. On the other hand, I can imagine that there might be a bit of shared logic in whatever Widget::*::TreeView widgets exist. The current inheritance tree is as follows. Widget::Base | +-- Widget::HTML::Base | +-- Widget::HTML::Select #1. For these reasons, I recommend that the package structure *not* be changed. #2. However, if there exist multiple Widget::*::Select widgets which really should share code, then create a Widget::Base::Select which inherits from nothing, implements the logic which is common to all Widget::*::Select classes, and use multiple inheritance to let Widget::HTML::Select inherit from both Widget::HTML::Base and Widget::Base::Select. ------------------------------------ This raises another issue. How are we going to innovate when each innovation would create sweeping changes to the code base, renaming packages, moving them in the package structure, etc.? (CVS does not take kindly to moving files around and then back.) #3. I suggest that each of us who wants to revolutionize the code base (rather than evolve it), feel free to start with the Widget-0.02 code base (or any recent snapshot from CVS) and revolutionize it on your own machine. Ensure that the code still runs. (Making code actually work does a developer good.) Then share what you learn with the list. (Leave the CVS alone.) We'll see what happens from there. We may decide we don't want the revolutionized code in CVS, or we may put you in charge of updating it in CVS. Just don't get your feelings hurt. So even though I made recommendation #1, feel free to try it out on your own under recommendation #3 and share with the list what you learned. Until we get past this early period, we'd better not have each person trying to update CVS independently. Stephen P.S. I think some of these issues will become clearer only when we get a much richer set of widgets in place. >At 09:23 PM 6/5/2001 +1000, you wrote: >> >>I have a concern with the current structure of the base >>classes. Currently the way I see it, the structure is as follows >> >>Widget::Base - base class for all widgets >>Widget::HTML::Base - base class for all HTML widgets (inherits Widget::Base) >>Widget::HTML::Select - a widget class (inherits from Widget::HTML::Base) >> >>Now if we add WML we would get the following extra classes >> >>Widget::WML::Base - base class for all HTML widgets (inherits Widget::Base) >>Widget::WML::Select - a widget class (inherits from Widget::HTML::Base) >> >> >>My concern here is that there is no sharing of code between >>Widget::HTML::Select and Widget::WML::Select besides the Widget::Base and >>Widget::HTML::Base. I think there should be a base class for Select >>widgets that the HTML and WML Select widgets can inherit from. Otherwise >>we will be duplicating a tonne of code between the different interfaces. >> >> >>Essentially, I think we have our Base class structure backwards. What we >>need to think about is what similarities and differences there will be >>between the different interfaces. The only method that should be >>different in a Widget is the method that renders the actual widget. >>Everything else will most likely be the same. >> >>To fit a Widget::Select baseclass into the current structure would require >>multiple inheritance, and I don't know if that is such a good idea. >> >> >>What if we used the following structure: >> >>Widget::Base - base class for all widgets >>Widget::Select - a generic dropdown box widget (inherits from Widget::Base) >> >>Widget::HTML::Base - a base class for HTML widgets (doesn't inherit) >>Widget::HTML::Select - a display class for Select box >> (inherits from Widget::HTML::Base) >> >>The Widget::Select object can instantiate the correct display object from >>one of the interfaces once it knows (from the config file) which interface >>we are displaying to. It can choose to use Widget::HTML::Select or >>Widget::WML::Select depending on the requirements. >> >> >>Does anyone have any other ideas or comments on the implications of this? >>I haven't thought this out completely yet, but I wanted to throw it out >>before we got too deep into the coding. >> >> >>-- >>Cees Hek >> >> >>_______________________________________________ >>Perl-widget-developer mailing list >>Per...@li... >>http://lists.sourceforge.net/lists/listinfo/perl-widget-developer >> |
From: Stephen A. <ste...@of...> - 2001-06-05 19:53:08
|
Hi, We have gotten pretty focused over the last 24 hours on guts. I am still working my teambuilding plan, which recognizes that debating the guts is engaging, but it is the last step. This exercise is about defining the usage of widgets. I present here two files. cgi-bin/cgisample a CGI script using widgets cgi-bin/cgisample.xml a configuration file for widgets used Note: These two files are running code in CVS. See http://www.officevision.com/cgi-bin/pub/Widget/cgisample I would encourage others to post sample CGI scripts, templates, and config files that suggest how *they* would like to use widgets. Forget the internals for a moment. ;-) Stephen P.S. I agree with Cees's comments about improving DateDropDowns. shark:/usr/ov/acoc/dev/src/Widget/cgi-bin> more cgisample cgisample.xml :::::::::::::: cgisample :::::::::::::: #!/usr/local/bin/perl -w ############################################################## # cgisample ############################################################## # This is an example of a CGI script that uses the capabilities # of the Perl Widget Library minimally. # It looks like any other perl script which uses the CGI.pm # library. # See 'wexec' for an example of a CGI script that uses # the full capabilities of the Perl Widget Library. ############################################################## use lib "/usr/ov/acoc/dev/src/Widget"; use CGI; $query = new CGI; use Widget; $wc = Widget->controller(-cgi => $query); $wc->process_request(); print <<EOF; Content-type: text/html <head> <title>cgisample</title> </head> <body bgcolor=#ffffff> <h1>cgisample</h1> <hr> <form method='POST'> EOF # Please note that there is *nothing* in this code which indicates what physical # class is used to render each "logical" widget. # When the widget is instantiated, though, it is a physical one. # The controller decided which physical widget it would be based on configuration # information and runtime information (not yet implemented) # There's more than one way to do it... ;-) $first_name = $wc->widget("first_name")->html(); # you can skip the widget and just get its HTML $last_name = $wc->widget("last_name")->html(); $address = $wc->widget( -name => "address", -class => "Widget::HTML::Element", -tag => 'input', -type => 'text', -size => '14', -maxlength => '99', )->html(); $birth_dt = $wc->widget("birth_dt")->html; # of course, you don't need to provide parentheses ... $sex = $wc->widget("sex")->html(); $w_check_it = $wc->widget("check_it"); # or you can get the widget $check_it = $w_check_it->html(); # then get its HTML $anniv_dt = $wc->widget("anniv_dt")->html(); $anniv_dt_value = $wc->widget("anniv_dt")->value(); # you can also do other things to a widget, like get its value # note that $wc caches widget instances, so the previous two lines did use the same physical widget $anniv_dt_value = "" if (!defined $anniv_dt_value); print <<EOF; <table border=0> <tr> <td>First Name: </td><td>$first_name</td> <td>Widget::HTML::Element - a general widget for constructing any HTML element (remember, only the configurer worries about what physical class it is. It's transparent to the programmer)</td> </tr> <tr> <td>Last Name: </td><td>$last_name</td> <td>Widget::HTML::Element</td> </tr> <tr> <td>Birth Date: </td><td>$birth_dt</td> <td>Widget::HTML::Element</td> </tr> <tr> <td>Address: </td><td>$address</td> <td>Widget::HTML::Element (not in config file)</td> </tr> <tr> <td>Sex: </td><td>$sex</td> <td>Widget::HTML::Select</td> </tr> <tr> <td>Anniversary Date: </td><td>$anniv_dt</td> <td>Widget::HTML::DateDropDowns</td> </tr> <tr> <td> </td><td>$check_it</td> <td>Widget::HTML::Button</td> </tr> <tr> <td>Anniversary Date is ... </td><td>$anniv_dt_value</td> <td> (value) </td> </tr> </table> </form> </body> </html> EOF :::::::::::::: cgisample.xml :::::::::::::: <config> <widget name="first_name" tag='input' type='text' size='14' maxlength='99'/> <widget name="last_name" widget-class='Widget::HTML::Element' tag='input' type='text' size='14' maxlength='99'/> <widget name="birth_dt" widget-type='date'/> <widget name="anniv_dt" widget-type='date3'/> <widget name="anniv_dt.year" widget-type='year'/> <widget name="anniv_dt.month" widget-type='month'/> <widget name="anniv_dt.day" widget-type='day'/> <widget name="sex" widget-type='sex'/> <widget name="check_it" widget-type='check_anniv_dt'/> <widget-type name="date" tag='input' type='text' size='14' maxlength='99'/> <widget-type name="date3" widget-class='Widget::HTML::DateDropDowns'/> <widget-type name="sex" widget-class='Widget::HTML::Select' domain='sex'/> <widget-type name="year" widget-class='Widget::HTML::Select' domain='year'/> <widget-type name="month" widget-class='Widget::HTML::Select' domain='month'/> <widget-type name="day" widget-class='Widget::HTML::Select' domain='day'/> <widget-type name="check_anniv_dt" widget-class='Widget::HTML::Button' label=' Check Your Anniversary Date '/> <domain name="sex"> <item name="M" label="Male"/> <item name="F" label="Female"/> </domain> <domain name="year"> <item name="1980"/> <item name="1981"/> <item name="1982"/> <item name="1983"/> <item name="1984"/> <item name="1985"/> <item name="1986"/> <item name="1987"/> <item name="1988"/> <item name="1989"/> <item name="1990"/> <item name="1991"/> <item name="1992"/> <item name="1993"/> <item name="1994"/> <item name="1995"/> <item name="1996"/> <item name="1997"/> <item name="1998"/> <item name="1999"/> <item name="2000"/> <item name="2001"/> <item name="2002"/> <item name="2003"/> <item name="2004"/> <item name="2005"/> <item name="2006"/> <item name="2007"/> <item name="2008"/> <item name="2009"/> </domain> <domain name="month"> <item name="01" label="Jan"/> <item name="02" label="Feb"/> <item name="03" label="Mar"/> <item name="04" label="Apr"/> <item name="05" label="May"/> <item name="06" label="Jun"/> <item name="07" label="Jul"/> <item name="08" label="Aug"/> <item name="09" label="Sep"/> <item name="10" label="Oct"/> <item name="11" label="Nov"/> <item name="12" label="Dec"/> </domain> <domain name="day"> <item name="01"/> <item name="02"/> <item name="03"/> <item name="04"/> <item name="05"/> <item name="06"/> <item name="07"/> <item name="08"/> <item name="09"/> <item name="10"/> <item name="11"/> <item name="12"/> <item name="13"/> <item name="14"/> <item name="15"/> <item name="16"/> <item name="17"/> <item name="18"/> <item name="19"/> <item name="20"/> <item name="21"/> <item name="22"/> <item name="23"/> <item name="24"/> <item name="25"/> <item name="26"/> <item name="27"/> <item name="28"/> <item name="29"/> <item name="30"/> <item name="31"/> </domain> </config> |
From: <ja...@la...> - 2001-06-05 19:25:18
|
Great - and you are absolutely right about the two camps for implementation. In my work I took the 2nd strategy initially and ended up going back and redoing that code to use accessor methods anyway. By using accessors at all times you are going to allow people like me to override data type declarations with what I want but support Gunther's wish for total simplicity of implementation. I do accept that there is a performance tradeoff.* Perhaps, before getting too excited about performan implications we might choose to benchmark this. How you implement it will affect the performance. (ie/ using AUTOLOAD could be done slow - but creating closures can make it fast.) Also - by itemizing the list of possible keys upfront can you not open to the possiblity of a pseudohash which is faster and more compact that standard hashes? Jay * I remember Stephen's statement of flexibility over performance! On Tue, 05 June 2001, Stephen Adkins wrote: > > Hi, > > Yes, we absolutely need accessors. > I recommend an AUTOLOAD method implemented on Widget::Base to > create accessors automatically (for now, anyway). > > However, there are two schools of thought on use of accessors vs. > accessing the attributes directly. > > 1. use accessors everywhere, even inside the class > 2. use accessors outside the class, access the attribute directly > from within the class > > I prefer #2 for performance. > Some people argue #1 so that subclasses are resilient to change in the > superclass. I think we just don't have a complex enough code base to > make #1 critical. It won't be look before we finalize how to access > attributes internally. Then it should be stable. > > Stephen > > At 10:22 AM 6/5/2001 -0400, Jay Lawrence wrote: > >Hey all, > > > >I was looking at the code and noticed one thing that will severely limit our > >implementation flexibility. It has to do with how properties are accessed in > >a non-abstracted fashion. > > > >When an widget is created (Widget::Base::new) you pass your properties which > >then get stuffed in the object hash for later use. > > > >OK - so you're storing properties like $widget->{'name'} = "button1". (Oh, > >BTW, shouldn't you enclose hash keys in quotes? I know it generally works > >but it generates warnings). > > > >And you're obtaining it same way ie: > > print "My name is ".$self->{'name'}; > > > >However, if you choose to have a different storage mechanism OR want to get > >fancy with how properties are resolved you need to use accessor methods. ie/ > > print "My name is ".$self->name; > > > >This way you hide the implementation of the widget (abstraction) from the > >calling routine. You actually need to use this strategy everywhere. > > > >There are a number of ways to handle this: > > AUTOLOAD - resolve name of method to a property or raise error > > manual accessor contruction - lots 'n lots of subs > > automated accessor construction - 1/2 doz packages in CPAN that do the > >job > > > >I know there will be arguments of efficiency vs. flexibility but I do recall > >Stephen saying that at this stage we'll be thinking more on flexibility than > >efficiency. But down the road we might be able to trade the expense of a > >function call with a more efficient storage mechanism like pseudohashs. > > > >Jay > > > > > > > >_______________________________________________ > >Perl-widget-developer mailing list > >Per...@li... > >http://lists.sourceforge.net/lists/listinfo/perl-widget-developer > > |
From: Stephen A. <ste...@of...> - 2001-06-05 19:03:19
|
Hi, At 12:04 AM 6/6/2001 +0800, Gunther Birznieks wrote: >I think this is reasonable. > >I Don't know about Widget::Select since it is meant to be an abstract class >and not actually instantiated itself. So it's a bit odd. Perhaps > >Widget::Base::Select would be better to make it clear that anything under >Base direectory is an abstract skeleton of widgets that will belong under >Widget::HTML or Widget::WML or what have you. Yes. I like this (and reiterated it in my earlier recommendation). Stephen >At 09:23 PM 6/5/01 +1000, Cees Hek wrote: > >>I have a concern with the current structure of the base >>classes. Currently the way I see it, the structure is as follows >> >>Widget::Base - base class for all widgets >>Widget::HTML::Base - base class for all HTML widgets (inherits Widget::Base) >>Widget::HTML::Select - a widget class (inherits from Widget::HTML::Base) >> |
From: Stephen A. <ste...@of...> - 2001-06-05 19:01:50
|
Hi, I agree with all these good reasons. This supports my previous recommendation. Stephen At 12:02 AM 6/6/2001 +0800, Gunther Birznieks wrote: >I disagree in general with this. Having coded a lot of WML and HTML myself >for a local mobile company, I can say pretty strongly that I do not believe >in a 1-1 mapping between elements in WML and HTML except in a very loose sense. > >You really have to code the whole template very separately for WML vs HTML >and the choice you make (eg textfield vs textarea) is very different on WML >vs HTML. > >So you would not want some generic Widget::TextField that rents a WML >version for WML and HTML for HTML. It's quite possible that on web you may >want to allow the user to type in a lot of info in textarea but on wap, you >just restrict it a bit more. > >I think for most programmers, it will be easier to see HTML widgets and >then dive in there and then plainttext widgets and WAP widgets etc as a >substructure and then see when they are coding an HTML form what elements >are available to them when they are doing so. > >Later, > Gunther > |
From: Stephen A. <ste...@of...> - 2001-06-05 19:00:16
|
Hi, Yes, we absolutely need accessors. I recommend an AUTOLOAD method implemented on Widget::Base to create accessors automatically (for now, anyway). However, there are two schools of thought on use of accessors vs. accessing the attributes directly. 1. use accessors everywhere, even inside the class 2. use accessors outside the class, access the attribute directly from within the class I prefer #2 for performance. Some people argue #1 so that subclasses are resilient to change in the superclass. I think we just don't have a complex enough code base to make #1 critical. It won't be look before we finalize how to access attributes internally. Then it should be stable. Stephen At 10:22 AM 6/5/2001 -0400, Jay Lawrence wrote: >Hey all, > >I was looking at the code and noticed one thing that will severely limit our >implementation flexibility. It has to do with how properties are accessed in >a non-abstracted fashion. > >When an widget is created (Widget::Base::new) you pass your properties which >then get stuffed in the object hash for later use. > >OK - so you're storing properties like $widget->{'name'} = "button1". (Oh, >BTW, shouldn't you enclose hash keys in quotes? I know it generally works >but it generates warnings). > >And you're obtaining it same way ie: > print "My name is ".$self->{'name'}; > >However, if you choose to have a different storage mechanism OR want to get >fancy with how properties are resolved you need to use accessor methods. ie/ > print "My name is ".$self->name; > >This way you hide the implementation of the widget (abstraction) from the >calling routine. You actually need to use this strategy everywhere. > >There are a number of ways to handle this: > AUTOLOAD - resolve name of method to a property or raise error > manual accessor contruction - lots 'n lots of subs > automated accessor construction - 1/2 doz packages in CPAN that do the >job > >I know there will be arguments of efficiency vs. flexibility but I do recall >Stephen saying that at this stage we'll be thinking more on flexibility than >efficiency. But down the road we might be able to trade the expense of a >function call with a more efficient storage mechanism like pseudohashs. > >Jay > > > >_______________________________________________ >Perl-widget-developer mailing list >Per...@li... >http://lists.sourceforge.net/lists/listinfo/perl-widget-developer > |
From: James G S. <JG...@TA...> - 2001-06-05 16:17:28
|
Gunther Birznieks <gu...@ex...> wrote: >I disagree in general with this. Having coded a lot of WML and HTML myself >for a local mobile company, I can say pretty strongly that I do not believe >in a 1-1 mapping between elements in WML and HTML except in a very loose sense. > >You really have to code the whole template very separately for WML vs HTML >and the choice you make (eg textfield vs textarea) is very different on WML >vs HTML. > >So you would not want some generic Widget::TextField that rents a WML >version for WML and HTML for HTML. It's quite possible that on web you may >want to allow the user to type in a lot of info in textarea but on wap, you >just restrict it a bit more. Then perhaps the widgets are being too closely tied to the end result. The Widget::TextField should know which way is best for the environment in which it is being rendered. Why force the coder to figure out the best way to put up a text input field? That complicates the higher-level coding and we have lost the abstractions we are trying to put in place -- the developer has gained nothing from using the Widget set except having to learn yet another way to do things. The Widget::Thingy class will know which of it's classes to use for rendering. For HTML, it might use Widget::Thingy::HTML while in WAP it uses Widget::Thingy::WAP. The Widget::Thingy class itself contains the logic used to tie itself together, not actually render itself. If it has to worry about which way to render a constituant widget, then it's not using a sufficiently abstract widget. Hopefully widgets will be more abstract than just Perl wrappers around the HTML set of input objects. -- James Smith <JG...@TA...>, 979-862-3725 Texas A&M CIS Operating Systems Group, Unix |
From: Gunther B. <gu...@ex...> - 2001-06-05 16:02:06
|
I think this is reasonable. I Don't know about Widget::Select since it is meant to be an abstract class and not actually instantiated itself. So it's a bit odd. Perhaps Widget::Base::Select would be better to make it clear that anything under Base direectory is an abstract skeleton of widgets that will belong under Widget::HTML or Widget::WML or what have you. At 09:23 PM 6/5/01 +1000, Cees Hek wrote: >I have a concern with the current structure of the base >classes. Currently the way I see it, the structure is as follows > >Widget::Base - base class for all widgets >Widget::HTML::Base - base class for all HTML widgets (inherits Widget::Base) >Widget::HTML::Select - a widget class (inherits from Widget::HTML::Base) > >Now if we add WML we would get the following extra classes > >Widget::WML::Base - base class for all HTML widgets (inherits Widget::Base) >Widget::WML::Select - a widget class (inherits from Widget::HTML::Base) > > >My concern here is that there is no sharing of code between >Widget::HTML::Select and Widget::WML::Select besides the Widget::Base and >Widget::HTML::Base. I think there should be a base class for Select >widgets that the HTML and WML Select widgets can inherit from. Otherwise >we will be duplicating a tonne of code between the different interfaces. > > >Essentially, I think we have our Base class structure backwards. What we >need to think about is what similarities and differences there will be >between the different interfaces. The only method that should be >different in a Widget is the method that renders the actual widget. >Everything else will most likely be the same. > >To fit a Widget::Select baseclass into the current structure would require >multiple inheritance, and I don't know if that is such a good idea. > > >What if we used the following structure: > >Widget::Base - base class for all widgets >Widget::Select - a generic dropdown box widget (inherits from Widget::Base) > >Widget::HTML::Base - a base class for HTML widgets (doesn't inherit) >Widget::HTML::Select - a display class for Select box > (inherits from Widget::HTML::Base) > >The Widget::Select object can instantiate the correct display object from >one of the interfaces once it knows (from the config file) which interface >we are displaying to. It can choose to use Widget::HTML::Select or >Widget::WML::Select depending on the requirements. > > >Does anyone have any other ideas or comments on the implications of this? >I haven't thought this out completely yet, but I wanted to throw it out >before we got too deep into the coding. > > >-- >Cees Hek > > >_______________________________________________ >Perl-widget-developer mailing list >Per...@li... >http://lists.sourceforge.net/lists/listinfo/perl-widget-developer __________________________________________________ Gunther Birznieks (gun...@eX...) eXtropia - The Open Web Technology Company http://www.eXtropia.com/ |
From: Gunther B. <gu...@ex...> - 2001-06-05 16:00:02
|
I disagree in general with this. Having coded a lot of WML and HTML myself for a local mobile company, I can say pretty strongly that I do not believe in a 1-1 mapping between elements in WML and HTML except in a very loose sense. You really have to code the whole template very separately for WML vs HTML and the choice you make (eg textfield vs textarea) is very different on WML vs HTML. So you would not want some generic Widget::TextField that rents a WML version for WML and HTML for HTML. It's quite possible that on web you may want to allow the user to type in a lot of info in textarea but on wap, you just restrict it a bit more. I think for most programmers, it will be easier to see HTML widgets and then dive in there and then plainttext widgets and WAP widgets etc as a substructure and then see when they are coding an HTML form what elements are available to them when they are doing so. Later, Gunther At 10:41 PM 6/4/01 -0500, James G Smith wrote: >I'm looking through the code a bit closer finally. I had some >thoughts and a diff showing some of the code that comes out of >them - plus a few things that might make the code a but more >readable (it is fairly readable already, but I had to stop and >think through one or two things once in a while). > >Instead of Widget::HTML::Element, I think I'd prefer to see >Widget::Element::HTML. We could think of `Element' as the widget >archetype. > >Pro: > (1) Easier widget creation. Instead of having to supply the >full class name when using the create method, you can pass the >type of element and the create method can build the class name. > (2) Easier packaging and distribution of third-party widgets. > (3) (1) makes creating aggregate archetypes easier. > (4) Consolidation of logic. > >Con: > (1) HTML widgets are spread out, as are XML widgets and WML >widgets. No longer are all the widgets for a particular output >environment in one namespace. > >Note (4) above needs some more commentary. > >If we have Widget::Base as the base object for Widgets, then we >can have Widget::Base::HTML as the base for the HTML >specialization of Widgets. It could contain the html encoding/ >decoding code and other HTML specific functions. > >Widget::Element is a Widget::Base while >Widget::Element::HTML is a Widget::Element and Widget::Base::HTML. > >Widget::Element has all the processing logic for the widget while >the tertiary modules (::HTML, ::WML, etc.) contain the output >logic. > > >There might also be good reason for moving the create method to >the controller object. It knows more about the environment than >Widget does and can create the correct widgets given the >archetype requested. See the diff for one possible solution to >the problem of a non-existant class. >-- >James Smith <JG...@TA...>, 979-862-3725 >Texas A&M CIS Operating Systems Group, Unix > >*** Widget.pm.dist Mon Jun 4 22:11:23 2001 >--- Widget.pm Mon Jun 4 22:23:28 2001 >*************** >*** 69,75 **** > my $self = shift; > > my ($args); >! if ($#_ == -1) { > $args = {}; > } > elsif (ref($_[0]) eq "HASH") { >--- 69,75 ---- > my $self = shift; > > my ($args); >! if (!@_) { > $args = {}; > } > elsif (ref($_[0]) eq "HASH") { >*************** >*** 129,139 **** > return $self->create($args->{controller}, $args); > } > > sub create { > my $self = shift; > my $class = shift; > # TODO: what should I really do here if the class does not exist? >! return undef if (!Widget->use($class)); > return $class->new(@_); > } > >--- 129,148 ---- > return $self->create($args->{controller}, $args); > } > >+ # Question: Does the create function belong in the controller? >+ # Re: The controller knows what kind of widgets are needed (HTML, >+ # XML,Gtk+, etc.) > sub create { > my $self = shift; > my $class = shift; > # TODO: what should I really do here if the class does not exist? >! if(!Widget -> use($class)) { >! # TODO: figure out how we want to sub-class Widget::$class... >! # This does assume Widget::Thingy::HTML instead of >! # Widget::HTML::Thingy. >! $class = join("::", "Widget", $class); >! return undef unless Widget -> use($class); >! } > return $class->new(@_); > } > >*************** >*** 149,156 **** > $file = $class; > $file =~ s#::#/#g; > $file .= ".pm"; >! require $file; >! $ok = 0 if (! defined $INC{$file}); > } > $ok; > } >--- 158,164 ---- > $file = $class; > $file =~ s#::#/#g; > $file .= ".pm"; >! $ok = 0 unless require $file; > } > $ok; > } >*************** >*** 185,191 **** > print STDERR "Widget->html() $item => ref=[$ref]\n" if > ($Widget::DEBUG); > next if ($ref eq "CODE" || $ref eq "GLOB"); # TODO: are there > others? > >! if ($ref eq "" || $ref eq "SCALAR") { > # TODO: find out what other transforms are in the standard > $elem = $item; > # borrowed from CGI::Util::simple_escape() ... >--- 193,199 ---- > print STDERR "Widget->html() $item => ref=[$ref]\n" if > ($Widget::DEBUG); > next if ($ref eq "CODE" || $ref eq "GLOB"); # TODO: are there > others? > >! if (!$ref || $ref eq "SCALAR") { > # TODO: find out what other transforms are in the standard > $elem = $item; > # borrowed from CGI::Util::simple_escape() ... > >_______________________________________________ >Perl-widget-developer mailing list >Per...@li... >http://lists.sourceforge.net/lists/listinfo/perl-widget-developer __________________________________________________ Gunther Birznieks (gun...@eX...) eXtropia - The Open Web Technology Company http://www.eXtropia.com/ |
From: Stephen A. <ste...@of...> - 2001-06-05 15:51:37
|
Cees, At 08:07 PM 6/5/2001 +1000, Cees Hek wrote: ... >I guess what I am looking for is some hooks that allow developers to >generate widgets without requiring a configuration file. There are 2 >situation where I think this is necesary. I agree. This needs to be well-supported. I did not originally think so. I originally thought that every attribute should be required to be configured from the config file. Now I think that every configurable attribute should be *able* to be configured from the config file, but that it should also be *able* to be overridden by the constructor parameters. In fact, I think I can envision the internal plumbing of the objects getting a whole lot simpler... >First situation: If we build a complex widget by combining several simple >widgets (a good example is the DateDropDowns widget), then the simple >widgets should not be required to be configured by the config file. >Using the DateDropDowns as an example, there are never going to be more >than 31 days in a month, so why waste config file space to hold them? >The config file should contain options and values that the user may want >to change, if it doesn't make sense to change it, then it shouldn't be in >the config file. Right. >So the DateDropDowns.pm code should be able to do somethin like this: >$date.day = $wc->widget(-name => 'date.day', > -class => 'Widget::HTML::Select', > -values => ['01'..'31']); > >The same can be done for months and years, although we could add a config >option that asks if they want to use full months (ie 'January', >'February') or short months (ie 'Jan', 'Feb'), and perhaps the range of >years to include in the widget. Right. >This way the user doesn't need to know anything about the 'sub-widgets' >that DateDropDowns uses internally. It will make the configuration files >much cleaner and user friendly... > > >The second situation is where you need a dynamic widget. For example a >select box where the options depend on a database query. > >$sth = $dbh->prepare(q{ > SELECT category_id, category_name > FROM categories > ORDER BY category_name >}); >$sth->execute(); >$data = $sth->fetchall_arrayref(); >$categories = $wc->widget(-name => 'categories', -values => $data); > >Where -values will contain a 2 dimensional array of values and labels (or >some similar mechanism) I actually would like to create data-bound controls as well, where the SQL to populate the controls can be configured into the config file and the values are populated at run time. >Comments ?? See above. >Cees Hek Stephen |
From: Gunther B. <gu...@ex...> - 2001-06-05 15:45:02
|
I agree with this in principle. At 12:36 AM 6/4/01 -0400, Stephen Adkins wrote: >Hi, > >I would appreciate a high response rate on this question from members >of the list who expect to contribute any opinions or code in the coming >month. (i.e. *not* silent list members) > > * Do you agree with the following two statements? > >1. Perl Widget Library is a library of useful HTML user interface widgets, >and a framework for extending them and developing your own. > >2. The library is designed conceptually to support non-HTML widgets too, >such as WML, Gtk/X, Curses, but we'll only get to those if it doesn't >compromise our ability to make HTML widgets. > >Stephen > > >_______________________________________________ >Perl-widget-developer mailing list >Per...@li... >http://lists.sourceforge.net/lists/listinfo/perl-widget-developer __________________________________________________ Gunther Birznieks (gun...@eX...) eXtropia - The Open Web Technology Company http://www.eXtropia.com/ |
From: Gunther B. <gu...@ex...> - 2001-06-05 15:43:47
|
At 10:59 PM 6/3/01 -0400, Stephen Adkins wrote: >At 08:47 AM 6/4/2001 +0800, Gunther Birznieks wrote: > >At 05:53 PM 6/3/01 -0400, Stephen Adkins wrote: >The bigger vision is to create active widgets whose processing across >multiple requests should be handled internally to the widget library >and which should almost not even be noticed by the application code. > >(Uh oh. I said it was a bigger topic, and here I am getting into it.) > >Take, for example, a reorderable multi-select list. Imagine the car type >list selection control implemented at > > http://demo:de...@ww.../cgi-bin/prod/members/mv/MarketVision > >It is actually many items, but one logical widget. > > * a <select multiple> for the "non-selected" car types, > * a <select multiple> for the "selected" car types, > * a "select" (right arrow) image button, > * an "unselect" (left arrow) image button, > * an "UP" (up arrow) image button, > * a "DOWN" (down arrow) image button, > * an <input type=hidden> variable containing the "selected" list of car >types > * a bunch of Javascript needing inclusion at the top of the page > * a bunch of Perl code to handle the events if Javascript is disabled > >Let us suppose that Javascript is not being used. >Each button press makes a round trip to the server and back, but the >application >logic should not be engaged. In essence, this was an "event" completely >internal to the PWL. > >If key values of a widget (i.e. the class) are only known at rendering time >rather than through a config file separate from the widget ever being >rendered, >the library will not know how to process the event. > >It is this type of processing that requires the PWL to know the attributes of >a widget even if it has not been asked to be rendered. > >OK. That's all for now. >I'll come back to this point later. >I need to finish some coding. The hard pieces of this I think this can be handled quite easily because you have a controller. You need a widget to be a javascript generator. Each javascript routine is a widget/component. Then you configure a widget that requires a javascript routine to have that javascript subroutine widget inside of itself and tell it to tell the controller to please look for a special widget that understand how to accept javascript widgets and then hand all of the javascript subroutine widgets to the main one. The main javascript widget that you place at the top of the page would then take all the javascript routines and make sure they do not repeat and all that kind of stuff and would be responsible for printing the script header and footer. To handle the events in Perl is a tougher one. My feeling is that this was going to be handled within a widget anyway. eg based on the state of CGI.pm saying that the up arrow was pressed, then rearrange how the listbox is generated. If these are separate widgets, I think it can still be done, but you don't need an event mechanism. You can use the same mechansim of the small javascript widgets being encapsulated in a larger one. These widgets of course have to be built to know about each other because they are connected widgets. Normal HTML widgets would not know about each other. These are the simple widgets with the simple interface. It's when you build up these complex ones that you are allowed to add your arbitrary interfaces. the ones that need to be most settled on (just to have a standard) are the way in which JavaScript is passed to the main JavaScript subroutine header widget I think. I don't believe that the abstraction for events should be events. I think it would be much easier to create an up arrow widget that detects when it's pressed through a CGI.pm value. Then upon doing so, it should feel free to take another widget (b4 being rendered) and then call a method to manipulate the values in it and how it should be displayed. So an HTML listbox widget could very well have a method that is specific to listboxes to say moveAllSelectedItemsUpOneLevel(). Then your only CUSTOM widget is your up arrow one where you manually code a routine that checks if the widget was clicked and if so, look for a widget of a specific name and call it's moveAllSelectedItemsUpOneLevel() routine. This is flexible and keeps the core HTML widgets simple while moving the complexity of handling the event stuff with the code for the up arrow. |
From: Jay L. <Ja...@La...> - 2001-06-05 14:22:03
|
Hey all, I was looking at the code and noticed one thing that will severely limit our implementation flexibility. It has to do with how properties are accessed in a non-abstracted fashion. When an widget is created (Widget::Base::new) you pass your properties which then get stuffed in the object hash for later use. OK - so you're storing properties like $widget->{'name'} = "button1". (Oh, BTW, shouldn't you enclose hash keys in quotes? I know it generally works but it generates warnings). And you're obtaining it same way ie: print "My name is ".$self->{'name'}; However, if you choose to have a different storage mechanism OR want to get fancy with how properties are resolved you need to use accessor methods. ie/ print "My name is ".$self->name; This way you hide the implementation of the widget (abstraction) from the calling routine. You actually need to use this strategy everywhere. There are a number of ways to handle this: AUTOLOAD - resolve name of method to a property or raise error manual accessor contruction - lots 'n lots of subs automated accessor construction - 1/2 doz packages in CPAN that do the job I know there will be arguments of efficiency vs. flexibility but I do recall Stephen saying that at this stage we'll be thinking more on flexibility than efficiency. But down the road we might be able to trade the expense of a function call with a more efficient storage mechanism like pseudohashs. Jay |
From: Jay L. <Ja...@La...> - 2001-06-05 14:06:07
|
I see this the same way as James - put your generic logic in the parent class and then interface-specific logic in subclasses: Widget::Element.pm -> generic logic Widget::Element::HTML.pm -> HTML-specific When we make widgets I'd expect that Widget::Element ISA Widget::Base and Widget::Element::HTML ISA (Widget::Base::HTML, Widget::Element) Then if the app is in HTML it would make a new Element widget via: $element=Widget::Element::HTML->new( { params } ) OR we could make constructor take a hint as to which context the widget is to be used and return that object type: # pseudocode: Widget::Base sub new { # constructor logic goes here # $class will be "Widget::Element" at this point if ($widget->container->type eq "HTML") { bless $widget, "$class::HTML"; } OR if ($widget->type eq "HTML") { bless $widget, "$class::HTML"; } OR bless $widget, $class."::".$widget->type; } I personally don't advocate putting constructor into controller - instead have the contructor check with the controller. That is the one crucial link that will supply us all of the environmental details needed. J > I'm looking through the code a bit closer finally. I had some > thoughts and a diff showing some of the code that comes out of > them - plus a few things that might make the code a but more > readable (it is fairly readable already, but I had to stop and > think through one or two things once in a while). > > Instead of Widget::HTML::Element, I think I'd prefer to see > Widget::Element::HTML. We could think of `Element' as the widget > archetype. > > Pro: > (1) Easier widget creation. Instead of having to supply the > full class name when using the create method, you can pass the > type of element and the create method can build the class name. > (2) Easier packaging and distribution of third-party widgets. > (3) (1) makes creating aggregate archetypes easier. > (4) Consolidation of logic. > > Con: > (1) HTML widgets are spread out, as are XML widgets and WML > widgets. No longer are all the widgets for a particular output > environment in one namespace. > > Note (4) above needs some more commentary. > > If we have Widget::Base as the base object for Widgets, then we > can have Widget::Base::HTML as the base for the HTML > specialization of Widgets. It could contain the html encoding/ > decoding code and other HTML specific functions. > > Widget::Element is a Widget::Base while > Widget::Element::HTML is a Widget::Element and Widget::Base::HTML. > > Widget::Element has all the processing logic for the widget while > the tertiary modules (::HTML, ::WML, etc.) contain the output > logic. > > > There might also be good reason for moving the create method to > the controller object. It knows more about the environment than > Widget does and can create the correct widgets given the > archetype requested. See the diff for one possible solution to > the problem of a non-existant class. > -- > James Smith <JG...@TA...>, 979-862-3725 > Texas A&M CIS Operating Systems Group, Unix > > *** Widget.pm.dist Mon Jun 4 22:11:23 2001 > --- Widget.pm Mon Jun 4 22:23:28 2001 > *************** > *** 69,75 **** > my $self = shift; > > my ($args); > ! if ($#_ == -1) { > $args = {}; > } > elsif (ref($_[0]) eq "HASH") { > --- 69,75 ---- > my $self = shift; > > my ($args); > ! if (!@_) { > $args = {}; > } > elsif (ref($_[0]) eq "HASH") { > *************** > *** 129,139 **** > return $self->create($args->{controller}, $args); > } > > sub create { > my $self = shift; > my $class = shift; > # TODO: what should I really do here if the class does not exist? > ! return undef if (!Widget->use($class)); > return $class->new(@_); > } > > --- 129,148 ---- > return $self->create($args->{controller}, $args); > } > > + # Question: Does the create function belong in the controller? > + # Re: The controller knows what kind of widgets are needed (HTML, > + # XML,Gtk+, etc.) > sub create { > my $self = shift; > my $class = shift; > # TODO: what should I really do here if the class does not exist? > ! if(!Widget -> use($class)) { > ! # TODO: figure out how we want to sub-class Widget::$class... > ! # This does assume Widget::Thingy::HTML instead of > ! # Widget::HTML::Thingy. > ! $class = join("::", "Widget", $class); > ! return undef unless Widget -> use($class); > ! } > return $class->new(@_); > } > > *************** > *** 149,156 **** > $file = $class; > $file =~ s#::#/#g; > $file .= ".pm"; > ! require $file; > ! $ok = 0 if (! defined $INC{$file}); > } > $ok; > } > --- 158,164 ---- > $file = $class; > $file =~ s#::#/#g; > $file .= ".pm"; > ! $ok = 0 unless require $file; > } > $ok; > } > *************** > *** 185,191 **** > print STDERR "Widget->html() $item => ref=[$ref]\n" if ($Widget::DEBUG); > next if ($ref eq "CODE" || $ref eq "GLOB"); # TODO: are there others? > > ! if ($ref eq "" || $ref eq "SCALAR") { > # TODO: find out what other transforms are in the standard > $elem = $item; > # borrowed from CGI::Util::simple_escape() ... > --- 193,199 ---- > print STDERR "Widget->html() $item => ref=[$ref]\n" if ($Widget::DEBUG); > next if ($ref eq "CODE" || $ref eq "GLOB"); # TODO: are there others? > > ! if (!$ref || $ref eq "SCALAR") { > # TODO: find out what other transforms are in the standard > $elem = $item; > # borrowed from CGI::Util::simple_escape() ... > > _______________________________________________ > Perl-widget-developer mailing list > Per...@li... > http://lists.sourceforge.net/lists/listinfo/perl-widget-developer > |
From: James G S. <JG...@TA...> - 2001-06-05 04:11:58
|
I'm looking through the code a bit closer finally. I had some thoughts and a diff showing some of the code that comes out of them - plus a few things that might make the code a but more readable (it is fairly readable already, but I had to stop and think through one or two things once in a while). Instead of Widget::HTML::Element, I think I'd prefer to see Widget::Element::HTML. We could think of `Element' as the widget archetype. Pro: (1) Easier widget creation. Instead of having to supply the full class name when using the create method, you can pass the type of element and the create method can build the class name. (2) Easier packaging and distribution of third-party widgets. (3) (1) makes creating aggregate archetypes easier. (4) Consolidation of logic. Con: (1) HTML widgets are spread out, as are XML widgets and WML widgets. No longer are all the widgets for a particular output environment in one namespace. Note (4) above needs some more commentary. If we have Widget::Base as the base object for Widgets, then we can have Widget::Base::HTML as the base for the HTML specialization of Widgets. It could contain the html encoding/ decoding code and other HTML specific functions. Widget::Element is a Widget::Base while Widget::Element::HTML is a Widget::Element and Widget::Base::HTML. Widget::Element has all the processing logic for the widget while the tertiary modules (::HTML, ::WML, etc.) contain the output logic. There might also be good reason for moving the create method to the controller object. It knows more about the environment than Widget does and can create the correct widgets given the archetype requested. See the diff for one possible solution to the problem of a non-existant class. -- James Smith <JG...@TA...>, 979-862-3725 Texas A&M CIS Operating Systems Group, Unix *** Widget.pm.dist Mon Jun 4 22:11:23 2001 --- Widget.pm Mon Jun 4 22:23:28 2001 *************** *** 69,75 **** my $self = shift; my ($args); ! if ($#_ == -1) { $args = {}; } elsif (ref($_[0]) eq "HASH") { --- 69,75 ---- my $self = shift; my ($args); ! if (!@_) { $args = {}; } elsif (ref($_[0]) eq "HASH") { *************** *** 129,139 **** return $self->create($args->{controller}, $args); } sub create { my $self = shift; my $class = shift; # TODO: what should I really do here if the class does not exist? ! return undef if (!Widget->use($class)); return $class->new(@_); } --- 129,148 ---- return $self->create($args->{controller}, $args); } + # Question: Does the create function belong in the controller? + # Re: The controller knows what kind of widgets are needed (HTML, + # XML,Gtk+, etc.) sub create { my $self = shift; my $class = shift; # TODO: what should I really do here if the class does not exist? ! if(!Widget -> use($class)) { ! # TODO: figure out how we want to sub-class Widget::$class... ! # This does assume Widget::Thingy::HTML instead of ! # Widget::HTML::Thingy. ! $class = join("::", "Widget", $class); ! return undef unless Widget -> use($class); ! } return $class->new(@_); } *************** *** 149,156 **** $file = $class; $file =~ s#::#/#g; $file .= ".pm"; ! require $file; ! $ok = 0 if (! defined $INC{$file}); } $ok; } --- 158,164 ---- $file = $class; $file =~ s#::#/#g; $file .= ".pm"; ! $ok = 0 unless require $file; } $ok; } *************** *** 185,191 **** print STDERR "Widget->html() $item => ref=[$ref]\n" if ($Widget::DEBUG); next if ($ref eq "CODE" || $ref eq "GLOB"); # TODO: are there others? ! if ($ref eq "" || $ref eq "SCALAR") { # TODO: find out what other transforms are in the standard $elem = $item; # borrowed from CGI::Util::simple_escape() ... --- 193,199 ---- print STDERR "Widget->html() $item => ref=[$ref]\n" if ($Widget::DEBUG); next if ($ref eq "CODE" || $ref eq "GLOB"); # TODO: are there others? ! if (!$ref || $ref eq "SCALAR") { # TODO: find out what other transforms are in the standard $elem = $item; # borrowed from CGI::Util::simple_escape() ... |
From: Cees H. <ce...@si...> - 2001-06-05 03:59:17
|
I have a concern with the current structure of the base classes. Currently the way I see it, the structure is as follows Widget::Base - base class for all widgets Widget::HTML::Base - base class for all HTML widgets (inherits Widget::Base) Widget::HTML::Select - a widget class (inherits from Widget::HTML::Base) Now if we add WML we would get the following extra classes Widget::WML::Base - base class for all HTML widgets (inherits Widget::Base) Widget::WML::Select - a widget class (inherits from Widget::HTML::Base) My concern here is that there is no sharing of code between Widget::HTML::Select and Widget::WML::Select besides the Widget::Base and Widget::HTML::Base. I think there should be a base class for Select widgets that the HTML and WML Select widgets can inherit from. Otherwise we will be duplicating a tonne of code between the different interfaces. Essentially, I think we have our Base class structure backwards. What we need to think about is what similarities and differences there will be between the different interfaces. The only method that should be different in a Widget is the method that renders the actual widget. Everything else will most likely be the same. To fit a Widget::Select baseclass into the current structure would require multiple inheritance, and I don't know if that is such a good idea. What if we used the following structure: Widget::Base - base class for all widgets Widget::Select - a generic dropdown box widget (inherits from Widget::Base) Widget::HTML::Base - a base class for HTML widgets (doesn't inherit) Widget::HTML::Select - a display class for Select box (inherits from Widget::HTML::Base) The Widget::Select object can instantiate the correct display object from one of the interfaces once it knows (from the config file) which interface we are displaying to. It can choose to use Widget::HTML::Select or Widget::WML::Select depending on the requirements. Does anyone have any other ideas or comments on the implications of this? I haven't thought this out completely yet, but I wanted to throw it out before we got too deep into the coding. -- Cees Hek |
From: Cees H. <ce...@si...> - 2001-06-05 01:03:49
|
On Mon, 4 Jun 2001, Stephen Adkins wrote: > Hi, > > I would appreciate a high response rate on this question from members > of the list who expect to contribute any opinions or code in the coming > month. (i.e. *not* silent list members) > > * Do you agree with the following two statements? > > 1. Perl Widget Library is a library of useful HTML user interface widgets, > and a framework for extending them and developing your own. Yup > 2. The library is designed conceptually to support non-HTML widgets too, > such as WML, Gtk/X, Curses, but we'll only get to those if it doesn't > compromise our ability to make HTML widgets. Sure. I believe we should make this as generic as possible, but honestly, I will probably only ever use the HTML or WML interfaces (ie the web side of things) -- Cees Hek SiteSuite Corporation ce...@si... |
From: Cees H. <ce...@si...> - 2001-06-04 23:55:31
|
On Sun, 3 Jun 2001, Stephen Adkins wrote: > 1. I am encouraged that someone is looking at the code. > Good for you Cees. > 2. Your suggestions are good, but your patches conflict with things > that I am working on. I understand that it was worth it to you > just to play with the code. I figured as much, but that's no problem. After looking at version 0.02, I think you have covered most of what I talked about. > >In the first release, the Widgets were conpletely driven by hte Config > >object. I have added some support that allows the widgets to be > >configured at initialization time as well as from the Config object. > >This allows someone to create a Widget as such: > > > > $widget = $wc->widget( > > -name => 'category', > > -class => 'Widget::HTML::Select', > > -values => ['Foo', 'Bar'], > > ); > > I knew people would want to do this, and I have been working on adding > it myself. However, I consider this usage the "low road". It encourages > people to do exactly what the library is supposed to get them away from ... > caring about the details of the widget. It also inhibits the configurer > from snapping a new implementation of a widget in to upgrade the page. I guess what I am looking for is some hooks that allow developers to generate widgets without requiring a configuration file. There are 2 situation where I think this is necesary. First situation: If we build a complex widget by combining several simple widgets (a good example is the DateDropDowns widget), then the simple widgets should not be required to be configured by the config file. Using the DateDropDowns as an example, there are never going to be more than 31 days in a month, so why waste config file space to hold them? The config file should contain options and values that the user may want to change, if it doesn't make sense to change it, then it shouldn't be in the config file. So the DateDropDowns.pm code should be able to do somethin like this: $date.day = $wc->widget(-name => 'date.day', -class => 'Widget::HTML::Select', -values => ['01'..'31']); The same can be done for months and years, although we could add a config option that asks if they want to use full months (ie 'January', 'February') or short months (ie 'Jan', 'Feb'), and perhaps the range of years to include in the widget. This way the user doesn't need to know anything about the 'sub-widgets' that DateDropDowns uses internally. It will make the configuration files much cleaner and user friendly... The second situation is where you need a dynamic widget. For example a select box where the options depend on a database query. $sth = $dbh->prepare(q{ SELECT category_id, category_name FROM categories ORDER BY category_name }); $sth->execute(); $data = $sth->fetchall_arrayref(); $categories = $wc->widget(-name => 'categories', -values => $data); Where -values will contain a 2 dimensional array of values and labels (or some similar mechanism) Comments ?? Cees Hek |