[Catalyst] Form handling, urls and web design
Alex Kavanagh
alex at tinwood.homelinux.org
Mon Jan 23 22:47:17 CET 2006
Hi
Yes, another post, but I'm beginning to get into this and questions
just keep popping up.
Currently, I'm wondering what the best way of handling forms is in the
context of urls and what to do with error messages.
I have a system going, but I'm curious as to what others have done in
solving this particular design problem.
Scenario:
You want to manage a list of users. Each user has various attributes
and you want to be able to edit them.
At the moment, I have two URLs to deal with this:
/manage/users - provide the list of users
/manage/users/<username> - deal with a particular user.
I have a controller called Manage::Users.pm which appropriately looks
after the /manage/users url fragment.
Currently, I have two main functions which are called by the Catalyst
framework:
sub default : Private {
}
looks after the list of users
and
sub user : LocalRegex( '(\w+)$' ) { # ';
}
to handle the user.
In each of this functions I look at the params passed to work out what
we are doing (e.g. first entry, asked to add a user, sent back the
form for adding a user, etc.)
Thus as far as the web-user is concerned all they every see is
http://..../manage/users
or
http://..../manage/users/barty
(for the barty user).
regardless of the form they are looking at. I use redirects to push
them back to the appropriate page after an update.
To pull this off I examine the POSTed params from the forms and then
do a $c->forward(...) to the appropriate handler to look after the
action and then pick the appropriate template.
To get rid of the inevitable 'if' statements, I wrote a Utility
function that can compile up a list of param names to match values and
then return the appropriate string.
Thus:
my $s = Utils::Selector::compile( '/manage/users/user_add' =>
{ action => '(?i)add',
form_name => 'users' },
'/manage/users/user_add_confirm' =>
{ action => '(?i)add',
form_name => 'user-add' }, );
(note that's not a CPAN module, it's something I knocked up).
e.g. return '/manage/users/user_add' if ((action =~ /(?i)add) &&
(form_name =~ /users/));
then we can do $s->($c->request->params) and get back the appropriate
forward name:
e.g.
my $f = $s->($c->request->params);
$c->forward($f) if ($f);
for example (where _users_sel is a classdata):
sub default : Private {
my ($self, $c) = @_;
$c->stash->{template} = '/manage/users/users.mhtml';
my $f = $self->_users_sel->($c->request->params);
$c->forward($f) if ($f);
}
in one of the two handlers.
Seems a bit complex though, doesn't it.
So how do you handle this?
Cheers
Alex.
More information about the Catalyst
mailing list