Fixed changes
[catagits/Catalyst-Runtime.git] / lib / Catalyst.pm
CommitLineData
fc7ec1d9 1package Catalyst;
2
3use strict;
ac733264 4use base 'Catalyst::Base';
fc7ec1d9 5use UNIVERSAL::require;
6use Catalyst::Log;
812a28c9 7use Catalyst::Utils;
0f7ecc53 8use Text::ASCIITable;
4f6748f1 9use Path::Class;
367d15f8 10our $CATALYST_SCRIPT_GEN = 4;
fc7ec1d9 11
424b2705 12__PACKAGE__->mk_classdata($_) for qw/dispatcher engine log/;
fc7ec1d9 13
367d15f8 14our $VERSION = '5.20';
fc7ec1d9 15our @ISA;
16
17=head1 NAME
18
19Catalyst - The Elegant MVC Web Application Framework
20
21=head1 SYNOPSIS
22
23 # use the helper to start a new application
91864987 24 catalyst.pl MyApp
fc7ec1d9 25 cd MyApp
26
27 # add models, views, controllers
d01df17d 28 script/create.pl model Something
29 script/create.pl view Stuff
30 script/create.pl controller Yada
fc7ec1d9 31
32 # built in testserver
d01df17d 33 script/server.pl
fc7ec1d9 34
35 # command line interface
d01df17d 36 script/test.pl /yada
fc7ec1d9 37
38
fc7ec1d9 39 use Catalyst;
40
41 use Catalyst qw/My::Module My::OtherModule/;
42
43 use Catalyst '-Debug';
44
45 use Catalyst qw/-Debug -Engine=CGI/;
46
5a8ed4fe 47 sub default : Private { $_[1]->res->output('Hello') } );
48
e3dc9d78 49 sub index : Path('/index.html') {
5a8ed4fe 50 my ( $self, $c ) = @_;
51 $c->res->output('Hello');
064834ea 52 $c->forward('foo');
5a8ed4fe 53 }
54
064834ea 55 sub product : Regex('^product[_]*(\d*).html$') {
5a8ed4fe 56 my ( $self, $c ) = @_;
57 $c->stash->{template} = 'product.tt';
58 $c->stash->{product} = $c->req->snippets->[0];
59 }
fc7ec1d9 60
3803e98f 61See also L<Catalyst::Manual::Intro>
62
fc7ec1d9 63=head1 DESCRIPTION
64
65Catalyst is based upon L<Maypole>, which you should consider for smaller
66projects.
67
68The key concept of Catalyst is DRY (Don't Repeat Yourself).
69
70See L<Catalyst::Manual> for more documentation.
71
23f9d934 72Catalyst plugins can be loaded by naming them as arguments to the "use Catalyst" statement.
1985c30b 73Omit the C<Catalyst::Plugin::> prefix from the plugin name,
23f9d934 74so C<Catalyst::Plugin::My::Module> becomes C<My::Module>.
fc7ec1d9 75
76 use Catalyst 'My::Module';
77
23f9d934 78Special flags like -Debug and -Engine can also be specifed as arguments when
79Catalyst is loaded:
fc7ec1d9 80
81 use Catalyst qw/-Debug My::Module/;
82
23f9d934 83The position of plugins and flags in the chain is important, because they are
84loaded in exactly the order that they appear.
fc7ec1d9 85
23f9d934 86The following flags are supported:
87
88=over 4
89
90=item -Debug
91
92enables debug output, i.e.:
fc7ec1d9 93
94 use Catalyst '-Debug';
95
23f9d934 96this is equivalent to:
fc7ec1d9 97
98 use Catalyst;
99 sub debug { 1 }
100
23f9d934 101=item -Engine
fc7ec1d9 102
103Force Catalyst to use a specific engine.
23f9d934 104Omit the C<Catalyst::Engine::> prefix of the engine name, i.e.:
fc7ec1d9 105
106 use Catalyst '-Engine=CGI';
107
23f9d934 108=back
fc7ec1d9 109
23f9d934 110=head1 METHODS
111
112=over 4
113
114=item debug
fc7ec1d9 115
116Overload to enable debug messages.
117
118=cut
119
120sub debug { 0 }
121
23f9d934 122=item config
fc7ec1d9 123
124Returns a hashref containing your applications settings.
125
126=cut
127
fc7ec1d9 128sub import {
129 my ( $self, @options ) = @_;
130 my $caller = caller(0);
131
99fe1710 132 # Prepare inheritance
22402712 133 unless ( $caller->isa($self) ) {
fc7ec1d9 134 no strict 'refs';
22402712 135 push @{"$caller\::ISA"}, $self;
1c99e125 136 }
137
d96e14c2 138 if ( $caller->engine ) {
42a57832 139 return; # Catalyst is already initialized
d96e14c2 140 }
141
32620e3e 142 unless ( $caller->log ) {
143 $caller->log( Catalyst::Log->new );
fc7ec1d9 144 }
fc7ec1d9 145
99fe1710 146 # Debug?
1985c30b 147 if ( $ENV{CATALYST_DEBUG} || $ENV{ uc($caller) . '_DEBUG' } ) {
148 no strict 'refs';
149 *{"$caller\::debug"} = sub { 1 };
150 $caller->log->debug('Debug messages enabled');
151 }
152
424b2705 153 my $engine = 'Catalyst::Engine::CGI';
154 my $dispatcher = 'Catalyst::Dispatcher';
6dc87a0f 155
99fe1710 156 # Detect mod_perl
6dc87a0f 157 if ( $ENV{MOD_PERL} ) {
158
159 require mod_perl;
160
ceb7ed54 161 if ( $ENV{MOD_PERL_API_VERSION} == 2 ) {
300aea89 162 $engine = 'Catalyst::Engine::Apache::MP20';
163 }
164 elsif ( $mod_perl::VERSION >= 1.99 ) {
111728e3 165 $engine = 'Catalyst::Engine::Apache::MP19';
6dc87a0f 166 }
167 else {
111728e3 168 $engine = 'Catalyst::Engine::Apache::MP13';
6dc87a0f 169 }
170 }
1985c30b 171
300aea89 172 $caller->log->info( "You are running an old helper script! "
173 . "Please update your scripts by regenerating the "
174 . "application and copying over the new scripts." )
175 if ( $ENV{CATALYST_SCRIPT_GEN}
87232381 176 && ( $ENV{CATALYST_SCRIPT_GEN} < $CATALYST_SCRIPT_GEN ) );
300aea89 177
99fe1710 178 # Process options
937fcdd8 179 my @plugins;
fc7ec1d9 180 foreach (@options) {
99fe1710 181
fc7ec1d9 182 if (/^\-Debug$/) {
1985c30b 183 next if $caller->debug;
fc7ec1d9 184 no strict 'refs';
1c99e125 185 *{"$caller\::debug"} = sub { 1 };
fc7ec1d9 186 $caller->log->debug('Debug messages enabled');
187 }
99fe1710 188
424b2705 189 elsif (/^-Dispatcher=(.*)$/) {
190 $dispatcher = "Catalyst::Dispatcher::$1";
191 }
99fe1710 192
fc7ec1d9 193 elsif (/^-Engine=(.*)$/) { $engine = "Catalyst::Engine::$1" }
194 elsif (/^-.*$/) { $caller->log->error(qq/Unknown flag "$_"/) }
99fe1710 195
fc7ec1d9 196 else {
197 my $plugin = "Catalyst::Plugin::$_";
198
c4695f3a 199 $plugin->require;
91dc9907 200
f88238ea 201 if ($@) { die qq/Couldn't load plugin "$plugin", "$@"/ }
fc7ec1d9 202 else {
f5f84847 203 push @plugins, $plugin;
502619e5 204 no strict 'refs';
205 push @{"$caller\::ISA"}, $plugin;
fc7ec1d9 206 }
207 }
99fe1710 208
fc7ec1d9 209 }
99fe1710 210
211 # Plugin table
d2d570d4 212 my $t = Text::ASCIITable->new( { hide_HeadRow => 1, hide_HeadLine => 1 } );
0f7ecc53 213 $t->setCols('Class');
0822f9a4 214 $t->setColWidth( 'Class', 75, 1 );
cd677e12 215 $t->addRow($_) for @plugins;
0f7ecc53 216 $caller->log->debug( 'Loaded plugins', $t->draw )
937fcdd8 217 if ( @plugins && $caller->debug );
fc7ec1d9 218
424b2705 219 # Dispatcher
220 $dispatcher = "Catalyst::Dispatcher::$ENV{CATALYST_DISPATCHER}"
221 if $ENV{CATALYST_DISPATCHER};
367d15f8 222 my $appdis = $ENV{ uc($caller) . '_DISPATCHER' };
223 $dispatcher = "Catalyst::Dispatcher::$appdis" if $appdis;
424b2705 224
225 $dispatcher->require;
226 die qq/Couldn't load dispatcher "$dispatcher", "$@"/ if $@;
227 {
228 no strict 'refs';
229 push @{"$caller\::ISA"}, $dispatcher;
230 }
231 $caller->dispatcher($dispatcher);
232 $caller->log->debug(qq/Loaded dispatcher "$dispatcher"/) if $caller->debug;
233
e8bf1b2d 234 # Engine
235 $engine = "Catalyst::Engine::$ENV{CATALYST_ENGINE}"
236 if $ENV{CATALYST_ENGINE};
367d15f8 237 my $appeng = $ENV{ uc($caller) . '_ENGINE' };
238 $engine = "Catalyst::Engine::$appeng" if $appeng;
e8bf1b2d 239
240 $engine->require;
241 die qq/Couldn't load engine "$engine", "$@"/ if $@;
242 {
243 no strict 'refs';
244 push @{"$caller\::ISA"}, $engine;
245 }
246 $caller->engine($engine);
247 $caller->log->debug(qq/Loaded engine "$engine"/) if $caller->debug;
4f6748f1 248
249 # Find home
812a28c9 250 my $home = Catalyst::Utils::home($caller);
4f6748f1 251 if ( $caller->debug ) {
252 $home
253 ? ( -d $home )
254 ? $caller->log->debug(qq/Found home "$home"/)
255 : $caller->log->debug(qq/Home "$home" doesn't exist/)
256 : $caller->log->debug(q/Couldn't find home/);
257 }
75aeff23 258 $caller->config->{home} = $home || '';
259 $caller->config->{root} = defined $home ? dir($home)->subdir('root') : '';
fc7ec1d9 260}
261
70cb38f0 262=item $c->engine
263
264Contains the engine class.
265
145074c2 266=item $c->log
267
268Contains the logging object. Unless it is already set Catalyst sets this up with a
269C<Catalyst::Log> object. To use your own log class:
270
271 $c->log( MyLogger->new );
272 $c->log->info("now logging with my own logger!");
273
274Your log class should implement the methods described in the C<Catalyst::Log>
275man page.
276
87232381 277=item $c->plugin( $name, $class, @args )
278
279Instant plugins for Catalyst.
280Classdata accessor/mutator will be created, class loaded and instantiated.
281
282 MyApp->plugin( 'prototype', 'HTML::Prototype' );
283
284 $c->prototype->define_javascript_functions;
285
286=cut
287
288sub plugin {
289 my ( $class, $name, $plugin, @args ) = @_;
290 $plugin->require;
291 my $error = $UNIVERSAL::require::ERROR;
292 die qq/Couldn't load instant plugin "$plugin", "$error"/ if $error;
293 eval { $plugin->import };
294 $class->mk_classdata($name);
295 my $obj;
296 eval { $obj = $plugin->new(@args) };
297 die qq/Couldn't instantiate instant plugin "$plugin", "$@"/ if $@;
298 $class->$name($obj);
299 $class->log->debug(qq/Initialized instant plugin "$plugin" as "$name"/)
300 if $class->debug;
301}
145074c2 302
23f9d934 303=back
304
d1a31ac6 305=head1 LIMITATIONS
306
b2b7d352 307mod_perl2 support is considered experimental and may contain bugs.
d1a31ac6 308
3cb1db8c 309=head1 SUPPORT
310
311IRC:
312
313 Join #catalyst on irc.perl.org.
314
315Mailing-Lists:
316
317 http://lists.rawmode.org/mailman/listinfo/catalyst
318 http://lists.rawmode.org/mailman/listinfo/catalyst-dev
1985c30b 319
432d507d 320Web:
321
322 http://catalyst.perl.org
323
fc7ec1d9 324=head1 SEE ALSO
325
61b1e958 326=over 4
327
328=item L<Catalyst::Manual> - The Catalyst Manual
329
330=item L<Catalyst::Engine> - Core Engine
331
332=item L<Catalyst::Log> - The Log Class.
333
334=item L<Catalyst::Request> - The Request Object
335
336=item L<Catalyst::Response> - The Response Object
337
338=item L<Catalyst::Test> - The test suite.
339
340=back
fc7ec1d9 341
342=head1 AUTHOR
343
344Sebastian Riedel, C<sri@oook.de>
345
346=head1 THANK YOU
347
84cf74e7 348Andy Grundman, Andrew Ford, Andrew Ruthven, Autrijus Tang, Christian Hansen,
ce2b098c 349Christopher Hicks, Dan Sully, Danijel Milicevic, David Naughton,
75aeff23 350Gary Ashton Jones, Geoff Richards, Jesse Sheidlower, Jody Belka,
351Johan Lindstrom, Leon Brocard, Marcus Ramberg, Tatsuhiko Miyagawa
352and all the others who've helped.
fc7ec1d9 353
354=head1 LICENSE
355
356This library is free software . You can redistribute it and/or modify it under
357the same terms as perl itself.
358
359=cut
360
3611;