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

Perl 如何引入正则表达式操作以匹配Catalyst URI中的第一个元素?,perl,catalyst,Perl,Catalyst,背景: 我在Catalyst中使用了一个CRUD框架,它自动为给定数据库中的所有表生成表单和列表。例如: /admin/list/person或/admin/add/person或/admin/edit/person/3根据表格“person”动态生成页面或表格。(换句话说,Admin.pm具有编辑、列出、添加、删除等操作,这些操作需要一个表参数,可能还需要一个行标识参数。) 问题: 在我正在构建的特定应用程序中,数据库将由多个客户使用,因此我想介绍一个URI方案,其中第一个元素是客户的标识符,

背景:

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

问题:

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

  • /客户1/管理员/列表/人员
  • /客户2/管理员/添加/个人
  • /客户2/管理/编辑/个人/3
这是为了“品牌化”的目的,也是为了确保从一个用户传递到另一个用户的书签或URL达到预期效果

但是我很难让它工作。我希望不必在现有框架中修改SUB,因此我一直在尝试以下方面的变化:

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的第一个“桶”中似乎异常痛苦。感激地收到任何建议。

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

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

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

有关更多信息,请参见

我已将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(@_) }
==Root.pm===
子客户主页:路径:Args(1){#eg/cust1
我的($self,$c,$custarg)=@;
...
}
subourclub:Chained('/'):路径部分(''):CaptureArgs(1){例如/cust1/
我的($self,$c,$custarg)=@;
...
}
==Admin.pm===
使用base'Framework::Controller';
#创建框架操作的链接操作版本
子管理员:链接('/customer'):路径部分('admin'){shift->SUPER::admin(@)}
子列表:链接('/customer'):路径部分('list'){shift->SUPER::list(@)}
子视图:链接('/customer'):路径部分('view'){shift->SUPER::view(@)}
子添加:链接('/customer'):路径部分('add'){shift->SUPER::add(@)}
子编辑:链接('/customer'):路径部分('edit'){shift->SUPER::edit(@)}
子删除:链接('/customer'):路径部分('delete'){shift->SUPER::delete(@)}
子搜索:链接('/customer'):路径部分('search'){shift->SUPER::search(@)}
子模型:Chained('/customer'):PathPart('model'){shift->SUPER::model(@)}

我曾尝试通过
*{$action}=eval“sub…”
和相关想法动态生成所有这些sub,但最终不得不承认失败。

这不是关于正则表达式本身的问题,因此我删除了编辑器添加的regex标记。在您的示例中,正则表达式将不匹配,因为URI中的第一个
/
——在这种情况下,
^\w
将不匹配<代码>子客户:Regex('^(\w+/(admin)$){这不是Catalyst Regex操作的工作方式。上面的示例位于根目录中(空命名空间)控制器,因此正斜杠不相关。您是否尝试将
\w
转义为
\\w
?这也在我的答案中?如果不是,我将删除我的答案。这不是正则表达式的问题,也不是反斜杠的问题。这是专门关于Catalyst行为的。实际的正则表达式并不相关,这就是我没有这么做的原因在我发布问题时包含regex标记。谢谢Dimitar。不幸的是,它不是那么简单,因为admin不是一个sub,而是另一个包含各种操作的控制器。事实上它甚至没有那么简单,因为它继承了原始CRUD framework控制器的大多数操作。例如:admin.pm包含一个sub-auto,但其他ise从Framework::Controller.pm继承了列表、添加、编辑子类。因此,我实际上没有任何子类可以挂起:链接到…我使用您的建议的变体解决了这个问题(基本上,使用定义的:属性对所有继承的子类进行子分类)。请参阅我的答案。