4 use base 'Catalyst::Component';
6 use Catalyst::Exception;
9 use Catalyst::Request::Upload;
10 use Catalyst::Response;
12 use Catalyst::Controller;
13 use Catalyst::Runtime;
14 use Devel::InnerPackage ();
16 use Module::Pluggable::Object;
18 use Text::SimpleTable;
20 use Path::Class::File;
21 use Time::HiRes qw/gettimeofday tv_interval/;
23 use Scalar::Util qw/weaken blessed/;
24 use Tree::Simple qw/use_weak_refs/;
25 use Tree::Simple::Visitor::FindByUID;
30 BEGIN { require 5.008001; }
32 __PACKAGE__->mk_accessors(
33 qw/counter request response state action stack namespace stats/
36 attributes->import( __PACKAGE__, \&namespace, 'lvalue' );
38 sub depth { scalar @{ shift->stack || [] }; }
45 # For backwards compatibility
46 *finalize_output = \&finalize_body;
51 our $RECURSION = 1000;
52 our $DETACH = "catalyst_detach\n";
54 __PACKAGE__->mk_classdata($_)
55 for qw/components arguments dispatcher engine log dispatcher_class
56 engine_class context_class request_class response_class setup_finished/;
58 __PACKAGE__->dispatcher_class('Catalyst::Dispatcher');
59 __PACKAGE__->engine_class('Catalyst::Engine::CGI');
60 __PACKAGE__->request_class('Catalyst::Request');
61 __PACKAGE__->response_class('Catalyst::Response');
63 our $VERSION = $Catalyst::Runtime::VERSION;
66 my ( $class, @arguments ) = @_;
68 # We have to limit $class to Catalyst to avoid pushing Catalyst upon every
70 return unless $class eq 'Catalyst';
72 my $caller = caller(0);
74 unless ( $caller->isa('Catalyst') ) {
76 push @{"$caller\::ISA"}, $class, 'Catalyst::Controller';
79 $caller->arguments( [@arguments] );
85 Catalyst - The Elegant MVC Web Application Framework
89 # use the helper to create a new application
92 # add models, views, controllers
93 script/myapp_create.pl model Database DBIC::SchemaLoader dbi:SQLite:/path/to/db
94 script/myapp_create.pl view TT TT
95 script/myapp_create.pl controller Search
97 # built in testserver -- use -r to restart automatically on changes
98 script/myapp_server.pl
100 # command line testing interface
101 script/myapp_test.pl /yada
104 use Catalyst qw/-Debug/; # include plugins here as well
106 ### In lib/MyApp/Controller/Root.pm (autocreated)
107 sub foo : Global { # called for /foo, /foo/1, /foo/1/2, etc.
108 my ( $self, $c, @args ) = @_; # args are qw/1 2/ for /foo/1/2
109 $c->stash->{template} = 'foo.tt'; # set the template
110 # lookup something from db -- stash vars are passed to TT
112 $c->model('Database::Foo')->search( { country => $args[0] } );
113 if ( $c->req->params->{bar} ) { # access GET or POST parameters
114 $c->forward( 'bar' ); # process another action
115 # do something else after forward returns
119 # The foo.tt TT template can use the stash data from the database
120 [% WHILE (item = data.next) %]
124 # called for /bar/of/soap, /bar/of/soap/10, etc.
125 sub bar : Path('/bar/of/soap') { ... }
127 # called for all actions, from the top-most controller downwards
129 my ( $self, $c ) = @_;
130 if ( !$c->user_exists ) { # Catalyst::Plugin::Authentication
131 $c->res->redirect( '/login' ); # require login
132 return 0; # abort request and go immediately to end()
134 return 1; # success; carry on to next action
137 # called after all actions are finished
139 my ( $self, $c ) = @_;
140 if ( scalar @{ $c->error } ) { ... } # handle errors
141 return if $c->res->body; # already have a response
142 $c->forward( 'MyApp::View::TT' ); # render template
145 ### in MyApp/Controller/Foo.pm
146 # called for /foo/bar
147 sub bar : Local { ... }
149 # called for /blargle
150 sub blargle : Global { ... }
152 # an index action matches /foo, but not /foo/1, etc.
153 sub index : Private { ... }
155 ### in MyApp/Controller/Foo/Bar.pm
156 # called for /foo/bar/baz
157 sub baz : Local { ... }
159 # first Root auto is called, then Foo auto, then this
160 sub auto : Private { ... }
162 # powerful regular expression paths are also possible
163 sub details : Regex('^product/(\w+)/details$') {
164 my ( $self, $c ) = @_;
165 # extract the (\w+) from the URI
166 my $product = $c->req->captures->[0];
169 See L<Catalyst::Manual::Intro> for additional information.
173 Catalyst is a modern framework for making web applications without the pain usually associated with this process. This document is a reference to the main Catalyst application. If you are a new user, we suggest you start with L<Catalyst::Manual::Tutorial> or L<Catalyst::Manual::Intro>
175 See L<Catalyst::Manual> for more documentation.
177 Catalyst plugins can be loaded by naming them as arguments to the "use
178 Catalyst" statement. Omit the C<Catalyst::Plugin::> prefix from the
179 plugin name, i.e., C<Catalyst::Plugin::My::Module> becomes
182 use Catalyst qw/My::Module/;
184 If your plugin starts with a name other than C<Catalyst::Plugin::>, you can
185 fully qualify the name by using a unary plus:
189 +Fully::Qualified::Plugin::Name
192 Special flags like C<-Debug> and C<-Engine> can also be specified as
193 arguments when Catalyst is loaded:
195 use Catalyst qw/-Debug My::Module/;
197 The position of plugins and flags in the chain is important, because
198 they are loaded in exactly the order in which they appear.
200 The following flags are supported:
204 Enables debug output. You can also force this setting from the system
205 environment with CATALYST_DEBUG or <MYAPP>_DEBUG. The environment settings
206 override the app, with <MYAPP>_DEBUG having highest priority.
210 Forces Catalyst to use a specific engine. Omit the
211 C<Catalyst::Engine::> prefix of the engine name, i.e.:
213 use Catalyst qw/-Engine=CGI/;
217 Forces Catalyst to use a specific home directory, e.g.:
219 use Catalyst qw[-Home=/usr/sri];
227 =head2 INFORMATION ABOUT THE CURRENT REQUEST
231 Returns a L<Catalyst::Action> object for the current action, which
232 stringifies to the action name. See L<Catalyst::Action>.
236 Returns the namespace of the current action, i.e., the uri prefix
237 corresponding to the controller of the current action. For example:
239 # in Controller::Foo::Bar
240 $c->namespace; # returns 'foo/bar';
246 Returns the current L<Catalyst::Request> object. See
247 L<Catalyst::Request>.
249 =head2 REQUEST FLOW HANDLING
251 =head2 $c->forward( $action [, \@arguments ] )
253 =head2 $c->forward( $class, $method, [, \@arguments ] )
255 Forwards processing to another action, by it's private name. If you give a
256 class name but no method, C<process()> is called. You may also optionally
257 pass arguments in an arrayref. The action will receive the arguments in
258 C<@_> and C<$c-E<gt>req-E<gt>args>. Upon returning from the function,
259 C<$c-E<gt>req-E<gt>args> will be restored to the previous values.
261 Any data C<return>ed from the action forwarded to, will be returned by the
264 my $foodata = $c->forward('/foo');
265 $c->forward('index');
266 $c->forward(qw/MyApp::Model::DBIC::Foo do_stuff/);
267 $c->forward('MyApp::View::TT');
269 Note that forward implies an C<<eval { }>> around the call (well, actually
270 C<execute> does), thus de-fatalizing all 'dies' within the called action. If
271 you want C<die> to propagate you need to do something like:
274 die $c->error if $c->error;
276 Or make sure to always return true values from your actions and write your code
279 $c->forward('foo') || return;
283 sub forward { my $c = shift; $c->dispatcher->forward( $c, @_ ) }
285 =head2 $c->detach( $action [, \@arguments ] )
287 =head2 $c->detach( $class, $method, [, \@arguments ] )
289 The same as C<forward>, but doesn't return to the previous action when
290 processing is finished.
294 sub detach { my $c = shift; $c->dispatcher->detach( $c, @_ ) }
300 Returns the current L<Catalyst::Response> object.
304 Returns a hashref to the stash, which may be used to store data and pass
305 it between components during a request. You can also set hash keys by
306 passing arguments. The stash is automatically sent to the view. The
307 stash is cleared at the end of a request; it cannot be used for
310 $c->stash->{foo} = $bar;
311 $c->stash( { moose => 'majestic', qux => 0 } );
312 $c->stash( bar => 1, gorch => 2 ); # equivalent to passing a hashref
314 # stash is automatically passed to the view for use in a template
315 $c->forward( 'MyApp::V::TT' );
322 my $stash = @_ > 1 ? {@_} : $_[0];
323 croak('stash takes a hash or hashref') unless ref $stash;
324 foreach my $key ( keys %$stash ) {
325 $c->{stash}->{$key} = $stash->{$key};
333 =head2 $c->error($error, ...)
335 =head2 $c->error($arrayref)
337 Returns an arrayref containing error messages. If Catalyst encounters an
338 error while processing a request, it stores the error in $c->error. This
339 method should not be used to store non-fatal error messages.
341 my @error = @{ $c->error };
345 $c->error('Something bad happened');
352 my $error = ref $_[0] eq 'ARRAY' ? $_[0] : [@_];
353 croak @$error unless ref $c;
354 push @{ $c->{error} }, @$error;
356 elsif ( defined $_[0] ) { $c->{error} = undef }
357 return $c->{error} || [];
363 Contains the return value of the last executed action.
365 =head2 $c->clear_errors
367 Clear errors. You probably don't want to clear the errors unless you are
368 implementing a custom error screen.
370 This is equivalent to running
386 my ( $c, @names ) = @_;
388 foreach my $name (@names) {
389 foreach my $component ( keys %{ $c->components } ) {
390 return $c->components->{$component} if $component =~ /$name/i;
397 # try explicit component names
399 my ( $c, @names ) = @_;
401 foreach my $try (@names) {
402 return $c->components->{$try} if ( exists $c->components->{$try} );
408 # like component, but try just these prefixes before regex searching,
409 # and do not try to return "sort keys %{ $c->components }"
411 my ( $c, $name, @prefixes ) = @_;
413 my $appclass = ref $c || $c;
415 my @names = map { "${appclass}::${_}::${name}" } @prefixes;
417 my $comp = $c->_comp_explicit(@names);
418 return $comp if defined($comp);
419 $comp = $c->_comp_search($name);
423 # Find possible names for a prefix
426 my ( $c, @prefixes ) = @_;
428 my $appclass = ref $c || $c;
430 my @pre = map { "${appclass}::${_}::" } @prefixes;
434 COMPONENT: foreach my $comp ($c->component) {
435 foreach my $p (@pre) {
436 if ($comp =~ s/^$p//) {
446 # Return a component if only one matches.
448 my ( $c, @prefixes ) = @_;
450 my $appclass = ref $c || $c;
452 my ( $comp, $rest ) =
453 map { $c->_comp_search("^${appclass}::${_}::") } @prefixes;
454 return $comp unless $rest;
457 # Filter a component before returning by calling ACCEPT_CONTEXT if available
458 sub _filter_component {
459 my ( $c, $comp, @args ) = @_;
460 if ( eval { $comp->can('ACCEPT_CONTEXT'); } ) {
461 return $comp->ACCEPT_CONTEXT( $c, @args );
463 else { return $comp }
466 =head2 COMPONENT ACCESSORS
468 =head2 $c->controller($name)
470 Gets a L<Catalyst::Controller> instance by name.
472 $c->controller('Foo')->do_stuff;
474 If name is omitted, will return the controller for the dispatched action.
479 my ( $c, $name, @args ) = @_;
480 return $c->_filter_component( $c->_comp_prefixes( $name, qw/Controller C/ ),
483 return $c->component( $c->action->class );
486 =head2 $c->model($name)
488 Gets a L<Catalyst::Model> instance by name.
490 $c->model('Foo')->do_stuff;
492 If the name is omitted, it will look for a config setting 'default_model',
493 or check if there is only one view, and return it if that's the case.
498 my ( $c, $name, @args ) = @_;
499 return $c->_filter_component( $c->_comp_prefixes( $name, qw/Model M/ ),
502 return $c->component( $c->config->{default_model} )
503 if $c->config->{default_model};
504 return $c->_filter_component( $c->_comp_singular(qw/Model M/), @args );
508 =head2 $c->controllers
510 Returns the available names which can be passed to $c->controller
516 return $c->_comp_names(qw/Controller C/);
520 =head2 $c->view($name)
522 Gets a L<Catalyst::View> instance by name.
524 $c->view('Foo')->do_stuff;
526 If the name is omitted, it will look for a config setting 'default_view',
527 or check if there is only one view, and forward to it if that's the case.
532 my ( $c, $name, @args ) = @_;
533 return $c->_filter_component( $c->_comp_prefixes( $name, qw/View V/ ),
536 return $c->component( $c->config->{default_view} )
537 if $c->config->{default_view};
538 return $c->_filter_component( $c->_comp_singular(qw/View V/) );
543 Returns the available names which can be passed to $c->model
549 return $c->_comp_names(qw/Model M/);
555 Returns the available names which can be passed to $c->view
561 return $c->_comp_names(qw/View V/);
564 =head2 $c->comp($name)
566 =head2 $c->component($name)
568 Gets a component object by name. This method is no longer recommended,
569 unless you want to get a specific component by full
570 class. C<$c-E<gt>controller>, C<$c-E<gt>model>, and C<$c-E<gt>view>
571 should be used instead.
582 my $appclass = ref $c || $c;
585 $name, "${appclass}::${name}",
586 map { "${appclass}::${_}::${name}" }
587 qw/Model M Controller C View V/
590 my $comp = $c->_comp_explicit(@names);
591 return $c->_filter_component( $comp, @_ ) if defined($comp);
593 $comp = $c->_comp_search($name);
594 return $c->_filter_component( $comp, @_ ) if defined($comp);
597 return sort keys %{ $c->components };
602 =head2 CLASS DATA AND HELPER CLASSES
606 Returns or takes a hashref containing the application's configuration.
608 __PACKAGE__->config( { db => 'dsn:SQLite:foo.db' } );
610 You can also use a L<YAML> config file like myapp.yml in your
611 applications home directory.
614 db: dsn:SQLite:foo.db
622 $c->log->warn("Setting config after setup has been run is not a good idea.")
623 if ( @_ and $c->setup_finished );
625 $c->NEXT::config(@_);
630 Returns the logging object instance. Unless it is already set, Catalyst sets
631 this up with a L<Catalyst::Log> object. To use your own log class, set the
632 logger with the C<< __PACKAGE__->log >> method prior to calling
633 C<< __PACKAGE__->setup >>.
635 __PACKAGE__->log( MyLogger->new );
640 $c->log->info( 'Now logging with my own logger!' );
642 Your log class should implement the methods described in the
643 L<Catalyst::Log> man page.
648 Overload to enable debug messages (same as -Debug option).
650 Note that this is a static method, not an accessor and should be overloaded
651 by declaring "sub debug { 1 }" in your MyApp.pm, not by calling $c->debug(1).
657 =head2 $c->dispatcher
659 Returns the dispatcher instance. Stringifies to class name. See
660 L<Catalyst::Dispatcher>.
664 Returns the engine instance. Stringifies to the class name. See
668 =head2 UTILITY METHODS
670 =head2 $c->path_to(@path)
672 Merges C<@path> with C<$c-E<gt>config-E<gt>{home}> and returns a
673 L<Path::Class> object.
677 $c->path_to( 'db', 'sqlite.db' );
682 my ( $c, @path ) = @_;
683 my $path = Path::Class::Dir->new( $c->config->{home}, @path );
684 if ( -d $path ) { return $path }
685 else { return Path::Class::File->new( $c->config->{home}, @path ) }
688 =head2 $c->plugin( $name, $class, @args )
690 Helper method for plugins. It creates a classdata accessor/mutator and
691 loads and instantiates the given class.
693 MyApp->plugin( 'prototype', 'HTML::Prototype' );
695 $c->prototype->define_javascript_functions;
700 my ( $class, $name, $plugin, @args ) = @_;
701 $class->_register_plugin( $plugin, 1 );
703 eval { $plugin->import };
704 $class->mk_classdata($name);
706 eval { $obj = $plugin->new(@args) };
709 Catalyst::Exception->throw( message =>
710 qq/Couldn't instantiate instant plugin "$plugin", "$@"/ );
714 $class->log->debug(qq/Initialized instant plugin "$plugin" as "$name"/)
720 Initializes the dispatcher and engine, loads any plugins, and loads the
721 model, view, and controller components. You may also specify an array
722 of plugins to load here, if you choose to not load them in the C<use
726 MyApp->setup( qw/-Debug/ );
731 my ( $class, @arguments ) = @_;
733 $class->log->warn("Running setup twice is not a good idea.")
734 if ( $class->setup_finished );
736 unless ( $class->isa('Catalyst') ) {
738 Catalyst::Exception->throw(
739 message => qq/'$class' does not inherit from Catalyst/ );
742 if ( $class->arguments ) {
743 @arguments = ( @arguments, @{ $class->arguments } );
749 foreach (@arguments) {
753 ( $flags->{log} ) ? 'debug,' . $flags->{log} : 'debug';
755 elsif (/^-(\w+)=?(.*)$/) {
756 $flags->{ lc $1 } = $2;
759 push @{ $flags->{plugins} }, $_;
763 $class->setup_home( delete $flags->{home} );
765 $class->setup_log( delete $flags->{log} );
766 $class->setup_plugins( delete $flags->{plugins} );
767 $class->setup_dispatcher( delete $flags->{dispatcher} );
768 $class->setup_engine( delete $flags->{engine} );
770 for my $flag ( sort keys %{$flags} ) {
772 if ( my $code = $class->can( 'setup_' . $flag ) ) {
773 &$code( $class, delete $flags->{$flag} );
776 $class->log->warn(qq/Unknown flag "$flag"/);
780 eval { require Catalyst::Devel; };
781 if( !$@ && $ENV{CATALYST_SCRIPT_GEN} && ( $ENV{CATALYST_SCRIPT_GEN} < $Catalyst::Devel::CATALYST_SCRIPT_GEN ) ) {
782 $class->log->warn(<<"EOF");
783 You are running an old script!
785 Please update by running (this will overwrite existing files):
786 catalyst.pl -force -scripts $class
788 or (this will not overwrite existing files):
789 catalyst.pl -scripts $class
793 if ( $class->debug ) {
800 map { $_ . ' ' . ( $_->VERSION || '' ) }
801 grep { /^Catalyst::Plugin/ } @{"$class\::ISA"};
805 my $t = Text::SimpleTable->new(74);
806 $t->row($_) for @plugins;
807 $class->log->debug( "Loaded plugins:\n" . $t->draw );
810 my $dispatcher = $class->dispatcher;
811 my $engine = $class->engine;
812 my $home = $class->config->{home};
814 $class->log->debug(qq/Loaded dispatcher "$dispatcher"/);
815 $class->log->debug(qq/Loaded engine "$engine"/);
819 ? $class->log->debug(qq/Found home "$home"/)
820 : $class->log->debug(qq/Home "$home" doesn't exist/)
821 : $class->log->debug(q/Couldn't find home/);
826 no warnings qw/redefine/;
827 local *setup = sub { };
831 # Initialize our data structure
832 $class->components( {} );
834 $class->setup_components;
836 if ( $class->debug ) {
837 my $t = Text::SimpleTable->new( [ 63, 'Class' ], [ 8, 'Type' ] );
838 for my $comp ( sort keys %{ $class->components } ) {
839 my $type = ref $class->components->{$comp} ? 'instance' : 'class';
840 $t->row( $comp, $type );
842 $class->log->debug( "Loaded components:\n" . $t->draw )
843 if ( keys %{ $class->components } );
846 # Add our self to components, since we are also a component
847 $class->components->{$class} = $class;
849 $class->setup_actions;
851 if ( $class->debug ) {
852 my $name = $class->config->{name} || 'Application';
853 $class->log->info("$name powered by Catalyst $Catalyst::VERSION");
855 $class->log->_flush() if $class->log->can('_flush');
857 $class->setup_finished(1);
860 =head2 $c->uri_for( $path, @args?, \%query_values? )
862 Merges path with C<$c-E<gt>request-E<gt>base> for absolute uri's and
863 with C<$c-E<gt>namespace> for relative uri's, then returns a
864 normalized L<URI> object. If any args are passed, they are added at the
865 end of the path. If the last argument to uri_for is a hash reference,
866 it is assumed to contain GET parameter key/value pairs, which will be
867 appended to the URI in standard fashion.
869 Instead of $path, you can also optionally pass a $action object which will
870 be resolved to a path using $c->dispatcher->uri_for_action; if the first
871 element of @args is an arrayref it is treated as a list of captures to be
872 passed to uri_for_action.
877 my ( $c, $path, @args ) = @_;
878 my $base = $c->request->base->clone;
879 my $basepath = $base->path;
880 $basepath =~ s/\/$//;
882 my $namespace = $c->namespace || '';
884 if ( Scalar::Util::blessed($path) ) { # action object
885 my $captures = ( scalar @args && ref $args[0] eq 'ARRAY'
888 $path = $c->dispatcher->uri_for_action($path, $captures);
889 return undef unless defined($path);
892 # massage namespace, empty if absolute path
893 $namespace =~ s/^\/// if $namespace;
894 $namespace .= '/' if $namespace;
896 $namespace = '' if $path =~ /^\//;
900 ( scalar @args && ref $args[$#args] eq 'HASH' ? pop @args : {} );
902 for my $value ( values %$params ) {
\r
903 my $isa_ref = ref $value;
\r
904 if( $isa_ref and $isa_ref ne 'ARRAY' ) {
\r
905 croak( "Non-array reference ($isa_ref) passed to uri_for()" );
\r
907 utf8::encode( $_ ) for grep { defined } $isa_ref ? @$value : $value;
\r
910 # join args with '/', or a blank string
911 my $args = ( scalar @args ? '/' . join( '/', @args ) : '' );
912 $args =~ s/^\/// unless $path;
914 URI->new_abs( URI->new_abs( "$path$args", "$basepath$namespace" ), $base )
916 $res->query_form(%$params);
920 =head2 $c->welcome_message
922 Returns the Catalyst welcome HTML page.
926 sub welcome_message {
928 my $name = $c->config->{name};
929 my $logo = $c->uri_for('/static/images/catalyst_logo.png');
930 my $prefix = Catalyst::Utils::appprefix( ref $c );
931 $c->response->content_type('text/html; charset=utf-8');
933 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
934 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
935 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
937 <meta http-equiv="Content-Language" content="en" />
938 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
939 <title>$name on Catalyst $VERSION</title>
940 <style type="text/css">
943 background-color: #eee;
952 background-color: #ccc;
953 border: 1px solid #aaa;
958 font-family: verdana, tahoma, sans-serif;
961 font-family: verdana, tahoma, sans-serif;
964 text-decoration: none;
966 border-bottom: 1px dotted #bbb;
968 :link:hover, :visited:hover {
981 background-color: #fff;
982 border: 1px solid #aaa;
1008 <h1><span id="appname">$name</span> on <a href="http://catalyst.perl.org">Catalyst</a>
1013 <img src="$logo" alt="Catalyst Logo" />
1015 <p>Welcome to the wonderful world of Catalyst.
1016 This <a href="http://en.wikipedia.org/wiki/MVC">MVC</a>
1017 framework will make web development something you had
1018 never expected it to be: Fun, rewarding, and quick.</p>
1019 <h2>What to do now?</h2>
1020 <p>That really depends on what <b>you</b> want to do.
1021 We do, however, provide you with a few starting points.</p>
1022 <p>If you want to jump right into web development with Catalyst
1023 you might want to check out the documentation.</p>
1024 <pre><code>perldoc <a href="http://cpansearch.perl.org/dist/Catalyst/lib/Catalyst/Manual/Intro.pod">Catalyst::Manual::Intro</a>
1025 perldoc <a href="http://cpansearch.perl.org/dist/Catalyst/lib/Catalyst/Manual/Tutorial.pod">Catalyst::Manual::Tutorial</a></code>
1026 perldoc <a href="http://cpansearch.perl.org/dist/Catalyst/lib/Catalyst/Manual.pod">Catalyst::Manual</a></code></pre>
1027 <h2>What to do next?</h2>
1028 <p>Next it's time to write an actual application. Use the
1029 helper scripts to generate <a href="http://cpansearch.perl.org/search?query=Catalyst%3A%3AController%3A%3A&mode=all">controllers</a>,
1030 <a href="http://cpansearch.perl.org/search?query=Catalyst%3A%3AModel%3A%3A&mode=all">models</a>, and
1031 <a href="http://cpansearch.perl.org/search?query=Catalyst%3A%3AView%3A%3A&mode=all">views</a>;
1032 they can save you a lot of work.</p>
1033 <pre><code>script/${prefix}_create.pl -help</code></pre>
1034 <p>Also, be sure to check out the vast and growing
1035 collection of <a href="http://cpansearch.perl.org/search?query=Catalyst%3A%3APlugin%3A%3A&mode=all">plugins for Catalyst on CPAN</a>;
1036 you are likely to find what you need there.
1040 <p>Catalyst has a very active community. Here are the main places to
1041 get in touch with us.</p>
1044 <a href="http://dev.catalyst.perl.org">Wiki</a>
1047 <a href="http://lists.rawmode.org/mailman/listinfo/catalyst">Mailing-List</a>
1050 <a href="irc://irc.perl.org/catalyst">IRC channel #catalyst on irc.perl.org</a>
1053 <h2>In conclusion</h2>
1054 <p>The Catalyst team hopes you will enjoy using Catalyst as much
1055 as we enjoyed making it. Please contact us if you have ideas
1056 for improvement or other feedback.</p>
1064 =head1 INTERNAL METHODS
1066 These methods are not meant to be used by end users.
1068 =head2 $c->components
1070 Returns a hash of components.
1072 =head2 $c->context_class
1074 Returns or sets the context class.
1078 Returns a hashref containing coderefs and execution counts (needed for
1079 deep recursion detection).
1083 Returns the number of actions on the current internal execution stack.
1087 Dispatches a request to actions.
1091 sub dispatch { my $c = shift; $c->dispatcher->dispatch( $c, @_ ) }
1093 =head2 $c->dispatcher_class
1095 Returns or sets the dispatcher class.
1097 =head2 $c->dump_these
1099 Returns a list of 2-element array references (name, structure) pairs
1100 that will be dumped on the error page in debug mode.
1106 [ Request => $c->req ],
1107 [ Response => $c->res ],
1108 [ Stash => $c->stash ],
1109 [ Config => $c->config ];
1112 =head2 $c->engine_class
1114 Returns or sets the engine class.
1116 =head2 $c->execute( $class, $coderef )
1118 Execute a coderef in given class and catch exceptions. Errors are available
1124 my ( $c, $class, $code ) = @_;
1125 $class = $c->component($class) || $class;
1128 if ( $c->depth >= $RECURSION ) {
1129 my $action = "$code";
1130 $action = "/$action" unless $action =~ /\-\>/;
1131 my $error = qq/Deep recursion detected calling "$action"/;
1132 $c->log->error($error);
1138 my $stats_info = $c->_stats_start_execute( $code );
1140 push( @{ $c->stack }, $code );
1142 eval { $c->state( &$code( $class, $c, @{ $c->req->args } ) || 0 ) };
1144 $c->_stats_finish_execute( $stats_info );
1146 my $last = ${ $c->stack }[-1];
1147 pop( @{ $c->stack } );
1149 if ( my $error = $@ ) {
1150 if ( $error eq $DETACH ) { die $DETACH if $c->depth > 1 }
1152 unless ( ref $error ) {
1154 my $class = $last->class;
1155 my $name = $last->name;
1156 $error = qq/Caught exception in $class->$name "$error"/;
1165 sub _stats_start_execute {
1166 my ( $c, $code ) = @_;
1168 return unless $c->debug;
1170 my $action = "$code";
1172 $action = "/$action" unless $action =~ /\-\>/;
1173 $c->counter->{"$code"}++;
1175 # determine if the call was the result of a forward
1176 # this is done by walking up the call stack and looking for a calling
1177 # sub of Catalyst::forward before the eval
1179 for my $index ( 2 .. 11 ) {
1181 if ( ( caller($index) )[0] eq 'Catalyst'
1182 && ( caller($index) )[3] eq '(eval)' );
1184 if ( ( caller($index) )[3] =~ /forward$/ ) {
1185 $callsub = ( caller($index) )[3];
1186 $action = "-> $action";
1191 my $node = Tree::Simple->new(
1194 elapsed => undef, # to be filled in later
1198 $node->setUID( "$code" . $c->counter->{"$code"} );
1200 unless ( ( $code->name =~ /^_.*/ )
1201 && ( !$c->config->{show_internal_actions} ) )
1203 # is this a root-level call or a forwarded call?
1204 if ( $callsub =~ /forward$/ ) {
1206 # forward, locate the caller
1207 if ( my $parent = $c->stack->[-1] ) {
1208 my $visitor = Tree::Simple::Visitor::FindByUID->new;
1209 $visitor->searchForUID(
1210 "$parent" . $c->counter->{"$parent"} );
1211 $c->stats->accept($visitor);
1212 if ( my $result = $visitor->getResult ) {
1213 $result->addChild($node);
1218 # forward with no caller may come from a plugin
1219 $c->stats->addChild($node);
1225 $c->stats->addChild($node);
1229 my $start = [gettimeofday];
1230 my $elapsed = tv_interval($start);
1234 elapsed => $elapsed,
1240 sub _stats_finish_execute {
1241 my ( $c, $info ) = @_;
1243 return unless $c->debug;
1245 my ( $code, $start, $elapsed ) = @{ $info }{qw/code start elapsed/};
1247 unless ( ( $code->name =~ /^_.*/ )
1248 && ( !$c->config->{show_internal_actions} ) )
1251 # FindByUID uses an internal die, so we save the existing error
1254 # locate the node in the tree and update the elapsed time
1255 my $visitor = Tree::Simple::Visitor::FindByUID->new;
1256 $visitor->searchForUID( "$code" . $c->counter->{"$code"} );
1257 $c->stats->accept($visitor);
1258 if ( my $result = $visitor->getResult ) {
1259 my $value = $result->getNodeValue;
1260 $value->{elapsed} = sprintf( '%fs', $elapsed );
1261 $result->setNodeValue($value);
1265 $@ = $error || undef;
1269 =head2 $c->_localize_fields( sub { }, \%keys );
1273 sub _localize_fields {
1274 my ( $c, $localized, $code ) = ( @_ );
1276 my $request = delete $localized->{request} || {};
1277 my $response = delete $localized->{response} || {};
1279 local @{ $c }{ keys %$localized } = values %$localized;
1280 local @{ $c->request }{ keys %$request } = values %$request;
1281 local @{ $c->response }{ keys %$response } = values %$response;
1288 Finalizes the request.
1295 for my $error ( @{ $c->error } ) {
1296 $c->log->error($error);
1299 # Allow engine to handle finalize flow (for POE)
1300 if ( $c->engine->can('finalize') ) {
1301 $c->engine->finalize($c);
1305 $c->finalize_uploads;
1308 if ( $#{ $c->error } >= 0 ) {
1312 $c->finalize_headers;
1315 if ( $c->request->method eq 'HEAD' ) {
1316 $c->response->body('');
1322 return $c->response->status;
1325 =head2 $c->finalize_body
1331 sub finalize_body { my $c = shift; $c->engine->finalize_body( $c, @_ ) }
1333 =head2 $c->finalize_cookies
1339 sub finalize_cookies { my $c = shift; $c->engine->finalize_cookies( $c, @_ ) }
1341 =head2 $c->finalize_error
1347 sub finalize_error { my $c = shift; $c->engine->finalize_error( $c, @_ ) }
1349 =head2 $c->finalize_headers
1355 sub finalize_headers {
1358 # Check if we already finalized headers
1359 return if $c->response->{_finalized_headers};
1362 if ( my $location = $c->response->redirect ) {
1363 $c->log->debug(qq/Redirecting to "$location"/) if $c->debug;
1364 $c->response->header( Location => $location );
1368 if ( $c->response->body && !$c->response->content_length ) {
1370 # get the length from a filehandle
1371 if ( blessed( $c->response->body ) && $c->response->body->can('read') )
1373 if ( my $stat = stat $c->response->body ) {
1374 $c->response->content_length( $stat->size );
1377 $c->log->warn('Serving filehandle without a content-length');
1381 $c->response->content_length( bytes::length( $c->response->body ) );
1386 if ( $c->response->status =~ /^(1\d\d|[23]04)$/ ) {
1387 $c->response->headers->remove_header("Content-Length");
1388 $c->response->body('');
1391 $c->finalize_cookies;
1393 $c->engine->finalize_headers( $c, @_ );
1396 $c->response->{_finalized_headers} = 1;
1399 =head2 $c->finalize_output
1401 An alias for finalize_body.
1403 =head2 $c->finalize_read
1405 Finalizes the input after reading is complete.
1409 sub finalize_read { my $c = shift; $c->engine->finalize_read( $c, @_ ) }
1411 =head2 $c->finalize_uploads
1413 Finalizes uploads. Cleans up any temporary files.
1417 sub finalize_uploads { my $c = shift; $c->engine->finalize_uploads( $c, @_ ) }
1419 =head2 $c->get_action( $action, $namespace )
1421 Gets an action in a given namespace.
1425 sub get_action { my $c = shift; $c->dispatcher->get_action(@_) }
1427 =head2 $c->get_actions( $action, $namespace )
1429 Gets all actions of a given name in a namespace and all parent
1434 sub get_actions { my $c = shift; $c->dispatcher->get_actions( $c, @_ ) }
1436 =head2 $c->handle_request( $class, @arguments )
1438 Called to handle each HTTP request.
1442 sub handle_request {
1443 my ( $class, @arguments ) = @_;
1445 # Always expect worst case!
1448 my $stats = ( $class->debug ) ? Tree::Simple->new: q{};
1451 my $c = $class->prepare(@arguments);
1454 return $c->finalize;
1457 if ( $class->debug ) {
1458 my $start = [gettimeofday];
1459 $status = &$handler;
1460 my $elapsed = tv_interval $start;
1461 $elapsed = sprintf '%f', $elapsed;
1462 my $av = sprintf '%.3f',
1463 ( $elapsed == 0 ? '??' : ( 1 / $elapsed ) );
1464 my $t = Text::SimpleTable->new( [ 62, 'Action' ], [ 9, 'Time' ] );
1469 my $stat = $action->getNodeValue;
1470 $t->row( ( q{ } x $action->getDepth ) . $stat->{action} . $stat->{comment},
1471 $stat->{elapsed} || '??' );
1476 "Request took ${elapsed}s ($av/s)\n" . $t->draw );
1478 else { $status = &$handler }
1482 if ( my $error = $@ ) {
1484 $class->log->error(qq/Caught exception in engine "$error"/);
1488 $class->log->_flush() if $class->log->can('_flush');
1492 =head2 $c->prepare( @arguments )
1494 Creates a Catalyst context from an engine-specific request (Apache, CGI,
1500 my ( $class, @arguments ) = @_;
1502 $class->context_class( ref $class || $class ) unless $class->context_class;
1503 my $c = $class->context_class->new(
1507 request => $class->request_class->new(
1510 body_parameters => {},
1512 headers => HTTP::Headers->new,
1514 query_parameters => {},
1520 response => $class->response_class->new(
1524 headers => HTTP::Headers->new(),
1533 # For on-demand data
1534 $c->request->{_context} = $c;
1535 $c->response->{_context} = $c;
1536 weaken( $c->request->{_context} );
1537 weaken( $c->response->{_context} );
1540 my $secs = time - $START || 1;
1541 my $av = sprintf '%.3f', $COUNT / $secs;
1542 my $time = localtime time;
1543 $c->log->info("*** Request $COUNT ($av/s) [$$] [$time] ***");
1544 $c->res->headers->header( 'X-Catalyst' => $Catalyst::VERSION );
1547 # Allow engine to direct the prepare flow (for POE)
1548 if ( $c->engine->can('prepare') ) {
1549 $c->engine->prepare( $c, @arguments );
1552 $c->prepare_request(@arguments);
1553 $c->prepare_connection;
1554 $c->prepare_query_parameters;
1555 $c->prepare_headers;
1556 $c->prepare_cookies;
1560 $c->prepare_body unless $c->config->{parse_on_demand};
1563 my $method = $c->req->method || '';
1564 my $path = $c->req->path || '/';
1565 my $address = $c->req->address || '';
1567 $c->log->debug(qq/"$method" request for "$path" from "$address"/)
1575 =head2 $c->prepare_action
1577 Prepares action. See L<Catalyst::Dispatcher>.
1581 sub prepare_action { my $c = shift; $c->dispatcher->prepare_action( $c, @_ ) }
1583 =head2 $c->prepare_body
1585 Prepares message body.
1592 # Do we run for the first time?
1593 return if defined $c->request->{_body};
1595 # Initialize on-demand data
1596 $c->engine->prepare_body( $c, @_ );
1597 $c->prepare_parameters;
1598 $c->prepare_uploads;
1600 if ( $c->debug && keys %{ $c->req->body_parameters } ) {
1601 my $t = Text::SimpleTable->new( [ 35, 'Parameter' ], [ 36, 'Value' ] );
1602 for my $key ( sort keys %{ $c->req->body_parameters } ) {
1603 my $param = $c->req->body_parameters->{$key};
1604 my $value = defined($param) ? $param : '';
1606 ref $value eq 'ARRAY' ? ( join ', ', @$value ) : $value );
1608 $c->log->debug( "Body Parameters are:\n" . $t->draw );
1612 =head2 $c->prepare_body_chunk( $chunk )
1614 Prepares a chunk of data before sending it to L<HTTP::Body>.
1616 See L<Catalyst::Engine>.
1620 sub prepare_body_chunk {
1622 $c->engine->prepare_body_chunk( $c, @_ );
1625 =head2 $c->prepare_body_parameters
1627 Prepares body parameters.
1631 sub prepare_body_parameters {
1633 $c->engine->prepare_body_parameters( $c, @_ );
1636 =head2 $c->prepare_connection
1638 Prepares connection.
1642 sub prepare_connection {
1644 $c->engine->prepare_connection( $c, @_ );
1647 =head2 $c->prepare_cookies
1653 sub prepare_cookies { my $c = shift; $c->engine->prepare_cookies( $c, @_ ) }
1655 =head2 $c->prepare_headers
1661 sub prepare_headers { my $c = shift; $c->engine->prepare_headers( $c, @_ ) }
1663 =head2 $c->prepare_parameters
1665 Prepares parameters.
1669 sub prepare_parameters {
1671 $c->prepare_body_parameters;
1672 $c->engine->prepare_parameters( $c, @_ );
1675 =head2 $c->prepare_path
1677 Prepares path and base.
1681 sub prepare_path { my $c = shift; $c->engine->prepare_path( $c, @_ ) }
1683 =head2 $c->prepare_query_parameters
1685 Prepares query parameters.
1689 sub prepare_query_parameters {
1692 $c->engine->prepare_query_parameters( $c, @_ );
1694 if ( $c->debug && keys %{ $c->request->query_parameters } ) {
1695 my $t = Text::SimpleTable->new( [ 35, 'Parameter' ], [ 36, 'Value' ] );
1696 for my $key ( sort keys %{ $c->req->query_parameters } ) {
1697 my $param = $c->req->query_parameters->{$key};
1698 my $value = defined($param) ? $param : '';
1700 ref $value eq 'ARRAY' ? ( join ', ', @$value ) : $value );
1702 $c->log->debug( "Query Parameters are:\n" . $t->draw );
1706 =head2 $c->prepare_read
1708 Prepares the input for reading.
1712 sub prepare_read { my $c = shift; $c->engine->prepare_read( $c, @_ ) }
1714 =head2 $c->prepare_request
1716 Prepares the engine request.
1720 sub prepare_request { my $c = shift; $c->engine->prepare_request( $c, @_ ) }
1722 =head2 $c->prepare_uploads
1728 sub prepare_uploads {
1731 $c->engine->prepare_uploads( $c, @_ );
1733 if ( $c->debug && keys %{ $c->request->uploads } ) {
1734 my $t = Text::SimpleTable->new(
1735 [ 12, 'Parameter' ],
1740 for my $key ( sort keys %{ $c->request->uploads } ) {
1741 my $upload = $c->request->uploads->{$key};
1742 for my $u ( ref $upload eq 'ARRAY' ? @{$upload} : ($upload) ) {
1743 $t->row( $key, $u->filename, $u->type, $u->size );
1746 $c->log->debug( "File Uploads are:\n" . $t->draw );
1750 =head2 $c->prepare_write
1752 Prepares the output for writing.
1756 sub prepare_write { my $c = shift; $c->engine->prepare_write( $c, @_ ) }
1758 =head2 $c->request_class
1760 Returns or sets the request class.
1762 =head2 $c->response_class
1764 Returns or sets the response class.
1766 =head2 $c->read( [$maxlength] )
1768 Reads a chunk of data from the request body. This method is designed to
1769 be used in a while loop, reading C<$maxlength> bytes on every call.
1770 C<$maxlength> defaults to the size of the request if not specified.
1772 You have to set C<MyApp-E<gt>config-E<gt>{parse_on_demand}> to use this
1777 sub read { my $c = shift; return $c->engine->read( $c, @_ ) }
1785 sub run { my $c = shift; return $c->engine->run( $c, @_ ) }
1787 =head2 $c->set_action( $action, $code, $namespace, $attrs )
1789 Sets an action in a given namespace.
1793 sub set_action { my $c = shift; $c->dispatcher->set_action( $c, @_ ) }
1795 =head2 $c->setup_actions($component)
1797 Sets up actions for a component.
1801 sub setup_actions { my $c = shift; $c->dispatcher->setup_actions( $c, @_ ) }
1803 =head2 $c->setup_components
1805 Sets up components. Specify a C<setup_components> config option to pass additional options
1806 directly to L<Module::Pluggable>. To add additional search paths, specify a key named
1807 C<search_extra> as an array reference. Items in the array beginning with C<::> will have the
1808 application class name prepended to them.
1812 sub setup_components {
1815 my @paths = qw( ::Controller ::C ::Model ::M ::View ::V );
1816 my $config = $class->config->{ setup_components };
1817 my $extra = delete $config->{ search_extra } || [];
1819 push @paths, @$extra;
1821 my $locator = Module::Pluggable::Object->new(
1822 search_path => [ map { s/^(?=::)/$class/; $_; } @paths ],
1826 for my $component ( sort { length $a <=> length $b } $locator->plugins ) {
1827 Catalyst::Utils::ensure_class_loaded( $component );
1829 my $module = $class->setup_component( $component );
1831 $component => $module,
1833 $_ => $class->setup_component( $_ )
1834 } Devel::InnerPackage::list_packages( $component )
1837 for my $key ( keys %modules ) {
1838 $class->components->{ $key } = $modules{ $key };
1843 =head2 $c->setup_component
1847 sub setup_component {
1848 my( $class, $component ) = @_;
1850 unless ( $component->can( 'COMPONENT' ) ) {
1854 my $suffix = Catalyst::Utils::class2classsuffix( $component );
1855 my $config = $class->config->{ $suffix } || {};
1857 my $instance = eval { $component->COMPONENT( $class, $config ); };
1859 if ( my $error = $@ ) {
1861 Catalyst::Exception->throw(
1862 message => qq/Couldn't instantiate component "$component", "$error"/
1866 Catalyst::Exception->throw(
1868 qq/Couldn't instantiate component "$component", "COMPONENT() didn't return an object-like value"/
1869 ) unless eval { $instance->can( 'can' ) };
1874 =head2 $c->setup_dispatcher
1880 sub setup_dispatcher {
1881 my ( $class, $dispatcher ) = @_;
1884 $dispatcher = 'Catalyst::Dispatcher::' . $dispatcher;
1887 if ( $ENV{CATALYST_DISPATCHER} ) {
1888 $dispatcher = 'Catalyst::Dispatcher::' . $ENV{CATALYST_DISPATCHER};
1891 if ( $ENV{ uc($class) . '_DISPATCHER' } ) {
1893 'Catalyst::Dispatcher::' . $ENV{ uc($class) . '_DISPATCHER' };
1896 unless ($dispatcher) {
1897 $dispatcher = $class->dispatcher_class;
1900 unless (Class::Inspector->loaded($dispatcher)) {
1901 require Class::Inspector->filename($dispatcher);
1904 # dispatcher instance
1905 $class->dispatcher( $dispatcher->new );
1908 =head2 $c->setup_engine
1915 my ( $class, $engine ) = @_;
1918 $engine = 'Catalyst::Engine::' . $engine;
1921 if ( $ENV{CATALYST_ENGINE} ) {
1922 $engine = 'Catalyst::Engine::' . $ENV{CATALYST_ENGINE};
1925 if ( $ENV{ uc($class) . '_ENGINE' } ) {
1926 $engine = 'Catalyst::Engine::' . $ENV{ uc($class) . '_ENGINE' };
1929 if ( $ENV{MOD_PERL} ) {
1931 # create the apache method
1934 *{"$class\::apache"} = sub { shift->engine->apache };
1937 my ( $software, $version ) =
1938 $ENV{MOD_PERL} =~ /^(\S+)\/(\d+(?:[\.\_]\d+)+)/;
1941 $version =~ s/(\.[^.]+)\./$1/g;
1943 if ( $software eq 'mod_perl' ) {
1947 if ( $version >= 1.99922 ) {
1948 $engine = 'Catalyst::Engine::Apache2::MP20';
1951 elsif ( $version >= 1.9901 ) {
1952 $engine = 'Catalyst::Engine::Apache2::MP19';
1955 elsif ( $version >= 1.24 ) {
1956 $engine = 'Catalyst::Engine::Apache::MP13';
1960 Catalyst::Exception->throw( message =>
1961 qq/Unsupported mod_perl version: $ENV{MOD_PERL}/ );
1966 # install the correct mod_perl handler
1967 if ( $version >= 1.9901 ) {
1968 *handler = sub : method {
1969 shift->handle_request(@_);
1973 *handler = sub ($$) { shift->handle_request(@_) };
1978 elsif ( $software eq 'Zeus-Perl' ) {
1979 $engine = 'Catalyst::Engine::Zeus';
1983 Catalyst::Exception->throw(
1984 message => qq/Unsupported mod_perl: $ENV{MOD_PERL}/ );
1989 $engine = $class->engine_class;
1992 unless (Class::Inspector->loaded($engine)) {
1993 require Class::Inspector->filename($engine);
1996 # check for old engines that are no longer compatible
1998 if ( $engine->isa('Catalyst::Engine::Apache')
1999 && !Catalyst::Engine::Apache->VERSION )
2004 elsif ( $engine->isa('Catalyst::Engine::Server::Base')
2005 && Catalyst::Engine::Server->VERSION le '0.02' )
2010 elsif ($engine->isa('Catalyst::Engine::HTTP::POE')
2011 && $engine->VERSION eq '0.01' )
2016 elsif ($engine->isa('Catalyst::Engine::Zeus')
2017 && $engine->VERSION eq '0.01' )
2023 Catalyst::Exception->throw( message =>
2024 qq/Engine "$engine" is not supported by this version of Catalyst/
2029 $class->engine( $engine->new );
2032 =head2 $c->setup_home
2034 Sets up the home directory.
2039 my ( $class, $home ) = @_;
2041 if ( $ENV{CATALYST_HOME} ) {
2042 $home = $ENV{CATALYST_HOME};
2045 if ( $ENV{ uc($class) . '_HOME' } ) {
2046 $home = $ENV{ uc($class) . '_HOME' };
2050 $home = Catalyst::Utils::home($class);
2054 $class->config->{home} ||= $home;
2055 $class->config->{root} ||= Path::Class::Dir->new($home)->subdir('root');
2059 =head2 $c->setup_log
2066 my ( $class, $debug ) = @_;
2068 unless ( $class->log ) {
2069 $class->log( Catalyst::Log->new );
2072 my $app_flag = Catalyst::Utils::class2env($class) . '_DEBUG';
2075 ( defined( $ENV{CATALYST_DEBUG} ) || defined( $ENV{$app_flag} ) )
2076 ? ( $ENV{CATALYST_DEBUG} || $ENV{$app_flag} )
2081 *{"$class\::debug"} = sub { 1 };
2082 $class->log->debug('Debug messages enabled');
2086 =head2 $c->setup_plugins
2092 =head2 $c->registered_plugins
2094 Returns a sorted list of the plugins which have either been stated in the
2095 import list or which have been added via C<< MyApp->plugin(@args); >>.
2097 If passed a given plugin name, it will report a boolean value indicating
2098 whether or not that plugin is loaded. A fully qualified name is required if
2099 the plugin name does not begin with C<Catalyst::Plugin::>.
2101 if ($c->registered_plugins('Some::Plugin')) {
2109 sub registered_plugins {
2111 return sort keys %{ $proto->_plugins } unless @_;
2113 return 1 if exists $proto->_plugins->{$plugin};
2114 return exists $proto->_plugins->{"Catalyst::Plugin::$plugin"};
2117 sub _register_plugin {
2118 my ( $proto, $plugin, $instant ) = @_;
2119 my $class = ref $proto || $proto;
2121 unless (Class::Inspector->loaded($plugin)) {
2122 require Class::Inspector->filename($plugin);
2125 $proto->_plugins->{$plugin} = 1;
2128 unshift @{"$class\::ISA"}, $plugin;
2134 my ( $class, $plugins ) = @_;
2136 $class->_plugins( {} ) unless $class->_plugins;
2138 for my $plugin ( reverse @$plugins ) {
2140 unless ( $plugin =~ s/\A\+// ) {
2141 $plugin = "Catalyst::Plugin::$plugin";
2144 $class->_register_plugin($plugin);
2151 Returns an arrayref of the internal execution stack (actions that are currently
2154 =head2 $c->write( $data )
2156 Writes $data to the output stream. When using this method directly, you
2157 will need to manually set the C<Content-Length> header to the length of
2158 your output data, if known.
2165 # Finalize headers if someone manually writes output
2166 $c->finalize_headers;
2168 return $c->engine->write( $c, @_ );
2173 Returns the Catalyst version number. Mostly useful for "powered by"
2174 messages in template systems.
2178 sub version { return $Catalyst::VERSION }
2180 =head1 INTERNAL ACTIONS
2182 Catalyst uses internal actions like C<_DISPATCH>, C<_BEGIN>, C<_AUTO>,
2183 C<_ACTION>, and C<_END>. These are by default not shown in the private
2184 action table, but you can make them visible with a config parameter.
2186 MyApp->config->{show_internal_actions} = 1;
2188 =head1 CASE SENSITIVITY
2190 By default Catalyst is not case sensitive, so C<MyApp::C::FOO::Bar> is
2191 mapped to C</foo/bar>. You can activate case sensitivity with a config
2194 MyApp->config->{case_sensitive} = 1;
2196 This causes C<MyApp::C::Foo::Bar> to map to C</Foo/Bar>.
2198 =head1 ON-DEMAND PARSER
2200 The request body is usually parsed at the beginning of a request,
2201 but if you want to handle input yourself or speed things up a bit,
2202 you can enable on-demand parsing with a config parameter.
2204 MyApp->config->{parse_on_demand} = 1;
2206 =head1 PROXY SUPPORT
2208 Many production servers operate using the common double-server approach,
2209 with a lightweight frontend web server passing requests to a larger
2210 backend server. An application running on the backend server must deal
2211 with two problems: the remote user always appears to be C<127.0.0.1> and
2212 the server's hostname will appear to be C<localhost> regardless of the
2213 virtual host that the user connected through.
2215 Catalyst will automatically detect this situation when you are running
2216 the frontend and backend servers on the same machine. The following
2217 changes are made to the request.
2219 $c->req->address is set to the user's real IP address, as read from
2220 the HTTP X-Forwarded-For header.
2222 The host value for $c->req->base and $c->req->uri is set to the real
2223 host, as read from the HTTP X-Forwarded-Host header.
2225 Obviously, your web server must support these headers for this to work.
2227 In a more complex server farm environment where you may have your
2228 frontend proxy server(s) on different machines, you will need to set a
2229 configuration option to tell Catalyst to read the proxied data from the
2232 MyApp->config->{using_frontend_proxy} = 1;
2234 If you do not wish to use the proxy support at all, you may set:
2236 MyApp->config->{ignore_frontend_proxy} = 1;
2238 =head1 THREAD SAFETY
2240 Catalyst has been tested under Apache 2's threading mpm_worker, mpm_winnt,
2241 and the standalone forking HTTP server on Windows. We believe the Catalyst
2242 core to be thread-safe.
2244 If you plan to operate in a threaded environment, remember that all other
2245 modules you are using must also be thread-safe. Some modules, most notably
2246 L<DBD::SQLite>, are not thread-safe.
2252 Join #catalyst on irc.perl.org.
2256 http://lists.rawmode.org/mailman/listinfo/catalyst
2257 http://lists.rawmode.org/mailman/listinfo/catalyst-dev
2261 http://catalyst.perl.org
2265 http://dev.catalyst.perl.org
2269 =head2 L<Task::Catalyst> - All you need to start with Catalyst
2271 =head2 L<Catalyst::Manual> - The Catalyst Manual
2273 =head2 L<Catalyst::Component>, L<Catalyst::Base> - Base classes for components
2275 =head2 L<Catalyst::Engine> - Core engine
2277 =head2 L<Catalyst::Log> - Log class.
2279 =head2 L<Catalyst::Request> - Request object
2281 =head2 L<Catalyst::Response> - Response object
2283 =head2 L<Catalyst::Test> - The test suite.
2355 Sebastian Riedel, C<sri@oook.de>
2359 This library is free software, you can redistribute it and/or modify it under
2360 the same terms as Perl itself.