Saturday, June 20, 2009

CatalystX::Comments - RFC

In Packaging cross cutting Catalyst features I promised to start developing a generic Catalyst comment sub-system. Now I have incorporated the code samples into another experiment - ravlog(a blog engine by Gerda), and I would like to ask you what you think about it before releasing it to CPAN.

Here is the current API - any comments are welcome. First you need to declare the controller using the new Moose style:

package RavLog::Controller::View;

use Moose;
extends 'Catalyst::Controller';
with 'CatalystX::Comments::ControllerFormRole';

has model_name => ( is => 'ro', isa => 'Str', default => 'DB' );

The important part for us is of course with 'CatalystX::Comments::ControllerFormRole', the model_name attribute should hold the name of the model CatalystX::Comments will use to store the comments.
After the declarations you can use CatalystX::Comments to put the comment form on the stash:

sub view : Chained('base') PathPart('view') Args(0)
my ( $self, $c, $id ) = @_;


$self->stash_comment_form( $c, $self->article->id );

That's the whole controller part - what it handles is generating the form for display and saving the submitted comments. In the view templates you need to add:

[% comment_form.render %]

For displaying the comments themselves ravlog already had some template code and I did not change it.

Next is the model part. The library assumes that the DBIC model contains a Comment Result class like that one in ravlog. Of course it does not need to have all of the columns, and can also have other columns - but these are the columns that will be filled by the CatalystX::Comments form. Ideally that model part should be a Result base class - so that it can be subclassed and adapted to local circumstances (for example the belongs_to relationship to article needs to be changed), but for now I don't know how to do that.

Now some more details. Thanks to html_prefix all parameters sent from this form are prefixed with the form name - so this form can be added to pages with other forms, it will recognize it's parameters. The comments are saved only when the HTTP method used is POST, and after a successful comment creation the user is redirected to the same page (this seems a bit constraining - but see next paragraph - this is only meant to be temporary solution - I try to keep the API simple).

Of course I understand that this can never cover the needs of a comment sub-system in a mature social web site. I am thinking about it as more of scaffolding - code that let's you quickly develop a feature, see how it integrates with the rest of the user experience, formulate a more complete requirements list - and replace it part by part.


Anonymous said...

Heya, this is really cool, nice component.

I've been thinking about this same sort of stuff, but from an infrastructure angle. What you really want to be able to do is graft entire chunks of functionality (e.g. login form + user / role admin interface) as scaffolding, by just including something in the plugins list, and adding some config..

From there you use some more custom templates, and then start replacing (or just augmenting) the standard controller &etc code with your own stuff..

So I don't know if you've seen CatalystX-DynamicComponent, but that (and CatalystX-InjectComponent) are kinda prototypes of the component injection stuff..

Someone needs to properly Moosify View::TT, so that adding roles onto it worked nicely, then doing nice stuff so that extensions could push a role onto the view to get their shared templates included etc.

We should chat about this more in #catalyst-dev at some point, and I should re-read the thread you linked :)

zby said...

Thanks. I think we have exchanged a few words on IRC about CatalystX-DynamicComponent - so yeah I am aware of it. I think it can be useful to 'Catalyze' some non Catalyst libraries (like making a DBIC model without writing that empty model class) - but I am not so sure if there is much dynamism needed in the case of comments (and login forms). But shared templates seem like something that I need.

Frankly login form was also in my plans - but since there is already the authentication helper that generates the form - then I thought I'll leave that one, but the next thing I am working on is registration.