Book-Chinese-MasterPerlToday

 view release on metacpan or  search on metacpan

lib/Book/Chinese/MasterPerlToday/Catalyst.pod  view on Meta::CPAN

=head2 扩展 Catalyst

参阅 L<Catalyst::Manual::ExtendingCatalyst>, L<Catalyst::Manual::Internals>, L<Catalyst::Manual::Plugins>

=head3 Plugin

Plugin 在 5.80 以前(乃至现在)是使用最广的一种扩展方式,虽然有些 plugin 其实没必要成为一个 plugin。

Plugin 通过更新 Catalyst 流程中的某些子程序,或者给 $c 添加一些函数。

通常更改 Catalyst 流程的 plugin 是值得的。但是如果仅仅是方便调用,给 $c 添加某个函数,是非常没有必要成为一个 plugin 的。

Catalyst 的整个流程包括两个部分。

=over 4

=item * setup

一个是 setup 部分,在 Catalyst 启动的时候调用一次。

    setup
      setup_home
      setup_log
      setup_plugins
      setup_dispatcher
      setup_engine
      setup_stats
      setup_components
      setup_actions
      setup_finalize

上述 setup_* 函数我们一般不进行改动,如果自定义的 Plugin 需要在启动的时候检查 config 或做一些初始化的话,一般直接改 sub setup

  use MRO::Compat;
  sub setup {
    my $c = shift;

    $c->maybe::next::method(@_);
    $c->setup_my_plugin_stuff;
  }

上述 setup plugin 例子有 L<Catalyst::Plugin::ConfigLoader>, L<Catalyst::Plugin::I18N> 等

L<Catalyst::Plugin::Server> 使用了 setup_dispatcher

=item * request

另一个是 request 部分,每个 url 的 request 都调用一次。

    handle_request
      prepare
        prepare_request
        prepare_connection
        prepare_query_parameters
        prepare_headers
        prepare_cookies
        prepare_path
        prepare_body (unless parse_on_demand)
          prepare_body_parameters
          prepare_parameters
          prepare_uploads
        prepare_action
      dispatch
      finalize
        finalize_uploads
        finalize_error (if one happened)
        finalize_headers
          finalize_cookies
        finalize_body

这种 plugin 很多。

L<Catalyst::Plugin::PageCache> 使用 dispatch+finalize

L<Catalyst::Plugin::Unicode> 使用 prepare_parameters+finalize

=back

=head3 Controller/View/Model

这种类型的扩展一般用于被 use base 或 use parent

=over 4

=item * View

View 是最常见的一种扩展,最常用的如 L<Catalyst::View::TT>, L<Catalyst::View::JSON>, TT::Alloy, PHP, Mason, Template::Declare, GraphViz, GD 等。所有的 View 扩展都基于 L<Catalyst::View>, 它们都覆盖 sub process, 并且在å‡...

=item * Model

Model 的扩展不多,最常用的当然是 L<Catalyst::Model::DBIC::Schema> 和 L<Catalyst::Model::Adaptor>. 大部分的 Model 都跟 storage 有关。

所有的 Model 扩展语法跟我们平常写的并无任何区别,所不同的仅仅在于公用性。

写 Model 扩展的时候,有时候我们会用到 L<Catalyst::Component::InstancePerContext>, 该模块是对 B<ACCEPT_CONTEXT> 的一个技巧应用。当你的模块需要在每个 request 里都应用一些代码时非常有用。

=item * Controller

Controller 的模块并不多,毕竟共享的 Controller 内容很窄。更多的我们将在下文中讲到。

最有名气的当属 L<Catalyst::Controller::WrapCGI> 该模块能让 cgi 脚本运行在 Catalyst 里,这将有助于你的计划安排,你可以在以后恰当的时间将该 cgi 改为 Catalyst

其他的有 L<Catalyst::Controller::REST>, L<Catalyst::Controller::reCAPTCHA>

=back

=head3 ActionClass

Action 类似于 L<Moose> 的 C<around>, 最常见的 ActionClass 是 L<Catalyst::Action::RenderView>

所有的 Action 都基于 L<Catalyst::Action> 并且需要 sub execute, 原始的 sub 调用通过 L<MRO::Compat>, 大致类似

  sub execute {
    my $self = shift;
    my ($controller, $c ) = @_;
    
    $self->next::method( @_ );

$self->next::method( @_ ); 可以放到 sub execute 的任何地方。这意味你可以在原始 sub 之前写代码也可以在其之后。

=head3 Controller 属性

如果你阅读过 L<Catalyst::Controller> 的源码的话,你会发现一些 _parse_*_attr 的 sub 类如 _parse_Global_attr, _parse_Path_attr, _parse_Regex_attr, _parse_Chained_attr 等

我们可以通过自定义属性和增加该属性对应的 _parse_*_attr 来扩展 Catalyst Controller.



( run in 0.693 second using v1.01-cache-2.11-cpan-b16cb0d3907 )