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

发布于 2024-11-17 00:22:39 字数 950 浏览 7 评论 0原文

背景

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

问题:

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

  • /cust1/admin/list/person
  • /cust2/admin/添加/人
  • /cust2/admin/edit/person/3

这是为了“品牌”目的,也是为了确保从一个用户传递到另一个用户的书签或 URL 执行预期的操作。

但我在让它发挥作用时遇到了很多麻烦。我不想修改现有框架中的子程序,因此我一直在尝试以下方面的变体:

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

Background:

I'm using a CRUD framework in Catalyst that auto-generates forms and lists for all tables in a given database. For example:
/admin/list/person or /admin/add/person or /admin/edit/person/3 all dynamically generate pages or forms as appropriate for the table 'person'. (In other words, Admin.pm has actions edit, list, add, delete and so on that expect a table argument and possibly a row-identifying argument.)

Question:

In the particular application I'm building, the database will be used by multiple customers, so I want to introduce a URI scheme where the first element is the customer's identifier, followed by the administrative action/table etc:

  • /cust1/admin/list/person
  • /cust2/admin/add/person
  • /cust2/admin/edit/person/3

This is for "branding" purposes, and also to ensure that bookmarks or URLs passed from one user to another do the expected thing.

But I'm having a lot of trouble getting this to work. I would prefer not to have to modify the subs in the existing framework, so I've been trying variations on the following:

sub customer : Regex('^(\w+)/(admin)

But it just will not behave. I've used regex matching actions many times, but putting one in the very first 'barrel' of a URI seems unusually traumatic. Any suggestions gratefully received.

) { 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); }

But it just will not behave. I've used regex matching actions many times, but putting one in the very first 'barrel' of a URI seems unusually traumatic. Any suggestions gratefully received.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

罪#恶を代价 2024-11-24 00:22:39

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

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

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

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

Make the customer action :Chained and then chain the admin action to that one. For example:

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

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

For more information see the Catalyst::DispatchType::Chained

夏末 2024-11-24 00:22:39

我已将迪米塔的答案标记为正确的答案,因为它使我走上了解决这个问题的正确轨道。 (直到现在我才真正需要 - 或领会 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 ..." 和相关想法动态生成所有这些子项,但最终不得不承认失败。

I've marked Dimitar's answer as the correct one, because it put me on the right track to solving this problem. (I've never really had a need for - or grokked FTM - Chained actions until now.)

Here's what I've got in the various controllers, for anyone who's interested.

=== 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(@_) }

I had a red-hot go at dynamically generating all those subs via *{$action} = eval "sub ..." and related ideas, but eventually had to admit defeat on that.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文