2

问候,

我是 Catalyst 的新手,我正在尝试实现一些调度逻辑。

我的数据库有一个项目表,每个项目都有一个唯一的url_part字段,每个项目在同一个表中都有一个父项,形成一个树结构。如果baz是一个孩子的bar孩子foo是根的孩子的孩子,我希望 URL/foo/bar/baz映射到这个对象。树可以是任何深度,用户需要能够访问任何节点,无论是分支还是叶子。

我一直在查看 Chained dispatchers 的文档,但我不确定这是否可以满足我的要求。似乎链式调度程序中的每个步骤都必须为PathPart属性定义一个名称,但我希望我的 URL 仅由数据库结构确定。

这是否易于使用现有的 Catalyst 调度程序实现,还是我需要编写自己的调度类?

谢谢!:)

预计到达时间:

我发现我可以使用一个空Args属性来捕获任意数量的参数。以下似乎成功捕获了根下的每个请求:

sub default :Path :Args() {
    my ( $self, $c ) = @_;

    my $path = $c->request->path;

    $c->response->status( 200 );
    $c->response->body( "Your path is $path" );
}

从那里我可以手动解析路径并获得我需要的东西,但是,我不知道这是否是完成我所追求的最佳方式。

4

2 回答 2

2

这取决于您的数据结构,我从您的问题中并不完全清楚。

如果有固定数量的级别(或至少有限数量的级别),每个级别对应于特定类型的事物,那么 Chained 可以做你想做的事——拥有链式动作:CaptureArgs(1) PathPart('')/*/在路径中创建一个段 - 也就是说,它吞噬路径的一个段,而不需要显示任何特定的固定字符串。

如果没有这样的事情——例如,你在任意树下追逐无限数量的级别,那么可变参数:Args动作可能正是你想要的,并且使用它没有什么脏东西。但是您不需要$c->req->path自己解码 - 您可以从 获取剩余的路径段$c->req->args,或者只是my ($self, $c, @args) = @_;在您的操作中执行。您可以编写一个新的 DispatchType,但它不太可能值得付出代价。

于 2011-02-19T03:01:25.830 回答
0

在尝试了各种选项之后,我相信我已经找到了一个可以接受的解决方案。不幸的是,我无法进行递归调度:Chained(如果您尝试将处理程序链接到自身,Catalyst 会抱怨。这不好玩。)

所以我最终使用了一个带有大的处理程序CaptureArgs,如下所示:

sub default : CaptureArgs(10) PathInfo('') { 
    my ( $self, $c, @args ) = @_;

    foreach my $i( 0 .. $#args ) { 
        my $sub_path = join '/', @args[ 0 .. $i ];

        if ( my $ent = $self->_lookup_entity( $c, $sub_path ) ) { 
            push @{ $c->stash->{ent_chain} }, $ent;
            next;
        }

        $c->detach( 'error_not_found' );
    }

    my $chain = join "\n", map { $_->entity_id } @{ $c->stash->{ent_chain} };
    $c->response->content_type( 'text/plain' );
    $c->response->body( $chain );
}

如果我做一个GET/foo/bar/baz得到

foo
foo/bar
foo/bar/baz

这就是我想要的。如果 URL 的任何部分与数据库中的对象不对应,我会得到 404。

这适用于我的应用程序,它永远不会有十级深度,但我希望我能找到一个更通用的解决方案,可以支持任意深度的树。

于 2011-02-23T22:09:03.643 回答