From time to time the talk about cross cutting Catalyst components is recurring on the mailing list. This is hard - but the basis libraries are improving - so I am sure at some point we'll have them. I believe the way to reach this is by writing examples of functionality that could become such a component - and continuously refining it. Perhaps moving parts to libraries. Enough introduction - let's start the example.
This is a comment system using DBIx::Class and HTML::FormHandler:
First the DBIC definition:
package DBSchema::Comment;
use strict;
use warnings;
use base 'DBIx::Class';
__PACKAGE__->load_components(qw/TimeStamp PK::Auto Core/);
__PACKAGE__->table('comment');
__PACKAGE__->add_columns(
id => { data_type => 'integer', is_auto_increment => 1, is_nullable => 0 },
item_id => { data_type => 'integer', is_nullable => 0 },
body => { data_type => 'text', default_value => undef, is_nullable => 1 },
nick => { data_type => 'varchar', default_value => undef, is_nullable => 1 },
email => { data_type => 'varchar', default_value => undef, is_nullable => 1 },
web_site => { data_type => 'varchar', default_value => undef, is_nullable => 1 },
ip => { data_type => 'varchar', default_value => undef, is_nullable => 1 },
t_created => { data_type => 'datetime', set_on_create => 1 },
t_updated => { data_type => 'datetime', set_on_create => 1, set_on_update => 1 },
);
__PACKAGE__->set_primary_key('id');
__PACKAGE__->belongs_to('item', 'DBSchema::Item', { id => 'item_id' });
1;
This needs to be linked to the Item table - the thing that the comments belong to. I wander how can I package this - so that this could be variable.
Next the FormHandler form:
package CommentForm;
use HTML::FormHandler::Moose;
extends 'HTML::FormHandler::Model::DBIC';
with 'HTML::FormHandler::Render::Simple';
has '+item_class' => ( default => 'Comment' );
has_field body => ( type => 'TextArea', cols => 30, rows => 6, required => 1 );
has_field email => ( type => 'Email', required => 1 );
has_field web_site => ( type => 'URI' );
has_field nick => ( required => 1 );
has_field ip => ( widget => 'no_render' );
has_field item_id => ( widget => 'no_render' );
has_field submit => ( widget => 'submit', value => 'Add Comment' );
And finally the controller method for building the comment form and saving the comments:
sub stash_comment_form {
my( $self, $c, @pks ) = @_;
my $params = $c->req->params;
my $form = CommentForm->new(
schema => $c->model( $self->model_name ),
);
if( $c->req->method eq 'POST' ){
$params->{item_id} = $pks[0];
$params->{ip} = $c->req->address;
$form->params( $params );
if( $form->process ){
$c->res->redirect( $c->uri_for( $self->redir_after_comment, @pks ) );
}
}
$c->stash( comment_form => $form );
}
This can be called in any action that displays the comment form like this:
$self->stash_comment_form( $c, $pk )
For now I leave out the templates for displaying the comments - but this is rather simple.
Cook zby! I've been looking for some code implementations using HTML::FormHandler
Showing changes from previous revision. Added | Removed
