根据Catalyst的胖Model,瘦Controller原则,在controller里面应该使用最少的代码来保持整个逻辑的清爽。 但对于任何一个web app来说,最复杂的逻辑之一就是表单的提交,验证表单,之后再根据需要从做相关 的操作,查询数据库或者返回错误。而这些都是Controller的任务
如果在Controller里面hardcode这部分逻辑,整个代码会变得冗长而丑陋,HTML::FormHandler就是为了简化 表单的处理而编写的模块。HTML::FormHandler使用Moose作为底层的OO库,代码实现比较优雅和干净。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 | package SEA::Forms::User; use HTML::FormHandler::Moose; extends 'HTML::FormHandler::Model::DBIC'; use namespace::autoclean; use Digest::MD5 qw/md5_hex/;
has '+name' => (default => 'user'); has '+auto_fieldset' => (default => 0); has '+item_class' => (default => 'User'); has '+dependency' => (default => sub { [[qw/password confirm/]] }); has_field 'id' => ( type => 'Text', required => 1, accessor => 'username', unique => 1, apply => [ { check => qr/^\w{7}$/, message => 'Invalid username' } ], messages => { required => 'username is required', unique => 'This username is already taken' }, );
has_field 'email' => ( unique => 1, messages => {unique => 'This email is already taken'}, apply => [ { check => qr/^\w+\.\w+\@ericsson\.com$/, message => 'Invalid Email' } ], );
has_field 'password' => ( type => 'Password', accessor => 'password', apply => [ { transform => sub { md5_hex(shift) } } ], );
has_field 'confirm' => ( type => 'Password', apply => [ { transform => sub { md5_hex(shift) } } ], );
has_field 'submit' => ( value => 'submit', type => 'Submit', css_class => 'submit' );
sub validate { my ($self) = @_; if ($self->field('confirm')->value ne $self->field('password')->value) { $self->field('password')->add_error("password not match"); } }
__PACKAGE__->meta->make_immutable; |
HTML::FormHandler主要分为这么几个部分
- HTML::FormHandler::Field::*
Field主要用来定义表单单元的类型,对某一种类型,会有相应的验证方法和属性,比如定义一个Text类型单元
has_field 'name' => (Type => 'Text', maxlength => 30, minlength =>
6);
- HTML::FormHandler::Widget::*
Widget用来生成Field的HTML代码,查看源代码,每一个widget都有个render方法,用来创建wdiget的HTML code,这里有两个特殊的widget。HTML::FormHandler::Widget::Wrapper::*,用来添加包裹每个表单单元的HTML,比如添加的是div
<input name="name", type="text">
还有一个是Widget::Form,定义…..部分如何生成
使用Moose定义的语法糖,比如has_field
HTML::FormHandler::Model::
与数据库交互的模块,值得注意的是FormHandler没有添加任何数据库操作的代码,而只是使用Moose Role定义了数据库操作所需要的方法。
to be continued…
Posted via email from Tech Blog of Woosley.Xu