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