如何引入正则表达式操作以匹配Catalyst URI中的第一个元素?

时间:2011-06-25 02:51:05

标签: perl catalyst

背景

我在Catalyst中使用CRUD框架,为给定数据库中的所有表自动生成表单和列表。例如: / admin / list / person或/ admin / add / person或/ admin / edit / person / 3都会动态生成适合表'person'的页面或表单。 (换句话说,Admin.pm有动作编辑,列表,添加,删除等等,它们需要一个表参数,可能还有一个行标识参数。)

问题:

在我正在构建的特定应用程序中,数据库将由多个客户使用,因此我想引入一个URI方案,其中第一个元素是客户的标识符,后跟管理操作/表等:

  • / cust1 /管理/列表/人
  • / cust2 /管理/添加/人
  • / cust2 /管理/编辑/人/ 3

这是出于“品牌化”的目的,也是为了确保从一个用户传递到另一个用户的书签或URL能够完成预期的工作。

但是我在使用它时遇到了很多麻烦。我宁愿不必修改现有框架中的subs,所以我一直在尝试对以下内容进行修改:

sub customer : Regex('^(\w+)/(admin)$') {
    my ($self, $c, @args) = @_;
    #validation of captured arg snipped..
    my $path = join('/', 'admin', @args);
    $c->request->path($path);
    $c->dispatcher->prepare_action($c);
    $c->forward($c->action, $c->req->args);
}

但它不会表现出来。我已多次使用正则表达式匹配操作,但将一个放在URI的第一个“桶”中似乎异常创伤。感激地收到任何建议。

2 个答案:

答案 0 :(得分:3)

进行客户操作:链接,然后将管理操作链接到该操作。例如:

sub customer :Chained('/') :PathPart('') :CaptureArgs(1) {
    # load current customer into the stash
}

sub admin :Chained('customer') :PathPart('admin') :Args(0) {
}

有关详细信息,请参阅Catalyst::DispatchType::Chained

答案 1 :(得分:1)

我已经将Dimitar的答案标记为正确答案,因为它让我走上正确的道路来解决这个问题。 (到目前为止,我从来没有真正需要 - 或者使用FTM - 链接动作。)

这是我在各种控制器中所拥有的,对于任何有兴趣的人。

=== Root.pm ===

sub customer_home : Path: Args(1) { # eg /cust1
    my ($self, $c, $custarg) = @_;
    ...
}

sub ourclub :Chained('/') :PathPart('') :CaptureArgs(1) { # eg /cust1/<admin-function>
    my ($self, $c, $custarg) = @_;
    ...
}

=== Admin.pm ===

use base 'Framework::Controller';

# create chained action versions of the framework actions
sub admin       :Chained('/customer') :PathPart('admin')     { shift->SUPER::admin(@_) }
sub list        :Chained('/customer') :PathPart('list')      { shift->SUPER::list(@_) }
sub view        :Chained('/customer') :PathPart('view')      { shift->SUPER::view(@_) }
sub add         :Chained('/customer') :PathPart('add')       { shift->SUPER::add(@_) }
sub edit        :Chained('/customer') :PathPart('edit')      { shift->SUPER::edit(@_) }
sub delete      :Chained('/customer') :PathPart('delete')    { shift->SUPER::delete(@_) }
sub search      :Chained('/customer') :PathPart('search')    { shift->SUPER::search(@_) }
sub model       :Chained('/customer') :PathPart('model')     { shift->SUPER::model(@_) }

我通过*{$action} = eval "sub ..."和相关的想法动态生成所有潜艇,但我最终不得不承认失败。