Session “Flash” in PHP
December 7th, 2005Doing some PHP hacking tonight, I was missing Rails’ “flash”. So I coded up a quick and dirty implementation of the read-once session status notification pattern. The code
February 1, 2006
⇒ GvR: “Please Teach me Web Frameworks for Python!”.The 90+ comments are probably the best coverage on the rather fractured state-of-the-art of Python webstack
0.
(Aside django, python, rails, web, webdev) January 22, 2006
⇒ Firebug.Firefox extension for debugging HTML, CSS, AJAX, and Javascript
0.
(Aside ajax, css, debugging, firefox, javascript, webdev) Doing some PHP hacking tonight, I was missing Rails’ “flash”. So I coded up a quick and dirty implementation of the read-once session status notification pattern. The code
September 11, 2005
⇒ Spun, a web developer’s notebook.New tech focused blog from Gina Trapani
0.
(Aside blog, webdev) August 18, 2005
⇒ JavaScript Shell – an interactive eval environment with access to the current page..How come no one told me this existed?! Now I just need some time to play with it
0.
(Aside javascript, shell, web2.0, webdev) August 17, 2005
⇒ de hÓra: Automated mapping between RDF and forms, part I.The problem with RDF? Even something as fundamental to webdev as round tripping to a form is hard. Looking forward to part II
0.
(Aside foaf, rdf, semweb, web, webdev) March 18, 2005
⇒ COMA: Coldfusion on Molasses.I wonder if I should put that on my resume?
0.
(Aside buzz, coldfusion, meme, rails, webdev) Several months ago, inspired as I recall by Kate’s How to Avoid Writing Code article, I started playing with Class::DBI and Template Toolkit as a rapid development environment.
So with great pleasure I present OO::Form 0.01-alpha-experimental. (which has been kicking around for a week fews, but I finally added some POD)
OO::Form – an object oriented framework for building, displaying, and processing forms.
package MyApp::AddWidgetForm;
use base ‘OO::Form’;
our $FIELDPROFILE = {
fields =>
[qw(name widgetstyle note expirationdate) ],
types => {
widgetstyle => 'select',
note => 'textarea',
expirationdate => 'date'
},
options => {
widgetstyle => [qw(blue green chrome)]
},
required => [qw(name widgetstyle)]
};
sub new {
my $class = shift;
my $self = $class->SUPER::new(@);
$self->addfields($FIELDPROFILE);
$self->submitfield('addwidget');
return $self;
}
….
(else where in your application)
my $form = MyApp::AddWidgetForm->new({query => $query, ...});
if ($form->issubmitted and $form->validates ) {
MyAdd::Widget->newwidget({
name => $form->name->value,
widgetstyle => $form->widgetstyle->value,
note => $form->note->value,
expiration-date => $form->expirationdate->value
});
displaywidgetaddedconfirmation();
}
else {
# form hasn't been submitted, or we encountered an error
displaypage($template, { form => $form } );
}
…,
(mean while, in a nearby template)
[% IF form.errors %]
<ul class="errors">
[% FOREACH e = form.errors %]<li>[% e %]</li>[% END %]
</ul>
[% END %]
Name: [% form.name.html(size => '40') %]<br /> Style: [% form.widgetstyle.html(default => 'blue') %] <br /> Expiration: [% form.expirationdate.html %] Note: <br /> [% form.note.html(rows =>4, cols=>50) %]<br /> <input type="submit" name="[%form.submitfield%]" value="Add Widget" />...,
OO::Form represents an HTML form as a collection of OO::Form::Field objects, a state (is submitted), and some basic error handling. It was inspired by CGI::FormBuilder, and by the difficulty I had integrating CGI::FormBuilder into my application. The OO::Form was designed to be used in conjuction with the Template Toolkit, and Class::DBI though they aren’t tightly coupled.
The most straightforward way to use OO::Form is to create your own subclass of OO::Form for each form in your application. (though create and update pages can usually re-use the same form object, and for very simple forms, it is probably less useful)
Then pass a ‘fields profile’ to the OO::Form->addfields() method which is a factory method for creating object of type OO::Form::Field and its varied subclasses.
A field profile is a compact form of specifying all the fields in your form. (Alternately you could insantiate OO::Form:Field::* objects one by one and add each one with $form->field($field))
A field profile is a hashref with 6 fields.
html() method is called.
OO::Form::Field-factory()> will be called for each field, and be passed its type. The default factory() method tries to instantiate an object of type OO::Form::Field::$type. You can subclass OO::Form::Field to provide a whole set of new field types, or new behaviour for old field types. Additionally if anyone has suggestions for a smarter factory method, I’m interested.
Current types are the basic HTML fields: text, password, checkbox, textarea, select
Also the composite field type: date (represented as 3 pulldowns) is available.
See OO::Form::Field for more detail
A hashref of field names pointing to either an arrayref of options (when you want value and text to be the same) or a hashref of value to text mappings.
If your values hashref contains a subclass of Class::Accessor (like a Class::DBI object) then the objects get() method will be called, allowing forms to be rapidly populated from a database.
OO::Form-validate> will return false (and populate an errors array) if any required fields are missing
There are hooks for a future implementation of a full blown validation framework (probably using Data::FormValidator).
In the meantime OO::Form checks that required fields have been filled in, and that none of the various fields through their own error.
Calling the instance method validate() (validates() is a synonym), returns true or false depending on whether there are any error conditions in the current form. It also populates and errors array, useful for re-displaying the form page with a list of errors.
A useful idiom for calling validates in demonstrated in the synops.
Besides the form wide errors array (accessible at $form->errors() ), each field can have their own error (though only one) accessible at $form->widgetstyle->error(), this is useful for re-displaying a form, with error messages inlined.
OO::Form is pretty straightforward, much of the complexity is actually in OO::Form::Field. Almost all OO::Form methods accept a hashref of named arguments.
Note this is all experimental.
new($params)query'',submitfield”, “time_zone”.
* query is a CGI.pm object, or something else which masquerades as one
* submitfield is the name of the button that submits this form (checked by issubmitted.
* time_zone is used by OO::Form::Field::date to do intelligent localization of date/time values
Additionally in the future OO::Form::new should take a locale.
addfields($fieldprofile)field(...)OO::Form::Field-factory()>, and attach the results to the current form.
Otherwise assume a string was passed in, and return the field with that name. (AUTOLOAD will call field($field_name) for unknown methods)
In preparation for doing the Protest.net re-write I’m doing some research on web frameworks. I find myself rewriting the same central dispatcher code, adding refinements, like a redirect method (similiar to the forward() method in servlets) and in general missing some of the refinements of Java’s web environments (servlets, Struts, bundles for i18n) while refusing to give up Perl, CPAN, and Template Toolkit.
This is my brain dump so far. Lots of questions, a few answers. The next step will be firing up the text editor and looking under the hood.
UPDATE: After looking at the available options, and at Struts 1.1, I would go with Java if I didn’t know I would have an insurrection on my hands.