[Catalyst] Feedback requested on HTML::FormHandler's new widget
system
Gerda Shank
gs364 at cornell.edu
Tue Sep 1 02:41:04 GMT 2009
A new widget system for HTML::FormHandler is currently under
development, and it would be nice to get feedback from those who might
be interested in it before putting it out in a release.
It's currently in the HTML::FormHandler repository on github:
http://github.com/gshank/html-formhandler/tree/master
I've copied the current version of HTML::FormHandler::Manual::Rendering
at the end of this email.
Please respond offlist or on #formhandler.
Thanks,
Gerda Shank
=========================================
=head1 NAME
HTML::FormHandler::Manual::Rendering
=head1 SYNOPSIS
HFH has a number of different rendering methods.
1. Handcoded html with no assist from HFH at all
2. Use templates and the field 'widget' to determine the template snippet
3. Use a rendering role in your form class, like Render::Simple
and now:
4. Automatically installed rendering widgets using a combination of
rendering roles, which can easily be customized by the user.
=head1 Rendering with Widgets
All FormHandler widgets are Moose roles.
Default widget roles are installed into HTML::FormHandler::Widget. They
include
widgets for the fields in the distribution. Each field can render itself
with
C<< $field->render >>. The widget rendering roles are applied at build
time in
each field object.
The name space used to look for the widget roles can be specified on a
form or
field basis by setting 'widget_name_space' to a scalar name space, like:
has '+widget_name_space' => ( default => 'MyApp::Form::Widget' );
or to an arrayref of name spaces:
has '+widget_name_space' => ( default => sub { ['MyApp::Form::Submit',
'MyApp::Form::Widget' ]);
The HTML::FormHandler::Widget name space is always searched as the last
name space.
This means that you can set up an application or form specific set of
widgets.
Widgets in a widget directory (specified in widget_name_space) are
located in either
a 'Field', 'Wrapper', or 'Form' subdirectory.
The form's rendering role is looked for in the widget name space plus
'Form'. The
default form rendering roles are in HTML::FormHandler::Widget::Form. The
form
widget is specified in the form with 'widget_form'.
package MyApp::Form;
....
has '+widget_form' => ( widget_form => 'Simple' );
...
The 'wrapper' for field rendering can also be specified with
'widget_wrapper'.
The widget specified will be looked for in the widget directories' 'Wrapper'
subdirectory. It contains a 'wrap_field' method which is called from the
Field
widgets. The wrap_field method takes the basic rendered field (passed
from the
field widget) and wraps it with HTML. The defaults provided are 'Div'
and 'Table'.
You can specify a wrapper class for all the fields in the form by setting
'widget_wrapper' in the form class, or you can set them individually by
setting
'widget_wrapper' on individual fields.
has 'some_field' => ( widget_wrapper => 'MyWrapper' );
The 'widget' attribute is set to a default in FormHandler fields, or you
can
set it to a different widget in your field declarations.
has 'another_field' => ( widget => 'MyWidget', widget_wrapper =>
'MyWrapper' );
Can be set in the form:
widget_name_space
widget_wrapper
widget_form
Can be set in the field:
widget_name_space
widget_wrapper
widget
The widget_name_space and widget_wrapper will be copied into the fields
from the
form if they are not already defined.
By default, a form will use the Form::Simple and Wrapper::Div widgets.
If you
want to use the table format you can change the 'widget_form' and
'widget_wrapper'
attributes in the form, or do it on new:
my $form = MyApp::Form->new( widget_form => 'Table', widget_wrapper
=> 'Table' );
The form widgets will not be applied if a 'render' method already exists
in the form,
such as is the case when you've done a 'with' for
L<HTML::FormHandler::Render::Simple>.
=head1 Customized Widgets
You can create custom widgets for your complete application or on a
per-form basis.
One possible layout for your widgets;
lib/MyApp/Form
lib/MyApp/Form/Widget/Form
lib/MyApp/Form/Widget/Field (contains MyWidget.pm)
lib/MyApp/Form/Widget/Wrapper
Create custom widgets and put them in the respective directories, and
then specify your
widget name space:
MyApp::Form::User:
...
has '+widget_name_space' => ( default => 'MyApp::Form::Widget' );
..
has 'some_field' => ( widget => 'MyWidget' );
Your rendering widgets will be applied into your field classes.
=head1 Creating Widgets
The new widgets are designed to be used with either the original
FormHandler
form objects or the new L<HTML::FormHandler::Result> objects. For that
reason,
you should use C<< $field->result >> to access the current value, errors
and
'fif' (fill-in-form) in field widgets, so that they will work
for both form and result rendering.
The basic structure for a field widget:
package MyApp::Form::Widget::Field::MyWidget;
use Moose::Role;
sub render
{
my ( $self, $result ) = @_;
$result ||= $self->result;
my $output;
< create rendered field >
my $fif = $result->fif;
my $value = $result->value;
my $errors = $result->errors;
< done creating rendered field )
return $self->wrap_field($result, $output);
}
no Moose::Role;
1;
=cut
More information about the Catalyst
mailing list