4 use base 'Catalyst::Component';
6 use Catalyst::Exception;
9 use Catalyst::Request::Upload;
10 use Catalyst::Response;
12 use Catalyst::Controller;
15 use Text::SimpleTable;
17 use Path::Class::File;
18 use Time::HiRes qw/gettimeofday tv_interval/;
20 use Scalar::Util qw/weaken blessed/;
21 use Tree::Simple qw/use_weak_refs/;
22 use Tree::Simple::Visitor::FindByUID;
27 BEGIN { require 5.008001; }
29 __PACKAGE__->mk_accessors(
30 qw/counter request response state action stack namespace stats/
33 attributes->import( __PACKAGE__, \&namespace, 'lvalue' );
35 sub depth { scalar @{ shift->stack || [] }; }
42 # For backwards compatibility
43 *finalize_output = \&finalize_body;
48 our $RECURSION = 1000;
49 our $DETACH = "catalyst_detach\n";
51 require Module::Pluggable::Fast;
53 # Helper script generation
54 our $CATALYST_SCRIPT_GEN = 27;
56 __PACKAGE__->mk_classdata($_)
57 for qw/components arguments dispatcher engine log dispatcher_class
58 engine_class context_class request_class response_class setup_finished/;
60 __PACKAGE__->dispatcher_class('Catalyst::Dispatcher');
61 __PACKAGE__->engine_class('Catalyst::Engine::CGI');
62 __PACKAGE__->request_class('Catalyst::Request');
63 __PACKAGE__->response_class('Catalyst::Response');
65 our $VERSION = '5.6902';
68 my ( $class, @arguments ) = @_;
70 # We have to limit $class to Catalyst to avoid pushing Catalyst upon every
72 return unless $class eq 'Catalyst';
74 my $caller = caller(0);
76 unless ( $caller->isa('Catalyst') ) {
78 push @{"$caller\::ISA"}, $class, 'Catalyst::Controller';
81 $caller->arguments( [@arguments] );
87 Catalyst - The Elegant MVC Web Application Framework
91 # use the helper to create a new application
94 # add models, views, controllers
95 script/myapp_create.pl model Database DBIC::SchemaLoader dbi:SQLite:/path/to/db
96 script/myapp_create.pl view TT TT
97 script/myapp_create.pl controller Search
99 # built in testserver -- use -r to restart automatically on changes
100 script/myapp_server.pl
102 # command line testing interface
103 script/myapp_test.pl /yada
106 use Catalyst qw/-Debug/; # include plugins here as well
108 ### In libMyApp/Controller/Root.pm (autocreated)
109 sub foo : Global { # called for /foo, /foo/1, /foo/1/2, etc.
110 my ( $self, $c, @args ) = @_; # args are qw/1 2/ for /foo/1/2
111 $c->stash->{template} = 'foo.tt'; # set the template
112 # lookup something from db -- stash vars are passed to TT
114 $c->model('Database::Foo')->search( { country => $args[0] } );
115 if ( $c->req->params->{bar} ) { # access GET or POST parameters
116 $c->forward( 'bar' ); # process another action
117 # do something else after forward returns
121 # The foo.tt TT template can use the stash data from the database
122 [% WHILE (item = data.next) %]
126 # called for /bar/of/soap, /bar/of/soap/10, etc.
127 sub bar : Path('/bar/of/soap') { ... }
129 # called for all actions, from the top-most controller downwards
131 my ( $self, $c ) = @_;
132 if ( !$c->user_exists ) { # Catalyst::Plugin::Authentication
133 $c->res->redirect( '/login' ); # require login
134 return 0; # abort request and go immediately to end()
136 return 1; # success; carry on to next action
139 # called after all actions are finished
141 my ( $self, $c ) = @_;
142 if ( scalar @{ $c->error } ) { ... } # handle errors
143 return if $c->res->body; # already have a response
144 $c->forward( 'MyApp::View::TT' ); # render template
147 ### in MyApp/Controller/Foo.pm
148 # called for /foo/bar
149 sub bar : Local { ... }
151 # called for /blargle
152 sub blargle : Global { ... }
154 # an index action matches /foo, but not /foo/1, etc.
155 sub index : Private { ... }
157 ### in MyApp/Controller/Foo/Bar.pm
158 # called for /foo/bar/baz
159 sub baz : Local { ... }
161 # first Root auto is called, then Foo auto, then this
162 sub auto : Private { ... }
164 # powerful regular expression paths are also possible
165 sub details : Regex('^product/(\w+)/details$') {
166 my ( $self, $c ) = @_;
167 # extract the (\w+) from the URI
168 my $product = $c->req->captures->[0];
171 See L<Catalyst::Manual::Intro> for additional information.
175 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>
177 See L<Catalyst::Manual> for more documentation.
179 Catalyst plugins can be loaded by naming them as arguments to the "use
180 Catalyst" statement. Omit the C<Catalyst::Plugin::> prefix from the
181 plugin name, i.e., C<Catalyst::Plugin::My::Module> becomes
184 use Catalyst qw/My::Module/;
186 If your plugin starts with a name other than C<Catalyst::Plugin::>, you can
187 fully qualify the name by using a unary plus:
191 +Fully::Qualified::Plugin::Name
194 Special flags like C<-Debug> and C<-Engine> can also be specified as
195 arguments when Catalyst is loaded:
197 use Catalyst qw/-Debug My::Module/;
199 The position of plugins and flags in the chain is important, because
200 they are loaded in exactly the order in which they appear.
202 The following flags are supported:
206 Enables debug output. You can also force this setting from the system
207 environment with CATALYST_DEBUG or <MYAPP>_DEBUG. The environment settings
208 override the app, with <MYAPP>_DEBUG having highest priority.
212 Forces Catalyst to use a specific engine. Omit the
213 C<Catalyst::Engine::> prefix of the engine name, i.e.:
215 use Catalyst qw/-Engine=CGI/;
219 Forces Catalyst to use a specific home directory, e.g.:
221 use Catalyst qw[-Home=/usr/sri];
229 =head2 INFORMATION ABOUT THE CURRENT REQUEST
233 Returns a L<Catalyst::Action> object for the current action, which
234 stringifies to the action name. See L<Catalyst::Action>.
238 Returns the namespace of the current action, i.e., the uri prefix
239 corresponding to the controller of the current action. For example:
241 # in Controller::Foo::Bar
242 $c->namespace; # returns 'foo/bar';
248 Returns the current L<Catalyst::Request> object. See
249 L<Catalyst::Request>.
251 =head2 REQUEST FLOW HANDLING
253 =head2 $c->forward( $action [, \@arguments ] )
255 =head2 $c->forward( $class, $method, [, \@arguments ] )
257 Forwards processing to another action, by it's private name. If you give a
258 class name but no method, C<process()> is called. You may also optionally
259 pass arguments in an arrayref. The action will receive the arguments in
260 C<@_> and C<$c-E<gt>req-E<gt>args>. Upon returning from the function,
261 C<$c-E<gt>req-E<gt>args> will be restored to the previous values.
263 Any data C<return>ed from the action forwarded to, will be returned by the
266 my $foodata = $c->forward('/foo');
267 $c->forward('index');
268 $c->forward(qw/MyApp::Model::DBIC::Foo do_stuff/);
269 $c->forward('MyApp::View::TT');
271 Note that forward implies an C<<eval { }>> around the call (well, actually
272 C<execute> does), thus de-fatalizing all 'dies' within the called action. If
273 you want C<die> to propagate you need to do something like:
276 die $c->error if $c->error;
278 Or make sure to always return true values from your actions and write your code
281 $c->forward('foo') || return;
285 sub forward { my $c = shift; $c->dispatcher->forward( $c, @_ ) }
287 =head2 $c->detach( $action [, \@arguments ] )
289 =head2 $c->detach( $class, $method, [, \@arguments ] )
291 The same as C<forward>, but doesn't return to the previous action when
292 processing is finished.
296 sub detach { my $c = shift; $c->dispatcher->detach( $c, @_ ) }
302 Returns the current L<Catalyst::Response> object.
306 Returns a hashref to the stash, which may be used to store data and pass
307 it between components during a request. You can also set hash keys by
308 passing arguments. The stash is automatically sent to the view. The
309 stash is cleared at the end of a request; it cannot be used for
312 $c->stash->{foo} = $bar;
313 $c->stash( { moose => 'majestic', qux => 0 } );
314 $c->stash( bar => 1, gorch => 2 ); # equivalent to passing a hashref
316 # stash is automatically passed to the view for use in a template
317 $c->forward( 'MyApp::V::TT' );
324 my $stash = @_ > 1 ? {@_} : $_[0];
325 croak('stash takes a hash or hashref') unless ref $stash;
326 foreach my $key ( keys %$stash ) {
327 $c->{stash}->{$key} = $stash->{$key};
335 =head2 $c->error($error, ...)
337 =head2 $c->error($arrayref)
339 Returns an arrayref containing error messages. If Catalyst encounters an
340 error while processing a request, it stores the error in $c->error. This
341 method should not be used to store non-fatal error messages.
343 my @error = @{ $c->error };
347 $c->error('Something bad happened');
354 my $error = ref $_[0] eq 'ARRAY' ? $_[0] : [@_];
355 croak @$error unless ref $c;
356 push @{ $c->{error} }, @$error;
358 elsif ( defined $_[0] ) { $c->{error} = undef }
359 return $c->{error} || [];
365 Contains the return value of the last executed action.
367 =head2 $c->clear_errors
369 Clear errors. You probably don't want to clear the errors unless you are
370 implementing a custom error screen.
372 This is equivalent to running
388 my ( $c, @names ) = @_;
390 foreach my $name (@names) {
391 foreach my $component ( keys %{ $c->components } ) {
392 return $c->components->{$component} if $component =~ /$name/i;
399 # try explicit component names
401 my ( $c, @names ) = @_;
403 foreach my $try (@names) {
404 return $c->components->{$try} if ( exists $c->components->{$try} );
410 # like component, but try just these prefixes before regex searching,
411 # and do not try to return "sort keys %{ $c->components }"
413 my ( $c, $name, @prefixes ) = @_;
415 my $appclass = ref $c || $c;
417 my @names = map { "${appclass}::${_}::${name}" } @prefixes;
419 my $comp = $c->_comp_explicit(@names);
420 return $comp if defined($comp);
421 $comp = $c->_comp_search($name);
425 # Find possible names for a prefix
428 my ( $c, @prefixes ) = @_;
430 my $appclass = ref $c || $c;
432 my @pre = map { "${appclass}::${_}::" } @prefixes;
436 COMPONENT: foreach my $comp ($c->component) {
437 foreach my $p (@pre) {
438 if ($comp =~ s/^$p//) {
448 # Return a component if only one matches.
450 my ( $c, @prefixes ) = @_;
452 my $appclass = ref $c || $c;
454 my ( $comp, $rest ) =
455 map { $c->_comp_search("^${appclass}::${_}::") } @prefixes;
456 return $comp unless $rest;
459 # Filter a component before returning by calling ACCEPT_CONTEXT if available
460 sub _filter_component {
461 my ( $c, $comp, @args ) = @_;
462 if ( eval { $comp->can('ACCEPT_CONTEXT'); } ) {
463 return $comp->ACCEPT_CONTEXT( $c, @args );
465 else { return $comp }
468 =head2 COMPONENT ACCESSORS
470 =head2 $c->controller($name)
472 Gets a L<Catalyst::Controller> instance by name.
474 $c->controller('Foo')->do_stuff;
476 If name is omitted, will return the controller for the dispatched action.
481 my ( $c, $name, @args ) = @_;
482 return $c->_filter_component( $c->_comp_prefixes( $name, qw/Controller C/ ),
485 return $c->component( $c->action->class );
488 =head2 $c->model($name)
490 Gets a L<Catalyst::Model> instance by name.
492 $c->model('Foo')->do_stuff;
494 If the name is omitted, it will look for a config setting 'default_model',
495 or check if there is only one view, and return it if that's the case.
500 my ( $c, $name, @args ) = @_;
501 return $c->_filter_component( $c->_comp_prefixes( $name, qw/Model M/ ),
504 return $c->component( $c->config->{default_model} )
505 if $c->config->{default_model};
506 return $c->_filter_component( $c->_comp_singular(qw/Model M/), @args );
510 =head2 $c->controllers
512 Returns the available names which can be passed to $c->controller
518 return $c->_comp_names(qw/Controller C/);
522 =head2 $c->view($name)
524 Gets a L<Catalyst::View> instance by name.
526 $c->view('Foo')->do_stuff;
528 If the name is omitted, it will look for a config setting 'default_view',
529 or check if there is only one view, and forward to it if that's the case.
534 my ( $c, $name, @args ) = @_;
535 return $c->_filter_component( $c->_comp_prefixes( $name, qw/View V/ ),
538 return $c->component( $c->config->{default_view} )
539 if $c->config->{default_view};
540 return $c->_filter_component( $c->_comp_singular(qw/View V/) );
545 Returns the available names which can be passed to $c->model
551 return $c->_comp_names(qw/Model M/);
557 Returns the available names which can be passed to $c->view
563 return $c->_comp_names(qw/View V/);
566 =head2 $c->comp($name)
568 =head2 $c->component($name)
570 Gets a component object by name. This method is no longer recommended,
571 unless you want to get a specific component by full
572 class. C<$c-E<gt>controller>, C<$c-E<gt>model>, and C<$c-E<gt>view>
573 should be used instead.
584 my $appclass = ref $c || $c;
587 $name, "${appclass}::${name}",
588 map { "${appclass}::${_}::${name}" }
589 qw/Model M Controller C View V/
592 my $comp = $c->_comp_explicit(@names);
593 return $c->_filter_component( $comp, @_ ) if defined($comp);
595 $comp = $c->_comp_search($name);
596 return $c->_filter_component( $comp, @_ ) if defined($comp);
599 return sort keys %{ $c->components };
604 =head2 CLASS DATA AND HELPER CLASSES
608 Returns or takes a hashref containing the application's configuration.
610 __PACKAGE__->config( { db => 'dsn:SQLite:foo.db' } );
612 You can also use a L<YAML> config file like myapp.yml in your
613 applications home directory.
616 db: dsn:SQLite:foo.db
624 $c->log->warn("Setting config after setup has been run is not a good idea.")
625 if ( @_ and $c->setup_finished );
627 $c->NEXT::config(@_);
632 Returns the logging object instance. Unless it is already set, Catalyst sets
633 this up with a L<Catalyst::Log> object. To use your own log class, set the
634 logger with the C<< __PACKAGE__->log >> method prior to calling
635 C<< __PACKAGE__->setup >>.
637 __PACKAGE__->log( MyLogger->new );
642 $c->log->info( 'Now logging with my own logger!' );
644 Your log class should implement the methods described in the
645 L<Catalyst::Log> man page.
650 Overload to enable debug messages (same as -Debug option).
652 Note that this is a static method, not an accessor and should be overloaded
653 by declaring "sub debug { 1 }" in your MyApp.pm, not by calling $c->debug(1).
659 =head2 $c->dispatcher
661 Returns the dispatcher instance. Stringifies to class name. See
662 L<Catalyst::Dispatcher>.
666 Returns the engine instance. Stringifies to the class name. See
670 =head2 UTILITY METHODS
672 =head2 $c->path_to(@path)
674 Merges C<@path> with C<$c-E<gt>config-E<gt>{home}> and returns a
675 L<Path::Class> object.
679 $c->path_to( 'db', 'sqlite.db' );
684 my ( $c, @path ) = @_;
685 my $path = Path::Class::Dir->new( $c->config->{home}, @path );
686 if ( -d $path ) { return $path }
687 else { return Path::Class::File->new( $c->config->{home}, @path ) }
690 =head2 $c->plugin( $name, $class, @args )
692 Helper method for plugins. It creates a classdata accessor/mutator and
693 loads and instantiates the given class.
695 MyApp->plugin( 'prototype', 'HTML::Prototype' );
697 $c->prototype->define_javascript_functions;
702 my ( $class, $name, $plugin, @args ) = @_;
703 $class->_register_plugin( $plugin, 1 );
705 eval { $plugin->import };
706 $class->mk_classdata($name);
708 eval { $obj = $plugin->new(@args) };
711 Catalyst::Exception->throw( message =>
712 qq/Couldn't instantiate instant plugin "$plugin", "$@"/ );
716 $class->log->debug(qq/Initialized instant plugin "$plugin" as "$name"/)
722 Initializes the dispatcher and engine, loads any plugins, and loads the
723 model, view, and controller components. You may also specify an array
724 of plugins to load here, if you choose to not load them in the C<use
728 MyApp->setup( qw/-Debug/ );
733 my ( $class, @arguments ) = @_;
735 $class->log->warn("Running setup twice is not a good idea.")
736 if ( $class->setup_finished );
738 unless ( $class->isa('Catalyst') ) {
740 Catalyst::Exception->throw(
741 message => qq/'$class' does not inherit from Catalyst/ );
744 if ( $class->arguments ) {
745 @arguments = ( @arguments, @{ $class->arguments } );
751 foreach (@arguments) {
755 ( $flags->{log} ) ? 'debug,' . $flags->{log} : 'debug';
757 elsif (/^-(\w+)=?(.*)$/) {
758 $flags->{ lc $1 } = $2;
761 push @{ $flags->{plugins} }, $_;
765 $class->setup_home( delete $flags->{home} );
767 $class->setup_log( delete $flags->{log} );
768 $class->setup_plugins( delete $flags->{plugins} );
769 $class->setup_dispatcher( delete $flags->{dispatcher} );
770 $class->setup_engine( delete $flags->{engine} );
772 for my $flag ( sort keys %{$flags} ) {
774 if ( my $code = $class->can( 'setup_' . $flag ) ) {
775 &$code( $class, delete $flags->{$flag} );
778 $class->log->warn(qq/Unknown flag "$flag"/);
783 <<"EOF") if ( $ENV{CATALYST_SCRIPT_GEN} && ( $ENV{CATALYST_SCRIPT_GEN} < $Catalyst::CATALYST_SCRIPT_GEN ) );
784 You are running an old script!
786 Please update by running (this will overwrite existing files):
787 catalyst.pl -force -scripts $class
789 or (this will not overwrite existing files):
790 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.
872 my ( $c, $path, @args ) = @_;
873 my $base = $c->request->base->clone;
874 my $basepath = $base->path;
875 $basepath =~ s/\/$//;
877 my $namespace = $c->namespace || '';
879 # massage namespace, empty if absolute path
880 $namespace =~ s/^\/// if $namespace;
881 $namespace .= '/' if $namespace;
883 $namespace = '' if $path =~ /^\//;
887 ( scalar @args && ref $args[$#args] eq 'HASH' ? pop @args : {} );
889 for my $value ( values %$params ) {
\r
890 my $isa_ref = ref $value;
\r
891 if( $isa_ref and $isa_ref ne 'ARRAY' ) {
\r
892 croak( "Non-array reference ($isa_ref) passed to uri_for()" );
\r
894 utf8::encode( $_ ) for grep { defined } $isa_ref ? @$value : $value;
\r
897 # join args with '/', or a blank string
898 my $args = ( scalar @args ? '/' . join( '/', @args ) : '' );
899 $args =~ s/^\/// unless $path;
901 URI->new_abs( URI->new_abs( "$path$args", "$basepath$namespace" ), $base )
903 $res->query_form(%$params);
907 =head2 $c->welcome_message
909 Returns the Catalyst welcome HTML page.
913 sub welcome_message {
915 my $name = $c->config->{name};
916 my $logo = $c->uri_for('/static/images/catalyst_logo.png');
917 my $prefix = Catalyst::Utils::appprefix( ref $c );
918 $c->response->content_type('text/html; charset=utf-8');
920 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
921 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
922 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
924 <meta http-equiv="Content-Language" content="en" />
925 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
926 <title>$name on Catalyst $VERSION</title>
927 <style type="text/css">
930 background-color: #eee;
939 background-color: #ccc;
940 border: 1px solid #aaa;
945 font-family: verdana, tahoma, sans-serif;
948 font-family: verdana, tahoma, sans-serif;
951 text-decoration: none;
953 border-bottom: 1px dotted #bbb;
955 :link:hover, :visited:hover {
968 background-color: #fff;
969 border: 1px solid #aaa;
995 <h1><span id="appname">$name</span> on <a href="http://catalyst.perl.org">Catalyst</a>
1000 <img src="$logo" alt="Catalyst Logo" />
1002 <p>Welcome to the wonderful world of Catalyst.
1003 This <a href="http://en.wikipedia.org/wiki/MVC">MVC</a>
1004 framework will make web development something you had
1005 never expected it to be: Fun, rewarding, and quick.</p>
1006 <h2>What to do now?</h2>
1007 <p>That really depends on what <b>you</b> want to do.
1008 We do, however, provide you with a few starting points.</p>
1009 <p>If you want to jump right into web development with Catalyst
1010 you might want to check out the documentation.</p>
1011 <pre><code>perldoc <a href="http://cpansearch.perl.org/dist/Catalyst/lib/Catalyst/Manual/Intro.pod">Catalyst::Manual::Intro</a>
1012 perldoc <a href="http://cpansearch.perl.org/dist/Catalyst/lib/Catalyst/Manual/Tutorial.pod">Catalyst::Manual::Tutorial</a></code>
1013 perldoc <a href="http://cpansearch.perl.org/dist/Catalyst/lib/Catalyst/Manual.pod">Catalyst::Manual</a></code></pre>
1014 <h2>What to do next?</h2>
1015 <p>Next it's time to write an actual application. Use the
1016 helper scripts to generate <a href="http://cpansearch.perl.org/search?query=Catalyst%3A%3AController%3A%3A&mode=all">controllers</a>,
1017 <a href="http://cpansearch.perl.org/search?query=Catalyst%3A%3AModel%3A%3A&mode=all">models</a>, and
1018 <a href="http://cpansearch.perl.org/search?query=Catalyst%3A%3AView%3A%3A&mode=all">views</a>;
1019 they can save you a lot of work.</p>
1020 <pre><code>script/${prefix}_create.pl -help</code></pre>
1021 <p>Also, be sure to check out the vast and growing
1022 collection of <a href="http://cpansearch.perl.org/search?query=Catalyst%3A%3APlugin%3A%3A&mode=all">plugins for Catalyst on CPAN</a>;
1023 you are likely to find what you need there.
1027 <p>Catalyst has a very active community. Here are the main places to
1028 get in touch with us.</p>
1031 <a href="http://dev.catalyst.perl.org">Wiki</a>
1034 <a href="http://lists.rawmode.org/mailman/listinfo/catalyst">Mailing-List</a>
1037 <a href="irc://irc.perl.org/catalyst">IRC channel #catalyst on irc.perl.org</a>
1040 <h2>In conclusion</h2>
1041 <p>The Catalyst team hopes you will enjoy using Catalyst as much
1042 as we enjoyed making it. Please contact us if you have ideas
1043 for improvement or other feedback.</p>
1051 =head1 INTERNAL METHODS
1053 These methods are not meant to be used by end users.
1055 =head2 $c->components
1057 Returns a hash of components.
1059 =head2 $c->context_class
1061 Returns or sets the context class.
1065 Returns a hashref containing coderefs and execution counts (needed for
1066 deep recursion detection).
1070 Returns the number of actions on the current internal execution stack.
1074 Dispatches a request to actions.
1078 sub dispatch { my $c = shift; $c->dispatcher->dispatch( $c, @_ ) }
1080 =head2 $c->dispatcher_class
1082 Returns or sets the dispatcher class.
1084 =head2 $c->dump_these
1086 Returns a list of 2-element array references (name, structure) pairs
1087 that will be dumped on the error page in debug mode.
1093 [ Request => $c->req ],
1094 [ Response => $c->res ],
1095 [ Stash => $c->stash ],
1096 [ Config => $c->config ];
1099 =head2 $c->engine_class
1101 Returns or sets the engine class.
1103 =head2 $c->execute( $class, $coderef )
1105 Execute a coderef in given class and catch exceptions. Errors are available
1111 my ( $c, $class, $code ) = @_;
1112 $class = $c->component($class) || $class;
1115 if ( $c->depth >= $RECURSION ) {
1116 my $action = "$code";
1117 $action = "/$action" unless $action =~ /\-\>/;
1118 my $error = qq/Deep recursion detected calling "$action"/;
1119 $c->log->error($error);
1125 my $stats_info = $c->_stats_start_execute( $code );
1127 push( @{ $c->stack }, $code );
1129 eval { $c->state( &$code( $class, $c, @{ $c->req->args } ) || 0 ) };
1131 $c->_stats_finish_execute( $stats_info );
1133 my $last = ${ $c->stack }[-1];
1134 pop( @{ $c->stack } );
1136 if ( my $error = $@ ) {
1137 if ( $error eq $DETACH ) { die $DETACH if $c->depth > 1 }
1139 unless ( ref $error ) {
1141 my $class = $last->class;
1142 my $name = $last->name;
1143 $error = qq/Caught exception in $class->$name "$error"/;
1152 sub _stats_start_execute {
1153 my ( $c, $code ) = @_;
1155 return unless $c->debug;
1157 my $action = "$code";
1159 $action = "/$action" unless $action =~ /\-\>/;
1160 $c->counter->{"$code"}++;
1162 # determine if the call was the result of a forward
1163 # this is done by walking up the call stack and looking for a calling
1164 # sub of Catalyst::forward before the eval
1166 for my $index ( 2 .. 11 ) {
1168 if ( ( caller($index) )[0] eq 'Catalyst'
1169 && ( caller($index) )[3] eq '(eval)' );
1171 if ( ( caller($index) )[3] =~ /forward$/ ) {
1172 $callsub = ( caller($index) )[3];
1173 $action = "-> $action";
1178 my $node = Tree::Simple->new(
1181 elapsed => undef, # to be filled in later
1185 $node->setUID( "$code" . $c->counter->{"$code"} );
1187 unless ( ( $code->name =~ /^_.*/ )
1188 && ( !$c->config->{show_internal_actions} ) )
1190 # is this a root-level call or a forwarded call?
1191 if ( $callsub =~ /forward$/ ) {
1193 # forward, locate the caller
1194 if ( my $parent = $c->stack->[-1] ) {
1195 my $visitor = Tree::Simple::Visitor::FindByUID->new;
1196 $visitor->searchForUID(
1197 "$parent" . $c->counter->{"$parent"} );
1198 $c->stats->accept($visitor);
1199 if ( my $result = $visitor->getResult ) {
1200 $result->addChild($node);
1205 # forward with no caller may come from a plugin
1206 $c->stats->addChild($node);
1212 $c->stats->addChild($node);
1216 my $start = [gettimeofday];
1217 my $elapsed = tv_interval($start);
1221 elapsed => $elapsed,
1227 sub _stats_finish_execute {
1228 my ( $c, $info ) = @_;
1230 return unless $c->debug;
1232 my ( $code, $start, $elapsed ) = @{ $info }{qw/code start elapsed/};
1234 unless ( ( $code->name =~ /^_.*/ )
1235 && ( !$c->config->{show_internal_actions} ) )
1238 # FindByUID uses an internal die, so we save the existing error
1241 # locate the node in the tree and update the elapsed time
1242 my $visitor = Tree::Simple::Visitor::FindByUID->new;
1243 $visitor->searchForUID( "$code" . $c->counter->{"$code"} );
1244 $c->stats->accept($visitor);
1245 if ( my $result = $visitor->getResult ) {
1246 my $value = $result->getNodeValue;
1247 $value->{elapsed} = sprintf( '%fs', $elapsed );
1248 $result->setNodeValue($value);
1252 $@ = $error || undef;
1256 =head2 $c->_localize_fields( sub { }, \%keys );
1260 sub _localize_fields {
1261 my ( $c, $localized, $code ) = ( @_ );
1263 my $request = delete $localized->{request} || {};
1264 my $response = delete $localized->{response} || {};
1266 local @{ $c }{ keys %$localized } = values %$localized;
1267 local @{ $c->request }{ keys %$request } = values %$request;
1268 local @{ $c->response }{ keys %$response } = values %$response;
1275 Finalizes the request.
1282 for my $error ( @{ $c->error } ) {
1283 $c->log->error($error);
1286 # Allow engine to handle finalize flow (for POE)
1287 if ( $c->engine->can('finalize') ) {
1288 $c->engine->finalize($c);
1292 $c->finalize_uploads;
1295 if ( $#{ $c->error } >= 0 ) {
1299 $c->finalize_headers;
1302 if ( $c->request->method eq 'HEAD' ) {
1303 $c->response->body('');
1309 return $c->response->status;
1312 =head2 $c->finalize_body
1318 sub finalize_body { my $c = shift; $c->engine->finalize_body( $c, @_ ) }
1320 =head2 $c->finalize_cookies
1326 sub finalize_cookies { my $c = shift; $c->engine->finalize_cookies( $c, @_ ) }
1328 =head2 $c->finalize_error
1334 sub finalize_error { my $c = shift; $c->engine->finalize_error( $c, @_ ) }
1336 =head2 $c->finalize_headers
1342 sub finalize_headers {
1345 # Check if we already finalized headers
1346 return if $c->response->{_finalized_headers};
1349 if ( my $location = $c->response->redirect ) {
1350 $c->log->debug(qq/Redirecting to "$location"/) if $c->debug;
1351 $c->response->header( Location => $location );
1355 if ( $c->response->body && !$c->response->content_length ) {
1357 # get the length from a filehandle
1358 if ( blessed( $c->response->body ) && $c->response->body->can('read') )
1360 if ( my $stat = stat $c->response->body ) {
1361 $c->response->content_length( $stat->size );
1364 $c->log->warn('Serving filehandle without a content-length');
1368 $c->response->content_length( bytes::length( $c->response->body ) );
1373 if ( $c->response->status =~ /^(1\d\d|[23]04)$/ ) {
1374 $c->response->headers->remove_header("Content-Length");
1375 $c->response->body('');
1378 $c->finalize_cookies;
1380 $c->engine->finalize_headers( $c, @_ );
1383 $c->response->{_finalized_headers} = 1;
1386 =head2 $c->finalize_output
1388 An alias for finalize_body.
1390 =head2 $c->finalize_read
1392 Finalizes the input after reading is complete.
1396 sub finalize_read { my $c = shift; $c->engine->finalize_read( $c, @_ ) }
1398 =head2 $c->finalize_uploads
1400 Finalizes uploads. Cleans up any temporary files.
1404 sub finalize_uploads { my $c = shift; $c->engine->finalize_uploads( $c, @_ ) }
1406 =head2 $c->get_action( $action, $namespace )
1408 Gets an action in a given namespace.
1412 sub get_action { my $c = shift; $c->dispatcher->get_action(@_) }
1414 =head2 $c->get_actions( $action, $namespace )
1416 Gets all actions of a given name in a namespace and all parent
1421 sub get_actions { my $c = shift; $c->dispatcher->get_actions( $c, @_ ) }
1423 =head2 $c->handle_request( $class, @arguments )
1425 Called to handle each HTTP request.
1429 sub handle_request {
1430 my ( $class, @arguments ) = @_;
1432 # Always expect worst case!
1435 my $stats = ( $class->debug ) ? Tree::Simple->new: q{};
1438 my $c = $class->prepare(@arguments);
1441 return $c->finalize;
1444 if ( $class->debug ) {
1445 my $start = [gettimeofday];
1446 $status = &$handler;
1447 my $elapsed = tv_interval $start;
1448 $elapsed = sprintf '%f', $elapsed;
1449 my $av = sprintf '%.3f',
1450 ( $elapsed == 0 ? '??' : ( 1 / $elapsed ) );
1451 my $t = Text::SimpleTable->new( [ 62, 'Action' ], [ 9, 'Time' ] );
1456 my $stat = $action->getNodeValue;
1457 $t->row( ( q{ } x $action->getDepth ) . $stat->{action} . $stat->{comment},
1458 $stat->{elapsed} || '??' );
1463 "Request took ${elapsed}s ($av/s)\n" . $t->draw );
1465 else { $status = &$handler }
1469 if ( my $error = $@ ) {
1471 $class->log->error(qq/Caught exception in engine "$error"/);
1475 $class->log->_flush() if $class->log->can('_flush');
1479 =head2 $c->prepare( @arguments )
1481 Creates a Catalyst context from an engine-specific request (Apache, CGI,
1487 my ( $class, @arguments ) = @_;
1489 $class->context_class( ref $class || $class ) unless $class->context_class;
1490 my $c = $class->context_class->new(
1494 request => $class->request_class->new(
1497 body_parameters => {},
1499 headers => HTTP::Headers->new,
1501 query_parameters => {},
1507 response => $class->response_class->new(
1511 headers => HTTP::Headers->new(),
1520 # For on-demand data
1521 $c->request->{_context} = $c;
1522 $c->response->{_context} = $c;
1523 weaken( $c->request->{_context} );
1524 weaken( $c->response->{_context} );
1527 my $secs = time - $START || 1;
1528 my $av = sprintf '%.3f', $COUNT / $secs;
1529 my $time = localtime time;
1530 $c->log->info("*** Request $COUNT ($av/s) [$$] [$time] ***");
1531 $c->res->headers->header( 'X-Catalyst' => $Catalyst::VERSION );
1534 # Allow engine to direct the prepare flow (for POE)
1535 if ( $c->engine->can('prepare') ) {
1536 $c->engine->prepare( $c, @arguments );
1539 $c->prepare_request(@arguments);
1540 $c->prepare_connection;
1541 $c->prepare_query_parameters;
1542 $c->prepare_headers;
1543 $c->prepare_cookies;
1547 $c->prepare_body unless $c->config->{parse_on_demand};
1550 my $method = $c->req->method || '';
1551 my $path = $c->req->path || '/';
1552 my $address = $c->req->address || '';
1554 $c->log->debug(qq/"$method" request for "$path" from "$address"/)
1562 =head2 $c->prepare_action
1564 Prepares action. See L<Catalyst::Dispatcher>.
1568 sub prepare_action { my $c = shift; $c->dispatcher->prepare_action( $c, @_ ) }
1570 =head2 $c->prepare_body
1572 Prepares message body.
1579 # Do we run for the first time?
1580 return if defined $c->request->{_body};
1582 # Initialize on-demand data
1583 $c->engine->prepare_body( $c, @_ );
1584 $c->prepare_parameters;
1585 $c->prepare_uploads;
1587 if ( $c->debug && keys %{ $c->req->body_parameters } ) {
1588 my $t = Text::SimpleTable->new( [ 35, 'Parameter' ], [ 36, 'Value' ] );
1589 for my $key ( sort keys %{ $c->req->body_parameters } ) {
1590 my $param = $c->req->body_parameters->{$key};
1591 my $value = defined($param) ? $param : '';
1593 ref $value eq 'ARRAY' ? ( join ', ', @$value ) : $value );
1595 $c->log->debug( "Body Parameters are:\n" . $t->draw );
1599 =head2 $c->prepare_body_chunk( $chunk )
1601 Prepares a chunk of data before sending it to L<HTTP::Body>.
1603 See L<Catalyst::Engine>.
1607 sub prepare_body_chunk {
1609 $c->engine->prepare_body_chunk( $c, @_ );
1612 =head2 $c->prepare_body_parameters
1614 Prepares body parameters.
1618 sub prepare_body_parameters {
1620 $c->engine->prepare_body_parameters( $c, @_ );
1623 =head2 $c->prepare_connection
1625 Prepares connection.
1629 sub prepare_connection {
1631 $c->engine->prepare_connection( $c, @_ );
1634 =head2 $c->prepare_cookies
1640 sub prepare_cookies { my $c = shift; $c->engine->prepare_cookies( $c, @_ ) }
1642 =head2 $c->prepare_headers
1648 sub prepare_headers { my $c = shift; $c->engine->prepare_headers( $c, @_ ) }
1650 =head2 $c->prepare_parameters
1652 Prepares parameters.
1656 sub prepare_parameters {
1658 $c->prepare_body_parameters;
1659 $c->engine->prepare_parameters( $c, @_ );
1662 =head2 $c->prepare_path
1664 Prepares path and base.
1668 sub prepare_path { my $c = shift; $c->engine->prepare_path( $c, @_ ) }
1670 =head2 $c->prepare_query_parameters
1672 Prepares query parameters.
1676 sub prepare_query_parameters {
1679 $c->engine->prepare_query_parameters( $c, @_ );
1681 if ( $c->debug && keys %{ $c->request->query_parameters } ) {
1682 my $t = Text::SimpleTable->new( [ 35, 'Parameter' ], [ 36, 'Value' ] );
1683 for my $key ( sort keys %{ $c->req->query_parameters } ) {
1684 my $param = $c->req->query_parameters->{$key};
1685 my $value = defined($param) ? $param : '';
1687 ref $value eq 'ARRAY' ? ( join ', ', @$value ) : $value );
1689 $c->log->debug( "Query Parameters are:\n" . $t->draw );
1693 =head2 $c->prepare_read
1695 Prepares the input for reading.
1699 sub prepare_read { my $c = shift; $c->engine->prepare_read( $c, @_ ) }
1701 =head2 $c->prepare_request
1703 Prepares the engine request.
1707 sub prepare_request { my $c = shift; $c->engine->prepare_request( $c, @_ ) }
1709 =head2 $c->prepare_uploads
1715 sub prepare_uploads {
1718 $c->engine->prepare_uploads( $c, @_ );
1720 if ( $c->debug && keys %{ $c->request->uploads } ) {
1721 my $t = Text::SimpleTable->new(
1722 [ 12, 'Parameter' ],
1727 for my $key ( sort keys %{ $c->request->uploads } ) {
1728 my $upload = $c->request->uploads->{$key};
1729 for my $u ( ref $upload eq 'ARRAY' ? @{$upload} : ($upload) ) {
1730 $t->row( $key, $u->filename, $u->type, $u->size );
1733 $c->log->debug( "File Uploads are:\n" . $t->draw );
1737 =head2 $c->prepare_write
1739 Prepares the output for writing.
1743 sub prepare_write { my $c = shift; $c->engine->prepare_write( $c, @_ ) }
1745 =head2 $c->request_class
1747 Returns or sets the request class.
1749 =head2 $c->response_class
1751 Returns or sets the response class.
1753 =head2 $c->read( [$maxlength] )
1755 Reads a chunk of data from the request body. This method is designed to
1756 be used in a while loop, reading C<$maxlength> bytes on every call.
1757 C<$maxlength> defaults to the size of the request if not specified.
1759 You have to set C<MyApp-E<gt>config-E<gt>{parse_on_demand}> to use this
1764 sub read { my $c = shift; return $c->engine->read( $c, @_ ) }
1772 sub run { my $c = shift; return $c->engine->run( $c, @_ ) }
1774 =head2 $c->set_action( $action, $code, $namespace, $attrs )
1776 Sets an action in a given namespace.
1780 sub set_action { my $c = shift; $c->dispatcher->set_action( $c, @_ ) }
1782 =head2 $c->setup_actions($component)
1784 Sets up actions for a component.
1788 sub setup_actions { my $c = shift; $c->dispatcher->setup_actions( $c, @_ ) }
1790 =head2 $c->setup_components
1796 sub setup_components {
1799 my $callback = sub {
1800 my ( $component, $context ) = @_;
1802 unless ( $component->can('COMPONENT') ) {
1806 my $suffix = Catalyst::Utils::class2classsuffix($component);
1807 my $config = $class->config->{$suffix} || {};
1811 eval { $instance = $component->COMPONENT( $context, $config ); };
1813 if ( my $error = $@ ) {
1817 Catalyst::Exception->throw( message =>
1818 qq/Couldn't instantiate component "$component", "$error"/ );
1821 Catalyst::Exception->throw( message =>
1822 qq/Couldn't instantiate component "$component", "COMPONENT() didn't return a object"/
1824 unless ref $instance;
1828 eval "package $class;\n" . q!Module::Pluggable::Fast->import(
1829 name => '_catalyst_components',
1831 "$class\::Controller", "$class\::C",
1832 "$class\::Model", "$class\::M",
1833 "$class\::View", "$class\::V"
1835 callback => $callback
1839 if ( my $error = $@ ) {
1843 Catalyst::Exception->throw(
1844 message => qq/Couldn't load components "$error"/ );
1847 for my $component ( $class->_catalyst_components($class) ) {
1848 $class->components->{ ref $component || $component } = $component;
1852 =head2 $c->setup_dispatcher
1858 sub setup_dispatcher {
1859 my ( $class, $dispatcher ) = @_;
1862 $dispatcher = 'Catalyst::Dispatcher::' . $dispatcher;
1865 if ( $ENV{CATALYST_DISPATCHER} ) {
1866 $dispatcher = 'Catalyst::Dispatcher::' . $ENV{CATALYST_DISPATCHER};
1869 if ( $ENV{ uc($class) . '_DISPATCHER' } ) {
1871 'Catalyst::Dispatcher::' . $ENV{ uc($class) . '_DISPATCHER' };
1874 unless ($dispatcher) {
1875 $dispatcher = $class->dispatcher_class;
1878 unless (Class::Inspector->loaded($dispatcher)) {
1879 require Class::Inspector->filename($dispatcher);
1882 # dispatcher instance
1883 $class->dispatcher( $dispatcher->new );
1886 =head2 $c->setup_engine
1893 my ( $class, $engine ) = @_;
1896 $engine = 'Catalyst::Engine::' . $engine;
1899 if ( $ENV{CATALYST_ENGINE} ) {
1900 $engine = 'Catalyst::Engine::' . $ENV{CATALYST_ENGINE};
1903 if ( $ENV{ uc($class) . '_ENGINE' } ) {
1904 $engine = 'Catalyst::Engine::' . $ENV{ uc($class) . '_ENGINE' };
1907 if ( $ENV{MOD_PERL} ) {
1909 # create the apache method
1912 *{"$class\::apache"} = sub { shift->engine->apache };
1915 my ( $software, $version ) =
1916 $ENV{MOD_PERL} =~ /^(\S+)\/(\d+(?:[\.\_]\d+)+)/;
1919 $version =~ s/(\.[^.]+)\./$1/g;
1921 if ( $software eq 'mod_perl' ) {
1925 if ( $version >= 1.99922 ) {
1926 $engine = 'Catalyst::Engine::Apache2::MP20';
1929 elsif ( $version >= 1.9901 ) {
1930 $engine = 'Catalyst::Engine::Apache2::MP19';
1933 elsif ( $version >= 1.24 ) {
1934 $engine = 'Catalyst::Engine::Apache::MP13';
1938 Catalyst::Exception->throw( message =>
1939 qq/Unsupported mod_perl version: $ENV{MOD_PERL}/ );
1944 # install the correct mod_perl handler
1945 if ( $version >= 1.9901 ) {
1946 *handler = sub : method {
1947 shift->handle_request(@_);
1951 *handler = sub ($$) { shift->handle_request(@_) };
1956 elsif ( $software eq 'Zeus-Perl' ) {
1957 $engine = 'Catalyst::Engine::Zeus';
1961 Catalyst::Exception->throw(
1962 message => qq/Unsupported mod_perl: $ENV{MOD_PERL}/ );
1967 $engine = $class->engine_class;
1970 unless (Class::Inspector->loaded($engine)) {
1971 require Class::Inspector->filename($engine);
1974 # check for old engines that are no longer compatible
1976 if ( $engine->isa('Catalyst::Engine::Apache')
1977 && !Catalyst::Engine::Apache->VERSION )
1982 elsif ( $engine->isa('Catalyst::Engine::Server::Base')
1983 && Catalyst::Engine::Server->VERSION le '0.02' )
1988 elsif ($engine->isa('Catalyst::Engine::HTTP::POE')
1989 && $engine->VERSION eq '0.01' )
1994 elsif ($engine->isa('Catalyst::Engine::Zeus')
1995 && $engine->VERSION eq '0.01' )
2001 Catalyst::Exception->throw( message =>
2002 qq/Engine "$engine" is not supported by this version of Catalyst/
2007 $class->engine( $engine->new );
2010 =head2 $c->setup_home
2012 Sets up the home directory.
2017 my ( $class, $home ) = @_;
2019 if ( $ENV{CATALYST_HOME} ) {
2020 $home = $ENV{CATALYST_HOME};
2023 if ( $ENV{ uc($class) . '_HOME' } ) {
2024 $home = $ENV{ uc($class) . '_HOME' };
2028 $home = Catalyst::Utils::home($class);
2032 $class->config->{home} ||= $home;
2033 $class->config->{root} ||= Path::Class::Dir->new($home)->subdir('root');
2037 =head2 $c->setup_log
2044 my ( $class, $debug ) = @_;
2046 unless ( $class->log ) {
2047 $class->log( Catalyst::Log->new );
2050 my $app_flag = Catalyst::Utils::class2env($class) . '_DEBUG';
2053 ( defined( $ENV{CATALYST_DEBUG} ) || defined( $ENV{$app_flag} ) )
2054 ? ( $ENV{CATALYST_DEBUG} || $ENV{$app_flag} )
2059 *{"$class\::debug"} = sub { 1 };
2060 $class->log->debug('Debug messages enabled');
2064 =head2 $c->setup_plugins
2070 =head2 $c->registered_plugins
2072 Returns a sorted list of the plugins which have either been stated in the
2073 import list or which have been added via C<< MyApp->plugin(@args); >>.
2075 If passed a given plugin name, it will report a boolean value indicating
2076 whether or not that plugin is loaded. A fully qualified name is required if
2077 the plugin name does not begin with C<Catalyst::Plugin::>.
2079 if ($c->registered_plugins('Some::Plugin')) {
2087 sub registered_plugins {
2089 return sort keys %{ $proto->_plugins } unless @_;
2091 return 1 if exists $proto->_plugins->{$plugin};
2092 return exists $proto->_plugins->{"Catalyst::Plugin::$plugin"};
2095 sub _register_plugin {
2096 my ( $proto, $plugin, $instant ) = @_;
2097 my $class = ref $proto || $proto;
2099 unless (Class::Inspector->loaded($plugin)) {
2100 require Class::Inspector->filename($plugin);
2103 $proto->_plugins->{$plugin} = 1;
2106 unshift @{"$class\::ISA"}, $plugin;
2112 my ( $class, $plugins ) = @_;
2114 $class->_plugins( {} ) unless $class->_plugins;
2116 for my $plugin ( reverse @$plugins ) {
2118 unless ( $plugin =~ s/\A\+// ) {
2119 $plugin = "Catalyst::Plugin::$plugin";
2122 $class->_register_plugin($plugin);
2129 Returns an arrayref of the internal execution stack (actions that are currently
2132 =head2 $c->write( $data )
2134 Writes $data to the output stream. When using this method directly, you
2135 will need to manually set the C<Content-Length> header to the length of
2136 your output data, if known.
2143 # Finalize headers if someone manually writes output
2144 $c->finalize_headers;
2146 return $c->engine->write( $c, @_ );
2151 Returns the Catalyst version number. Mostly useful for "powered by"
2152 messages in template systems.
2156 sub version { return $Catalyst::VERSION }
2158 =head1 INTERNAL ACTIONS
2160 Catalyst uses internal actions like C<_DISPATCH>, C<_BEGIN>, C<_AUTO>,
2161 C<_ACTION>, and C<_END>. These are by default not shown in the private
2162 action table, but you can make them visible with a config parameter.
2164 MyApp->config->{show_internal_actions} = 1;
2166 =head1 CASE SENSITIVITY
2168 By default Catalyst is not case sensitive, so C<MyApp::C::FOO::Bar> is
2169 mapped to C</foo/bar>. You can activate case sensitivity with a config
2172 MyApp->config->{case_sensitive} = 1;
2174 This causes C<MyApp::C::Foo::Bar> to map to C</Foo/Bar>.
2176 =head1 ON-DEMAND PARSER
2178 The request body is usually parsed at the beginning of a request,
2179 but if you want to handle input yourself or speed things up a bit,
2180 you can enable on-demand parsing with a config parameter.
2182 MyApp->config->{parse_on_demand} = 1;
2184 =head1 PROXY SUPPORT
2186 Many production servers operate using the common double-server approach,
2187 with a lightweight frontend web server passing requests to a larger
2188 backend server. An application running on the backend server must deal
2189 with two problems: the remote user always appears to be C<127.0.0.1> and
2190 the server's hostname will appear to be C<localhost> regardless of the
2191 virtual host that the user connected through.
2193 Catalyst will automatically detect this situation when you are running
2194 the frontend and backend servers on the same machine. The following
2195 changes are made to the request.
2197 $c->req->address is set to the user's real IP address, as read from
2198 the HTTP X-Forwarded-For header.
2200 The host value for $c->req->base and $c->req->uri is set to the real
2201 host, as read from the HTTP X-Forwarded-Host header.
2203 Obviously, your web server must support these headers for this to work.
2205 In a more complex server farm environment where you may have your
2206 frontend proxy server(s) on different machines, you will need to set a
2207 configuration option to tell Catalyst to read the proxied data from the
2210 MyApp->config->{using_frontend_proxy} = 1;
2212 If you do not wish to use the proxy support at all, you may set:
2214 MyApp->config->{ignore_frontend_proxy} = 1;
2216 =head1 THREAD SAFETY
2218 Catalyst has been tested under Apache 2's threading mpm_worker, mpm_winnt,
2219 and the standalone forking HTTP server on Windows. We believe the Catalyst
2220 core to be thread-safe.
2222 If you plan to operate in a threaded environment, remember that all other
2223 modules you are using must also be thread-safe. Some modules, most notably
2224 L<DBD::SQLite>, are not thread-safe.
2230 Join #catalyst on irc.perl.org.
2234 http://lists.rawmode.org/mailman/listinfo/catalyst
2235 http://lists.rawmode.org/mailman/listinfo/catalyst-dev
2239 http://catalyst.perl.org
2243 http://dev.catalyst.perl.org
2247 =head2 L<Task::Catalyst> - All you need to start with Catalyst
2249 =head2 L<Catalyst::Manual> - The Catalyst Manual
2251 =head2 L<Catalyst::Component>, L<Catalyst::Base> - Base classes for components
2253 =head2 L<Catalyst::Engine> - Core engine
2255 =head2 L<Catalyst::Log> - Log class.
2257 =head2 L<Catalyst::Request> - Request object
2259 =head2 L<Catalyst::Response> - Response object
2261 =head2 L<Catalyst::Test> - The test suite.
2333 Sebastian Riedel, C<sri@oook.de>
2337 This library is free software, you can redistribute it and/or modify it under
2338 the same terms as Perl itself.