4 use base 'Catalyst::Base';
5 use UNIVERSAL::require;
6 use Catalyst::Exception;
11 our $CATALYST_SCRIPT_GEN = 4;
13 __PACKAGE__->mk_classdata($_) for qw/dispatcher engine log/;
15 our $VERSION = '5.24';
20 Catalyst - The Elegant MVC Web Application Framework
24 # use the helper to start a new application
28 # add models, views, controllers
29 script/myapp_create.pl model Something
30 script/myapp_create.pl view Stuff
31 script/myapp_create.pl controller Yada
34 script/myapp_server.pl
36 # command line interface
37 script/myapp_test.pl /yada
42 use Catalyst qw/My::Module My::OtherModule/;
44 use Catalyst '-Debug';
46 use Catalyst qw/-Debug -Engine=CGI/;
48 sub default : Private { $_[1]->res->output('Hello') } );
50 sub index : Path('/index.html') {
51 my ( $self, $c ) = @_;
52 $c->res->output('Hello');
56 sub product : Regex('^product[_]*(\d*).html$') {
57 my ( $self, $c ) = @_;
58 $c->stash->{template} = 'product.tt';
59 $c->stash->{product} = $c->req->snippets->[0];
62 See also L<Catalyst::Manual::Intro>
66 The key concept of Catalyst is DRY (Don't Repeat Yourself).
68 See L<Catalyst::Manual> for more documentation.
70 Catalyst plugins can be loaded by naming them as arguments to the "use Catalyst" statement.
71 Omit the C<Catalyst::Plugin::> prefix from the plugin name,
72 so C<Catalyst::Plugin::My::Module> becomes C<My::Module>.
74 use Catalyst 'My::Module';
76 Special flags like -Debug and -Engine can also be specifed as arguments when
79 use Catalyst qw/-Debug My::Module/;
81 The position of plugins and flags in the chain is important, because they are
82 loaded in exactly the order that they appear.
84 The following flags are supported:
90 enables debug output, i.e.:
92 use Catalyst '-Debug';
94 this is equivalent to:
101 Force Catalyst to use a specific engine.
102 Omit the C<Catalyst::Engine::> prefix of the engine name, i.e.:
104 use Catalyst '-Engine=CGI';
114 Overload to enable debug messages.
122 Returns a hashref containing your applications settings.
127 my ( $class, @arguments ) = @_;
129 my $caller = caller(0);
131 if ( $caller eq 'main' ) {
135 # Prepare inheritance
136 unless ( $caller->isa($class) ) {
138 push @{"$caller\::ISA"}, $class;
141 if ( $caller->engine ) {
142 $caller->log->warn( qq/Attempt to re-initialize "$caller"/ );
149 foreach (@arguments) {
152 $flags->{log} = ( $flags->{log} ) ? 'debug,' . $flags->{log} : 'debug';
154 elsif (/^-(\w+)=?(.*)$/) {
155 $flags->{ lc $1 } = $2;
158 push @{ $flags->{plugins} }, $_;
162 $caller->setup_log ( delete $flags->{log} );
163 $caller->setup_plugins ( delete $flags->{plugins} );
164 $caller->setup_dispatcher ( delete $flags->{dispatcher} );
165 $caller->setup_engine ( delete $flags->{engine} );
166 $caller->setup_home ( delete $flags->{home} );
168 for my $flag ( sort keys %{ $flags } ) {
170 if ( my $code = $caller->can( 'setup_' . $flag ) ) {
171 &$code( $caller, delete $flags->{$flag} );
174 $caller->log->warn(qq/Unknown flag "$flag"/);
178 $caller->log->warn( "You are running an old helper script! "
179 . "Please update your scripts by regenerating the "
180 . "application and copying over the new scripts." )
181 if ( $ENV{CATALYST_SCRIPT_GEN}
182 && ( $ENV{CATALYST_SCRIPT_GEN} < $CATALYST_SCRIPT_GEN ) );
185 if ( $caller->debug ) {
191 @plugins = grep { /^Catalyst::Plugin/ } @{"$caller\::ISA"};
195 my $t = Text::ASCIITable->new;
196 $t->setOptions( 'hide_HeadRow', 1 );
197 $t->setOptions( 'hide_HeadLine', 1 );
198 $t->setCols('Class');
199 $t->setColWidth( 'Class', 75, 1 );
200 $t->addRow($_) for @plugins;
201 $caller->log->debug( "Loaded plugins:\n" . $t->draw );
204 my $dispatcher = $caller->dispatcher;
205 my $engine = $caller->engine;
206 my $home = $caller->config->{home};
208 $caller->log->debug(qq/Loaded dispatcher "$dispatcher"/);
209 $caller->log->debug(qq/Loaded engine "$engine"/);
213 ? $caller->log->debug(qq/Found home "$home"/)
214 : $caller->log->debug(qq/Home "$home" doesn't exist/)
215 : $caller->log->debug(q/Couldn't find home/);
221 Contains the engine class.
225 Contains the logging object. Unless it is already set Catalyst sets this up with a
226 C<Catalyst::Log> object. To use your own log class:
228 $c->log( MyLogger->new );
229 $c->log->info("now logging with my own logger!");
231 Your log class should implement the methods described in the C<Catalyst::Log>
234 =item $c->plugin( $name, $class, @args )
236 Instant plugins for Catalyst.
237 Classdata accessor/mutator will be created, class loaded and instantiated.
239 MyApp->plugin( 'prototype', 'HTML::Prototype' );
241 $c->prototype->define_javascript_functions;
246 my ( $class, $name, $plugin, @args ) = @_;
249 if ( my $error = $UNIVERSAL::require::ERROR ) {
250 Catalyst::Exception->throw(
251 message => qq/Couldn't load instant plugin "$plugin", "$error"/
255 eval { $plugin->import };
256 $class->mk_classdata($name);
258 eval { $obj = $plugin->new(@args) };
261 Catalyst::Exception->throw(
262 message => qq/Couldn't instantiate instant plugin "$plugin", "$@"/
267 $class->log->debug(qq/Initialized instant plugin "$plugin" as "$name"/)
271 =item $c->setup_dispatcher
275 sub setup_dispatcher {
276 my ( $class, $dispatcher ) = @_;
279 $dispatcher = 'Catalyst::Dispatcher::' . $dispatcher;
282 if ( $ENV{CATALYST_DISPATCHER} ) {
283 $dispatcher = 'Catalyst::Dispatcher::' . $ENV{CATALYST_DISPATCHER};
286 if ( $ENV{ uc($class) . '_DISPATCHER' } ) {
287 $dispatcher = 'Catalyst::Dispatcher::' . $ENV{ uc($class) . '_DISPATCHER' };
290 unless ( $dispatcher ) {
291 $dispatcher = 'Catalyst::Dispatcher';
294 $dispatcher->require;
297 Catalyst::Exception->throw(
298 message => qq/Couldn't load dispatcher "$dispatcher", "$@"/
304 push @{"$class\::ISA"}, $dispatcher;
307 $class->dispatcher($dispatcher);
310 =item $c->setup_engine
315 my ( $class, $engine ) = @_;
318 $engine = 'Catalyst::Engine::' . $engine;
321 if ( $ENV{CATALYST_ENGINE} ) {
322 $engine = 'Catalyst::Engine::' . $ENV{CATALYST_ENGINE};
325 if ( $ENV{ uc($class) . '_ENGINE' } ) {
326 $engine = 'Catalyst::Engine::' . $ENV{ uc($class) . '_ENGINE' };
329 if ( ! $engine && $ENV{MOD_PERL} ) {
331 my ( $software, $version ) = $ENV{MOD_PERL} =~ /^(\S+)\/(\d+(?:[\.\_]\d+)+)/;
334 $version =~ s/(\.[^.]+)\./$1/g;
336 if ( $software eq 'mod_perl') {
338 if ( $version >= 1.99922 ) {
340 $engine = 'Catalyst::Engine::Apache::MP20';
342 if ( Apache2::Request->require ) {
343 $engine = 'Catalyst::Engine::Apache::MP20::Apreq';
347 elsif ( $version >= 1.9901 ) {
349 $engine = 'Catalyst::Engine::Apache::MP19';
351 if ( Apache::Request->require ) {
352 $engine = 'Catalyst::Engine::Apache::MP19::Apreq';
356 elsif ( $version >= 1.24 ) {
358 $engine = 'Catalyst::Engine::Apache::MP13';
360 if ( Apache::Request->require ) {
361 $engine = 'Catalyst::Engine::Apache::MP13::Apreq';
366 Catalyst::Exception->throw(
367 message => qq/Unsupported mod_perl version: $ENV{MOD_PERL}/
372 elsif ( $software eq 'Zeus-Perl' ) {
373 $engine = 'Catalyst::Engine::Zeus';
377 Catalyst::Exception->throw(
378 message => qq/Unsupported mod_perl: $ENV{MOD_PERL}/
384 $engine = 'Catalyst::Engine::CGI';
390 Catalyst::Exception->throw(
391 message => qq/Couldn't load engine "$engine", "$@"/
397 push @{"$class\::ISA"}, $engine;
400 $class->engine($engine);
408 my ( $class, $home ) = @_;
410 if ( $ENV{CATALYST_HOME} ) {
411 $home = $ENV{CATALYST_HOME};
414 if ( $ENV{ uc($class) . '_HOME' } ) {
415 $home = $ENV{ uc($class) . '_HOME' };
419 $home = Catalyst::Utils::home($class);
423 $class->config->{home} = $home;
424 $class->config->{root} = dir($home)->subdir('root');
433 my ( $class, $debug ) = @_;
435 unless ( $class->log ) {
436 $class->log( Catalyst::Log->new );
439 if ( $ENV{CATALYST_DEBUG} || $ENV{ uc($class) . '_DEBUG' } || $debug ) {
441 *{"$class\::debug"} = sub { 1 };
442 $class->log->debug('Debug messages enabled');
446 =item $c->setup_plugins
451 my ( $class, $plugins ) = @_;
453 for my $plugin ( @$plugins ) {
455 $plugin = "Catalyst::Plugin::$plugin";
460 Catalyst::Exception->throw(
461 message => qq/Couldn't load plugin "$plugin", "$@"/
467 push @{"$class\::ISA"}, $plugin;
476 mod_perl2 support is considered experimental and may contain bugs.
482 Join #catalyst on irc.perl.org.
486 http://lists.rawmode.org/mailman/listinfo/catalyst
487 http://lists.rawmode.org/mailman/listinfo/catalyst-dev
491 http://catalyst.perl.org
497 =item L<Catalyst::Manual> - The Catalyst Manual
499 =item L<Catalyst::Engine> - Core Engine
501 =item L<Catalyst::Log> - The Log Class.
503 =item L<Catalyst::Request> - The Request Object
505 =item L<Catalyst::Response> - The Response Object
507 =item L<Catalyst::Test> - The test suite.
513 Sebastian Riedel, C<sri@oook.de>
517 Andy Grundman, Andrew Ford, Andrew Ruthven, Autrijus Tang, Christian Hansen,
518 Christopher Hicks, Dan Sully, Danijel Milicevic, David Naughton,
519 Gary Ashton Jones, Geoff Richards, Jesse Sheidlower, Jody Belka,
520 Johan Lindstrom, Juan Camacho, Leon Brocard, Marcus Ramberg,
521 Tatsuhiko Miyagawa and all the others who've helped.
525 This library is free software . You can redistribute it and/or modify it under
526 the same terms as perl itself.