tags:

views:

265

answers:

3

I want two special methods:

  • one that runs for all URLs
  • one that runs only for a specific path (/admin)

I thought the most general would be using begin, and the method for /admin would use auto. For example, in these two Catalyst controllers:

package MyApp::Controller::Root;

sub begin :Private {
    my ($self, $c) = @_;

    $c->log->debug('Run for all URLs');
}

[...]

package MyApp::Controller::Admin;

sub auto :Private {
    my ($self, $c) = @_;

    $c->log->debug('Run for /admin only');
}

But this does not achieve what I want. What is the correct solution?

EDIT: the problem is that Addmin::auto() is never called, not when I access /admin or /admin/

After more tests, auto is never called. I've tried to put auto at different places, it is never called.

+2  A: 

There's no obvious reason why what you've described doesn't do what you require. That would be the correct way to do it.

The log should show the dispatch path and whether your request was routed through these actions or not. If not, it will tell you how it is being handled.

The second line of each sub should be terminated with a ';'. I'm assuming that's a typo in SO, not your original code.

RET
The missing ; was a typo, thanks
Julien
+1  A: 

Do you have a begin action in Controller::Admin? As RET says, the way you've described things it should work just fine; the only caveat with a "global begin" is that if you put a begin in any other controller it will "shadow" the global one, because only one begin is run per action, and it's the "most specific" one (longest in terms of private path namespace).

hobbs
+3  A: 

The problem was actually the following: both controllers had this line:

__PACKAGE__->config->{namespace} = '';

This prevented the auto function to trigger in Admin.pm

Julien