This is part of The Pile, a partial archive of some open source mailing lists and newsgroups.
To: <modperl@apache.org> From: "Jay Lawrence" <Jay@Lawrence.Net> Subject: Re: Real Widgets and Template Languages Date: Thu, 24 May 2001 12:28:28 -0400 Hey all, Let me describe what I have been imagining as the ideal widget for what I am writing: 1 - it can look to its environment to determine how to render itsself - am I on an HTML page or something else? 2 - it has properties that can be set and remain static no matter who's using it - size, shape, colour, max, min 3 - it has properties that are customized by the individual user of the widget - current value, theme choice, 4 - it can tell developers and environments what it can do - switch_on, switch_off, increment, decrement, etc. 5 - it is capable of persisting from invocation to invocation - user 1 sets current_value to x - which always comes back for user 1 6 - it can look to its environment for interhitable properties - global theme choice, global font, etc. 7 - templating systems know how to call widgets - because they always use the same method to display themselves 8 - widget can interact with each other - increasing value on slider widget changes current record # value for database record widget 9 - access restrctions - users can override some values but not others - not everyone can even use this widget, etc. 10 - multilingual - some things are language neutral others are not - "size" would probably be neutral whereas "label" would be language sensitive 11 - above all it is easy to use - ie/ don't make me set a zillion properties just to make it work! I am going to throw out a buzzword, gasp, which may serve as a model for what we are talking about: JavaBeans. I do feel there is a lot of additional complexity there but it is along the right direction IMHO. If you translate my wishlist into technologies I think I am talking about: A - a good persistant object management environment B - user sessions C - integration of widgets (objects) to user sessions D - Object API (properties and methods) which are consistant and predictable E - self documenting objects This is what I have been looking for/writing myself! I am really eager to chip in on this project and get it going ASAP - but do acknowledge the need for hearty discussion about what people really want not just my own views. :)) Jay === To: Stephen Adkins <stephen.adkins@officevision.com>, modperl@apache.org From: Gunther Birznieks <gunther@extropia.com> Subject: Re: Real Widgets and Template Languages Date: Fri, 25 May 2001 00:51:48 +0800 At 04:18 PM 5/23/01 -0400, Stephen Adkins wrote: >Hi, > >I will step up to write this code. (if it is what I think it is) >I have responded to the message by beginning a requirements document. > > http://www.officevision.com/pub/HTML-Widget/ > >Please read it and send me any comments. >The following are the questions I need advice on in order to proceed. > > * What CPAN package namespace should I use? > I studied the existing packages, and what we are trying to do looks > like it fits under the existing top level package HTML. > I propose to take the space "HTML::Widget" (see package layout in > design doc). Gunther suggested the top-level "Widget" name space. > I was under the impression that we should stay away from creating > new top-level entries at CPAN unless there was really *nothing* > similar. Confusingly, there is already an HTML::Widgets. Thoughts? Yes I prefer Widget::* to HTML::Widget::*. HTML is one driver, not what a widget is. The only problem is that people need to find the widget library. My expectation is that the widget library on CPAN will actually be aided by plugs in like TT::Widget would make use of Widget::* to do the majority of the work. But TT::Widget would be providing the tag wrapping code for TT. > * What CPAN packages should I begin with and build upon? > CGI and Apache::Request were mentioned. I figure I will use these. > HTML::StickyWidgets was also mentioned. Do you mean HTML::StickyForms? > Are there others I should build dependencies on? Yes, HTML::StickyForms is probably the right one. I think they may all be supported. > * Should I begin immediately with a new Sourceforge project? another way? > The codebase I will begin with is in CVS on my local server. > Perhaps I should just continue that way and post versions to CPAN > for distribution. However, we may have email traffic for the project > that exceeds the general interests of the modperl list. Thoughts? > I would need to get enough responses from people who would join that > Sourceforge mailing list before it would be worth it to go do that. Like Stas, I say yes to SourceForge. It's easy and saves a lot of time. When the first distro is ready, then CPAN can be the distro mechanism. Later, Gunther PS I will in advance warn that I will be quiet on this topic for the next 24-36 hours as I have some immediate pressing matters at work. But I figured I would back up and respond to things I thought were most pressing in the early stage as well as offer my support. === To: Adi Fairbank <adi@certsite.com>, From: Gunther Birznieks <gunther@extropia.com> Subject: Re: Real Widgets and Template Languages Date: Fri, 25 May 2001 01:00:09 +0800 At 08:50 PM 5/23/01 -0400, Adi Fairbank wrote: >Stephen, > >I read your proposal and I like it a lot. I will help filling out the >HTML::Widget::HTML* space (in your package structure suggestion). > >However, I like Gunther's suggestion for a namespace of Widget:: better than >HTML::Widget::, because it will not be exclusively HTML, but WML, JS10, >etc. But either one is fine with me. What is JS10? JavaScript version 1.0? Should we call it JavaScript or EcmaScript? :) I actually think that Perl objects to generate JS validation routines is worthy of its own abstraction. There are several reasons for this. One is that you need to be able to decouple the javascript tags. So if you validate, say, a text field to contain only numbers, the routine to do it should be in the header of the HTML but the widget that gets drawn needs to reference the right routine. So such a library that can generate this stuff needs to be a little more wise and the new JS tags have to be intelligent to know about each other so that a tag at the top of the page that generates the routines can know ahead of time what routines to generate based on the widgets that appear later in the page. It seems solvable but also a bit hard and scary. While it is possible to make JS-specific components (as a first cut)... I wouldn't want to lose site of the fact that the JS could be an add-on and maybe it is possible that it should be it's own abstract that the widget set needs to be able to hook into but isn't built into separate widgets. The red flag comes in seeing examples like Widget::HTML::DateDropDown Widget::HTML::UserAgentDate Widget::HTML::JSDate if it is like this, then you may have many date widgets flying aroudn that are all HTML widgets but share features with a lot of copy and paste between them which isn't very clean OO. As I write this I am quite sleepy and so please forgive my lack of constructive critique. I just want to point it out and maybe we can revisit this. We don't have to code the JS abstraction but if it is clearly outlined where stuff like JS should interact with the widget library and where it should not, then it will make the job of developing the widget library easier. >Sounds fun! I agree! === To: Chip Turner <cturner@redhat.com>, From: Gunther Birznieks <gunther@extropia.com> Subject: Re: Real Widgets and Template Languages Date: Fri, 25 May 2001 01:10:24 +0800 Related to the previous discussion of closures vs object interface (eg param) for getting CGI form data into the widgets: While I think that it is clever to allow an interface to change where the parameters come from, I think in practice there are different things to expect. eg how to deal with multi-values? How to deal with file upload field? I think there are quirks in various libraries. I do not think these things are insurmountable. And Chip's suggestion stands a good chance of working. I do also think there are so few libraries to deal with parameters that it would not be an unreasonable design decision to make the Widget controller hard code knowledge of CGI.pm, Apache::Request and any others since there really aren't many. At least at first cut. If it looks like there are too many data sources of widget data to deal with then it has to be dealt with. I would also offer the possibility that the data source for a widget should not solely be a CGI.pm object but could conceivably come from many types of data sources and that these data sources might have priorities yet all apply to the same widget controller. Let's take a lesson (not necessarily one to be followed) from PHP. In PHP, variables come into existence automatically. But there are rules that are followed. eg Cookies, Get,. Post which means that if the variable is somehow resulting from a cookie instantiate the var as a the value of the cookie. If there is a GET param of the same name, override the var with the value of the Get param, and if there is a POST as well, then override the value from $ENV{QUERY_STRING} with the value from the POST. Likewise, we might consider that CGI.pm is the primary source of information, but if I pass a db record set to the widget controller along with CGI.pm, I may want CGI.pm to override the database but if there is no CGI.pm value, then the value from the database field will be placed in the widget instead. Anyway, I am sorry if this sounds quite odd. I am not good at explaining things when I am tired, but I did at least want to throw out the idea of not being married yet to a particular way of having a widget consume data from a data source. === To: Chip Turner <cturner@redhat.com> From: Paul Lindner <lindner@inuus.com> Subject: Re: Real Widgets and Template Languages Date: Thu, 24 May 2001 10:22:25 -0700 On Thu, May 24, 2001 at 09:59:36AM -0400, Chip Turner wrote: > darren chamberlain <dlc@users.sourceforge.net> writes: > > The nice thing about closures is they could hide any interface at all > behind them; all that is required is that the function that generates > the closure follow the very simple convention of "return the formvar > of the name starting with the first parameter you're called with." > There is absolutely no reliance upon the underlying object structure. > What you're suggesting is equivalent to assuming the object is derived > from some kind of base class that supports the param() method though > without actually having to be ISA of that class. That's naughty OO > programming :) Just because perl lets you be typeless doesn't mean > it's always in the best interest of clean design to do so. I don't find a problem with passing an object that has a certain set of method signatures. This is functionally loosely equivalent to a Java Interface.. Any perl object can implement a particular interface just by implementing the methods.. No base class required.. But I agree, closure are very cool, and allow for an additional layer of abstraction between the objects, without having to create a proxy class.. > Closures are excellent in hiding implementation details of simple > operations, and I think in this case they fit quite well. The system > can even be written to work just fine without the user using closures > if they're using CGI.pm, as in my previous example. === To: "Gunther Birznieks" <gunther@extropia.com>, From: "David Harris" <dharris@drh.net> Subject: RE: Real Widgets and Template Languages [resend] Date: Thu, 24 May 2001 15:44:38 -0400 [[ This is a resend.. did some cutting and pasting of code into telnet windows that messed it up through shell expansion. My bad. ]] I have a couple modules that might be the start of what you are calling a Widget system. I'm not sure if my modules are in line with the thoughts expressed on this list. Pardon me if this is something different: I've been loosely following this discussion.. Using my library, whenever I want a form I specify in one list all of the elements along with the type of data and any validation routines. Some information about how the form should look is also included. My code then automatically generates the form (it looks like a dialogue box) from this information. The same informational hash is used to parse the form and validate the data. If the data is not validated correctly, the form is shown again with the validation errors and the data remaining sticky. If the data is validated then it is returned in a hash. Here is a simplified example of the widget definitions for a form that allows a customer to charge money on their credit card into their balance: [ amount => { width => "20", same_line => 1, label => "Amount to charge (in dollars)", _label => "Amount to charge", _looks_like => "number", _required => 1, }, [{ addl_require => [{ type => "sub", fields => [qw(amount)], sub => sub { my ($require, $values, $labels) = @_; return "You may not initiate a charge for less than \$5.00." if ( $values->[0] < 5 ); return "You may not initiate a charge for more than \$900.00. If you really do want to charge this much, then you need to call us and we can do it for you." if ( $values->[0] > 900 ); return undef; }, }], }], ] Note the elements "label", "_label", and "same_line" for the "amount" widget specify display attributes. (My actual definition of the form contains more than the widgets themselves but rather the whole look and feel form.) The element "_required" specifies that this widget may not be left blank by the user. The element "_looks_like" with value "number" specifies that the value in this text box must be a number. I can also specify dates, free text, or whatever I needed as types for the widget. The "addl_require" stuff you see is a way of in lining an additional requirement: this requires that the value for the amount field must be between 5.00 and 900.00. The additional requirement is tied specifically to the fields that it is dependent on. For example, if the field "amount" was left blank thus not satisfying the "_required" specification, then this addl_require you see would not be checked, as its dependants has not been verified. Here is another example. This is the definition for the form elements to collect credit card information: [ [qq[ <table border=0> ]], card_type => { c_table => 1, et => "select", label => "Card type", options => [ map { [ $CUST::DbAccess::Lookup::ccard__card_type->{$_}, $_ ] } @$CUST::DbAccess::Lookup::ccard__card_type__keys ], }, card_num => { c_table => 1, width => 30, label => "Card number" }, [{ addl_require => [{ type => "sub", fields => [qw(card_num)], sub => sub { my ($require, $values, $labels) = @_; return "The credit card number you entered is not valid." if ( not Business::CreditCard::validate($values->[0]) ); return undef; }, }], }], [qq[ <tr><td><font size="-1">Expiration</font></td><td> ]], exp_month => { c_blank => 1, et => "select", label => "Exp month", options => [ map { [ $CUST::DbAccess::Lookup::ccard__exp_month->{$_}, $_ ] } @$CUST::DbAccess::Lookup::ccard__exp_month__keys ], }, [qq[ / ]], exp_year => { c_blank => 1, et => "select", label => "Exp year", options => [ map { [ $CUST::DbAccess::Lookup::ccard__exp_year->{$_}, $_ ] } @$CUST::DbAccess::Lookup::ccard__exp_year__keys ], }, [qq[ </td></tr> ]], [q[ <tr><td colspan=2><font size="-1"> <img src="/resources/clear.gif" height=10 width=1><br> If the name on the card is different than your billing address you can enter it below. <br><img src="/resources/clear.gif" height=10 width=1><br> </font></td></tr> ]], card_name => { width => 30, c_table => 1, label => "Name on card" }, [qq[ </table> ]], ] This above code is showing the strains of evolution of my system. :-) Notice all the [qq[ ... ]] constructs which allow HTML text to be inlined. Originally there wasn't much inlined HTML, as each widget knew how to display itself and its label. However I was stuck to one specific display look constrained me. So I told the widgets how to print their labels with "c_blank" and "c_table" parameters and inlined HTML code. This really calls for the widgets to be embedded directly in the HTML template which contains the formatting a la <widget name=card_name> that Gunther proposed. This above code actually sits in a subroutine that returns a list of the definitional information. This list is then simply included other places so I can write stuff like this: [ [qq[ Enter your billing information and credit card.<p> ]], [qq[ <b>Billing information</b><p> ]], [{ default_by_name => CUST::DbAccess::Cust::default_by_name("custs") }], CUST::InterfaceUtil::opensrs_contact_fields($country_select_box, "bill", "Billing"), undef, [qq[ <b>Credit card information</b><p> ]], [{ default_by_name => CUST::DbAccess::Ccard::default_by_name("ccards") }], CUST::InterfaceUtil::credit_card_fields(), undef, ] It's great for reuse. The default_by_name does something interesting: it imports all the defaults for the fields (_looks_like and _required and _size) information from the database table. If I change the size of a text field in a table all the forms which use that text field are automatically updated. (However, I should change the default_by_name system so that it doesn't need to be specified when I'm including default confirmation. Like I said, this system is straining under the evolution.) I can contribute this library if it would help. I'll warn you that there's not too much documentation. I can also contribute some examples of my code that use the library. === To: "Jay Lawrence" <Jay@Lawrence.Net>, <modperl@apache.org> From: Stephen Adkins <stephen.adkins@officevision.com> Subject: Re: Real Widgets and Template Languages Date: Fri, 25 May 2001 02:16:59 -0400 Jay, I think that pretty much describes what I have in mind ... plus a few other features. Hopefully within a week or two (based on demands of other *paying* jobs), I will have a working distribution with most of the bare-bones plumbing in place and a little configurable date widget implemented. This will allow me to solicit feedback on the plumbing and concepts before I go hog wild on implementing a host of widgets. (In fact, I predict the package will be downright boring for a month or more, to those who don't want to shape its development, while I get the concept and the internals right.) I have done the Widget.pm convenience functions and factory code. I am working on the Widget::Config class to read XML config data using XML::Simple. Then on to Widget::Base a parent class for all implemented widgets. Then on to Widget::Controller which will be handed a CGI object (or Apache::Request or whatever using one of the much-commented on schemes) and dispatches events detected from submit buttons, etc. Then I do my first actual widget, Widget::HTML::Date. I'll camp on this while I get lots of feedback. Stephen P.S. I have submitted an application for a Sourceforge project called the "Perl Widget Library". The short name is "perl-widget". I am waiting for approval from Sourceforge. This won't hold me up though. I plan on posting distributions on my web site. === To: Gunther Birznieks <gunther@extropia.com> From: Chip Turner <cturner@redhat.com> Subject: Re: Real Widgets and Template Languages Date: 25 May 2001 02:12:09 -0400 Gunther Birznieks <gunther@extropia.com> writes: > While I think that it is clever to allow an interface to change where > the parameters come from, I think in practice there are different > things to expect. eg how to deal with multi-values? How to deal with > file upload field? I think there are quirks in various libraries. Indeed, these are open questions that aren't dealt with so easily with a closure. But I think for a general widget set, a closure would work. If you want to get really tricky, you can bless the closure... but at that point, you should just be using a class in the first place. > I do not think these things are insurmountable. And Chip's suggestion > stands a good chance of working. I do also think there are so few > libraries to deal with parameters that it would not be an unreasonable > design decision to make the Widget controller hard code knowledge of > CGI.pm, Apache::Request and any others since there really aren't many. I disagree here; Mason, Apache::ASP, embperl, straight modperl, CGI.pm, the various CGI accelerators, etc, are a variety of interfaces. Anytime you have an application framework (or whatever they're called this week), you can have a different interface to even the simplest of things like form variables. Another nice thing about not requiring CGI.pm or libapreq is you can actually feed the formvars from something besides an HTTP submission (useful for page generation into flat html, or for testing). > Likewise, we might consider that CGI.pm is the primary source of > information, but if I pass a db record set to the widget controller > along with CGI.pm, I may want CGI.pm to override the database but if > there is no CGI.pm value, then the value from the database field will > be placed in the widget instead. > > Anyway, I am sorry if this sounds quite odd. I am not good at > explaining things when I am tired, but I did at least want to throw > out the idea of not being married yet to a particular way of having a > widget consume data from a data source. I agree that there are a lot of various issues here for when it comes to handling data input and output. But I think that for something like a Widget set to be useful, it needs to be as decoupled as possible from all external libraries, and still be able to play with them. Now, that means one of two things. (a) Some kind of base class (Some people suggest using an "implied" interface without a true abstract base class that defines the various methods; I am very much against this because it can lead to somewhat sloppy programming. If you're going to use objects, use them in a way that other languages tend to use them and not as typeless chunks that respond to various kinds of black magic poking and prodding). I personally only see this being not-the-best-option because of unnecessary complexity for the fairly simple task at hand. If the task were more complicated, there is no doubt this is the proper route. (b) The other option, a closure, makes the simple things simple, but the harder things a bit harder. File uploads, for instance, and cookies. Of course, since a Widget set rarely (if ever) would need to display the content of an upload as part of a re-rendering of the widget, I don't see this being a common use. Likewise, cookies don't seem as needed to be for more or less the same reason (if you're using raw cookies to pass complex data around, you're probably doing more work than you need to; things like Apache::Session make life easier without forcing you to muck with cookies at every data access point). It gets ugly though if you -do- want cookies. Does your abstract base class (ABT) have to be typed for every possible pair of form var input and cookie input methods? Is there a separate interface for each, thus complicating the API slightly? The more I think about it, the more wrong it seems for the Widget library to assume anything about where its data is coming from. It should either be from a closure or a class based on an ABT. A third option is that all widgets are actually generated by a generator instance of a class; this could simplify the API so that you needn't pass the CGI object or closure around all the time. In this case, you could derive from this base class to create new ways of gathering data from CGI and cookies. This is more or less a standard design pattern -- data interfacing. There are a number of solutions. I just hope whatever gets written is present and future proof enough to not depend on any particular interface (such as CGI or libapreq), or at the very least made to easily use others. You never know when someone else may have another templating technology that has a different interface! === To: lindner@inuus.com From: Chip Turner <cturner@redhat.com> Subject: Re: Real Widgets and Template Languages Date: 25 May 2001 02:16:55 -0400 Paul Lindner <lindner@inuus.com> writes: > On Thu, May 24, 2001 at 09:59:36AM -0400, Chip Turner wrote: > > darren chamberlain <dlc@users.sourceforge.net> writes: > > > > The nice thing about closures is they could hide any interface at all > > behind them; all that is required is that the function that generates > > the closure follow the very simple convention of "return the formvar > > of the name starting with the first parameter you're called with." > > There is absolutely no reliance upon the underlying object structure. > > What you're suggesting is equivalent to assuming the object is derived > > from some kind of base class that supports the param() method though > > without actually having to be ISA of that class. That's naughty OO > > programming :) Just because perl lets you be typeless doesn't mean > > it's always in the best interest of clean design to do so. > > I don't find a problem with passing an object that has a certain set > of method signatures. This is functionally loosely equivalent to a > Java Interface.. Any perl object can implement a particular interface > just by implementing the methods.. No base class required.. My only objection to this (as I stated in another email) is that it leaves things largely unspecified. It's similar to the old perl problem of passing big hashes around; you assume the data is there, but there's no real way to find out without checking keys and so forth. A simple $foo->isa('Widget::CGIData') can ensure that what you're talking to is at least derived from the right thing. Just because perl would let you call methods on a class not derived from a standard base doesn't mean it's necessarily appropriate. An abstract base class offers little overhead (especially if you override all of the methods) while still giving that little bit of insurance about just what you've been passed. In a library that conceivably could be used by a number of people, such discipline would probably be a nice thing, even if it didn't actually buy anything in terms of performance or features. > But I agree, closure are very cool, and allow for an additional layer > of abstraction between the objects, without having to create a proxy > class.. Closures are definitely cool. As someone else mentioned, requiring -all- users of Widgets to use them probably limits the audience, though, so some level of "smartness" in the Widget system would be nice; perhaps autogenerating a closure for the things it knows about (CGI.pm, libapreq, etc). === To: Gunther Birznieks <gunther@extropia.com> From: Chip Turner <cturner@redhat.com> Subject: Re: Real Widgets and Template Languages Date: 25 May 2001 02:31:03 -0400 Gunther Birznieks <gunther@extropia.com> writes: > However, I think it is reasonable to make the interface to support a > data source for the widgets flexible and object based to make it easy > for someone to write a DBI source, a DBM source, an LDAP source, an > Apache::Session source or whatever anyone wants really. I happen to > think DBI and Session sources are cool. I agree; unfortunately writing classes to interface to all of these would be difficult, and it would be difficult to be futureproof. When you hit LDAP and DBI you must then worry about databases, tables, servers, usernames, passwords, etc. It can become cumbersome to do the simple things. > By default, it could be GPC chaining like PHP (Get, Post, > Cookie).... But with enough widget data sources to choose from you > could do > > GPCSD (Get, Post, Cookie, Session, Database) type of thing. This can be done quite well from a closure: my $dbh = DBI->connect(...); my $sth = $dbh->prepare('SELECT foo FROM persistant_data WHERE id = ?'); my $cgi = new CGI; my $data_closre = sub { my $key = shift; my $return = $cgi->param($key); $return = $cgi->cookie($key) unless defined $return; if (not defined $return) { $sth->execute($key); ($return) = $sth->fetchrow; $sth->finish; } return $return; }; Now the closre, though slightly more complicated, doesn't need to know anything about the world around it, and neatly cinches off the interface from Widget into DBI, CGI, cookies, etc etc. Using classes for this would work, but it could be cumbersome; a closure allows for near infinite flexibility... but at the price of complexity. > I think but am not sure that closures likely also have better > performance than method lookups. If this is the case, it could make > sense to support a few data sources that need high performance because > of their common use: CGI.pm and Apache::Request. Yet provide the > extensibility for other developers to inject their own data sources > into the chain using an Object-based API. Closures are indeed faster than both instance method calls and package method calls. However, this is a very basic thing; if performance is critical enough to optimize this portion of a program then likely someone wouldn't be using Widgets anyway :) > Maybe someone else could comment on the technical merit of closure vs > objects as well as the way in which they have been expecting the > widgets to get populated? Is what I am saying make sense? Below is a script to benchark the various invocations. The baseline is for a function (method, closure, package method) to take one data parameter and return something based on it. The results I get on a dual P3 500 are: [cturner@magneto cturner]$ perl bench.pl Benchmark: timing 4000000 iterations of closure, method, pkgmethod... closure: 10 wallclock secs ( 9.88 usr + 0.00 sys = 9.88 CPU) @ 404858.30/s (n=4000000) method: 22 wallclock secs (20.98 usr + 0.00 sys = 20.98 CPU) @ 190657.77/s (n=4000000) pkgmethod: 35 wallclock secs (35.59 usr + 0.00 sys = 35.59 CPU) @ 112391.12/s (n=4000000) bench.pl: #!/usr/bin/perl -w use strict; use Benchmark; my $meth = new Foo; my $cref = sub { my $data = shift; return 1 }; timethese(4000000, { 'method' => sub { return $meth->bar }, 'closure' => sub { return $cref->() }, 'pkgmethod' => sub { return Foo->bar }}); package Foo; sub new { return bless {}, shift; } sub bar { my $self = shift; my $data = shift; return 1; } === To: <modperl@apache.org> From: brian moseley <bcm@maz.org> Subject: Re: Real Widgets and Template Languages Date: Fri, 25 May 2001 01:39:47 -0700 (PDT) On 25 May 2001, Chip Turner wrote: > My only objection to this (as I stated in another email) > is that it leaves things largely unspecified. It's > similar to the old perl problem of passing big hashes > around; you assume the data is there, but there's no > real way to find out without checking keys and so forth. > A simple $foo->isa('Widget::CGIData') can ensure that > what you're talking to is at least derived from the > right thing. Just because perl would let you call > methods on a class not derived from a standard base > doesn't mean it's necessarily appropriate. An abstract > base class offers little overhead (especially if you > override all of the methods) while still giving that > little bit of insurance about just what you've been > passed. In a library that conceivably could be used by > a number of people, such discipline would probably be a > nice thing, even if it didn't actually buy anything in > terms of performance or features. so the only reason you'd provide a superclass is to be able to do an isa check? in what circumstances do you use this kind of check? do you apply it to every argument in every method call? what do you do on failure? i've been wondering how best to specify interfaces (in the java sense) in perl, whether or not to make them classes. possible benefits are type checking (as you've noted above) and verification of the implementation of methods specified by the interface. altho if i could get benefit #2, i wouldn't care about #1, cos i just want to be sure that the implementing class (or one of its ancestors) declares each of the interface methods. and i want this verification at compile time, not runtime. === To: brian moseley <bcm@maz.org> From: Chip Turner <cturner@redhat.com> Subject: Re: Real Widgets and Template Languages Date: 25 May 2001 04:49:48 -0400 brian moseley <bcm@maz.org> writes: > > My only objection to this (as I stated in another email) is that > > it leaves things largely unspecified. It's similar to the old > > perl problem of passing big hashes around; you assume the data is > > there, but there's no real way to find out without checking keys > > and so forth. A simple $foo->isa('Widget::CGIData') can ensure > > that what you're talking to is at least derived from the right > > thing. Just because perl would let you call methods on a class > > not derived from a standard base doesn't mean it's necessarily > > appropriate. An abstract base class offers little overhead > > (especially if you override all of the methods) while still giving > > that little bit of insurance about just what you've been passed. > > In a library that conceivably could be used by a number of people, > > such discipline would probably be a nice thing, even if it didn't > > actually buy anything in terms of performance or features. > > so the only reason you'd provide a superclass is to be able to do an > isa check? in what circumstances do you use this kind of check? do > you apply it to every argument in every method call? what do you do > on failure? Well, not entirely. It's like the difference between using symbolic references and not using symbolic references. Sure, they work, and can be powerful, but they can also be obfuscating and a little obscure. I don't like tossing objects around and expecting them to adhere to some unknown interface that they aren't derived from. The only real difference at the code layer is ->isa, but that's not a large benefit; instead, it's at the design level. Making an abstract base class is very simple, and there's no performance overhead for a class to derive from it if it implements all of its own methods (and one could argue if there -is- common code that can be implemented in non-abstract base methods then there is even more benefit in having an abstract base class). Basically it's "enforcing" a tiny bit of type data in an otherwise more or less typeless world. Code is cleaner if you can say "the nth parameter is derived from the base class Foo::Bar" as opposed to "the nth parameter is an object that must support the baz, blah, foop, and fitz methods that accept parameters in the following way..." > i've been wondering how best to specify interfaces (in the java > sense) in perl, whether or not to make them classes. possible > benefits are type checking (as you've noted above) and verification > of the implementation of methods specified by the interface. altho > if i could get benefit #2, i wouldn't care about #1, cos i just want > to be sure that the implementing class (or one of its ancestors) > declares each of the interface methods. and i want this verification > at compile time, not runtime. Well, you could always do something like: my Foo::Bar $x = shift; This doesn't really gain anything now, but it makes things a bit clearer what exactly is going on. Future perl's may optimize this (right now, if I recall, it only optimizes in the case of pseudohashes). Sadly, you'll never really be able to get compile time type verification in perl (at least, in perl as it stands today). Even the above syntax is only a promise to perl for possible optimizations and not a request for perl to enforce the type of whatever shift returns. Chip === To: <modperl@apache.org> From: brian moseley <bcm@maz.org> Subject: Re: Real Widgets and Template Languages Date: Fri, 25 May 2001 01:57:59 -0700 (PDT) On 25 May 2001, Chip Turner wrote: > Code is cleaner if you can say "the nth parameter is > derived from the base class Foo::Bar" as opposed to "the > nth parameter is an object that must support the baz, > blah, foop, and fitz methods that accept parameters in > the following way..." you can certainly say "the nth parameter implements interface Foo::Bar", and provide Foo/Bar.pod that describes the interface, and get the exact same benefit. i question the wisdom of relying on a code-level inheritance usage to communicate class relationships. isn't that why we use class diagrams and pod? === To: brian moseley <bcm@maz.org> From: Chip Turner <cturner@redhat.com> Subject: Re: Real Widgets and Template Languages Date: 25 May 2001 05:03:35 -0400 brian moseley <bcm@maz.org> writes: > you can certainly say "the nth parameter implements > interface Foo::Bar", and provide Foo/Bar.pod that describes > the interface, and get the exact same benefit. Of course. But you lose nothing by actually making it an ISA relationship; you don't even lose performance. Plus you could do something like this: sub foo { my $self = shift; my $bar = shift; $self->die_because_of_bad_bar_parameter if $DEBUG and not $bar->isa('SomeBase::Class'); ... } You can have the checks in during development, and pull during production. It's not 100% efficient, but it's pretty close. With some use constant magic, you may even be able to get the compiler to optimize away the entire line at compile time, resulting not even in a check on the value of $DEBUG in production environments. > i question the wisdom of relying on a code-level inheritance > usage to communicate class relationships. isn't that why we > use class diagrams and pod? I don't understand why you would rather not have a very simple base class that defines the interface, and then have an ISA relationship with it, instead of simply having several classes with no code level relationship other than supporting the same method calls. Chip === To: Chip Turner <cturner@redhat.com> From: Stas Bekman <stas@stason.org> Subject: Re: Real Widgets and Template Languages Date: Fri, 25 May 2001 17:47:35 +0800 (SGT) On 25 May 2001, Chip Turner wrote: > brian moseley <bcm@maz.org> writes: > > > you can certainly say "the nth parameter implements > > interface Foo::Bar", and provide Foo/Bar.pod that describes > > the interface, and get the exact same benefit. > > Of course. But you lose nothing by actually making it an ISA > relationship; you don't even lose performance. Plus you could do > something like this: > > sub foo { > my $self = shift; > my $bar = shift; > > $self->die_because_of_bad_bar_parameter > if $DEBUG and not $bar->isa('SomeBase::Class'); > ... > } > > You can have the checks in during development, and pull during > production. It's not 100% efficient, but it's pretty close. With > some use constant magic, you may even be able to get the compiler to > optimize away the entire line at compile time, resulting not even in a > check on the value of $DEBUG in production environments. which is true only if it's: use constant DEBUG => 1; and not: $DEBUG = 1; Basically you should be able to turn the development checking at compile time for the whole project via startup.pl: use My::Init qw(PRODUCTION); vs. use My::Init qw(DEVELOPMENT); where the My::Init::import() method will load and compile all the modules that are going to be used, but only after My::Config::DEBUG constant is either set to 0 or 1. So you don't have to remember to manually modify every module, in fact none of them. startup.pl time resolution will make things really flexible. On the other hand under mod_cgi this can be done in the first BEGIN block of every script that you use (but then it's cumbersome, since you have to modify all the scripts all the time, and possibly conflict with CVS) but hey, we are on the mod_perl list :) To conclude, if you make all your checkings/validations only in debug version it doesn't matter how fast or slow they are. I think what matters here is the clearness of the code. === To: "mod_perl list" <modperl@apache.org> From: Gunther Birznieks <gunther@extropia.com> Subject: RE: Real Widgets and Template Languages [resend] Date: Mon, 28 May 2001 22:41:31 +0800 I read this post a few times. At 03:44 PM 5/24/01 -0400, David Harris wrote: >[[ This is a resend.. did some cutting and pasting of code into telnet >windows that messed it up through shell expansion. My bad. ]] > >I have a couple modules that might be the start of what you are calling a >Widget system. I'm not sure if my modules are in line with the thoughts >expressed on this list. Pardon me if this is something different: I've been >loosely following this discussion.. > >Using my library, whenever I want a form I specify in one list all of the >elements along with the type of data and any validation routines. Some >information about how the form should look is also included. My code then >automatically generates the form (it looks like a dialogue box) from this >information. The same informational hash is used to parse the form and >validate the data. If the data is not validated correctly, the form is shown >again with the validation errors and the data remaining sticky. If the data >is validated then it is returned in a hash. I think this is reasonable and correct direction and its good that you've functionally broken the pieces down. But the syntax feels like you are wrapping up too many things at once. We don't really want to define any HTML for the individual widgets. Nor should the widgets know how to validate themselves. Nor should the widgets know how to draw stuff around themselves like tables. >Here is a simplified example of the widget definitions for a form that >allows a customer to charge money on their credit card into their balance: > >[ > amount => { width => "20", same_line => 1, > label => "Amount to charge (in dollars)", _label => "Amount to >charge", > _looks_like => "number", _required => 1, }, > > [{ addl_require => [{ > type => "sub", > fields => [qw(amount)], > sub => sub { > my ($require, $values, $labels) = @_; > return "You may not initiate a charge for less than \$5.00." > if ( $values->[0] < 5 ); > return "You may not initiate a charge for more than \$900.00. If >you really do want to > charge this much, then you need to call us and we can do it >for you." > if ( $values->[0] > 900 ); > return undef; > }, > }], }], >] "Simplified". :) Well, while I think this is interesting, it is too much for a widget library. I think this is fairly clear from the examples. Let's focus a bit. All I (just my opinion) really want is a widget library for is to get and set data in a widget and have the widget subclass know how to display itself. In addition, there should be some mechanism for specifying how the widget sets up it's internal state based on CGI.pm, Apache::Request, Session data or what have you. 1. Data Validation logic. No, this does not belong there. This is a separate library. I already have a rich Data handling library in my toolkit that I intend to plug widgets into. All I need is to be able to get widget data from the data handling/validation library. 2. External display stuff. No, I just want the widget to know how to draw itself and only itself. It's up to a template language plugin like TT or some other template language to provide the wrappings. Or it can be a toolkit like your drawing forms library -- but the widget itself shouldn't have to know about external decoration around it. Just how to draw itself. >This above code is showing the strains of evolution of my system. :-) Notice I don't think it is a strain on the evolution, just that you attempt to combine many different concepts together. I think it's too much. You can abstract away some of these things as noted above. >This really calls for the widgets to be embedded directly in the HTML >template which contains the formatting a la <widget name=card_name> that >Gunther proposed. Yes, but the widgets I propose could also go into a form builder functions like the ones you laid out as well. The widgets are supposed to be flexible to suit any template needs not just TT. >This above code actually sits in a subroutine that returns a list of the >definitional information. This list is then simply included other places so >I can write stuff like this: > >[ > [qq[ > Enter your billing information and credit card.<p> > ]], > > [qq[ <b>Billing information</b><p> ]], > > [{ default_by_name => CUST::DbAccess::Cust::default_by_name("custs") }], > > CUST::InterfaceUtil::opensrs_contact_fields($country_select_box, "bill", >"Billing"), > undef, > > [qq[ <b>Credit card information</b><p> ]], > > [{ default_by_name => CUST::DbAccess::Ccard::default_by_name("ccards") }], > > CUST::InterfaceUtil::credit_card_fields(), > undef, >] > >It's great for reuse. > >The default_by_name does something interesting: it imports all the defaults >for the fields (_looks_like and _required and _size) information from the >database table. If I change the size of a text field in a table all the >forms which use that text field are automatically updated. (However, I >should change the default_by_name system so that it doesn't need to be >specified when I'm including default confirmation. Like I said, this system >is straining under the evolution.) This may be interesting, but I still see this as being too much. It looks more like you have a mini-templating system which is really a language for drawing GUIs but you are also adding extra stuff like the data validation on top of it in the same config. But I think that config can be broken out so that it would make your GUI drawing library much easier to see. >I can contribute this library if it would help. I'll warn you that there's >not too much documentation. I can also contribute some examples of my code >that use the library. It's possible, but I am not quite sure because the primary complexity seems to be the data handling (which I have already in a separate abstraction) and the UI generation which I have already in Template Toolkit. So all I really want is an object abstract called a Widget along with a WidgetCollection to allow grouping widgets together that belong on a given HTML page. So on a personal level, I would say this library is not compelling for what I would like the end-product to be. But others may feel differently. === To: Chip Turner <cturner@redhat.com> From: Gunther Birznieks <gunther@extropia.com> Subject: Re: Real Widgets and Template Languages Date: Mon, 28 May 2001 23:07:49 +0800 I think this post is quite apt. At 02:12 AM 5/25/01 -0400, Chip Turner wrote: >Gunther Birznieks <gunther@extropia.com> writes: > > > While I think that it is clever to allow an interface to change where > > the parameters come from, I think in practice there are different > > things to expect. eg how to deal with multi-values? How to deal with > > file upload field? I think there are quirks in various libraries. > >Indeed, these are open questions that aren't dealt with so easily with >a closure. But I think for a general widget set, a closure would >work. If you want to get really tricky, you can bless the >closure... but at that point, you should just be using a class in the >first place. > > > I do not think these things are insurmountable. And Chip's suggestion > > stands a good chance of working. I do also think there are so few > > libraries to deal with parameters that it would not be an unreasonable > > design decision to make the Widget controller hard code knowledge of > > CGI.pm, Apache::Request and any others since there really aren't many. > >I disagree here; Mason, Apache::ASP, embperl, straight modperl, >CGI.pm, the various CGI accelerators, etc, are a variety of >interfaces. Anytime you have an application framework (or whatever >they're called this week), you can have a different interface to even >the simplest of things like form variables. > >Another nice thing about not requiring CGI.pm or libapreq is you can >actually feed the formvars from something besides an HTTP submission >(useful for page generation into flat html, or for testing). > > > Likewise, we might consider that CGI.pm is the primary source of > > information, but if I pass a db record set to the widget controller > > along with CGI.pm, I may want CGI.pm to override the database but if > > there is no CGI.pm value, then the value from the database field will > > be placed in the widget instead. > > > > Anyway, I am sorry if this sounds quite odd. I am not good at > > explaining things when I am tired, but I did at least want to throw > > out the idea of not being married yet to a particular way of having a > > widget consume data from a data source. > >I agree that there are a lot of various issues here for when it comes >to handling data input and output. But I think that for something >like a Widget set to be useful, it needs to be as decoupled as >possible from all external libraries, and still be able to play with >them. Now, that means one of two things. > >(a) Some kind of base class (Some people suggest using an "implied" >interface without a true abstract base class that defines the various >methods; I am very much against this because it can lead to somewhat >sloppy programming. If you're going to use objects, use them in a way >that other languages tend to use them and not as typeless chunks that >respond to various kinds of black magic poking and prodding). I >personally only see this being not-the-best-option because of >unnecessary complexity for the fairly simple task at hand. If the >task were more complicated, there is no doubt this is the proper >route. > >(b) The other option, a closure, makes the simple things simple, but >the harder things a bit harder. File uploads, for instance, and >cookies. Of course, since a Widget set rarely (if ever) would need to >display the content of an upload as part of a re-rendering of the >widget, I don't see this being a common use. Likewise, cookies don't >seem as needed to be for more or less the same reason (if you're using >raw cookies to pass complex data around, you're probably doing more >work than you need to; things like Apache::Session make life easier >without forcing you to muck with cookies at every data access point). > >It gets ugly though if you -do- want cookies. Does your abstract base >class (ABT) have to be typed for every possible pair of form var >input and cookie input methods? Is there a separate interface for >each, thus complicating the API slightly? > >The more I think about it, the more wrong it seems for the Widget >library to assume anything about where its data is coming from. It >should either be from a closure or a class based on an ABT. A third >option is that all widgets are actually generated by a generator >instance of a class; this could simplify the API so that you needn't >pass the CGI object or closure around all the time. In this case, you >could derive from this base class to create new ways of gathering data >from CGI and cookies. > >This is more or less a standard design pattern -- data interfacing. >There are a number of solutions. I just hope whatever gets written is >present and future proof enough to not depend on any particular >interface (such as CGI or libapreq), or at the very least made to >easily use others. You never know when someone else may have another >templating technology that has a different interface! I think your post makes a lot of sense. How about this as a simple proposal. Widgets should be able to get data from a data source. The interface to obtaining data consists of a name/value pair where a value that is returned is a scalar if one value, a ref to an array if multi valued. Widgets should be able to set data to a data source. The same interface applies (setting data based on name/value pair). I think this is fairly future proof for what widgets need to know. The following Widget-specific data sources would be interesting to me: 1) CGI.pm get/post param 2) CGi.pm cookie name/value 3) Apache::Request 4) DBI result set row 5) Apache::Session As a first cut of possible default supported interfaces. In our contribution, we would support an interface to Extropia::Session (which wraps around Apache::Session but has a few more classes to it) and Extropia::DataSource (which is our abstraction on top of DBI and other data sources in our toolkit). Otherwise, we need 1 and 2 for the Extropia toolkit. So I only need 4 data sources initially. I recommend that this be a Widget::DataSource Later, Gunther === To: Stephen Adkins <stephen.adkins@officevision.com>, From: Gunther Birznieks <gunther@extropia.com> Subject: Re: Real Widgets and Template Languages Date: Mon, 28 May 2001 23:10:33 +0800 At 02:16 AM 5/25/01 -0400, Stephen Adkins wrote: >Jay, > >I think that pretty much describes what I have in mind ... >plus a few other features. > >Hopefully within a week or two (based on demands of other *paying* jobs), >I will have a working distribution with most of the bare-bones plumbing in >place and a little configurable date widget implemented. > >This will allow me to solicit feedback on the plumbing and concepts >before I go hog wild on implementing a host of widgets. >(In fact, I predict the package will be downright boring for a month or more, >to those who don't want to shape its development, while I get the >concept and the internals right.) > >I have done the Widget.pm convenience functions and factory code. >I am working on the Widget::Config class to read XML config data using >XML::Simple. >Then on to Widget::Base a parent class for all implemented widgets. >Then on to Widget::Controller which will be handed a CGI object >(or Apache::Request or whatever using one of the much-commented on schemes) >and dispatches events detected from submit buttons, etc. >Then I do my first actual widget, Widget::HTML::Date. >I'll camp on this while I get lots of feedback. I don't understand the Widget::Controller. Can you say more about this? Also will we require XML to configure? Or is this also an optional feature that you more or less want for yourself but others can choose to not use? Thanks, Gunther === To: Chip Turner <cturner@redhat.com> From: Gunther Birznieks <gunther@extropia.com> Subject: Re: Real Widgets and Template Languages Date: Mon, 28 May 2001 23:13:48 +0800 At 02:31 AM 5/25/01 -0400, Chip Turner wrote: >Gunther Birznieks <gunther@extropia.com> writes: > > > However, I think it is reasonable to make the interface to support a > > data source for the widgets flexible and object based to make it easy > > for someone to write a DBI source, a DBM source, an LDAP source, an > > Apache::Session source or whatever anyone wants really. I happen to > > think DBI and Session sources are cool. > >I agree; unfortunately writing classes to interface to all of these >would be difficult, and it would be difficult to be futureproof. When >you hit LDAP and DBI you must then worry about databases, tables, >servers, usernames, passwords, etc. It can become cumbersome to do >the simple things. I disagree. I've written interfaces like this before to LDAP and DBI. The constructor (or config method) on a data source is stuff like usernames/ passwords, and in the case of LDAP, schema mappings. As long as the actual methods for getting and setting the data are the same, you just can get away with making the constructor for the data source the place where you define all this driver specific stuff. The design pattern here is that driver specific stuff goes into a constructor or config method. But leave the rest of the methods alone. This allows you to plug and play the objects. === To: modperl@apache.org From: James G Smith <JGSmith@TAMU.Edu> Subject: Re: Real Widgets and Template Languages Date: Mon, 28 May 2001 10:49:14 -0500 Gunther Birznieks <gunther@extropia.com> wrote: >At 02:31 AM 5/25/01 -0400, Chip Turner wrote: >>Gunther Birznieks <gunther@extropia.com> writes: >> >> > However, I think it is reasonable to make the interface to support a >> > data source for the widgets flexible and object based to make it easy >> > for someone to write a DBI source, a DBM source, an LDAP source, an >> > Apache::Session source or whatever anyone wants really. I happen to >> > think DBI and Session sources are cool. >> >>I agree; unfortunately writing classes to interface to all of these >>would be difficult, and it would be difficult to be futureproof. When >>you hit LDAP and DBI you must then worry about databases, tables, >>servers, usernames, passwords, etc. It can become cumbersome to do >>the simple things. > >I disagree. I've written interfaces like this before to LDAP and DBI. The >constructor (or config method) on a data source is stuff like usernames/ >passwords, and in the case of LDAP, schema mappings. Hmm... Something I'd like to see is a set of classes in Perl for managing LDAP. These classes would need to be generic (configurable) enough to work with any LDAP schema. They would need to provide an audit trail, transaction log, etc., that could be used to replay changes made to LDAP. They would need to be able to enforce data consistancy across branches and data integrity. If noone gets to it before I do, I'll port my PHP code to Perl :) Oh, and locking mechanisms used must be transferable between machines -- I lock resource A on machine X and then hand off the lock to machine Y -- this code must be useful in a distributed environment (web farm) and robust enough for use in a PKI. === To: modperl@apache.org From: Kip Hampton <khampton@totalcinema.com> Subject: Re: Real Widgets and Template Languages Date: Mon, 28 May 2001 11:41:33 -0400 Gunther Birznieks wrote: <snip/> > The design pattern here is that driver specific stuff goes into a > constructor or config method. But leave the rest of the methods alone. This > allows you to plug and play the objects. I like that. Every time the idea of widgets (small w) comes up, my mind wanders back to UIML [1]. In a nutshell, UIML tries to define a simple markup syntax for making device/language-agnostic user interfaces. So, theoretically, you could build Web, WAP, Tk, etc. applications from the same base document. It may be worth another look in this context. I'm not suggesting, BTW, that Widget::* stuff should be based on UIML (or any other ML du jour) only that it's a bit of prior art relevant to building client/device-neutral UIs that we might be able to borrow from. -kip [1] http://www.uiml.org/specs/uiml2/index.htm === To: Gunther Birznieks <gunther@extropia.com>, From: Stephen Adkins <stephen.adkins@officevision.com> Subject: Re: Real Widgets and Template Languages Date: Mon, 28 May 2001 12:15:54 -0400 Hi, Development of a straw-man set of Perl Widget Library core classes is going well. A Sourceforge project (perl-widget) is in the process of being set up too. (I will announce when it is set up.) The first 0.01 release will be for public comment on the structure and concepts of the core classes. With regard to all of the debate on closures/classes/etc., let me say that I intend for the PWL to be useful in a variety of environments with different people using more or less of the features. I am favoring flexibility over performance at the moment, so full classes are being used to access the different features of the different systems with which it will need to interface. At the low end, the PWL will support the simple use that Gunther requires: simple generation of HTML of a named widget based on configuration information. At the high end, Jay Lawrence and I envision much more sophisticated features ... but let's not let the consideration of those get in the way of accomplishing our first task as described above. A Template Toolkit user should be able to say [%PERL%] use Widget; $stash->{wc} = Widget->controller(); [%END%] Birth Date: [% wc.widget("birth_date") %] or eventually something simpler like [% USE wc = Widget %] Birth Date: [% wc.birth_date %] and the appropriately configured HTML will be inserted. For non-users of Template Toolkit, they can do the comparable perl ... use Widget; $wc = Widget->controller(); $widget = $wc->widget("birth_dt"); print "Birth Date: ", $widget->html(), "\n"; The rendering of this widget as HTML requires at least the following * config information (Widget::Config) * state information (to get the current value) (Widget::CGI::State in a CGI environment) The state information can be accessed from *any* source by implementing an appropriate Widget::<DataSource>::State class (and using some additional, not-yet-implemented arguments to Widget->controller()). see below for more comments ... At 11:10 PM 5/28/2001 +0800, Gunther Birznieks wrote: >At 02:16 AM 5/25/01 -0400, Stephen Adkins wrote: >... >>I have done the Widget.pm convenience functions and factory code. >>I am working on the Widget::Config class to read XML config data using >>XML::Simple. >>Then on to Widget::Base a parent class for all implemented widgets. >>Then on to Widget::Controller which will be handed a CGI object >>(or Apache::Request or whatever using one of the much-commented on schemes) >>and dispatches events detected from submit buttons, etc. >>Then I do my first actual widget, Widget::HTML::Date. >>I'll camp on this while I get lots of feedback. > >I don't understand the Widget::Controller. Can you say more about this? The Widget::Controller (or perhaps, Widget::CGI::Controller) is the container class that you spoke about in your original post. I call it a Controller rather than a Container because I envision it being able to dispatch events generated by the widgets. >Also will we require XML to configure? Or is this also an optional feature >that you more or less want for yourself but others can choose to not use? Configuration data is read in via the Widget::Config class, and this class can be replaced with a class which reads config data from any other source, as long as it conforms to the same calling interface. I was under the impression that XML was your desired means of writing a config file. Do you have a preference to use something different? >Thanks, > Gunther Stephen === To: Gunther Birznieks <gunther@extropia.com>, From: Stephen Adkins <stephen.adkins@officevision.com> Subject: Re: Real Widgets and Template Languages Date: Mon, 28 May 2001 17:17:12 -0400 > >I don't understand the Widget::Controller. Can you say more about this? > >Also will we require XML to configure? Or is this also an optional feature >that you more or less want for yourself but others can choose to not use? > Hi, Below is running code for the Perl Widget Library. So far, there are only two widgets. * a generic Widget::HTML::Element * a drop-down menu Widget::HTML::Select Are there early comments on the interface from Perl? Is this shaping up into what was desired? Stephen shark:/usr/ov/acoc/dev/src/Widget/examples> more Widget.xml Widget.2 :::::::::::::: Widget.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="sex" widget-type='sex'/> <widget-type name="date" tag='input' type='text' size='14' maxlength='99'/> <widget-type name="sex" widget-class='Widget::HTML::Select' domain='sex'/> <domain name="sex"> <item name="M" label="Male"/> <item name="F" label="Female"/> </domain> </config> :::::::::::::: Widget.2 :::::::::::::: #!/usr/local/bin/perl use lib ".."; use Widget; my ($wc, $widget, @widgets); $wc = Widget->controller(); $widget = $wc->widget("first_name"); print "First Name: ", $widget->html(), "\n"; $widget = $wc->widget("last_name"); print "Last Name: ", $widget->html(), "\n"; $widget = $wc->widget("birth_dt"); print "Birth Date: ", $widget->html(), "\n"; $widget = $wc->widget("sex"); print "Sex: ", $widget->html(), "\n"; shark:/usr/ov/acoc/dev/src/Widget/examples> Widget.2 First Name: <input name='first_name' maxlength='99' size='14' type='text'/> Last Name: <input name='last_name' maxlength='99' size='14' type='text'/> Birth Date: <input name='birth_dt' maxlength='99' size='14' type='text'/> Sex: <select name='sex'> <option value='M'>Male</option> <option value='F'>Female</option> </select> === To: Stephen Adkins <stephen.adkins@officevision.com>, From: Gunther Birznieks <gunther@extropia.com> Subject: Re: Real Widgets and Template Languages Date: Tue, 29 May 2001 21:49:02 +0800 At 12:15 PM 5/28/01 -0400, Stephen Adkins wrote: >Hi, > >Development of a straw-man set of Perl Widget Library core classes is >going well. A Sourceforge project (perl-widget) is in the process of being >set up too. (I will announce when it is set up.) > >The first 0.01 release will be for public comment on >the structure and concepts of the core classes. > >With regard to all of the debate on closures/classes/etc., let me say that >I intend for the PWL to be useful in a variety of environments with >different people using more or less of the features. >I am favoring flexibility over performance at the moment, so full classes >are being used to access the different features of the different systems >with which it will need to interface. I think this makes sense. I would like to see the model worked out well before eeking out the performance. >At the low end, the PWL will support the simple use that Gunther requires: >simple generation of HTML of a named widget based on configuration >information. Thanks. :) >At the high end, Jay Lawrence and I envision much more sophisticated >features ... >but let's not let the consideration of those get in the way of >accomplishing our >first task as described above. > >A Template Toolkit user should be able to say > > [%PERL%] > use Widget; > $stash->{wc} = Widget->controller(); > [%END%] > > Birth Date: [% wc.widget("birth_date") %] > >or eventually something simpler like > > [% USE wc = Widget %] > > Birth Date: [% wc.birth_date %] > >and the appropriately configured HTML will be inserted. >For non-users of Template Toolkit, they can do the comparable perl ... > > use Widget; > $wc = Widget->controller(); > $widget = $wc->widget("birth_dt"); > print "Birth Date: ", $widget->html(), "\n"; I think this seems reasonable. >The rendering of this widget as HTML requires at least the following > > * config information (Widget::Config) I'll talk about config in a bit. > * state information (to get the current value) (Widget::CGI::State in a >CGI environment) > >The state information can be accessed from *any* source by implementing an >appropriate >Widget::<DataSource>::State class (and using some additional, >not-yet-implemented arguments >to Widget->controller()). I think it would be better as a Widget::State::<DataSource> rather than the other way around. From the way you describe it, this is really an interface to getting state information that should be retrieved from a DataSource specific state driver. >see below for more comments ... > >At 11:10 PM 5/28/2001 +0800, Gunther Birznieks wrote: > >At 02:16 AM 5/25/01 -0400, Stephen Adkins wrote: > >... > >>I have done the Widget.pm convenience functions and factory code. > >>I am working on the Widget::Config class to read XML config data using > >>XML::Simple. > >>Then on to Widget::Base a parent class for all implemented widgets. > >>Then on to Widget::Controller which will be handed a CGI object > >>(or Apache::Request or whatever using one of the much-commented on schemes) > >>and dispatches events detected from submit buttons, etc. > >>Then I do my first actual widget, Widget::HTML::Date. > >>I'll camp on this while I get lots of feedback. > > > >I don't understand the Widget::Controller. Can you say more about this? > >The Widget::Controller (or perhaps, Widget::CGI::Controller) is the >container class >that you spoke about in your original post. I call it a Controller rather >than >a Container because I envision it being able to dispatch events generated >by the >widgets. Ah. I just want something to contain the widgets essentially. So perhaps from my perspective events aren't necessary and I would potentially just place the widgets into an array representing my HTML screen. > >Also will we require XML to configure? Or is this also an optional feature > >that you more or less want for yourself but others can choose to not use? > >Configuration data is read in via the Widget::Config class, and this class can >be replaced with a class which reads config data from any other source, as >long as >it conforms to the same calling interface. > >I was under the impression that XML was your desired means of writing a >config file. >Do you have a preference to use something different? I like XML for Config files, we use that in our Java stuff all the time. But Perl is one of the nicest and flexible config file languages out there. IE My config file is Perl. Anyway, I think it is weird to think of configuring just widgets. Usually you configure an application and widgets are a part of that. But everyone here will have a different way of preferring to write their application config whether it's XML or Perl and what features of these that are used (eg just a set of scalars or references to hashes or ... ?) or in the case of XML using attributes versus subtags... I am not quite sure that the configuration is so extensive for each individual widget that it can't be done by having a named parameter constructor similar to that handled by CGI.pm rearrange() calls. Maybe what makes sense is that your Widget::Controller that deals with events is separate and used in your application and is more complex so it needs config. I don't see it being something that necessarily needs to be included in what I need Widget's for. Anyway, no matter what I dislike forcing the use of a toolkit to have to use XML except as an advanced option. Many of the parsers require binary compilation and at that, parsing XML is much slower than simply passing a config data structure written in Perl itself. This is a problem for people like me who write applications that must run everywhere very easily. So although I like to optimize if possible for mod_perl, I also want mod_cgi users at most any ISP able to use our scripts without having to force the ISP to compile a module. Thanks, Gunther === To: Stephen Adkins <stephen.adkins@officevision.com>, From: Gunther Birznieks <gunther@extropia.com> Subject: Re: Real Widgets and Template Languages Date: Tue, 29 May 2001 21:53:44 +0800 At 05:17 PM 5/28/01 -0400, Stephen Adkins wrote: > > > >I don't understand the Widget::Controller. Can you say more about this? > > > >Also will we require XML to configure? Or is this also an optional feature > >that you more or less want for yourself but others can choose to not use? > > > >Hi, > >Below is running code for the Perl Widget Library. >So far, there are only two widgets. > > * a generic Widget::HTML::Element > * a drop-down menu Widget::HTML::Select > >Are there early comments on the interface from Perl? >Is this shaping up into what was desired? > >Stephen > >shark:/usr/ov/acoc/dev/src/Widget/examples> more Widget.xml Widget.2 >:::::::::::::: >Widget.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="sex" widget-type='sex'/> > <widget-type name="date" tag='input' type='text' size='14' maxlength='99'/> > <widget-type name="sex" widget-class='Widget::HTML::Select' domain='sex'/> > <domain name="sex"> > <item name="M" label="Male"/> > <item name="F" label="Female"/> > </domain> ></config> This config seems simple enough that it doesn't seem that necessary to use XML. >:::::::::::::: >Widget.2 >:::::::::::::: >#!/usr/local/bin/perl > >use lib ".."; > > use Widget; > > my ($wc, $widget, @widgets); > $wc = Widget->controller(); Don't you need to provide the controller with a CGI object? I guess this part hasn't been necessary yet, so the widget controller is just like a hash allowing widgets to be associated by name. > $widget = $wc->widget("first_name"); > print "First Name: ", $widget->html(), "\n"; A widget type has already been defined. So I don't see that the method to output it's display should be called html() which is, well, HTML specific. I prefer print "First Name: ", $widget->display(), "\n"; Since widgets are components that know how to display themselves whether its WML or HTML or whatever. Thanks, Gunther === To: "Stephen Adkins" <stephen.adkins@officevision.com>, <modperl@apache.org>, From: "Jay Lawrence" <Jay@Lawrence.Net> Subject: Re: Real Widgets and Template Languages Date: Tue, 29 May 2001 10:08:47 -0400 My $0.02 on XML config files. Although they may be attractive to some, personally, I don't like them. I see XML is merely the expression of the configurable parameters of the object. IE it is just a means to the end. Personally, I would like to define my widget properties through a GUI and then will probably use Storable to dehydrate and rehydrate my widget objects. I would never want to code up XML data and I don't think I'm alone. :) Definately when it comes to interchanging your widget data with another system something like XML really starts to make sense. I don't think it makes sense necessarily for your internal day-to-day operations. What I would advocate is that there are a variety of sources for widget configuration data from something as simple and elegant as Perl code to XML of some layout to Storable data stored in a blob field of a DBI source. e.g. $widget->serialize( [ "Storable" ] ) returns scalar ref to Storable data $widget->serialize("XML") returns scalar ref to XML string $widget->define( \$StorableData [, "Storable" ] ) $widget->define( \$XMLData, "XML") Then you can easily write a Widget Controller that can be configured as to what method to use and where to store it to/from. Ideally these methods would always be inherited from the base widget class which will dictate the runtime implementation of widget data. Jay === To: Gunther Birznieks <gunther@extropia.com>, From: Stephen Adkins <stephen.adkins@officevision.com> Subject: Re: Real Widgets and Template Languages Date: Tue, 29 May 2001 10:27:14 -0400 At 09:49 PM 5/29/2001 +0800, Gunther Birznieks wrote: >At 12:15 PM 5/28/01 -0400, Stephen Adkins wrote: >>Hi, >> >>Development of a straw-man set of Perl Widget Library core classes is >>going well. A Sourceforge project (perl-widget) is in the process of being >>set up too. (I will announce when it is set up.) ... >>The state information can be accessed from *any* source by implementing an >>appropriate >>Widget::<DataSource>::State class (and using some additional, >>not-yet-implemented arguments >>to Widget->controller()). > >I think it would be better as a Widget::State::<DataSource> rather than the >other way around. From the way you describe it, this is really an interface >to getting state information that should be retrieved from a DataSource >specific state driver. I have come to the same conclusion. I am changing the design to have three core base classes (other than the widgets): Widget::Controller Widget::Config Widget::State A CGI program might run with the following derived classes: (These are the initial defaults I am working on.) Widget::Controller::CGI Widget::Config::XML Widget::State::CGI All of these "drivers" may be overridden, as long as the driver you replace it with conforms to the interface definition described by the core base classes. (Kind of like a Java interface. You would be encouraged to derive from the core base classes, but that is not necessary.) ... >> > >> >I don't understand the Widget::Controller. Can you say more about this? >> >>The Widget::Controller (or perhaps, Widget::CGI::Controller) is the >>container class >>that you spoke about in your original post. I call it a Controller rather >>than >>a Container because I envision it being able to dispatch events generated >>by the >>widgets. > >Ah. I just want something to contain the widgets essentially. So perhaps >from my perspective events aren't necessary and I would potentially just >place the widgets into an array representing my HTML screen. > I have found that event handling comes in surprisingly handy even for simple tasks. Essentially, it allows widgets to define callbacks. For instance, the DateDropDowns widget defines an event "change" (modelled after the Javascript "onChange" event) that, when triggered, concatenates the YYYY, MM, and DD back into YYYY-MM-DD. The following is working code. Notice that the "$wc->dispatch_events($query);" statement takes care of whatever widget housecleaning there may be (in this case, recomposing the date as a single variable from the three drop-downs). :::::::::::::: 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(); $wc->dispatch_events($query); print <<EOF; Content-type: text/html <head> <title>cgisample</title> </head> <body bgcolor=#ffffff> <h1>cgisample</h1> <hr> <form method='POST'> EOF $anniv_dt = $wc->widget("anniv_dt"); $button = $wc->widget("check_it"); print "Anniversary Date: ", $anniv_dt->html(), "<br>\n"; print $button->html(), "<br>\n"; print "Your anniversary date appears to be: ", $anniv_dt->value("anniv_dt"), "<br>\n"; print <<EOF; </form> </body> </html> >> >Also will we require XML to configure? Or is this also an optional feature >> >that you more or less want for yourself but others can choose to not use? >> >>Configuration data is read in via the Widget::Config class, and this class can >>be replaced with a class which reads config data from any other source, as >>long as >>it conforms to the same calling interface. >> >>I was under the impression that XML was your desired means of writing a >>config file. >>Do you have a preference to use something different? > >I like XML for Config files, we use that in our Java stuff all the time. >But Perl is one of the nicest and flexible config file languages out there. >IE My config file is Perl. > >Anyway, I think it is weird to think of configuring just widgets. Usually >you configure an application and widgets are a part of that. But everyone >here will have a different way of preferring to write their application >config whether it's XML or Perl and what features of these that are used >(eg just a set of scalars or references to hashes or ... ?) or in the case >of XML using attributes versus subtags... I had the hunch that everyone's configuration needs would be different. Hence the Widget::Config (interface) and Widget::Config::XML (driver) design. (Thanks for the input.) >I am not quite sure that the configuration is so extensive for each >individual widget that it can't be done by having a named parameter >constructor similar to that handled by CGI.pm rearrange() calls. > >Maybe what makes sense is that your Widget::Controller that deals with >events is separate and used in your application and is more complex so it >needs config. I don't see it being something that necessarily needs to be >included in what I need Widget's for. Right. I have many more requirements I eventually want to support (such as internationalization). The trick is making the design such that it works in the simple case for simple things, while supporting advanced features for those who wish to use them. I think it is coming together pretty well. >Anyway, no matter what I dislike forcing the use of a toolkit to have to >use XML except as an advanced option. Many of the parsers require binary >compilation and at that, parsing XML is much slower than simply passing a >config data structure written in Perl itself. Good points. It is now optional, as long as you provide an alternative class. >This is a problem for people like me who write applications that must run >everywhere very easily. So although I like to optimize if possible for >mod_perl, I also want mod_cgi users at most any ISP able to use our scripts >without having to force the ISP to compile a module. Right. I absolutely want to support the plain vanilla CGI user as well. >Thanks, > Gunther Stephen P.S. uh oh. As I am about to send this, I see several more messages have come in on the thread. I'll check them in a moment. === To: "Jay Lawrence" <Jay@Lawrence.Net>, From: "Issac Goldstand" <neoi@writeme.com> Subject: Re: Real Widgets and Template Languages Date: Tue, 29 May 2001 17:27:37 +0200 > My $0.02 on XML config files. Although they may be attractive to some, > personally, I don't like them. > > I see XML is merely the expression of the configurable parameters of the > object. IE it is just a means to the end. Personally, I would like to define > my widget properties through a GUI and then will probably use Storable to > dehydrate and rehydrate my widget objects. I would never want to code up XML > data and I don't think I'm alone. :) > > Definately when it comes to interchanging your widget data with another > system something like XML really starts to make sense. I don't think it > makes sense necessarily for your internal day-to-day operations. > > What I would advocate is that there are a variety of sources for widget > configuration data from something as simple and elegant as Perl code to XML > of some layout to Storable data stored in a blob field of a DBI source. Actually, I personally think that you're both correct here - I think the proper way to stash the widgets would be through Storable. If you wish to do it through XML, then that should call for an extension to Storable which can store/retrieve data from XML. === To: Gunther Birznieks <gunther@extropia.com>, From: Robert Landrum <rlandrum@capitoladvantage.com> Subject: Re: Real Widgets and Template Languages Date: Tue, 29 May 2001 11:02:53 -0400 At 9:53 PM +0800 5/29/01, Gunther Birznieks wrote: >At 05:17 PM 5/28/01 -0400, Stephen Adkins wrote: >> > >>>I don't understand the Widget::Controller. Can you say more about this? >>> >>>Also will we require XML to configure? Or is this also an optional feature >>>that you more or less want for yourself but others can choose to not use? >>> >> >>Hi, >> >>Below is running code for the Perl Widget Library. >>So far, there are only two widgets. >> >> * a generic Widget::HTML::Element >> * a drop-down menu Widget::HTML::Select >> >>Are there early comments on the interface from Perl? >>Is this shaping up into what was desired? >> >>Stephen >> >>shark:/usr/ov/acoc/dev/src/Widget/examples> more Widget.xml Widget.2 >>:::::::::::::: >>Widget.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="sex" widget-type='sex'/> >> <widget-type name="date" tag='input' type='text' size='14' maxlength='99'/> >> <widget-type name="sex" widget-class='Widget::HTML::Select' domain='sex'/> >> <domain name="sex"> >> <item name="M" label="Male"/> >> <item name="F" label="Female"/> >> </domain> >></config> > >This config seems simple enough that it doesn't seem that necessary >to use XML. Yes, but that's only because it defines 4 widgets... I'd probably expect somewhere between 50-100 widgets on average, and more the 500 in extreme cases. A perl hashref config file requires knowledge of perl data structures, which most designers won't grasp. Since I'm not the designer for my site, nor am I the guy developing the underlying data structure, I wouldn't feel comfortable using perl as the config file. XML makes for a nice, easily understood medium for communicating configuration directives. >>:::::::::::::: >>Widget.2 >>:::::::::::::: >>#!/usr/local/bin/perl >> >>use lib ".."; >> >> use Widget; >> >> my ($wc, $widget, @widgets); >> $wc = Widget->controller(); > >Don't you need to provide the controller with a CGI object? I guess >this part hasn't been necessary yet, so the widget controller is >just like a hash allowing widgets to be associated by name. > >> $widget = $wc->widget("first_name"); >> print "First Name: ", $widget->html(), "\n"; > >A widget type has already been defined. So I don't see that the >method to output it's display should be called html() which is, >well, HTML specific. I prefer > >print "First Name: ", $widget->display(), "\n"; >Since widgets are components that know how to display themselves >whether its WML or HTML or whatever. What about draw? display might be misinterpreted. If I draw something, does that mean I've displayed it? Under the Xwindow system, widgets are drawn and then shown, IIRC... print "First Name: ", $widget->draw(),"\n"; === To: "Issac Goldstand" <neoi@writeme.com>, "Jay Lawrence" <Jay@Lawrence.Net>, From: Stephen Adkins <stephen.adkins@officevision.com> Subject: Re: Real Widgets and Template Languages Date: Tue, 29 May 2001 11:12:17 -0400 At 05:27 PM 5/29/2001 +0200, Issac Goldstand wrote: > >> My $0.02 on XML config files. Although they may be attractive to some, >> personally, I don't like them. >> >> I see XML is merely the expression of the configurable parameters of the >> object. IE it is just a means to the end. Personally, I would like to >define >> my widget properties through a GUI and then will probably use Storable to >> dehydrate and rehydrate my widget objects. I would never want to code up >XML >> data and I don't think I'm alone. :) >> >> Definately when it comes to interchanging your widget data with another >> system something like XML really starts to make sense. I don't think it >> makes sense necessarily for your internal day-to-day operations. >> >> What I would advocate is that there are a variety of sources for widget >> configuration data from something as simple and elegant as Perl code to >XML >> of some layout to Storable data stored in a blob field of a DBI source. > >Actually, I personally think that you're both correct here - I think the >proper way to stash the widgets would be through Storable. If you wish to >do it through XML, then that should call for an extension to Storable which >can store/retrieve data from XML. > > Issac I completely understand what all three of you are saying, and I think the needs of the Gunther and Jay are being accommodated in the new design. However, a note on XML and Storable ... The XML::Simple class allows you a "cache" option (which I am using) where it caches the perl data structure in a Storable. The XML::Simple class reads the XML file into a perl data structure, then stores it as a Storable. On subsequent reads, it checks the timestamps of the .xml file and the .stor file and only rereads the XML file if it is newer than the .stor file. Otherwise, it just reads the .stor file. This appears to be about 3x faster. It would be kind of interesting if the Storable class were extended to store as XML ... ;-) Stephen === To: Gunther Birznieks <gunther@extropia.com> From: James G Smith <JGSmith@TAMU.Edu> Subject: Re: Real Widgets and Template Languages Date: Tue, 29 May 2001 10:23:27 -0500 Gunther Birznieks <gunther@extropia.com> wrote: >At 12:15 PM 5/28/01 -0400, Stephen Adkins wrote: >>The rendering of this widget as HTML requires at least the following >> >> * config information (Widget::Config) [snip] >> >Also will we require XML to configure? Or is this also an optional feature >> >that you more or less want for yourself but others can choose to not use? >> >>Configuration data is read in via the Widget::Config class, and this class can >>be replaced with a class which reads config data from any other source, as >>long as >>it conforms to the same calling interface. >> >>I was under the impression that XML was your desired means of writing a >>config file. >>Do you have a preference to use something different? > >I like XML for Config files, we use that in our Java stuff all the time. >But Perl is one of the nicest and flexible config file languages out there. >IE My config file is Perl. > >Anyway, I think it is weird to think of configuring just widgets. Usually >you configure an application and widgets are a part of that. But everyone >here will have a different way of preferring to write their application >config whether it's XML or Perl and what features of these that are used >(eg just a set of scalars or references to hashes or ... ?) or in the case >of XML using attributes versus subtags... IMHO, having a configuration API is much better than requiring a particular way to do configuration. If the backend configuration is done via Perl code, then any configuration file format can be supported with an appropriate module handling it. These widget configurations will need to be flexible enough that I can construct a page with them without any knowledge of how they will look -- the configurations should be tie-able to an overall theme for the site. I've always been a champion of themes for websites. I should be able to select a configuration at run-time without a lot of trouble. === To: Gunther Birznieks <gunther@extropia.com>, From: Stephen Adkins <stephen.adkins@officevision.com> Subject: Re: Real Widgets and Template Languages Date: Tue, 29 May 2001 12:31:47 -0400 At 09:53 PM 5/29/2001 +0800, Gunther Birznieks wrote: >At 05:17 PM 5/28/01 -0400, Stephen Adkins wrote: ... >> $widget = $wc->widget("first_name"); >> print "First Name: ", $widget->html(), "\n"; > >A widget type has already been defined. So I don't see that the method to >output it's display should be called html() which is, well, HTML specific. >I prefer > >print "First Name: ", $widget->display(), "\n"; > >Since widgets are components that know how to display themselves whether >its WML or HTML or whatever. This is a philosophical design decision that I have been struggling with. The widget does indeed know that it should generate HTML, so it could have a method, $widget->display(), $widget->draw(), etc. However, this implies that the widget has the freedom to decide how it should render itself and that the caller does not need to know. This is not correct. The caller in this case has already cooked up a bunch of HTML and is counting on the widget to produce HTML which can be inserted. The widget does *not* have the freedom to render any other way. This is why I have (sort of stubbornly) stuck with the $widget->html() method despite the unanimous suggestions for a $widget->display() method. I do believe there is a place for a display() method, but it is at the controller level. The is the level at which the caller may not know what technologies are being used by the widgets. This whole discussion brings out two other important design decisions. 1. What are the UI technologies we really wish to support? (i.e. is this *really* a Widget or an HTML::Widget library?) 2. Which classes represent Logical Widgets and which Physical Widgets? 1. TECHNOLOGIES I propose that the following technologies will have supporting Controller/State/Widget combinations to make this not just another web widget library. * CGI/HTML - a web application * mod_perl/HTML - similar, a web application using mod_perl * WAP/WML - driven from a WAP device * X11 (Gtk-Perl) - an X windows application * Curses (terminal) - a screen-oriented terminal application * Term - a line-oriented (scrolling) terminal application * Cmd - similar to Term, but the state must be saved between each cmd (I know I'm stretching the paradigm a little bit here, probably beyond what is reasonable. If you don't think one or more of these is a good idea, please keep it to yourself. I have a vision for it, and even if it's not very useful, it will shape the "abstractness" of the design elements. On the other hand, I would welcome suggestions for additional UI technologies that I might consider supporting.) One of the primary design rules is to *not* fall into the "least common denominator" trap. Many cross-platform application frameworks have done this and failed. Rather, the design goal is to *enable* the widget to fully utilize the capabilities of the technical environment it is in. This brings me to the next topic. 2. LOGICAL vs. PHYSICAL USER INTERFACE ELEMENTS I have spoken about the separation of the logical and physical user interface. This facilitates applications being written to the logical interface. The physical UI is then determined at a combination of configuration-time (config file) and run-time (user preferences, browser capabilities, etc.). As the library has developed, it has become clear that the "logical UI" is really only a figment of the coder's imagination, represented by code like $widget = $wc->widget("file_name"); However, the Widget::Controller ($wc) decides (based on config and runtime values) which *physical* UI widget is returned. This could be a drop-down list box (<select>), a text box, a set of radio buttons, or some sort of complex/compound file chooser widget. So when you code a widget, it is a physical widget. The selection between physical widgets in order to fulfill the requirements of the logical widget are all decided by the Widget::Controller. Similarly if the Controller is a CGI/mod_perl Controller, it will only choose HTML widgets, whereas if the Controller is a WAP Controller, it would only choose WML widgets, etc. Note: This allows you to write physical widgets which are tied intimately with a particular browser version. The Controller and Config mechanism would *allow* you (not force you) to write an application that falls back gracefully and uses other physical widgets for different browsers. A "Menu" widget using all sorts of whiz-bang DHTML on IE 5.0 could be rendered sanely using a different visual paradigm on an NS 2.0 browser (or Lynx, or Curses!) using a different physical widget. This brings us back to the debate over the display() method vs. the html() method. Every widget class only runs in a certain environment. An HTML widget is being told to emit HTML, hence the method name "html()". In addition, the display() method really does not display anything. It simply returns HTML. It is only displayed when the HTML is printed to STDOUT. That is another reason why I think the display() method goes on the Controller something like this: $wc->display(@widget_list). (As a reasonable compromise, I think what I will probably do is add a convenience method "display()" which calls the html() method for Widget::HTML::* widgets.) As always, thoughts are welcomed. ;-) Stephen === To: JGSmith@TAMU.Edu From: jay@lawrence.net Subject: Re: Real Widgets and Template Languages Date: 29 May 2001 09:35:52 -0700 On Tue, 29 May 2001, James G Smith wrote: > IMHO, having a configuration API is much better than requiring a particular > way to do configuration. If the backend configuration is done via Perl code, > then any configuration file format can be supported with an appropriate module > handling it. This is what I am advocating - widgets have properties of various flavours. We describe how these properties and their different flavours operate. A lot of the runtime functionality of how stuff arrives into existance should be the choice of the developer. That includes things like XML, DBI, etc. I think that the case for Storable as a core format could be made: - its fast - its reliable - it can be translated into Perl code via Data::Dumper or XML through your favorite XML module > These widget configurations will need to be flexible enough that I can > construct a page with them without any knowledge of how they will look -- the > configurations should be tie-able to an overall theme for the site. I've > always been a champion of themes for websites. I should be able to select a > configuration at run-time without a lot of trouble. I have not mentioned it yet - but I have been thinking that widgets should check their container for the active theme to use. It would be up to the widget as to how it would render itsself under different themes. To make that job easier - there are a number of rendering elements that could potentially be re-used across widgets for an entire theme.... ie/ current theme would be: $widget->container->theme just like when a widget goes to render itself it would be checking: $widget->container->render_format to see if it should use "HTML", "WAP", or whatever. A container could be another widget or something more high level like an application handler or template processor. If a widget is serving as a container it probably won't hold the answer to things like theme or format - instead it would pass the request along to its container and so on. Jay J === To: stephen.adkins@officevision.com From: jay@lawrence.net Subject: Re: Real Widgets and Template Languages Date: 29 May 2001 10:04:06 -0700 On Tue, 29 May 2001, Stephen Adkins wrote: > Right. I have many more requirements I eventually want to support > (such as internationalization). The trick is making the design such > that it works in the simple case for simple things, while supporting > advanced features for those who wish to use them. I think it is coming > together pretty well. I hope you didn't mean to say eventually! ;-) Me - I need I18L'n right off the top. If my widgets aren't multilingual then I'll have to go elsewhere. 75% of my apps are bi and trilingual. I think we should bite the bullet and start talkin Unicode and ISO-639 language codes right at the beginning. If a widget has a textual element to be used in rendering (ie/ label) it should have as many language forms as the developer requires. If a language form is missing it should kick down to a default language (EN-CA for example - otherwise words like colour and flavour will be mispelled ;-) ). Where is this language value coming from? The widget's container. You only care about English? Then set it to "EN-US" and forget it. $widget->container->language="EN-CA" print $widget->label "What is your favorite flavour of ice cream?" $widget->container->language="EN-US" print $widget->label "What is your favorite flavor of ice cream?" $widget->container->language="FR-CA" print $widget->label "...." I'm sure you see the pattern. Not every property should be considered polylingual but ones that contain textual or language-specific visual elements should be. Implementation strategies can be as simple as: sub label { my $self=shift; my $lang=shift || $self->container->language; if (exists $self->{'label'}{$lang}) { return $self->{'label'}{$lang}; } return $self->{'label'}{$self->container->language('default'); } My personal strategy to date is to create meta data describing the class in general. Accessor functions for properties are created dynamically via AUTOLOAD mechanism. Based on metadata for class in question the AUTOLOADer will setup the accessor using one of a few different behaviors. In closing - although it seems like a drag in the beginning - it really makes sense to develop applications and components to support multiple languages. It is a zillion times more difficult to cobble in the fucntionality after the fact. Jay === To: Stephen Adkins <stephen.adkins@officevision.com> From: James G Smith <JGSmith@TAMU.Edu> Subject: Re: Real Widgets and Template Languages Date: Tue, 29 May 2001 17:10:18 -0500 Stephen Adkins <stephen.adkins@officevision.com> wrote: >At 09:53 PM 5/29/2001 +0800, Gunther Birznieks wrote: >>At 05:17 PM 5/28/01 -0400, Stephen Adkins wrote: >... >>> $widget = $wc->widget("first_name"); >>> print "First Name: ", $widget->html(), "\n"; >> >>A widget type has already been defined. So I don't see that the method to >>output it's display should be called html() which is, well, HTML specific. >>I prefer >> >>print "First Name: ", $widget->display(), "\n"; >> >>Since widgets are components that know how to display themselves whether >>its WML or HTML or whatever. > >This is a philosophical design decision that I have been struggling with. >The widget does indeed know that it should generate HTML, so it could have >a method, $widget->display(), $widget->draw(), etc. > >However, this implies that the widget has the freedom to decide how it >should render itself and that the caller does not need to know. >This is not correct. Actually, it could be. It would allow for general templates of widgets that are not specific to any particular format (thinking of the standard template library in C++). Perhaps overloading the stringizing operator for output... > :) >The caller in this case has already cooked up a bunch of HTML and is >counting on the widget to produce HTML which can be inserted. >The widget does *not* have the freedom to render any other way. >This is why I have (sort of stubbornly) stuck with the $widget->html() >method despite the unanimous suggestions for a $widget->display() >method. The actual output code could be controlled by a configuration option -- if the configuration is help in another object that the widget can query, then the caller will not *have* to know, though it could know, which format the widget will be rendered as. >I do believe there is a place for a display() method, but it is at >the controller level. The is the level at which the caller may not >know what technologies are being used by the widgets. Agree... but I don't see why we can't push this down as low as possible so we don't have to know how we are rendering until the absolute last possible moment. >1. TECHNOLOGIES > >I propose that the following technologies will have supporting >Controller/State/Widget combinations to make this not just another web >widget library. > > * CGI/HTML - a web application > * mod_perl/HTML - similar, a web application using mod_perl > * WAP/WML - driven from a WAP device > * X11 (Gtk-Perl) - an X windows application > * Curses (terminal) - a screen-oriented terminal application > * Term - a line-oriented (scrolling) terminal application > * Cmd - similar to Term, but the state must be saved >between each cmd > >(I know I'm stretching the paradigm a little bit here, probably beyond what >is reasonable. Stretching the paradigm can be good. My mind was going along the same direction -- figuring out an implementation is a bit of a problem at the moment though. >One of the primary design rules is to *not* fall into the "least common >denominator" >trap. Many cross-platform application frameworks have done this and failed. >Rather, the design goal is to *enable* the widget to fully utilize the >capabilities >of the technical environment it is in. Provide a way to query capabilities of the underlying technology -- how big is the screen, remote vs. local, degree of user interaction available, etc. === To: jay@lawrence.net From: James G Smith <JGSmith@TAMU.Edu> Subject: Re: Real Widgets and Template Languages Date: Tue, 29 May 2001 17:14:53 -0500 jay@lawrence.net wrote: >Where is this language value coming from? The widget's container. You only care about English? Then set it to "EN-US" and forget it. [snip] >Implementation strategies can be as simple as: > > >sub label { > > my $self=shift; > my $lang=shift || $self->container->language; > > if (exists $self->{'label'}{$lang}) { > return $self->{'label'}{$lang}; > } > return $self->{'label'}{$self->container->language('default'); > >} Something I've seen elsewhere is to have a master table of strings that the widgets can then reference. Different ways of doing this: index strings by number (MicroSoft resources in executables); index strings by the string in a particular language (TWIG with English as the indexing language). This allows for sharing of strings across widgets and memory savings, always a good thing in mod_perl. It also doesn't slow the system down much if any compared to storing the strings in each widget with duplication. === To: <JGSmith@TAMU.Edu> From: "Jay Lawrence" <Jay@Lawrence.Net> Subject: Re: Real Widgets and Template Languages Date: Tue, 29 May 2001 18:48:17 -0400 James, Yeh - that idea has merit. We don't always see that concepts map 1:1 between languages but probably 99% of the time it should be ok. Of course it is the 1% case that drives most people totally nuts. What might be of interest is a data type that is smart enough to hunt down its text tag from a text resource dictionary or use a string that is local just to that widget.... I am hesitant to advocate the use dictionaries because I do find them a bit confusing and unwieldly to think about managing in the context of a big web site. * Jay * I don't know about you guys - but when I am building stuff - I am also keeping in mind that humons [sic] will be doing much of the tweeking and managing of the site. Keeping systems simple is a big objective too! > Something I've seen elsewhere is to have a master table of strings that the > widgets can then reference. > > Different ways of doing this: > index strings by number (MicroSoft resources in executables); > index strings by the string in a particular language (TWIG with English as > the indexing language). > > This allows for sharing of strings across widgets and memory savings, always a > good thing in mod_perl. It also doesn't slow the system down much if any > compared to storing the strings in each widget with duplication. > -- > James Smith <JGSmith@TAMU.Edu>, 979-862-3725 > Texas A&M CIS Operating Systems Group, Unix > > > === To: jay@lawrence.net From: Stephen Adkins <stephen.adkins@officevision.com> Subject: Re: Real Widgets and Template Languages Date: Tue, 29 May 2001 19:22:15 -0400 At 10:04 AM 5/29/2001 -0700, jay@lawrence.net wrote: >On Tue, 29 May 2001, Stephen Adkins wrote: > >> Right. I have many more requirements I eventually want to support >> (such as internationalization). The trick is making the design such >> that it works in the simple case for simple things, while supporting >> advanced features for those who wish to use them. I think it is coming >> together pretty well. > >I hope you didn't mean to say eventually! ;-) Me - I need I18L'n right off the top. If my widgets aren't multilingual then I'll have to go elsewhere. 75% of my apps are bi and trilingual. > >I think we should bite the bullet and start talkin Unicode and ISO-639 language codes right at the beginning. > OK. The priority of internationalization has been increased. Here is the first snapshot of code. http://www.officevision.com/pub/Widget/ Soon I will have the Sourceforge site up and we can stop clogging up this mailing list. Stephen === To: "Issac Goldstand" <neoi@writeme.com>, <jay@lawrence.net> From: Stephen Adkins <stephen.adkins@officevision.com> Subject: Re: Real Widgets and Template Languages Date: Tue, 29 May 2001 21:32:53 -0400 At 03:42 AM 5/30/2001 +0200, Issac Goldstand wrote: >Wait a second, here... I was under the assumption that the Widget library >was not going to be limited to HTML output only. According to your page, it >seems that the only customization that you plan on doing is to modify the >HTML to work properly with specific browsers (eg, MSIE vs Mozilla/Netscape). ... > > Issac Don't get worked up. The documentation on the page is about a week old. http://www.officevision.com/pub/Widget/ The link to the code is the only new addition. All of the comments you have read on this mailing list are accurate. I recommend you download the code, take a look, then comment. Stephen === To: <modperl@apache.org> From: "Jay Lawrence" <Jay@Lawrence.Net> Subject: Re: Real Widgets and Template Languages - MOVING THE DISCUSSION Date: Thu, 31 May 2001 10:52:47 -0400 Dear Mod_Perl & Widget enthusiasts, Thanks to Stephen Adkins taking the bull by the horns we have a new Sourceforge project for the development of Perl Widgets strategies and code. To get the discussion off the mod_perl list - we're encouraging all those interested to join the perl-widget-developer list at: http://lists.sourceforge.net/lists/listinfo/perl-widget-developer In addition, you will be able to track progress and contribute to the cause directly via Sourceforge: http://sourceforge.net/projects/perl-widget/ and via two additional lists: http://lists.sourceforge.net/lists/listinfo/perl-widget-announce http://lists.sourceforge.net/lists/listinfo/perl-widget-users I know we all look forward to the results of this development effort and your valuable contributions. Jay Lawrence === To: "mod_perl list" <modperl@apache.org> From: Gunther Birznieks <gunther@extropia.com> Subject: Re: Real Widgets and Template Languages Date: Thu, 31 May 2001 22:38:12 +0800 At 05:52 PM 5/28/01 -0400, you wrote: > > Let's focus a bit. > Specifically on requirements more than implementation - *GOOD* I think you misread my intention. I think the requirements are simple and fairly clear except for some interesting enhancements people (includign yourself) propose on the list. I'd like to get a set of objects out more quickly that only do a few things well and in a small lightweight interface. >Could I paraphrase or reinterpret what you have said to be base classes >for handling widget properties and data sources? > >In the web world I see data coming from: > static widget properties - design/configuration values > user supplied values - Session and Request values > data sources - RDBMS, LDAP, yadda > >In addition I do see a variety of flavours for this data: scalar, array, >hash. Me, I want even more exotic flavours such as language sensitive (The >lable property check's user's language choice and will give them back the >lable in the right language). In order for a widget set to be useful we have >to agree on how to pass around a certain set of potentially complex data >types. > >READ: robust base object class with potentially fancy strategy for >rationalizing a number of data sources and data structures. This is very vague to me. It just doesn't sound very concrete enough. I think an interface to be able to do reference to a hash where values are either ref to an array or scalar is good enough initially. >Additionally - when it comes to widget-specific actions - such as rendering, >then you're seeing this as a subclass (or group of methods) that has been >defined by the widget creator. > ie/ widget->render - generic method that checks container and calls >appropriate render subclass for this widget > since container is HTML return widget->render_HTML or whatever. I think breaking out render subwidgets is too complex for my tastes. >READ: object hierarchy. Objects check their parents for hints on how to do >things - like pick the form to render themselves, etc. > > > 1. Data Validation logic. No, this does not belong there. This is a > > separate library. I already have a rich Data handling library in my >toolkit > > that I intend to plug widgets into. All I need is to be able to get widget > > data from the data handling/validation library. > >If I place a widget into my user interface and allow a user to specify a >value how I am I to implement validation? > >ie/ Widget has property "choice" which can be "1","2", or "3". If the user >supplies any other value I want choice to be NULL and raise an error. > > A - does controlling application logic enforce choice validation > B - does widget have property information to say that choice property >must pass some validation process? > >I like B because it further compartmentalizes the behaviors of the widget >within its own specification. The source of the valication routines can be >external to the widget and classes but the validation rules would be >specified within here. This is exactly why config should not be part of the widget library except as a side optional item. You can make your config also optionally configure data handling rules, but mine might not. Then its up to your app toolkit (if it wants to) to set up the data handler methods to be called when the form is submitted to the CGI based on that config. > > 2. External display stuff. No, I just want the widget to know how to draw > > itself and only itself. It's up to a template language plugin like TT or > > some other template language to provide the wrappings. Or it can be a > > toolkit like your drawing forms library -- but the widget itself shouldn't > > have to know about external decoration around it. Just how to draw itself. > >If one is to create an HTML form on a web page then all of the form elements >should actually be contained within in a FORM container. The FORM container >can then facillitate the correct development of HTML etc. > >If the widgets are used within another context then the FORM container might >be necessary or it might not. But it is usually easier to ignore than try to >backpeddle and whack stuff in after its kinda too late. It's pretty rare for this to be an issue. If it is, I would rather see a form become a widget that is linked to another widget if you really require functionality like this. > > It's possible, but I am not quite sure because the primary complexity >seems > > to be the data handling (which I have already in a separate abstraction) > > and the UI generation which I have already in Template Toolkit. So all I > > really want is an object abstract called a Widget along with a > > WidgetCollection to allow grouping widgets together that belong on a given > > HTML page. > >The way I am seeing a solution come together is somewhat different. First of >all I am now tending to really really really want to work with persistant >object collections. As my application needs new widgets I instanciate a new >object of that class into the app's collection of objects. Then I can set >its properties as I wish. From that point onwards I can just boss the >widgets around and make 'em do what I want. > >If you do not want to work with persistent object system then you can come >up with any number of tactics to define your widget objects as needed: XML, >inline code, Data::Dumper, etc. > >A few of my thoughts, I think your thoughts are interesting but way too complex for my own interests. The stuff that you describe that's complex is also described anecdotally. I really shudder to think what would happen when it is really coded and when it is really put in practice. I just would hate to have a really complex library that takes people a long time to grasp and understand because it is hyper broken out. Let's put it this way, I have actually used widgets for the last 6 months in real world applications using JSPs and widget libraries in Java. I can't tell you what a joy it is to work with something so relatively simple and just easy to put things in a page. And Java is known for being overdesigned and complex. :) So I guess I am really against bloating the feature set and the API of something that should be relatively simple and that I could enjoy if it actually comes together in a couple weeks instead of being something where I have to have a Visio to understand the hierarchy at all. What I am NOT against is you stating what would be cool. So I think that is useful. I am not intending to be disparaging. But I am against implementing all these features right away so there's gotta be some choice. And I really do think that some of the warnings about thinking things through are not really warranted because I have been working with this stuff on another platform. I just want Perl to enjoy the same feature. There is some room for adding a few more fancy features, but I do not believe everything in this mail can be accomplished. One other thing. For me, this must work on mod_cgi. And if it's going to cause long load times because the hierarchy is complex and there's a ton of interfaces to do everything then that will make me unhappy. I am willing to slow down a bit for mod_cgi in adding a widget feature, but not a lot. Definitely should not be the equivalent of loading a second copy of CGI.pm for a normal app. === To: modperl@apache.org From: Gunther Birznieks <gunther@extropia.com> Subject: Re: Real Widgets and Template Languages Date: Thu, 31 May 2001 23:15:49 +0800 At 10:04 AM 5/29/01 -0700, jay@lawrence.net wrote: >On Tue, 29 May 2001, Stephen Adkins wrote: > > > Right. I have many more requirements I eventually want to support > > (such as internationalization). The trick is making the design such > > that it works in the simple case for simple things, while supporting > > advanced features for those who wish to use them. I think it is coming > > together pretty well. > >I hope you didn't mean to say eventually! ;-) Me - I need I18L'n right off >the top. If my widgets aren't multilingual then I'll have to go elsewhere. >75% of my apps are bi and trilingual. Sounds kinky. Anyway, I think there are two things that have to be gotten straight. 1) I18L support should exist immediately such as being able to render a Chinese label. 2) Multilingual support is VERY different from I18L and is MUCH more complex. I vote no on supporting this. I think it can be supported through a custom subclass of what you have been describing as a container/controller for the widgets. I think if it is done at the widget level it is bloating the widget set and I honestly don't see why a widget should know about languages. I should rather configure my widgets in French and other widgets in English etc... And then I tell a multilingual container subclass about all my sets of widgets and then using a setLocale(), then the getWidget() method will return the appropriate configured language widget. You also would need a Widget Config that is multilingual and can configure the multi languages very easily. But please do not touch the core widget api itself. Please please keep it lightweight. >I think we should bite the bullet and start talkin Unicode and ISO-639 >language codes right at the beginning. > >If a widget has a textual element to be used in rendering (ie/ label) it >should have as many language forms as the developer requires. If a >language form is missing it should kick down to a default language (EN-CA >for example - otherwise words like colour and flavour will be mispelled ;-) ). > >Where is this language value coming from? The widget's container. You only >care about English? Then set it to "EN-US" and forget it. > > $widget->container->language="EN-CA" > print $widget->label > "What is your favorite flavour of ice cream?" > > $widget->container->language="EN-US" > print $widget->label > "What is your favorite flavor of ice cream?" > > $widget->container->language="FR-CA" > print $widget->label > "...." > >I'm sure you see the pattern. > >Not every property should be considered polylingual but ones that contain >textual or language-specific visual elements should be. > >Implementation strategies can be as simple as: > > >sub label { > > my $self=shift; > my $lang=shift || $self->container->language; > > if (exists $self->{'label'}{$lang}) { > return $self->{'label'}{$lang}; > } > return $self->{'label'}{$self->container->language('default'); > >} > >My personal strategy to date is to create meta data describing the class >in general. Accessor functions for properties are created dynamically via >AUTOLOAD mechanism. Based on metadata for class in question the AUTOLOADer >will setup the accessor using one of a few different behaviors. > >In closing - although it seems like a drag in the beginning - it really >makes sense to develop applications and components to support multiple >languages. It is a zillion times more difficult to cobble in the >fucntionality after the fact. Just don't make the core library have to support multilingual. This is just another bloated thing I don't want. It's fine for the hooks to exist, but not the logic. I don't mind if you make a subclass to support multiple sets of widgets as described above, but please do not add so much that this becomes a huge project. === To: <modperl@apache.org> From: Gunther Birznieks <gunther@extropia.com> Subject: Re: Real Widgets and Template Languages Date: Thu, 31 May 2001 22:42:21 +0800 At 10:08 AM 5/29/01 -0400, Jay Lawrence wrote: >My $0.02 on XML config files. Although they may be attractive to some, >personally, I don't like them. I personally do like them, but I find XML to be heavy weight for parsing in mod_cgi. And many of my users are on normal cheap ISPs that would not compile XML::Parser. I use XML config files in Java because the considerations are different and you can't code a config file for Java in Java without suffering a compile step for the end-user. I prefer config files written basically in Perl. >I see XML is merely the expression of the configurable parameters of the >object. IE it is just a means to the end. Personally, I would like to define >my widget properties through a GUI and then will probably use Storable to >dehydrate and rehydrate my widget objects. I would never want to code up XML >data and I don't think I'm alone. :) Yes, but I think serialization is a different API than construction. I think the default construction/config API should be raw Perl code because it would be FAST. Then optional to allow Config objects to create that raw Perl code based on XML or properties files or whatever someone wants. >Definately when it comes to interchanging your widget data with another >system something like XML really starts to make sense. I don't think it >makes sense necessarily for your internal day-to-day operations. > >What I would advocate is that there are a variety of sources for widget >configuration data from something as simple and elegant as Perl code to XML >of some layout to Storable data stored in a blob field of a DBI source. > >e.g. > $widget->serialize( [ "Storable" ] ) > returns scalar ref to Storable data > $widget->serialize("XML") > returns scalar ref to XML string > > $widget->define( \$StorableData [, "Storable" ] ) > $widget->define( \$XMLData, "XML") > >Then you can easily write a Widget Controller that can be configured as to >what method to use and where to store it to/from. > >Ideally these methods would always be inherited from the base widget class >which will dictate the runtime implementation of widget data. This seems reasonable. === To: <modperl@apache.org> From: Gunther Birznieks <gunther@extropia.com> Subject: Re: Real Widgets and Template Languages Date: Thu, 31 May 2001 22:51:57 +0800 At 11:02 AM 5/29/01 -0400, Robert Landrum wrote: >At 9:53 PM +0800 5/29/01, Gunther Birznieks wrote: >>At 05:17 PM 5/28/01 -0400, Stephen Adkins wrote: >>> > >>>>I don't understand the Widget::Controller. Can you say more about this? >>>> >>>>Also will we require XML to configure? Or is this also an optional feature >>>>that you more or less want for yourself but others can choose to not use? >>> >>>Hi, >>> >>>Below is running code for the Perl Widget Library. >>>So far, there are only two widgets. >>> >>>* a generic Widget::HTML::Element >>>* a drop-down menu Widget::HTML::Select >>> >>>Are there early comments on the interface from Perl? >>>Is this shaping up into what was desired? >>> >>>Stephen >>> >>>shark:/usr/ov/acoc/dev/src/Widget/examples> more Widget.xml Widget.2 >>>:::::::::::::: >>>Widget.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="sex" widget-type='sex'/> >>><widget-type name="date" tag='input' type='text' size='14' maxlength='99'/> >>><widget-type name="sex" widget-class='Widget::HTML::Select' domain='sex'/> >>><domain name="sex"> >>> <item name="M" label="Male"/> >>> <item name="F" label="Female"/> >>></domain> >>></config> >> >>This config seems simple enough that it doesn't seem that necessary to >>use XML. > >Yes, but that's only because it defines 4 widgets... I'd probably expect >somewhere between 50-100 widgets on average, and more the 500 in extreme cases. Really? I think you are an extreme case then. Do you really have more than 50 form elements on a page usually? I think the container of the widgets is roughly equivalent to a page that has to be rendered. It isn't necessarily every widget in the entire app. >A perl hashref config file requires knowledge of perl data structures, >which most designers won't grasp. Since I'm not the designer for my site, >nor am I the guy This is true. >developing the underlying data structure, I wouldn't feel comfortable >using perl as the config file. XML makes for a nice, easily understood >medium for communicating configuration directives. Yes, but nice as an option. The worst part about an XML Config file is everyone will have differences of opinion about what to XMLify and how complex to make the defaults. So I think it's best as noted before, to leave as a subclass. >>print "First Name: ", $widget->display(), "\n"; >>Since widgets are components that know how to display themselves whether >>its WML or HTML or whatever. > >What about draw? display might be misinterpreted. If I draw something, >does that mean I've displayed it? Under the Xwindow system, widgets are >drawn and then shown, IIRC... > >print "First Name: ", $widget->draw(),"\n"; I think this is a very good interface. === To: <modperl@apache.org> From: Gunther Birznieks <gunther@extropia.com> Subject: Re: Real Widgets and Template Languages Date: Thu, 31 May 2001 22:48:46 +0800 At 10:27 AM 5/29/01 -0400, Stephen Adkins wrote: >At 09:49 PM 5/29/2001 +0800, Gunther Birznieks wrote: > >At 12:15 PM 5/28/01 -0400, Stephen Adkins wrote: > >>Hi, > >> > >>Development of a straw-man set of Perl Widget Library core classes is > >>going well. A Sourceforge project (perl-widget) is in the process of being > >>set up too. (I will announce when it is set up.) >... > >>The state information can be accessed from *any* source by implementing an > >>appropriate > >>Widget::<DataSource>::State class (and using some additional, > >>not-yet-implemented arguments > >>to Widget->controller()). > > > >I think it would be better as a Widget::State::<DataSource> rather than the > >other way around. From the way you describe it, this is really an interface > >to getting state information that should be retrieved from a DataSource > >specific state driver. > >I have come to the same conclusion. >I am changing the design to have three core base classes (other than the >widgets): > > Widget::Controller > Widget::Config > Widget::State > >A CGI program might run with the following derived classes: >(These are the initial defaults I am working on.) > > Widget::Controller::CGI > Widget::Config::XML > Widget::State::CGI > >All of these "drivers" may be overridden, as long as the driver you replace it >with conforms to the interface definition described by the core base classes. >(Kind of like a Java interface. You would be encouraged to derive from the >core base classes, but that is not necessary.) >... I think this is good. > >> > > >> >I don't understand the Widget::Controller. Can you say more about this? > >> > >>The Widget::Controller (or perhaps, Widget::CGI::Controller) is the > >>container class > >>that you spoke about in your original post. I call it a Controller rather > >>than > >>a Container because I envision it being able to dispatch events generated > >>by the > >>widgets. > > > >Ah. I just want something to contain the widgets essentially. So perhaps > >from my perspective events aren't necessary and I would potentially just > >place the widgets into an array representing my HTML screen. > > > >I have found that event handling comes in surprisingly handy even for >simple tasks. >Essentially, it allows widgets to define callbacks. >For instance, the DateDropDowns widget defines an event "change" >(modelled after the Javascript "onChange" event) that, when triggered, >concatenates >the YYYY, MM, and DD back into YYYY-MM-DD. >The following is working code. >Notice that the "$wc->dispatch_events($query);" statement takes care of >whatever widget housecleaning there may be (in this case, recomposing the date >as a single variable from the three drop-downs). Oh that's what you mean by events. Hmmm. I don't think this is really an event as much as a massaging of data back and forth based on the widget data source interface. I don't think there are really events like JavaScript, so it seems to me like it would be a bit confusing to apply a model that is based around a real UI like JavaScript to something that is purely a simple request/response protocol. >I had the hunch that everyone's configuration needs would be different. >Hence the Widget::Config (interface) and Widget::Config::XML (driver) >design. (Thanks for the input.) I think this is reasonable. Although if you see my post to Jay, I would prefer if the core config is then through Perl data structures. And then all the drivers would map the XML and what have you to the Perl data structures that are native for speed. === To: modperl@apache.org From: Gunther Birznieks <gunther@extropia.com> Subject: Re: Real Widgets and Template Languages Date: Thu, 31 May 2001 22:54:07 +0800 At 10:23 AM 5/29/01 -0500, James G Smith wrote: >Gunther Birznieks <gunther@extropia.com> wrote: > >At 12:15 PM 5/28/01 -0400, Stephen Adkins wrote: > >>The rendering of this widget as HTML requires at least the following > >> > >> * config information (Widget::Config) >[snip] > >> >Also will we require XML to configure? Or is this also an optional > feature > >> >that you more or less want for yourself but others can choose to not use? > >> > >>Configuration data is read in via the Widget::Config class, and this class >can > >>be replaced with a class which reads config data from any other source, as > >>long as > >>it conforms to the same calling interface. > >> > >>I was under the impression that XML was your desired means of writing a > >>config file. > >>Do you have a preference to use something different? > > > >I like XML for Config files, we use that in our Java stuff all the time. > >But Perl is one of the nicest and flexible config file languages out there. > >IE My config file is Perl. > > > >Anyway, I think it is weird to think of configuring just widgets. Usually > >you configure an application and widgets are a part of that. But everyone > >here will have a different way of preferring to write their application > >config whether it's XML or Perl and what features of these that are used > >(eg just a set of scalars or references to hashes or ... ?) or in the case > >of XML using attributes versus subtags... > >IMHO, having a configuration API is much better than requiring a particular >way to do configuration. If the backend configuration is done via Perl code, >then any configuration file format can be supported with an appropriate >module >handling it. YES! >These widget configurations will need to be flexible enough that I can >construct a page with them without any knowledge of how they will look -- the >configurations should be tie-able to an overall theme for the site. I've >always been a champion of themes for websites. I should be able to select a >configuration at run-time without a lot of trouble. I agree. I think this is basically a capability that exists in the rough draft of the widgets though. To: modperl@apache.org From: Gunther Birznieks <gunther@extropia.com> Subject: Re: Real Widgets and Template Languages Date: Thu, 31 May 2001 22:54:07 +0800 At 10:23 AM 5/29/01 -0500, James G Smith wrote: >Gunther Birznieks <gunther@extropia.com> wrote: > >At 12:15 PM 5/28/01 -0400, Stephen Adkins wrote: > >>The rendering of this widget as HTML requires at least the following > >> > >> * config information (Widget::Config) >[snip] > >> >Also will we require XML to configure? Or is this also an optional > feature > >> >that you more or less want for yourself but others can choose to not use? > >> > >>Configuration data is read in via the Widget::Config class, and this class >can > >>be replaced with a class which reads config data from any other source, as > >>long as > >>it conforms to the same calling interface. > >> > >>I was under the impression that XML was your desired means of writing a > >>config file. > >>Do you have a preference to use something different? > > > >I like XML for Config files, we use that in our Java stuff all the time. > >But Perl is one of the nicest and flexible config file languages out there. > >IE My config file is Perl. > > > >Anyway, I think it is weird to think of configuring just widgets. Usually > >you configure an application and widgets are a part of that. But everyone > >here will have a different way of preferring to write their application > >config whether it's XML or Perl and what features of these that are used > >(eg just a set of scalars or references to hashes or ... ?) or in the case > >of XML using attributes versus subtags... > >IMHO, having a configuration API is much better than requiring a particular >way to do configuration. If the backend configuration is done via Perl code, >then any configuration file format can be supported with an appropriate >module >handling it. YES! >These widget configurations will need to be flexible enough that I can >construct a page with them without any knowledge of how they will look -- the >configurations should be tie-able to an overall theme for the site. I've >always been a champion of themes for websites. I should be able to select a >configuration at run-time without a lot of trouble. I agree. I think this is basically a capability that exists in the rough draft of the widgets though. === To: modperl@apache.org From: Gunther Birznieks <gunther@extropia.com> Subject: Re: Real Widgets and Template Languages Date: Thu, 31 May 2001 23:19:02 +0800 At 05:14 PM 5/29/01 -0500, James G Smith wrote: >jay@lawrence.net wrote: > >Where is this language value coming from? The widget's container. You only >care about English? Then set it to "EN-US" and forget it. >[snip] > >Implementation strategies can be as simple as: > > > > > >sub label { > > > > my $self=shift; > > my $lang=shift || $self->container->language; > > > > if (exists $self->{'label'}{$lang}) { > > return $self->{'label'}{$lang}; > > } > > return $self->{'label'}{$self->container->language('default'); > > > >} > >Something I've seen elsewhere is to have a master table of strings that the >widgets can then reference. > >Different ways of doing this: > index strings by number (MicroSoft resources in executables); > index strings by the string in a particular language (TWIG with > English as >the indexing language). The latter is what Java does by default with resource files associated with servlets. >This allows for sharing of strings across widgets and memory savings, >always a >good thing in mod_perl. It also doesn't slow the system down much if any >compared to storing the strings in each widget with duplication. Hmmm, I don't know about memory savings. But the feature you've outlined here could be taken advantage of by widgets but I don't think it should be part of the widget library. I think it's better as a separate CPAN module for dealing with I18N in general and maybe it already exists... === To: <modperl@apache.org> From: Gunther Birznieks <gunther@extropia.com> Subject: Re: Real Widgets and Template Languages Date: Thu, 31 May 2001 23:07:51 +0800 At 12:31 PM 5/29/01 -0400, Stephen Adkins wrote: >At 09:53 PM 5/29/2001 +0800, Gunther Birznieks wrote: > >At 05:17 PM 5/28/01 -0400, Stephen Adkins wrote: >... > >> $widget = $wc->widget("first_name"); > >> print "First Name: ", $widget->html(), "\n"; > > > >A widget type has already been defined. So I don't see that the method to > >output it's display should be called html() which is, well, HTML specific. > >I prefer > > > >print "First Name: ", $widget->display(), "\n"; > > > >Since widgets are components that know how to display themselves whether > >its WML or HTML or whatever. > >This is a philosophical design decision that I have been struggling with. >The widget does indeed know that it should generate HTML, so it could have >a method, $widget->display(), $widget->draw(), etc. > >However, this implies that the widget has the freedom to decide how it >should render itself and that the caller does not need to know. >This is not correct. I think it is correct. The widgets are specific to the technology like HTML or WML or whatever. It's up to your config in the Controller to determine which widgets you are putting into the controller. If you want to display both WML and HTML, you would create a WML controller and an HTML controller. Note that the controller itself doesn't know the difference, but you just are using it as a collection mechanism to group together like-sets of widgets. >The caller in this case has already cooked up a bunch of HTML and is >counting on the widget to produce HTML which can be inserted. >The widget does *not* have the freedom to render any other way. >This is why I have (sort of stubbornly) stuck with the $widget->html() >method despite the unanimous suggestions for a $widget->display() >method. and then also ->wml() and ->X() and whatever else? This does not seem right. >I do believe there is a place for a display() method, but it is at >the controller level. The is the level at which the caller may not >know what technologies are being used by the widgets. Yes its not at the controller level. It is at the widget level. So you have Widget::WML::TextField and Widget::HTML::TextField... And the firsto ne would go into a controller that is set up to contain WML widgets in general and the second would go into a controller that is set up to contain HTML widgets in general. >This whole discussion brings out two other important design decisions. > > 1. What are the UI technologies we really wish to support? > (i.e. is this *really* a Widget or an HTML::Widget library?) > 2. Which classes represent Logical Widgets and which Physical Widgets? > >1. TECHNOLOGIES > >I propose that the following technologies will have supporting >Controller/State/Widget combinations to make this not just another web >widget library. > > * CGI/HTML - a web application > * mod_perl/HTML - similar, a web application using mod_perl > * WAP/WML - driven from a WAP device > * X11 (Gtk-Perl) - an X windows application > * Curses (terminal) - a screen-oriented terminal application > * Term - a line-oriented (scrolling) terminal application > * Cmd - similar to Term, but the state must be saved >between each cmd > >(I know I'm stretching the paradigm a little bit here, probably beyond what >is reasonable. >If you don't think one or more of these is a good idea, please keep it to >yourself. >I have a vision for it, and even if it's not very useful, it will shape the >"abstractness" >of the design elements. On the other hand, I would welcome suggestions for >additional >UI technologies that I might consider supporting.) > >One of the primary design rules is to *not* fall into the "least common >denominator" >trap. Many cross-platform application frameworks have done this and failed. >Rather, the design goal is to *enable* the widget to fully utilize the >capabilities >of the technical environment it is in. I very much disagree. Least common denominator is not a trap. It's a design decision. This is why design patterns have consequences. Different design choices mean different things. I think you ask for failure and bloatedness when you try to ask too much of an API. The attempt to make this widget library even encompass X-Windows and normal GUIs is frustrating to me. As I have mentioned in a previous mail, I already use this technology on Java and JSPs. This is taking a small and simple concept and blowing it way out of proportion. Ok, that's the end of that rant and rave. Here's my constructive criticism. The design constraint on the widgets here is that you should assume a request/response model through HTTP for this library and basically assume compatibility with template libraries that use HTTP as a medium. X windows and curses and all that kind of stuff is not appropriate and will confuse the API from an HTML perspective. >This brings me to the next topic. > >2. LOGICAL vs. PHYSICAL USER INTERFACE ELEMENTS > >I have spoken about the separation of the logical and physical user interface. >This facilitates applications being written to the logical interface. >The physical UI is then determined at a combination of configuration-time >(config file) and run-time (user preferences, browser capabilities, etc.). > >As the library has developed, it has become clear that the "logical UI" >is really only a figment of the coder's imagination, represented by code like > > $widget = $wc->widget("file_name"); > >However, the Widget::Controller ($wc) decides (based on config and runtime >values) >which *physical* UI widget is returned. This could be a drop-down list box >(<select>), >a text box, a set of radio buttons, or some sort of complex/compound file >chooser widget. > >So when you code a widget, it is a physical widget. The selection between >physical >widgets in order to fulfill the requirements of the logical widget are all >decided >by the Widget::Controller. Similarly if the Controller is a CGI/mod_perl >Controller, >it will only choose HTML widgets, whereas if the Controller is a WAP >Controller, >it would only choose WML widgets, etc. Yes. A widget should be *physical*. And it is possible for controllers to be logical and understand how to call upon WAP widgets and HTML widgets when the time comes. Or it can be as simple as I mentioned before where you just define different containers -- a WAP container and an HTML container. And then that's it. It's up to the applicaiton to choose to use the WAP vs HTML container, not the container itself to understand what browser it is running under. >Note: This allows you to write physical widgets which are tied intimately with >a particular browser version. The Controller and Config mechanism would >*allow* >you (not force you) to write an application that falls back gracefully and >uses >other physical widgets for different browsers. A "Menu" widget using all >sorts >of whiz-bang DHTML on IE 5.0 could be rendered sanely using a different visual >paradigm on an NS 2.0 browser (or Lynx, or Curses!) using a different >physical >widget. > >This brings us back to the debate over the display() method vs. the html() >method. >Every widget class only runs in a certain environment. >An HTML widget is being told to emit HTML, hence the method name "html()". >In addition, the display() method really does not display anything. >It simply returns HTML. It is only displayed when the HTML is printed to >STDOUT. >That is another reason why I think the display() method goes on the Controller >something like this: $wc->display(@widget_list). > >(As a reasonable compromise, I think what I will probably do is add a >convenience >method "display()" which calls the html() method for Widget::HTML::* widgets.) > >As always, thoughts are welcomed. >;-) When I use widgets, I will use them the same way as I have used them in Java. I will make a widget tag for a template language and the widget tag will know to call the widget's display method. If I want to use the WML widgets instead, then I will make a WML JSP page and put all the WML widget equivalents on there instead. It's a simple model that works. === To: Gunther Birznieks <gunther@extropia.com>, <modperl@apache.org> From: Robert Landrum <rlandrum@capitoladvantage.com> Subject: Re: Real Widgets and Template Languages Date: Thu, 31 May 2001 15:36:58 -0400 At 10:51 PM +0800 5/31/01, Gunther Birznieks wrote: >At 11:02 AM 5/29/01 -0400, Robert Landrum wrote: >>At 9:53 PM +0800 5/29/01, Gunther Birznieks wrote: >>>At 05:17 PM 5/28/01 -0400, Stephen Adkins wrote: [snip] >>>>shark:/usr/ov/acoc/dev/src/Widget/examples> more Widget.xml Widget.2 >>>>:::::::::::::: >>>>Widget.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="sex" widget-type='sex'/> >>>><widget-type name="date" tag='input' type='text' size='14' maxlength='99'/> >>>><widget-type name="sex" widget-class='Widget::HTML::Select' domain='sex'/> >>>><domain name="sex"> >>>> <item name="M" label="Male"/> >>>> <item name="F" label="Female"/> >>>></domain> >>>></config> >>> >>>This config seems simple enough that it doesn't seem that >>>necessary to use XML. >> >>Yes, but that's only because it defines 4 widgets... I'd probably >>expect somewhere between 50-100 widgets on average, and more the >>500 in extreme cases. > >Really? I think you are an extreme case then. Do you really have >more than 50 form elements on a page usually? I think the container >of the widgets is roughly equivalent to a page that has to be >rendered. It isn't necessarily every widget in the entire app. Not on a single page, but throughout an entire site.... And we're not just talking about widgets that draw input boxes... Widgets are any page elements, such as images, buttons, links, etc... Right? Perhaps the way I've implemented widgets is different from the way you implement widgets. I define a widget as any configurable, reusable, code segment that produces output intended to be view by the end user. For instance, we have something called a CapWiz::Widget::CongressToday. And to call it, you pass it data from the database, and any configuration options, and out comes HTML. my $w = CapWiz::Widget::CongressToday->new({ 'data' => \@records_from_database, 'color' => '#CCCCCC', 'width' => 385 }); $r->print($w->draw()); And we have several hundred (200+) of these widgets to draw everything from Member Vote Tallies to Navigation Elements. Keep in mind that this is just how we have implemented widgets, and our only requirement was that it output XHTML... Not WM/WAPL, JavaScript, or GNOME/Gtk code.` > >>A perl hashref config file requires knowledge of perl data >>structures, which most designers won't grasp. Since I'm not the >>designer for my site, nor am I the guy > >This is true. > >>developing the underlying data structure, I wouldn't feel >>comfortable using perl as the config file. XML makes for a nice, >>easily understood medium for communicating configuration directives. > >Yes, but nice as an option. The worst part about an XML Config file >is everyone will have differences of opinion about what to XMLify >and how complex to make the defaults. So I think it's best as noted >before, to leave as a subclass. Agreed. === To: mod_perl list <modperl@apache.org> From: brian moseley <bcm@maz.org> Subject: Re: Real Widgets and Template Languages Date: Thu, 31 May 2001 16:21:49 -0700 (PDT) On Thu, 31 May 2001, Gunther Birznieks wrote: > Let's put it this way, I have actually used widgets for > the last 6 months in real world applications using JSPs > and widget libraries in Java. I can't tell you what a > joy it is to work with something so relatively simple > and just easy to put things in a page. which widget libraries? === To: <modperl@apache.org> From: brian moseley <bcm@maz.org> Subject: Re: Real Widgets and Template Languages Date: Thu, 31 May 2001 16:28:18 -0700 (PDT) On Thu, 31 May 2001, Gunther Birznieks wrote: > I think it can be supported through a custom subclass of > what you have been describing as a container/controller > for the widgets. I think if it is done at the widget > level it is bloating the widget set and I honestly don't > see why a widget should know about languages. depends on how granular your widgets are. if you have a menu widget that also displays a label, the widget needs to know where to place the label relative to the menu. this choice will probably differ for various languages. course you add some kind of location api to the widget, but then you're bloating again. or you can just keep labels outside widgets ;) === To: <modperl@apache.org> From: brian moseley <bcm@maz.org> Subject: Re: Real Widgets and Template Languages Date: Thu, 31 May 2001 16:29:03 -0700 (PDT) On Thu, 31 May 2001, Gunther Birznieks wrote: > Hmmm, I don't know about memory savings. But the feature > you've outlined here could be taken advantage of by > widgets but I don't think it should be part of the > widget library. I think it's better as a separate CPAN > module for dealing with I18N in general and maybe it > already exists... yeah, it's called gettext. === To: <modperl@apache.org> From: Gunther Birznieks <gunther@extropia.com> Subject: Re: Real Widgets and Template Languages Date: Fri, 01 Jun 2001 08:43:07 +0800 At 09:14 PM 5/31/01 +0200, Issac Goldstand wrote: > > At 12:31 PM 5/29/01 -0400, Stephen Adkins wrote: > > >At 09:53 PM 5/29/2001 +0800, Gunther Birznieks wrote: > > > >At 05:17 PM 5/28/01 -0400, Stephen Adkins wrote: > > >... >[...] > > >The caller in this case has already cooked up a bunch of HTML and is > > >counting on the widget to produce HTML which can be inserted. > > >The widget does *not* have the freedom to render any other way. > > >This is why I have (sort of stubbornly) stuck with the $widget->html() > > >method despite the unanimous suggestions for a $widget->display() > > >method. > > > > and then also ->wml() and ->X() and whatever else? This does not seem >right. > > > > >I do believe there is a place for a display() method, but it is at > > >the controller level. The is the level at which the caller may not > > >know what technologies are being used by the widgets. > > > > Yes its not at the controller level. It is at the widget level. So you >have > > Widget::WML::TextField and Widget::HTML::TextField... > > > > And the firsto ne would go into a controller that is set up to contain WML > > widgets in general and the second would go into a controller that is set >up > > to contain HTML widgets in general. > >This is also doable, but only if it's transparent to the user. In other >words, the developer _using_ the widget would have to mkae a >Widget::TextField, and only when it was _rendering_ the Widget, would the >libraries internally read the information in Widget::HTML::TextField or >Widget::WML::TextField - otherwise, it's just not worth making "generic" >widgets. In my opinion, this is very difficult in practice. The widgets should be atomic and do as little as possible. On occasion, application-specific widgets would be created to do interesting things like Dates to pull together several form fields. However, I think you can accomplish this dispatching to WML and HTML printing by using a composite widget or a widget container or the widget controller. It doesn't really matter which abstraction is used. You can use all 3 by merely subclassing widget and using a composite design pattern without bloating the original API. I want to keep the original API simple. >[...] > > > > Here's my constructive criticism. The design constraint on the widgets >here > > is that you should assume a request/response model through HTTP for this > > library and basically assume compatibility with template libraries that >use > > HTTP as a medium. X windows and curses and all that kind of stuff is not > > appropriate and will confuse the API from an HTML perspective. > >I disagree. I think that by having dynamic parameters for the widgets, in >conjunction with my "driver" idea, this can be made a lot more flexible >without these problems. It would take planning out, but if we make the >"snap-in" environment work correctly, then simple users who want easy HTML >can do that easily, while a developer writing a template that will display >on X-Windows as well as it will on a cellphone screen gets the HUGE benefit >of constant widgets in a single template. Now for advanced stuff, we may >very well need complex parameters - possibly even on a per-widget basis - >but this should be on an "extended parameters" basis. I disagree because the *behavior* of widgets in a free form, event driven environment is much more complex than a request/response protocol. Behavior differences means added methods and added complexity to the protocol as well as what a developer has to do to implement a widget. It's quite possible that it was wrong to call this a widget project and it should really be HTTP::Widgets because I don't think these are widgets you want to use in Perl/TK. >Since I'm actually starting to trip over my own words here, let me try to >illustrate with an example (note that I'm pulling methods and objects out of >thin air - the idea is to illustrait the idea I brought up, not necessarily >offer a draft of it): > >Complex Widget: > ><Widget type="textbox" maxsize="50" length="25" X-Offset="40" Y-Offset="20" >TabStop="True" TabIndex="3" name="text1" value="some sample text" >tooltip="Enter some text here"/> > >Now, let's say that the developer prints this with the HTML "Driver" - this >could do something like: ><INPUT TYPE="TEXT" MAXLENGTH="50" SIZE="25" NAME="text1" VALUE="some sample >text" onMouseOver="Window.status='Enter some text here'" >onMouseOut="Window.status=''"/> > >And in some other GTK-based environment, it could do something like: > >Label text1; >with (text1) >{ > .Length=50; > .Width=25*XCharSize; // The *XCharSize would have to be defined by the >driver or by the native interface > .Height=1*YCharSize; // This would be a default setting "plugged in" by >the driver > .Value="some sample text"; > .Left=40; > .Top=20; > .TabStop=1; > .TabIndex=2; // 3-1 for 0 based - also defined by the driver... >} > >Now, neither of these cases used _all_ of the widget parameters - a simple >HTML designer could have produced an IDENTICAL widget by doing: > ><Widget type="textbox" maxsize="50" length="25" name="text1" value="some >sample text" tooltip="Enter some text here"/> > >This shows a few things, actaully. First of all, the widget can get as many >or few parameters as the developer wants to supply it with - extra >parameters will be discarded by drivers who do not understand them, and >missing parameters will be supplied with "default" values wherever possible. >Now, I would suggest designing this such that the developer only interacts >with a Widget::textbox. Internally, there would have to be a >Widget::HTML::textbox and a Widget::GTK::textbox, each with the UI-specific >rendering instructions... > >The only problem is making sure that the overhead is kept to a minimal - in >that as few feautres that are not actually NEEDED for the specific >implementation are loaded as possible (eg, a user using only certain >elements in HTML will only load those elements, and only HTML, while if he >wants WML, it will also incur WML generic overhead too). I think this >approach should satisfy both the wants to keep the widgets as generic as >possible, as well as Gunther's wanting to keep the widgets as simple and >easy-to-use/understand as possible (for beginners, at least). While adding parameters to the constructor is not a problem, I guess I have a problem with adding behaviors. If you believe that simply adding more config hooks to allow XWindows to be supported is doable, then we should just leave it as mentioning this as a supposition and leave it to you or someone else to prove that the supposition works after v1.x of the widget set is released. > > > > Yes. A widget should be *physical*. And it is possible for controllers to > > be logical and understand how to call upon WAP widgets and HTML widgets > > when the time comes. Or it can be as simple as I mentioned before where >you > > just define different containers -- a WAP container and an HTML container. > > And then that's it. It's up to the applicaiton to choose to use the WAP vs > > HTML container, not the container itself to understand what browser it is > > running under. > >I think the idea here is similar (if not the same as) my "default control" >idea, in that if a Widget is requested in environment that doesn't actually >support it, the design could be "engineered" in a different manner producing >a similar result (similar to hardware vs software 3D graphics rendering - >we're essentially creating a HAL for our widgets) - or if that's impossible, >it would report it either to the programmer, the end-user or both. > > Issac Yes, this is probably a matter of semantics. Basically something else other than the widget should control what sort of widgets belong to it. === To: <modperl@apache.org> From: Gunther Birznieks <gunther@extropia.com> Subject: Re: Real Widgets and Template Languages Date: Fri, 01 Jun 2001 08:49:19 +0800 At 03:36 PM 5/31/01 -0400, Robert Landrum wrote: >At 10:51 PM +0800 5/31/01, Gunther Birznieks wrote: >>At 11:02 AM 5/29/01 -0400, Robert Landrum wrote: >>>At 9:53 PM +0800 5/29/01, Gunther Birznieks wrote: >>>>At 05:17 PM 5/28/01 -0400, Stephen Adkins wrote: > >>>[...] >>>Yes, but that's only because it defines 4 widgets... I'd probably >>>expect somewhere between 50-100 widgets on average, and more the 500 in >>>extreme cases. >> >>Really? I think you are an extreme case then. Do you really have more >>than 50 form elements on a page usually? I think the container of the >>widgets is roughly equivalent to a page that has to be rendered. It isn't >>necessarily every widget in the entire app. > >Not on a single page, but throughout an entire site.... > >And we're not just talking about widgets that draw input boxes... Widgets >are any page elements, such as images, buttons, links, etc... >Right? Perhaps the way I've implemented widgets is different from the way >you implement widgets. > >I define a widget as any configurable, reusable, code segment that >produces output intended to be view by the end user. > >For instance, we have something called a >CapWiz::Widget::CongressToday. And to call it, you pass it data from the >database, and any configuration options, and out comes HTML. > > my $w = CapWiz::Widget::CongressToday->new({ > 'data' => \@records_from_database, > 'color' => '#CCCCCC', > 'width' => 385 > }); > $r->print($w->draw()); > >And we have several hundred (200+) of these widgets to draw everything >from Member Vote Tallies to Navigation Elements. > >Keep in mind that this is just how we have implemented widgets, and our >only requirement was that it output XHTML... Not WM/WAPL, JavaScript, or >GNOME/Gtk code.` I think the way you are describing widgets is somewhat different from how I describe widgets. While widgets can be overloaded to be a draw-only component, the idea behind widgets is really as an application medium *not* a content management medium. What you are describing is closer to a model like Zope. Whilst I agree that content mgmt is important, my gut feeling is that there are subtle differences that make abstraction of simply any component like this quite hard. And that's exactly what I would call them, components. A widget has a specific behavior and is meant to interact with an application, have form data sent to it, have the data posted and sent back to data validator in the CGI script. etc.... I am not a content management guru, but I am frightened about the possibility that something as difficult as CMS will break into a version 1 widget library unless it's really clear that it won't bloat the API. I do not have experience with CMS, but I imagine it must be complex or Zope for Perl would already exist today. Although perhaps the same could be said for widgets. :) >>>A perl hashref config file requires knowledge of perl data structures, >>>which most designers won't grasp. Since I'm not the designer for my >>>site, nor am I the guy >> >>This is true. >> >>>developing the underlying data structure, I wouldn't feel comfortable >>>using perl as the config file. XML makes for a nice, easily understood >>>medium for communicating configuration directives. >> >>Yes, but nice as an option. The worst part about an XML Config file is >>everyone will have differences of opinion about what to XMLify and how >>complex to make the defaults. So I think it's best as noted before, to >>leave as a subclass. > >Agreed. And I guess through this mechanism you could use widgets as your components because you'll probably a very complex config because of how many widgets you are dealing with in the scope of CMS. Later, Gunther PS I am posting these last few msgs to mod_perl because I only just subscribed to the sourceforge list (which I recommend everyone doing). But I am waiting a day to let everyone else get caught up as well on signing up so that the first posts will go to everyone. === To: mod_perl list <modperl@apache.org> From: Gunther Birznieks <gunther@extropia.com> Subject: Re: Real Widgets and Template Languages Date: Fri, 01 Jun 2001 08:51:16 +0800 At 04:21 PM 5/31/01 -0700, brian moseley wrote: >On Thu, 31 May 2001, Gunther Birznieks wrote: > > > Let's put it this way, I have actually used widgets for > > the last 6 months in real world applications using JSPs > > and widget libraries in Java. I can't tell you what a > > joy it is to work with something so relatively simple > > and just easy to put things in a page. > >which widget libraries? Our own. But I understand Struts apache project has the same basic deal (as also confirmed by Matt Sergeant's post). And from looking at Struts I think their model is even simpler than the model we have in our Java toolkit. This is why I am quite frightened of all these additions to a widget API in Perl when I know it's been accomplished so simply as a framework in Java. === To: "Gunther Birznieks" <gunther@extropia.com> From: "Issac Goldstand" <neoi@writeme.com> Subject: Re: Real Widgets and Template Languages Date: Fri, 1 Jun 2001 03:50:49 +0200 > At 09:14 PM 5/31/01 +0200, Issac Goldstand wrote: > > > At 12:31 PM 5/29/01 -0400, Stephen Adkins wrote: > > > >At 09:53 PM 5/29/2001 +0800, Gunther Birznieks wrote: > > > > >At 05:17 PM 5/28/01 -0400, Stephen Adkins wrote: > > > >... > >[...] > > > >Complex Widget: > > > ><Widget type="textbox" maxsize="50" length="25" X-Offset="40" Y-Offset="20" > >TabStop="True" TabIndex="3" name="text1" value="some sample text" > >tooltip="Enter some text here"/> > > > >Now, let's say that the developer prints this with the HTML "Driver" - this > >could do something like: > ><INPUT TYPE="TEXT" MAXLENGTH="50" SIZE="25" NAME="text1" VALUE="some sample > >text" onMouseOver="Window.status='Enter some text here'" > >onMouseOut="Window.status=''"/> > > > >And in some other GTK-based environment, it could do something like: > > > >Label text1; > >with (text1) > >{ > > .Length=50; > > .Width=25*XCharSize; // The *XCharSize would have to be defined by the > >driver or by the native interface > > .Height=1*YCharSize; // This would be a default setting "plugged in" by > >the driver > > .Value="some sample text"; > > .Left=40; > > .Top=20; > > .TabStop=1; > > .TabIndex=2; // 3-1 for 0 based - also defined by the driver... > >} > > > >Now, neither of these cases used _all_ of the widget parameters - a simple > >HTML designer could have produced an IDENTICAL widget by doing: > > > ><Widget type="textbox" maxsize="50" length="25" name="text1" value="some > >sample text" tooltip="Enter some text here"/> > > > >This shows a few things, actaully. First of all, the widget can get as many > >or few parameters as the developer wants to supply it with - extra > >parameters will be discarded by drivers who do not understand them, and > >missing parameters will be supplied with "default" values wherever possible. > >Now, I would suggest designing this such that the developer only interacts > >with a Widget::textbox. Internally, there would have to be a > >Widget::HTML::textbox and a Widget::GTK::textbox, each with the UI-specific > >rendering instructions... > > > >The only problem is making sure that the overhead is kept to a minimal - in > >that as few feautres that are not actually NEEDED for the specific > >implementation are loaded as possible (eg, a user using only certain > >elements in HTML will only load those elements, and only HTML, while if he > >wants WML, it will also incur WML generic overhead too). I think this > >approach should satisfy both the wants to keep the widgets as generic as > >possible, as well as Gunther's wanting to keep the widgets as simple and > >easy-to-use/understand as possible (for beginners, at least). > > While adding parameters to the constructor is not a problem, I guess I have > a problem with adding behaviors. If you believe that simply adding more > config hooks to allow XWindows to be supported is doable, then we should > just leave it as mentioning this as a supposition and leave it to you or > someone else to prove that the supposition works after v1.x of the widget > set is released. > For arguments sake, I suppose it can be left as a supposition (OK, so I'm too swamped just now to do a proof-of-concept [especially one that would require me to learn GTK programming - something I've not yet touched]). I still think that if a proper abstraction layer is implemented, then parameters can either be "guessed" or silently discarded, thus enabling the widgets to be rendered in anything - even XWindows (or Win32 using Vis Basic, or a dialog resource file). Note that in these cases, only very generic code can be generated, but it's still possible. === To: <modperl@apache.org> From: Gunther Birznieks <gunther@extropia.com> Subject: Re: Real Widgets and Template Languages Date: Fri, 01 Jun 2001 08:59:50 +0800 At 04:28 PM 5/31/01 -0700, brian moseley wrote: >On Thu, 31 May 2001, Gunther Birznieks wrote: > > > I think it can be supported through a custom subclass of > > what you have been describing as a container/controller > > for the widgets. I think if it is done at the widget > > level it is bloating the widget set and I honestly don't > > see why a widget should know about languages. > >depends on how granular your widgets are. if you have a menu >widget that also displays a label, the widget needs to know >where to place the label relative to the menu. this choice >will probably differ for various languages. course you add >some kind of location api to the widget, but then you're >bloating again. or you can just keep labels outside widgets >;) Yes, but this is a more direct containment than a form which is likely to have many elements in it other than widgets. In this case, a widget directly contains other widgets. I think this is potentially OK and makes it easy to create a template-based tag. But when you have to keep track of a form tag that has widgets inside but may have arbitrary HTML as well, it's a more difficult/complex problem. As I have mentioned in a previous mail here, I think a composite widget is probably reasonable (for the locale and html vs wml output) but likewise, a composite widget could also be used to configure other widgets displaying simultaneously (and not as a switch based on language) to determine order of menu items and labels and whatnot. While I think these examples are good and they show advanced thought in all sorts of things widgets can be used for. The reality is many of these things are exceptions that are usually more an issue for windows systems than the abstraction that I would like to deal with a majority of the time -- just making my dealing with FORMs easier than it is now, within a short period of time was and is my primary goal. If you can accomplish the things you want without changing the basic behavior and without forcing me to fill-in a huge API whenever I write a widget class, then that is fine. But I think we need to focus on the *core* API and getting the *core* objects out so that they can be used. I believe atomic widgets, if we can at least agree on that can be fine for me and all of you who want fancy stuff can write controllers and composite widgets that do you fancy stuff exactly the way you want. I just don't want the widgets themselves to be large and difficult to implement. === To: "Issac Goldstand" <neoi@writeme.com> From: Gunther Birznieks <gunther@extropia.com> Subject: Re: Real Widgets and Template Languages Date: Fri, 01 Jun 2001 09:07:19 +0800 At 03:50 AM 6/1/01 +0200, Issac Goldstand wrote: > > At 09:14 PM 5/31/01 +0200, Issac Goldstand wrote: > > > > At 12:31 PM 5/29/01 -0400, Stephen Adkins wrote: > > > > >At 09:53 PM 5/29/2001 +0800, Gunther Birznieks wrote: > > > > > >At 05:17 PM 5/28/01 -0400, Stephen Adkins wrote: > > > > >... > > >[...] > > > > > >Complex Widget: > > > > > ><Widget type="textbox" maxsize="50" length="25" X-Offset="40" >Y-Offset="20" > > >TabStop="True" TabIndex="3" name="text1" value="some sample text" > > >tooltip="Enter some text here"/> > > > > > >Now, let's say that the developer prints this with the HTML "Driver" - >this > > >could do something like: > > ><INPUT TYPE="TEXT" MAXLENGTH="50" SIZE="25" NAME="text1" VALUE="some >sample > > >text" onMouseOver="Window.status='Enter some text here'" > > >onMouseOut="Window.status=''"/> > > > > > >And in some other GTK-based environment, it could do something like: > > > > > >Label text1; > > >with (text1) > > >{ > > > .Length=50; > > > .Width=25*XCharSize; // The *XCharSize would have to be defined by >the > > >driver or by the native interface > > > .Height=1*YCharSize; // This would be a default setting "plugged in" >by > > >the driver > > > .Value="some sample text"; > > > .Left=40; > > > .Top=20; > > > .TabStop=1; > > > .TabIndex=2; // 3-1 for 0 based - also defined by the driver... > > >} > > > > > >Now, neither of these cases used _all_ of the widget parameters - a >simple > > >HTML designer could have produced an IDENTICAL widget by doing: > > > > > ><Widget type="textbox" maxsize="50" length="25" name="text1" value="some > > >sample text" tooltip="Enter some text here"/> > > > > > >This shows a few things, actaully. First of all, the widget can get as >many > > >or few parameters as the developer wants to supply it with - extra > > >parameters will be discarded by drivers who do not understand them, and > > >missing parameters will be supplied with "default" values wherever >possible. > > >Now, I would suggest designing this such that the developer only >interacts > > >with a Widget::textbox. Internally, there would have to be a > > >Widget::HTML::textbox and a Widget::GTK::textbox, each with the >UI-specific > > >rendering instructions... > > > > > >The only problem is making sure that the overhead is kept to a minimal - >in > > >that as few feautres that are not actually NEEDED for the specific > > >implementation are loaded as possible (eg, a user using only certain > > >elements in HTML will only load those elements, and only HTML, while if >he > > >wants WML, it will also incur WML generic overhead too). I think this > > >approach should satisfy both the wants to keep the widgets as generic as > > >possible, as well as Gunther's wanting to keep the widgets as simple and > > >easy-to-use/understand as possible (for beginners, at least). > > > > While adding parameters to the constructor is not a problem, I guess I >have > > a problem with adding behaviors. If you believe that simply adding more > > config hooks to allow XWindows to be supported is doable, then we should > > just leave it as mentioning this as a supposition and leave it to you or > > someone else to prove that the supposition works after v1.x of the widget > > set is released. > > > >For arguments sake, I suppose it can be left as a supposition (OK, so I'm >too swamped just now to do a proof-of-concept [especially one that would >require me to learn GTK programming - something I've not yet touched]). > >I still think that if a proper abstraction layer is implemented, then >parameters can either be "guessed" or silently discarded, thus enabling the >widgets to be rendered in anything - even XWindows (or Win32 using Vis >Basic, or a dialog resource file). Note that in these cases, only very >generic code can be generated, but it's still possible. I would agree that the current widget set can be used to create a displayable component for Xwindows instead of a string of HTML. But it's all the event stuff and callbacks and the like that seem like extending the widget abstraction to GUIs is dangerous when the widgets I want only require the capability of being delivered based on a simple request/response protocol of HTTP so that a request comes in, the script/controller processes it and then static text or components are delivered down the wire that is HTML or WML or whatever but it's still request/response. Anyway, I don't mean to force anything down specifically. But I do know that making things complex also leads to a lack of adaptation and a lack of time for developing components. What I would like to see happen is that a simple API is discussed and agreed and the basic objects are created. Then given the assumption that those objects are simple, many more people can implement them. If I have to be concerned about a lot of stuff everytime I make a widget like multilingual support hooks and event hooks then I will never write a widget because I don't have time. This is why I want widgets to be tiny and atomic. Let's make it simple. If you want multilingual can there be some way of making the multilingual features a wrapper around existing atomic widgets? Same for events and other such expert features. === To: modperl@apache.org From: will trillich <will@serensoft.com> Subject: comparison of templating methods? Date: Wed, 6 Jun 2001 23:02:28 -0500 <warning type="religious holy war" level="pandora's box"> okay -- there's code (mod_perl modules) and there's html, and we should keep them separate -- which gives rise to templates... i've heard of Apache::PageKit Apache::Template AxKit eXtropia? HTML::Mason HTML::Embperl HTML::Template OpenBedrock Template-Toolkit XPathScript XSLT regarding the tools that dovetail into the mod_perl paradigm, who's got a comparison over relative performance (and other strengths/weaknesses) of various templating methods? === To: will trillich <will@serensoft.com> From: Steve Smith <steve.smith@isay.com.au> Subject: Re: comparison of templating methods? Date: Thu, 7 Jun 2001 14:26:20 +1000 > HTML::Embperl For me, this has one major win over the other toolkits: auto form population from a hash. The online mortgage application system I wrote has about 1,800 form fields, which have to be populated with data from a database. By making the form fields match DB column names, I can reduce the code to do this to: my $data = $dbh->fetchrow_hashref($query); %fdat = (%fdat, %$data); Embperl then parses the form and populates it with the matching name=>value pairs in %fdat, including select options. Beautiful! Steve === To: "will trillich" <will@serensoft.com>, <modperl@apache.org> From: "Gerald Richter" <richter@ecos.de> Subject: Re: comparison of templating methods? Date: Thu, 7 Jun 2001 06:48:38 +0200 > > regarding the tools that dovetail into the mod_perl paradigm, > who's got a comparison over relative performance (and other > strengths/weaknesses) of various templating methods? > There are various discussions on the mod_perl list about this topic in the past (so take a look at the archives). Also there was an start to write such a comparsion, but I am not aware that anybody has really finished it. The only benchmarks I know are from Joshua. I append his mail below. NOTE: While the hello.xxx benchmarks only prints "Hello world", so they only measures the startup overhead of the toolkit, the h2000.xxx tests tends a little bit more towards a real application. Gerald === To: mod_perl list <modperl@apache.org> From: "T.J. Mather" <tjmather@anidea.com> Subject: Re: comparison of templating methods? Date: Thu, 7 Jun 2001 00:19:31 -0400 (EDT) On Thu, 7 Jun 2001, Steve Smith wrote: > > HTML::Embperl > > For me, this has one major win over the other toolkits: auto form > population from a hash. The online mortgage application system I You may also fill in HTML forms with Apache::ASP and Apache::PageKit. With PageKit it automatically gets the data from the request parameters, but you may also set it using the fillinform method from the Model. Both of these applications use HTML::FillInForm to fill in the HTML Forms. === To: will trillich <will@serensoft.com> From: Stas Bekman <stas@stason.org> Subject: Re: comparison of templating methods? Date: Fri, 8 Jun 2001 10:49:39 +0800 (SGT) On Wed, 6 Jun 2001, will trillich wrote: > <warning type="religious holy war" level="pandora's box"> > > okay -- there's code (mod_perl modules) and there's html, and we > should keep them separate -- which gives rise to templates... > > i've heard of > Apache::PageKit > Apache::Template > AxKit > eXtropia? > HTML::Mason > HTML::Embperl > HTML::Template > OpenBedrock > Template-Toolkit > XPathScript > XSLT > > regarding the tools that dovetail into the mod_perl paradigm, > who's got a comparison over relative performance (and other > strengths/weaknesses) of various templating methods? This is your "ultimate" answer :) : Choosing a Templating System. http://conferences.oreillynet.com/cs/os2001/view/e_sess/1263 Hopefully Perrin will release his paper close to the conference. === To: Steve Smith <steve.smith@isay.com.au>, will trillich <will@serensoft.com> From: Gunther Birznieks <gunther@extropia.com> Subject: Re: comparison of templating methods? Date: Fri, 08 Jun 2001 18:52:14 +0800 At 02:26 PM 6/7/2001 +1000, Steve Smith wrote: > > HTML::Embperl > >For me, this has one major win over the other toolkits: auto form >population from a hash. The online mortgage application system I >wrote has about 1,800 form fields, which have to be populated with >data from a database. By making the form fields match DB column >names, I can reduce the code to do this to: > > my $data = $dbh->fetchrow_hashref($query); > %fdat = (%fdat, %$data); > >Embperl then parses the form and populates it with the matching >name=>value pairs in %fdat, including select options. Beautiful! Not that it's a reality now, but this is one of the things that the Perl Widget Library project on source forge is hoping to accomplish for template languages. It's a cross template way of organizing form information and map it to db fields. The reality is that there are many fields that cannot map easily 1-1 to a database as you say. eg a date in a database is usually a date field. But in a form, it might be a combination of 3 form fields (dropdown for month, year and day separately). Later, Gunther === To: modperl@apache.org From: will trillich <will@serensoft.com> Subject: templating benchmarks... Date: Fri, 8 Jun 2001 08:58:14 -0500 On Thu, Jun 07, 2001 at 06:48:38AM +0200, Gerald Richter wrote: > > regarding the tools that dovetail into the mod_perl paradigm, > > who's got a comparison over relative performance (and other > > strengths/weaknesses) of various templating methods? > > There are various discussions on the mod_perl list about this topic in the > past (so take a look at the archives). Also there was an start to write such > a comparsion, but I am not aware that anybody has really finished it. The > only benchmarks I know are from Joshua. I append his mail below. > > NOTE: While the hello.xxx benchmarks only prints "Hello world", so they only > measures the startup overhead of the toolkit, the h2000.xxx tests tends a > little bit more towards a real application. this is interesting information -- perhaps misleading to use the microscopic "hello world" but still it gives a starting point: here i sorted by hits-per-second > Test Name Test File Hits/sec Bytes/Hit > ------------ ---------- ---------- ---------- > HTML static hello.html 1158.4 311 bytes > mod_include SSI hello.shtm 996.6 198 bytes > mod_caucho JSP hello.jsp 860.6 230 bytes > mod_perl handler hello.benc 852.6 196 bytes > mod_php PHP hello.php 734.8 225 bytes > Apache::Registry v2.01 CGI Raw hello_raw. 706.4 52 bytes > Apache::Dispatch v0.08 handler hello/worl 656.1 196 bytes > HTML::Template v2.0 hello.htmp 567.2 198 bytes > Apache::SSI v2.16 hello.shtm 559.4 199 bytes > Template v2.00 Toolkit hello.tt 522.1 198 bytes > Apache::Registry v2.01 CGI.pm hello.reg 458.5 216 bytes > HTML::Embperl v2.0a18 hello.epl 458.2 219 bytes > Apache::ASP v2.07 hello.asp 390.6 241 bytes > Apache::ePerl hello.eper 344.8 217 bytes > HTML::Mason v0.895 hello.mas 365.3 197 bytes i bet CGI would be 200.0 or so... ? and here's the "handler actualy does some work" set: > mod_caucho JSP 2000 h2000.jsp 328.9 28964 byte > mod_php PHP 2000 h2000.php 261.8 28865 byte > HTML::Embperl v2.0a18 2000 h2000.epl 247.3 28809 byte > Apache::ASP v2.07 2000 h2000.asp 228.0 28997 byte > HTML::Mason v0.895 2000 h2000.mas 222.9 28798 byte > Template v2.00 Toolkit 2000 h2000.tt 55.6 28888 byte wow. template toolkil took a big hit, there. (no mod_perl on this list? hmm!) === To: Stas Bekman <stas@stason.org>-- From: Tom Lancaster <tom@grubby.net> Subject: Re: templating benchmarks... Date: Fri, 8 Jun 2001 23:30:38 -0700 > This benchmark can be very non-representive. If you don't know how to > optimize each and every "thing" under test, you end up with unfair > benchmark and come to potentially wrong conclusions. Take TT, add compiled > template caching on the disk and shared TT object and I bet TT won't be at > the bottom. > > In any case always remember that it's extremely hard to run a fair > benchmark. I'd say it's almost impossible. The only fair benchmarking can > be done if you know all the in's and out's of the 'things' under test and > provide many benchmark tests each exploring a single property and not just > 'one for all' benchmark. > > Of course it's a good thing to have benchmarks, but they all should be > taken with a grain of salt. > Absolutely. But I'd like to bring up something I've noticed in benchmarking 'real' sites: many, if not all, of the templating solutions appear to parse the whole of an html page. This is at least true of Apache::ASP and HTML::Mason, which I have used. Is it not ? I have produced really dramatic differences in performance in a two-tier setup by judicious use of mod_include vs. wholesale proxying of pages with dynamic content through to the mod_perl/Apache::ASP server. For example: In a situation with 1 lightweight frontend proxy and two backend mod_perl/Apache::ASP app servers ( with load distributed evenly using a patched mod_rewrite and its ability to select randomly from a list in a file ) , in one part of the site the dynamic headers and footers are generated by using <!--#include virtual="/apps/include/pane.html?pane=header&location=$REQUEST_URI" -->, where the file being included is in fact proxied back to the app servers to receive content; in other parts of the site similarly simple pages are proxied in their entirety to the app servers. The results I can produce ( granted only with 'ab' ) are stunningly different: when I request the header and footer from the app servers using mod_include plus my modified mod_rewrite ( the stock version refuses to rewrite proxied requests ), I get up to 600 requests / second. When proxying the whole page through I get around 6 requests / second. Granted, I have other major bottlenecks involved: using Berkeley DB v1.x for session state, for one. Perhaps this explains some of it -- maybe the proxied header/footer requests never make session calls. I suspect that the wholesale parsing/eval-ing of html pages also plays a part. What do y'all think ? === To: modperl@apache.org From: will trillich <will@serensoft.com> Subject: Re: comparison of templating methods? Date: Fri, 8 Jun 2001 08:59:51 -0500 On Fri, Jun 08, 2001 at 06:52:14PM +0800, Gunther Birznieks wrote: > At 02:26 PM 6/7/2001 +1000, Steve Smith wrote: > > > HTML::Embperl > > > >For me, this has one major win over the other toolkits: auto form > >population from a hash. The online mortgage application system I > >wrote has about 1,800 form fields, which have to be populated with > >data from a database. By making the form fields match DB column > >names, I can reduce the code to do this to: > > > > my $data = $dbh->fetchrow_hashref($query); > > %fdat = (%fdat, %$data); > > > >Embperl then parses the form and populates it with the matching > >name=>value pairs in %fdat, including select options. Beautiful! > > Not that it's a reality now, but this is one of the things that the Perl > Widget Library project on source forge is hoping to accomplish for template > languages. It's a cross template way of organizing form information and map > it to db fields. > > The reality is that there are many fields that cannot map easily 1-1 to a > database as you say. eg a date in a database is usually a date field. But > in a form, it might be a combination of 3 form fields (dropdown for month, > year and day separately). which of the existing paradigms will the widget farm most closely resemble? and what are your expectations for tradeoff in functionality/modularity-vs-performance? === To: will trillich <will@serensoft.com> From: Stas Bekman <stas@stason.org> Subject: Re: templating benchmarks... Date: Sat, 9 Jun 2001 13:29:14 +0800 (SGT) On Fri, 8 Jun 2001, will trillich wrote: > On Thu, Jun 07, 2001 at 06:48:38AM +0200, Gerald Richter wrote: > > > regarding the tools that dovetail into the mod_perl paradigm, > > > who's got a comparison over relative performance (and other > > > strengths/weaknesses) of various templating methods? > > > > There are various discussions on the mod_perl list about this topic in the > > past (so take a look at the archives). Also there was an start to write such > > a comparsion, but I am not aware that anybody has really finished it. The > > only benchmarks I know are from Joshua. I append his mail below. > > > > NOTE: While the hello.xxx benchmarks only prints "Hello world", so they only > > measures the startup overhead of the toolkit, the h2000.xxx tests tends a > > little bit more towards a real application. > > this is interesting information -- perhaps misleading to use the > microscopic "hello world" but still it gives a starting point: > > here i sorted by hits-per-second > > > Test Name Test File Hits/sec Bytes/Hit > > ------------ ---------- ---------- ---------- > > HTML static hello.html 1158.4 311 bytes > > mod_include SSI hello.shtm 996.6 198 bytes > > mod_caucho JSP hello.jsp 860.6 230 bytes > > mod_perl handler hello.benc 852.6 196 bytes > > mod_php PHP hello.php 734.8 225 bytes > > Apache::Registry v2.01 CGI Raw hello_raw. 706.4 52 bytes > > Apache::Dispatch v0.08 handler hello/worl 656.1 196 bytes > > HTML::Template v2.0 hello.htmp 567.2 198 bytes > > Apache::SSI v2.16 hello.shtm 559.4 199 bytes > > Template v2.00 Toolkit hello.tt 522.1 198 bytes > > Apache::Registry v2.01 CGI.pm hello.reg 458.5 216 bytes > > HTML::Embperl v2.0a18 hello.epl 458.2 219 bytes > > Apache::ASP v2.07 hello.asp 390.6 241 bytes > > Apache::ePerl hello.eper 344.8 217 bytes > > HTML::Mason v0.895 hello.mas 365.3 197 bytes > > i bet CGI would be 200.0 or so... ? > > and here's the "handler actualy does some work" set: > > > mod_caucho JSP 2000 h2000.jsp 328.9 28964 byte > > mod_php PHP 2000 h2000.php 261.8 28865 byte > > HTML::Embperl v2.0a18 2000 h2000.epl 247.3 28809 byte > > Apache::ASP v2.07 2000 h2000.asp 228.0 28997 byte > > HTML::Mason v0.895 2000 h2000.mas 222.9 28798 byte > > Template v2.00 Toolkit 2000 h2000.tt 55.6 28888 byte > > wow. template toolkil took a big hit, there. (no mod_perl on > this list? hmm!) This benchmark can be very non-representive. If you don't know how to optimize each and every "thing" under test, you end up with unfair benchmark and come to potentially wrong conclusions. Take TT, add compiled template caching on the disk and shared TT object and I bet TT won't be at the bottom. In any case always remember that it's extremely hard to run a fair benchmark. I'd say it's almost impossible. The only fair benchmarking can be done if you know all the in's and out's of the 'things' under test and provide many benchmark tests each exploring a single property and not just 'one for all' benchmark. Of course it's a good thing to have benchmarks, but they all should be taken with a grain of salt. === To: will trillich <will@serensoft.com> From: jherring@thinkstock.com Subject: Re: comparison of templating methods? Date: Fri, 08 Jun 2001 08:14:48 -0400 will trillich wrote: > HTML::Mason > Template-Toolkit <tuppence type='mine'> These are only two I have much experience with. I've found both to be well written, stable and well supported. TT makes it easier to separate the logic from the presentation layer IMHO. But every time I code a project in mason I find myself smiling and thinking 'This is fun', at least occasionally. Projects seem to come together _much_ faster with Mason, though overall coding time isn't much different. With Mason you have to work harder if you want to separate logic & presentation, but its fairly straightfoward if you put some thought into your component design ahead of time. So typically, if I need skinability, or if I need to give edit capability to html'ers with no perl but light scripting ability I use TT, otherwise I use Mason. </tuppence> J === To: will trillich <will@serensoft.com> From: jherring@thinkstock.com Subject: Re: comparison of templating methods? Date: Fri, 08 Jun 2001 08:19:22 -0400 will trillich wrote: > HTML::Mason > Template-Toolkit <tuppence type='mine'> These are only two I have much experience with. I've found both to be well written, stable and well supported. TT makes it easier to separate the logic from the presentation layer IMHO. But every time I code a project in mason I find myself smiling and thinking 'This is fun', at least occasionally. Projects seem to come together _much_ faster with Mason, though overall coding time isn't much different. With Mason you have to work harder if you want to separate logic & presentation, but its fairly straightfoward if you put some thought into your component design ahead of time. So typically, if I need skinability, or if I need to give edit capability to html'ers with no perl but light scripting ability I use TT, otherwise I use Mason. </tuppence> === To: <modperl@apache.org> From: Gunther Birznieks <gunther@extropia.com> Subject: Re: comparison of templating methods? Date: Sun, 10 Jun 2001 22:28:02 +0800 At 08:25 PM 6/8/2001 +0200, Gerald Richter wrote: > > At 02:26 PM 6/7/2001 +1000, Steve Smith wrote: > > > > HTML::Embperl > > > > > >For me, this has one major win over the other toolkits: auto form > > >population from a hash. The online mortgage application system I > > >wrote has about 1,800 form fields, which have to be populated with > > >data from a database. By making the form fields match DB column > > >names, I can reduce the code to do this to: > > > > > > my $data = $dbh->fetchrow_hashref($query); > > > %fdat = (%fdat, %$data); > > > > > >Embperl then parses the form and populates it with the matching > > >name=>value pairs in %fdat, including select options. Beautiful! > > > > Not that it's a reality now, but this is one of the things that the Perl > > Widget Library project on source forge is hoping to accomplish for >template > > languages. It's a cross template way of organizing form information and >map > > it to db fields. > > > > The reality is that there are many fields that cannot map easily 1-1 to a > > database as you say. eg a date in a database is usually a date field. But > > in a form, it might be a combination of 3 form fields (dropdown for month, > > year and day separately). > > > >Such things could be solved by using DBIx::Recordset for database access and >define some filters, which are able to transform the content of a field >to/from format you need it. Well, that assumes everything is a database... "everything I think I see, looks like a database to me..." If you look at PHP's GPC model and then realize that it goes farther into allowing other datasources such as S or a DB or a secondary DB if the first one is empty for that field, then you'll see that abstracting it in a common way rather than a DBI-specific view is much more powerful and is something that applications do occasionally have to do. Writing a filter is doable but really kind of a hack really. === To: will trillich <will@serensoft.com>, modperl@apache.org From: Gunther Birznieks <gunther@extropia.com> Subject: Re: comparison of templating methods? Date: Sun, 10 Jun 2001 22:36:17 +0800 At 08:59 AM 6/8/2001 -0500, will trillich wrote: >On Fri, Jun 08, 2001 at 06:52:14PM +0800, Gunther Birznieks wrote: > > At 02:26 PM 6/7/2001 +1000, Steve Smith wrote: > > > > HTML::Embperl > > > > > >For me, this has one major win over the other toolkits: auto form > > >population from a hash. The online mortgage application system I > > >wrote has about 1,800 form fields, which have to be populated with > > >data from a database. By making the form fields match DB column > > >names, I can reduce the code to do this to: > > > > > > my $data = $dbh->fetchrow_hashref($query); > > > %fdat = (%fdat, %$data); > > > > > >Embperl then parses the form and populates it with the matching > > >name=>value pairs in %fdat, including select options. Beautiful! > > > > Not that it's a reality now, but this is one of the things that the Perl > > Widget Library project on source forge is hoping to accomplish for > template > > languages. It's a cross template way of organizing form information and > map > > it to db fields. > > > > The reality is that there are many fields that cannot map easily 1-1 to a > > database as you say. eg a date in a database is usually a date field. But > > in a form, it might be a combination of 3 form fields (dropdown for month, > > year and day separately). > >which of the existing paradigms will the widget farm most >closely resemble? and what are your expectations for tradeoff in >functionality/modularity-vs-performance? 1) What do you mean by your first question? 2) I believe there is nothing being done in the widget farm that would really hinder performance other than being objects with methods. Really without a good object structure then a widget farm is wholly useless. If you need extremely high performance pages than you probably need to code more low level than throwing abstractions around like widgets. Please read the following, and then take the conversation to the widget-specific mailing list if you are interested in talking more about it. http://www.officevision.com/pub/Widget/ === To: "Stas Bekman" <stas@stason.org>, "will trillich" <will@serensoft.com> From: "Perrin Harkins" <perrin@elem.com> Subject: Re: templating benchmarks... Date: Wed, 13 Jun 2001 23:26:46 -0400 > > wow. template toolkil took a big hit, there. (no mod_perl on > > this list? hmm!) > > This benchmark can be very non-representive. If you don't know how to > optimize each and every "thing" under test, you end up with unfair > benchmark and come to potentially wrong conclusions. Take TT, add compiled > template caching on the disk and shared TT object and I bet TT won't be at > the bottom. I actually helped Joshua tune the TT example a little, and it using a cached Template object and caching the templates used in the test in memory. The "slowness" comes from the fact that it provides a major feature that the others don't, and it is being exercised in this test. The magic dot notation which allows templates to say foo.bar.baz, regardless of what kind of data structure, object, or code ref "foo", "bar", and "baz" may be takes a little more work. Whether it's a good idea or not is left as an exercise to the reader, but I will say this: if Template Toolkit is the bottleneck in your app's performance, you have either done some serious tuning or written a really simple application (like this benchmark). Nevertheless, it's good to see some numbers, if only to convince Andy to finish his optimized XS version of the TT stash. === To: "Tom Lancaster" <tom@grubby.net>, "Stas Bekman" <stas@stason.org> From: "Perrin Harkins" <perrin@elem.com> Subject: Re: templating benchmarks... Date: Wed, 13 Jun 2001 23:34:33 -0400 "Tom Lancaster" <tom@grubby.net> wrote: > Absolutely. But I'd like to bring up something I've noticed in benchmarking > 'real' sites: many, if not all, of the templating solutions appear to > parse the whole of an html page. This is at least true of Apache::ASP and > HTML::Mason, which I have used. Is it not ? Not really. They all cache the page in memory. It is not re-parsed every time. > I have produced really dramatic differences in performance in a two-tier > setup by judicious use of mod_include vs. wholesale proxying of pages > with dynamic content through to the mod_perl/Apache::ASP server. [snip] > Granted, I have other major bottlenecks involved: using Berkeley DB v1.x > for session state, for one. Perhaps this explains some of it -- maybe the > proxied header/footer requests never make session calls. I suspect that it's a combination of the database access and the network transfer. There is no difference in the amount of parsing going on, since it's all cached after the first time (per child). ===