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