[Catalyst] Program the logic

Marcello Romani mromani at ottotecnica.com
Mon Jul 3 10:32:24 CEST 2006

Brandon Black ha scritto:
> On 6/29/06, Nilson Santos Figueiredo Junior <acid06 at gmail.com> wrote:
>> On 6/29/06, Brandon Black <blblack at gmail.com> wrote:
>>> If you find yourself putting code in your View templates that isn't
>>> directly related to rendering this specific flavour of output, it
>>> probably needs to be moved to the Controller.  Good code in views:
>>> iterating an arrayref to generate a <ul> list, walking a data
>>> structure to generate a <table>, or walking a data structure to
>>> generate a graph image.
>> I've found myself building somewhat "fat" views lately. Mostly, I've
>> done it when trying to build generic "widget" thingies that might
>> appear in different pages. By "fat" I mean resultset-manipulating
>> views, but usually the manipulations are restricted only to the
>> view-related aspect of them, though. This means stuff like ordering
>> the resultset by some column (using order_by). I'm usually in doubt if
>> this is indeed a good practice or if it should be done another way,
>> but it sure makes things easier.
> I think its fine to have the controller generate a resultset, and have
> the view directly apply ordering and/or paging to the resultset before
> generating HTML from it.  But then again, I also find that approach a
> bit difficult and limiting.
> The approach I'm attempting lately (and I haven't gotten it all
> working right yet...) is to make Controller base-classes that
> implement generic concepts for things like paging and sorting tables
> of data (complete with handling form args like ?page=3&count=50 or
> ?sortby=foo:desc silently for the controller), which makes it
> effortless for the controller to apply those sorts of things to the
> resultset before its sent to the view.  These bits of controller
> functionality are of course View-agnostic.
> They (the base controllers implementing these features) basically boil
> down to: Check for some standardized GET form parameters, provide some
> data to the controller in the form of a paging object or some DBIC
> sorting hashref stuff, and also directly set stash variables for the
> views to see, regarding paging and sorting.  There are template
> includes that go along with these meta controller actions (displaying
> the << < 1 2 3 > >> paging clickies and whatnot, based on those stash
> vars...).
> Ultimately if I can ever get these concepts sufficiently genericized
> and bulletproof (or if anyone else does before me), it'd be a good
> idea to throw some out on CPAN as Catalyst::Controller::PageSort or
> something of the sort.
> -- Brandon

I've put together a solution that is inspired by the those same 
concepts. Instead of building controller base-classes, I've written a 
Catalyst::Controller::CRUD class which has only private methods, like 
setup_order(), setup_pager(), etc.
Those methods are called by the crud controller managing a particular 
type of objects (i.e. a table or view) using forward(). Maybe it's 
clearer with an example:

in MyApp::Controller::Products:

sub list : Local {
     my ($self, $c) = @_;
     $c->forward('/crud/setup_order');   # if one wants column sorting 
     $c->forward('/crud/setup_pager');   # if one wants pager support
     $c->forward('/crud/list');          # finally display the template

The logic to handle ordering parameters (which are named for example 
Xorder, Xo2, etc. to lessen the probability of param name clashing) is 
split between the /crud/setup_order and the "list" template.

You can find a working example of this setup (which I've used in some 
production apps) in a sample application named CrudApp, listed under the 
"Examples" section in the cat wiki home page.
While porting it to dbic (it all started out with cdbi), I'm also trying 
to rething the whole approach, which I don't find particularly elegant 
(some of the template code has roots in the factory list template 
provided with Maypole...).


> _______________________________________________
> List: Catalyst at lists.rawmode.org
> Listinfo: http://lists.rawmode.org/mailman/listinfo/catalyst
> Searchable archive: http://www.mail-archive.com/catalyst@lists.rawmode.org/
> Dev site: http://dev.catalyst.perl.org/

Marcello Romani
Responsabile IT
Ottotecnica s.r.l.

More information about the Catalyst mailing list