[Catalyst] Creating my own controller and another question

Matt S Trout dbix-class at trout.me.uk
Fri Apr 28 16:45:55 CEST 2006


John Napiorkowski wrote:
> Hi,
> 
> I'm creating a class that subclasses from
> Catalyst::Controller for use to encapsulate some
> functionality for certain pages on my site.  I realize
> that this could be potentially done with with a
> plugin, but for this purpose I feel subclassing
> Catalyst::Controller is the cleanest and most
> maintainable approach.
> 
> The problem I am having is that I want my controller
> to prepare some data when it is first loaded.  The
> function is to create a list of objects that will
> later be retrieved, so I can't just put it into the
> config.  However I can't figure out the best why (or
> the best practices way) to do that.  Should I just
> write my own new subroutine to do this?

If you're trying to do something at initialisation time, overriding new() is 
the logical approach. Just do something like

sub new {
   my $self = shift;
   my $new = $self->NEXT::new(@_);
   $new->init;
   return $new;
}

> Another problem.  There is some strange things going
> on when I have a config in a base controller.  For
> example I have a class "element" that inherits from
> "Catalyst::Controller" which has the following line
> (again this is contrived a bit for clarity):
> 
> package element;
> 
> use strict;
> use warnings;
> 
> use base qw/Catalyst::Controller/;
> 
> __PACKAGE__->config( view => 'element');
> 
> sub view
> {
>   $self = shift;
>   return $self->{view};
> }
> 
> Then I have two classes that inherit from this element
> class:
> 
> package page;
> 
> use base qw/element/;
> 
> __PACKAGE__->config( view => 'page');
> 
> 
> and
> 
> package portlet;
> 
> use base qw/element/;
> 
> __PACKAGE__->config( view => 'portlet');
> 
> So all three classes have a method called "view". 
> However this method doesn't do what I would think it
> would.  If I subclass any of these three classes for a
> catalyst controller and call $self->view on that
> subclass I always get 'portlet' as a response, instead
> of what was defined in the config for the local class.
>  Maybe I just don't understand how this is supposed to
> work?

Not sure, that looks pretty much fine. It may be something going a bit odd in 
the way the Class::Data::Inheritable setup works, though I've never 
encountered any major problems. Try doing

__PACKAGE__->_config({ %{ __PACKAGE__->_config } });

or so before you call ->config in the subclasses and see if it sorts it. If it 
does, a failing test case against Catalyst (since that shouldn't be necessary) 
would be welcome :)

> Oh, one last quick thing: Is there an easy way to get
> the context object if you only have the self object,
> like in a controller where you have make some local
> accessors?  This is causing me a lot of trouble.
> Any thoughts or questions from the community would be
> appreciated.

when Catalyst retrieves a component of any type for use, if the component has 
an ACCEPT_CONTEXT method it calls that with $c as an argument and returns the 
result.

-- 
      Matt S Trout       Offering custom development, consultancy and support
   Technical Director    contracts for Catalyst, DBIx::Class and BAST. Contact
Shadowcat Systems Ltd.  mst (at) shadowcatsystems.co.uk for more information

+ Help us build a better perl ORM: http://dbix-class.shadowcatsystems.co.uk/ +



More information about the Catalyst mailing list