[Catalyst] Chained ActionでスマートなURL
Chained Actionを使った例でこんな記事がありました。
/user/
ユーザー一覧
/user/add
ユーザー追加
/user/[ユーザー名]
[ユーザー名]の詳細
/user/[ユーザー名]/edit
[ユーザー名]の編集
/user/[ユーザー名]/delete
[ユーザー名]の削除
というURL構成を再現するのに
package MyApp::Controller::User;
use strict;
use warnings;
use base 'Catalyst::Controller';
sub _parse_PathPrefix_attr {
my ( $self, $c, $name, $value ) = @_;
return PathPart => $self->path_prefix;
}
sub root : Chained('/') PathPrefix CaptureArgs(0) {
my ( $self, $c ) = @_;
}
sub instance : Chained('root') PathPart('') CaptureArgs(1) {
my ( $self, $c ) = @_;
$c->stash->{user} = $c->req->captures->[0];
}
sub list : Chained('root') PathPart('') Args(0) {
my ( $self, $c ) = @_;
$c->res->body( ref($self) . '->list' );
}
sub add : Chained('root') PathPart Args(0) {
my ( $self, $c ) = @_;
$c->res->body( ref($self) . '->add' );
}
sub view : Chained('instance') PathPart('') Args(0) {
my ( $self, $c ) = @_;
my $user = $c->stash->{user};
$c->res->body( ref($self) . "->view $user" );
}
sub edit : Chained('instance') PathPart Args(0) {
my ( $self, $c ) = @_;
my $user = $c->stash->{user};
$c->res->body( ref($self) . "->edit $user" );
}
sub delete : Chained('instance') PathPart Args(0) {
my ( $self, $c ) = @_;
my $user = $c->stash->{user};
$c->res->body( ref($self) . "->delete $user" );
}
1;
非常に便利。
肝は_parse_PathPrefix_attrでPathPrefixという独自アトリビュートを作ってpath_prefixにディスパッチするところ。
さらにこんなことをしたい場合は
/user/[ユーザー名]/bookmark
[ユーザー名]のブックマーク一覧
/user/[ユーザー名]/bookmark/add
[ユーザー名]のブックマーク追加
/user/[ユーザー名]/bookmark/[ブックマーク]
[ユーザー名]のブックマーク[ブックマーク]の詳細
/user/[ユーザー名]/bookmark/[ブックマーク]/edit
[ユーザー名]のブックマーク[ブックマーク]の編集
/user/[ユーザー名]/bookmark/[ブックマーク]/delete
[ユーザー名]のブックマーク[ブックマーク]の削除
こうすればいいかと。
package MyApp::Controller::User::Bookmark;
use strict;
use warnings;
use base 'Catalyst::Controller';
sub root : Chained('/user/instance') PathPart('bookmark') CaptureArgs(0) {
my ( $self, $c ) = @_;
}
sub instance : Chained('root') PathPart('') CaptureArgs(1) {
my ( $self, $c ) = @_;
$c->stash->{bookmark} = $c->req->captures->[1];
}
sub list : Chained('root') PathPart('') Args(0) {
my ( $self, $c ) = @_;
$c->res->body( ref($self) . '->list' );
}
sub add : Chained('root') PathPart Args(0) {
my ( $self, $c ) = @_;
$c->res->body( ref($self) . '->add' );
}
sub view : Chained('instance') PathPart('') Args(0) {
my ( $self, $c ) = @_;
my $user = $c->stash->{user};
my $bookmark = $c->stash->{bookmark};
$c->res->body( ref($self) . "->view $user / $bookmark" );
}
sub edit : Chained('instance') PathPart Args(0) {
my ( $self, $c ) = @_;
my $user = $c->stash->{user};
my $bookmark = $c->stash->{bookmark};
$c->res->body( ref($self) . "->edit $user / $bookmark" );
}
sub delete : Chained('instance') PathPart Args(0) {
my ( $self, $c ) = @_;
my $user = $c->stash->{user};
my $bookmark = $c->stash->{bookmark};
$c->res->body( ref($self) . "->delete $user / $bookmark" );
}
1;
追記: typo訂正
