e7cc9a943d40e60e893142cf5526ad559225f87e
[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     # Prepare inheritance
130     unless ( $caller->isa($self) ) {
131         no strict 'refs';
132         push @{"$caller\::ISA"}, $self;
133     }
134
135     if ( $caller->engine ) {
136         return;    # Catalyst is allready initialized
137     }
138
139     unless ( $caller->log ) {
140         $caller->log( Catalyst::Log->new );
141     }
142
143     # Debug?
144     if ( $ENV{CATALYST_DEBUG} || $ENV{ uc($caller) . '_DEBUG' } ) {
145         no strict 'refs';
146         *{"$caller\::debug"} = sub { 1 };
147         $caller->log->debug('Debug messages enabled');
148     }
149
150     my $engine     = 'Catalyst::Engine::CGI';
151     my $dispatcher = 'Catalyst::Dispatcher';
152
153     # Detect mod_perl
154     if ( $ENV{MOD_PERL} ) {
155
156         require mod_perl;
157
158         if ( $mod_perl::VERSION >= 1.99 ) {
159             $engine = 'Catalyst::Engine::Apache::MP19';
160         }
161         else {
162             $engine = 'Catalyst::Engine::Apache::MP13';
163         }
164     }
165
166     # Process options
167     my @plugins;
168     foreach (@options) {
169
170         if (/^\-Debug$/) {
171             next if $caller->debug;
172             no strict 'refs';
173             *{"$caller\::debug"} = sub { 1 };
174             $caller->log->debug('Debug messages enabled');
175         }
176
177         elsif (/^-Dispatcher=(.*)$/) {
178             $dispatcher = "Catalyst::Dispatcher::$1";
179         }
180
181         elsif (/^-Engine=(.*)$/) { $engine = "Catalyst::Engine::$1" }
182         elsif (/^-.*$/) { $caller->log->error(qq/Unknown flag "$_"/) }
183
184         else {
185             my $plugin = "Catalyst::Plugin::$_";
186
187             $plugin->require;
188
189             if ($@) { die qq/Couldn't load plugin "$plugin", "$@"/ }
190             else {
191                 push @plugins, $plugin;
192                 no strict 'refs';
193                 push @{"$caller\::ISA"}, $plugin;
194             }
195         }
196
197     }
198
199     # Plugin table
200     my $t = Text::ASCIITable->new( { hide_HeadRow => 1, hide_HeadLine => 1 } );
201     $t->setCols('Class');
202     $t->setColWidth( 'Class', 75, 1 );
203     $t->addRow($_) for @plugins;
204     $caller->log->debug( 'Loaded plugins', $t->draw )
205       if ( @plugins && $caller->debug );
206
207     # Engine
208     $engine = "Catalyst::Engine::$ENV{CATALYST_ENGINE}"
209       if $ENV{CATALYST_ENGINE};
210
211     $engine->require;
212     die qq/Couldn't load engine "$engine", "$@"/ if $@;
213     {
214         no strict 'refs';
215         push @{"$caller\::ISA"}, $engine;
216     }
217     $caller->engine($engine);
218     $caller->log->debug(qq/Loaded engine "$engine"/) if $caller->debug;
219
220     # Dispatcher
221     $dispatcher = "Catalyst::Dispatcher::$ENV{CATALYST_DISPATCHER}"
222       if $ENV{CATALYST_DISPATCHER};
223
224     $dispatcher->require;
225     die qq/Couldn't load dispatcher "$dispatcher", "$@"/ if $@;
226     {
227         no strict 'refs';
228         push @{"$caller\::ISA"}, $dispatcher;
229     }
230     $caller->dispatcher($dispatcher);
231     $caller->log->debug(qq/Loaded dispatcher "$dispatcher"/) if $caller->debug;
232
233 }
234
235 =item $c->engine
236
237 Contains the engine class.
238
239 =item $c->log
240
241 Contains the logging object.  Unless it is already set Catalyst sets this up with a
242 C<Catalyst::Log> object.  To use your own log class:
243
244     $c->log( MyLogger->new );
245     $c->log->info("now logging with my own logger!");
246
247 Your log class should implement the methods described in the C<Catalyst::Log>
248 man page.
249
250
251 =back
252
253 =head1 LIMITATIONS
254
255 FCGI and mod_perl2 support are considered experimental and may contain bugs.
256
257 You may encounter problems accessing the built in test server on public ip
258 addresses on the internet, thats because of a bug in HTTP::Daemon.
259
260 =head1 SUPPORT
261
262 IRC:
263
264     Join #catalyst on irc.perl.org.
265
266 Mailing-Lists:
267
268     http://lists.rawmode.org/mailman/listinfo/catalyst
269     http://lists.rawmode.org/mailman/listinfo/catalyst-dev
270
271 =head1 SEE ALSO
272
273 =over 4
274
275 =item L<Catalyst::Manual> - The Catalyst Manual
276
277 =item L<Catalyst::Engine> - Core Engine
278
279 =item L<Catalyst::Log> - The Log Class.
280
281 =item L<Catalyst::Request> - The Request Object
282
283 =item L<Catalyst::Response> - The Response Object
284
285 =item L<Catalyst::Test> - The test suite.
286
287 =back
288
289 =head1 AUTHOR
290
291 Sebastian Riedel, C<sri@oook.de>
292
293 =head1 THANK YOU
294
295 Andrew Ford, Andrew Ruthven, Christian Hansen, Christopher Hicks,
296 Dan Sully, Danijel Milicevic, David Naughton, Gary Ashton Jones,
297 Jesse Sheidlower, Johan Lindstrom, Marcus Ramberg, Tatsuhiko Miyagawa
298 and all the others who've helped.
299
300 =head1 LICENSE
301
302 This library is free software . You can redistribute it and/or modify it under
303 the same terms as perl itself.
304
305 =cut
306
307 1;