Как я могу ввести действие регулярного выражения, чтобы сопоставить первый элемент в URI Catalyst? - PullRequest
4 голосов
/ 25 июня 2011

Справочная информация:

Я использую инфраструктуру CRUD в Catalyst, которая автоматически генерирует формы и списки для всех таблиц в данной базе данных.Например: / admin / list / person или / admin / add / person или / admin / edit / person / 3 - все динамически генерируют страницы или формы в соответствии с таблицей person.(Другими словами, в Admin.pm есть действия edit, list, add, delete и т. Д., Которые ожидают аргумент таблицы и, возможно, аргумент, идентифицирующий строку.)

Вопрос:

В конкретном приложении, которое я создаю, база данных будет использоваться несколькими клиентами, поэтому я хочу ввести схему URI, где первым элементом является идентификатор клиента, а затем административное действие / таблица и т. Д.

  • / cust1 / admin / list / person
  • / cust2 / admin / add / person
  • / 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 кажется необычайно травматичным.Любые предложения с благодарностью получены.

Ответы [ 2 ]

3 голосов
/ 27 июня 2011

Выполнить действие клиента: приковать цепью, а затем связать действие администратора с этим.Например:

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

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

Для получения дополнительной информации см. Catalyst :: DispatchType :: Chained

1 голос
/ 02 июля 2011

Я пометил ответ Димитара как правильный, потому что он поставил меня на правильный путь решения этой проблемы.(У меня до сих пор никогда не было необходимости - или уродливого 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 ..." и связанных с ними идей, но в конце концов мне пришлось признать это поражением.

...