fixed absolute forward in root and cleaned tables
[catagits/Catalyst-Runtime.git] / lib / Catalyst.pm
1 package Catalyst;
2
3 use strict;
4 use base 'Catalyst::Base';
5 use UNIVERSAL::require;
6 use Catalyst::Log;
7 use Text::ASCIITable;
8
9 __PACKAGE__->mk_classdata($_) for qw/dispatcher engine log/;
10
11 our $VERSION = '5.00';
12 our @ISA;
13
14 =head1 NAME
15
16 Catalyst - The Elegant MVC Web Application Framework
17
18 =head1 SYNOPSIS
19
20     # use the helper to start a new application
21     catalyst.pl MyApp
22     cd MyApp
23
24     # add models, views, controllers
25     script/create.pl model Something
26     script/create.pl view Stuff
27     script/create.pl controller Yada
28
29     # built in testserver
30     script/server.pl
31
32     # command line interface
33     script/test.pl /yada
34
35
36     use Catalyst;
37
38     use Catalyst qw/My::Module My::OtherModule/;
39
40     use Catalyst '-Debug';
41
42     use Catalyst qw/-Debug -Engine=CGI/;
43
44     sub default : Private { $_[1]->res->output('Hello') } );
45
46     sub index : Path('/index.html') {
47         my ( $self, $c ) = @_;
48         $c->res->output('Hello');
49         $c->forward('_foo');
50     }
51
52     sub product : Regex('/^product[_]*(\d*).html$/') {
53         my ( $self, $c ) = @_;
54         $c->stash->{template} = 'product.tt';
55         $c->stash->{product} = $c->req->snippets->[0];
56     }
57
58 See also L<Catalyst::Manual::Intro>
59
60 =head1 DESCRIPTION
61
62 Catalyst is based upon L<Maypole>, which you should consider for smaller
63 projects.
64
65 The key concept of Catalyst is DRY (Don't Repeat Yourself).
66
67 See L<Catalyst::Manual> for more documentation.
68
69 Catalyst plugins can be loaded by naming them as arguments to the "use Catalyst" statement.
70 Omit the C<Catalyst::Plugin::> prefix from the plugin name,
71 so C<Catalyst::Plugin::My::Module> becomes C<My::Module>.
72
73     use Catalyst 'My::Module';
74
75 Special flags like -Debug and -Engine can also be specifed as arguments when
76 Catalyst is loaded:
77
78     use Catalyst qw/-Debug My::Module/;
79
80 The position of plugins and flags in the chain is important, because they are
81 loaded in exactly the order that they appear.
82
83 The following flags are supported:
84
85 =over 4
86
87 =item -Debug
88
89 enables debug output, i.e.:
90
91     use Catalyst '-Debug';
92
93 this is equivalent to:
94
95     use Catalyst;
96     sub debug { 1 }
97
98 =item -Engine
99
100 Force Catalyst to use a specific engine.
101 Omit the C<Catalyst::Engine::> prefix of the engine name, i.e.:
102
103     use Catalyst '-Engine=CGI';
104
105 =back
106
107 =head1 METHODS
108
109 =over 4
110
111 =item debug
112
113 Overload to enable debug messages.
114
115 =cut
116
117 sub debug { 0 }
118
119 =item config
120
121 Returns a hashref containing your applications settings.
122
123 =cut
124
125 sub import {
126     my ( $self, @options ) = @_;
127     my $caller = caller(0);
128
129     unless ( $caller->isa($self) ) {
130         no strict 'refs';
131         push @{"$caller\::ISA"}, $self;
132     }
133
134     if ( $caller->engine ) {
135         return;    # Catalyst is allready initialized
136     }
137
138     unless ( $caller->log ) {
139         $caller->log( Catalyst::Log->new );
140     }
141
142     if ( $ENV{CATALYST_DEBUG} || $ENV{ uc($caller) . '_DEBUG' } ) {
143         no strict 'refs';
144         *{"$caller\::debug"} = sub { 1 };
145         $caller->log->debug('Debug messages enabled');
146     }
147
148     my $engine     = 'Catalyst::Engine::CGI';
149     my $dispatcher = 'Catalyst::Dispatcher';
150
151     if ( $ENV{MOD_PERL} ) {
152
153         require mod_perl;
154
155         if ( $mod_perl::VERSION >= 1.99 ) {
156             $engine = 'Catalyst::Engine::Apache::MP2';
157         }
158         else {
159             $engine = 'Catalyst::Engine::Apache::MP1';
160         }
161     }
162
163     my @plugins;
164     foreach (@options) {
165         if (/^\-Debug$/) {
166             next if $caller->debug;
167             no strict 'refs';
168             *{"$caller\::debug"} = sub { 1 };
169             $caller->log->debug('Debug messages enabled');
170         }
171         elsif (/^-Dispatcher=(.*)$/) {
172             $dispatcher = "Catalyst::Dispatcher::$1";
173         }
174         elsif (/^-Engine=(.*)$/) { $engine = "Catalyst::Engine::$1" }
175         elsif (/^-.*$/) { $caller->log->error(qq/Unknown flag "$_"/) }
176         else {
177             my $plugin = "Catalyst::Plugin::$_";
178
179             $plugin->require;
180
181             if ($@) {
182                 $caller->log->error(qq/Couldn't load plugin "$plugin", "$@"/);
183             }
184             else {
185                 push @plugins, $plugin;
186                 no strict 'refs';
187                 push @{"$caller\::ISA"}, $plugin;
188             }
189         }
190     }
191     my $t = Text::ASCIITable->new( { hide_HeadRow => 1, hide_HeadLine => 1 } );
192     $t->setCols('Class');
193     $t->setColWidth( 'Class', 75, 1 );
194     $t->addRow($_) for @plugins;
195     $caller->log->debug( 'Loaded plugins', $t->draw )
196       if ( @plugins && $caller->debug );
197
198     # Engine
199     $engine = "Catalyst::Engine::$ENV{CATALYST_ENGINE}"
200       if $ENV{CATALYST_ENGINE};
201
202     $engine->require;
203     die qq/Couldn't load engine "$engine", "$@"/ if $@;
204     {
205         no strict 'refs';
206         push @{"$caller\::ISA"}, $engine;
207     }
208     $caller->engine($engine);
209     $caller->log->debug(qq/Loaded engine "$engine"/) if $caller->debug;
210
211     # Dispatcher
212     $dispatcher = "Catalyst::Dispatcher::$ENV{CATALYST_DISPATCHER}"
213       if $ENV{CATALYST_DISPATCHER};
214
215     $dispatcher->require;
216     die qq/Couldn't load dispatcher "$dispatcher", "$@"/ if $@;
217     {
218         no strict 'refs';
219         push @{"$caller\::ISA"}, $dispatcher;
220     }
221     $caller->dispatcher($dispatcher);
222     $caller->log->debug(qq/Loaded dispatcher "$dispatcher"/) if $caller->debug;
223
224 }
225
226 =item $c->engine
227
228 Contains the engine class.
229
230 =item $c->log
231
232 Contains the logging object.  Unless it is already set Catalyst sets this up with a
233 C<Catalyst::Log> object.  To use your own log class:
234
235     $c->log( MyLogger->new );
236     $c->log->info("now logging with my own logger!");
237
238 Your log class should implement the methods described in the C<Catalyst::Log>
239 man page.
240
241
242 =back
243
244 =head1 SUPPORT
245
246 IRC:
247
248     Join #catalyst on irc.perl.org.
249
250 Mailing-Lists:
251
252     http://lists.rawmode.org/mailman/listinfo/catalyst
253     http://lists.rawmode.org/mailman/listinfo/catalyst-dev
254
255 =head1 SEE ALSO
256
257 =over 4
258
259 =item L<Catalyst::Manual> - The Catalyst Manual
260
261 =item L<Catalyst::Engine> - Core Engine
262
263 =item L<Catalyst::Log> - The Log Class.
264
265 =item L<Catalyst::Request> - The Request Object
266
267 =item L<Catalyst::Response> - The Response Object
268
269 =item L<Catalyst::Test> - The test suite.
270
271 =back
272
273 =head1 AUTHOR
274
275 Sebastian Riedel, C<sri@oook.de>
276
277 =head1 THANK YOU
278
279 Andrew Ford, Andrew Ruthven, Christian Hansen, Christopher Hicks,
280 Dan Sully, Danijel Milicevic, David Naughton, Gary Ashton Jones,
281 Jesse Sheidlower, Johan Lindstrom, Marcus Ramberg, Tatsuhiko Miyagawa
282 and all the others who've helped.
283
284 =head1 LICENSE
285
286 This library is free software . You can redistribute it and/or modify it under
287 the same terms as perl itself.
288
289 =cut
290
291 1;