Moved from Bundle:: to Task::
[catagits/Catalyst-Runtime.git] / lib / Catalyst / Manual / Tutorial.pod
1 =head1 NAME
2
3 Catalyst::Manual::Tutorial - Getting started with Catalyst
4
5 =head1 DESCRIPTION
6
7 This document aims to get you up and running with Catalyst.
8
9 NOTE: THIS DOCUMENT IS STILL VERY MUCH IN AN EARLY DRAFT STATE.  SEE 
10 THE NOTES AT THE BOTTOM OF THE DOCUMENT.
11
12 =head2 Installation
13
14 The first step is to install Catalyst, and the simplest way to do this 
15 is to install the Catalyst bundle from CPAN:
16
17     $ perl -MCPAN -e 'install Task::Catalyst'
18
19 This will retrieve Catalyst and a number of useful extensions and 
20 install them for you.
21
22
23 =head2 Setting up your application
24
25 Catalyst includes a helper script, C<catalyst.pl>, that will set up a 
26 skeleton application for you:
27
28     $ catalyst MyApp
29     
30     created "MyApp"
31     created "MyApp/script"
32     created "MyApp/lib"
33     created "MyApp/root"
34     created "MyApp/root/static"
35     created "MyApp/root/static/images"
36     created "MyApp/t"
37     created "MyApp/t/Model"
38     created "MyApp/t/View"
39     created "MyApp/t/Controller"
40     created "MyApp/lib/MyApp"
41     created "MyApp/lib/MyApp/Model"
42     created "MyApp/lib/MyApp/View"
43     created "MyApp/lib/MyApp/Controller"
44     created "MyApp/lib/MyApp.pm"
45     created "MyApp/Build.PL"
46     created "MyApp/Makefile.PL"
47     created "MyApp/README"
48     created "MyApp/Changes"
49     created "MyApp/t/01app.t"
50     created "MyApp/t/02pod.t"
51     created "MyApp/t/03podcoverage.t"
52     created "MyApp/root/static/images/catalyst_logo.png"
53     created "MyApp/root/static/images/btn_120x50_built.png"
54     created "MyApp/root/static/images/btn_120x50_built_shadow.png"
55     created "MyApp/root/static/images/btn_120x50_powered.png"
56     created "MyApp/root/static/images/btn_120x50_powered_shadow.png"
57     created "MyApp/root/static/images/btn_88x31_built.png"
58     created "MyApp/root/static/images/btn_88x31_built_shadow.png"
59     created "MyApp/root/static/images/btn_88x31_powered.png"
60     created "MyApp/root/static/images/btn_88x31_powered_shadow.png"
61     created "MyApp/root/favicon.ico"
62     created "MyApp/script/myapp_cgi.pl"
63     created "MyApp/script/myapp_fastcgi.pl"
64     created "MyApp/script/myapp_server.pl"
65     created "MyApp/script/myapp_test.pl"
66     created "MyApp/script/myapp_create.pl"
67
68 This creates the directory structure shown, populated with skeleton 
69 files.
70
71 =head2 Testing out the sample application
72
73 You can test out your new application by running the server script that
74 Catalyst provides:
75
76     $ cd MyApp
77     $ script/myapp_server.pl 
78
79     [...] [catalyst] [debug] Debug messages enabled
80     [...] [catalyst] [debug] Loaded plugins:
81     .------------------------------------------------------------------------------.
82     | Catalyst::Plugin::Static::Simple                                             |
83     '------------------------------------------------------------------------------'
84     [...] [catalyst] [debug] Loaded dispatcher "Catalyst::Dispatcher"
85     [...] [catalyst] [debug] Loaded engine "Catalyst::Engine::HTTP"
86     [...] [catalyst] [debug] Found home "/home/users/me/MyApp"
87     [...] [catalyst] [debug] Loaded Private actions:
88     .--------------------------------------+---------------------------------------.
89     | Private                              | Class                                 |
90     +--------------------------------------+---------------------------------------+
91     | /default                             | MyApp                                 |
92     '--------------------------------------+---------------------------------------'
93     
94     [...] [catalyst] [info] MyApp powered by Catalyst 5.5
95     You can connect to your server at http://localhost:3000
96
97 (Note that each line logged by Catalyst begins with a timestamp, which has
98 been replaced here with "C<...>" so that the text fits onto the lines.)
99
100 The server is now waiting for you to make requests of it.  Try using 
101 telnet to manually make a simple GET request of the server (when 
102 telnet responds with "Escape character is '^]'.", type "GET / HTTP/1.0"
103 and hit return twice):
104
105     $ telnet localhost 3000
106     Trying 127.0.0.1...
107     Connected to localhost.
108     Escape character is '^]'.
109     GET / HTTP/1.0
110     
111     HTTP/1.0 200 OK
112     Date: Mon, 07 Nov 2005 14:57:39 GMT
113     Content-Length: 5525
114     Content-Type: text/html; charset=utf-8
115     Status: 200
116     X-Catalyst: 5.5
117
118     [...]
119     Connection closed by foreign host.
120     $
121
122 You can see the full welcome message by visting
123 http://localhost:3000/ with your browser.
124
125 More trace messages will appear in the original terminal window:
126
127     [...] [catalyst] [debug] **********************************
128     [...] [catalyst] [debug] * Request 1 (0.063/s) [2148]
129     [...] [catalyst] [debug] **********************************
130     [...] [catalyst] [debug] Arguments are ""
131     [...] [catalyst] [debug] "GET" request for "" from localhost
132     [...] [catalyst] [info] Request took 0.046883s (21.330/s)
133     .------------------------------------------------------------------+-----------.
134     | Action                                                           | Time      |
135     +------------------------------------------------------------------+-----------+
136     | /default                                                         | 0.000000s |
137     '------------------------------------------------------------------+-----------'
138
139 The server will continue running until you interrupt it.
140
141 The application can also be tested from the command line using the generated
142 helper script, C<script/myapp_test.pl>.
143
144 =head2 Getting your application invoked
145
146 Catalyst applications are usually run from mod_perl, but can also be
147 run as CGI or FastCGI scripts.  Running under mod_perl gives better 
148 performance, but for development purposes you may want to run your 
149 application as a CGI script, especially as changes to your application 
150 code take effect under CGI without having to restart the web server.
151
152 To run from mod_perl you need to add something like this to your Apache
153 configuration file:
154
155     <Location /MyApp>
156         SetHandler  perl-script
157         PerlHandler MyApp
158     </Location>
159
160 To run as a CGI script you need a wrapper script like:
161
162     #!/usr/bin/perl -w
163     
164     use strict;
165     use lib '/path/to/MyApp/lib';
166     use MyApp;
167     
168     MyApp->run;
169
170 =head2 Examining the generated code
171
172 The generated application code is quite simple and looks something 
173 like this (comments removed):
174
175     package MyApp;
176     
177     use strict;
178     use warnings;
179     
180     use Catalyst qw/-Debug Static::Simple/;
181     
182     our $VERSION = '0.01';
183     
184     __PACKAGE__->config( name => 'MyApp' );
185     __PACKAGE__->setup;
186     
187     sub default : Private {
188         my ( $self, $c ) = @_;
189     
190         $c->response->body( $c->welcome_message );
191     }
192     
193     1;
194
195 When the C<Catalyst> module is imported by the application code, 
196 Catalyst performs the first stage of its initialization.  This includes
197 loading the appropriate Engine module for the environment in which the 
198 application is running, loading any plugins and ensuring that the 
199 calling module (the application module) inherits from C<Catalyst> 
200 (which makes the Catalyst methods C<config> and C<setup> available to 
201 the application module).
202
203 The call to C<config> sets up configuration data for the application.  
204 The C<name> parameter is the only required configuration parameter.
205 You may also specificy a C<root> parameter, which is the path to the
206 directory where documents, images, and templates can be found.
207
208 Catalyst associates I<actions> with URLs and on receiving a request 
209 dispatches to the action that matches to request URL.  The call to 
210 C<setup> in the code above registers a default action.  With just 
211 this action registered the application will respond to all requests 
212 with the same welcome page.
213
214 As you see, the default action is defined as a Private action. 
215 Most private actions are not directly available from a web url. This
216 also includes the built-in actions, 'default', 'begin', 'end', and
217 'auto', although they will be called as part of some chains.  
218 The rest can only be reached by using C<forward>.
219
220 The call to the C<setup> method also triggers the second stage of 
221 Catalyst's initialization process.  In this phase Catalyst searches 
222 for any component modules, locating and registering any actions it 
223 finds in those modules.
224
225 Component modules have names prefixed with the application module name,
226 followed by C<Model>, C<View> or C<Controller> (or the optional short
227 forms: C<M>, C<V> or C<C>) followed by the component
228 name, for example:
229
230     MyApp::Controller::ShoppingCart  # long (default) version
231     MyApp::C::ShoppingCart           # short version 
232
233     MyApp::Model::User               # long (default) version
234     MyApp::M::User                   # short version
235
236 =head2 Extending the generated code
237
238 You can start extending the application by adding new actions:
239
240     sub test1 : Global {
241         my ( $self, $c ) = @_;
242         $c->res->body('In a new test action #1');
243     }
244     sub default : Private {
245         my ( $self, $c ) = @_;
246         $c->res->body('Congratulations, MyApp is on Catalyst!');
247     }
248
249     # called like '/article/2005/06'
250     sub archive_month : Regex('^article/(\d{4})/(\d{2})$') {
251         my ( $self, $c ) = @_;
252
253         my $datetime = DateTime->new(
254             year  => $c->request->snippets->[0],
255             month => $c->request->snippets->[1]
256         );
257     }
258
259 TODO: explain briefly about plugins, actions, and components
260
261 If the action is a Regex type, you can use capturing parentheses to
262 extract values within the matching URL (2005, 06 in the above
263 example). Those values are available in the $c->req->snippets
264 anonymous array. See L<Catalyst::Manual::Intro#Actions> for details.
265
266 =head2 Hooking in to Template Toolkit
267
268 One of the first things you will probably want to add to your 
269 application is a templating system for generating your output.  
270 Catalyst works well with Template Toolkit.  If you are unfamiliar with 
271 Template Toolkit then I suggest you look at L<http://tt2.org>, install 
272 C<Template>, read the documentation and play around with it, and have 
273 a look at the I<Badger Book> (I<Template Toolkit> by Darren 
274 Chamberlain, Dave Cross, and Andy Wardley, O'Reilly & Associates, 2004).
275
276 You can create a stub Template Toolkit view component by installing
277 L<Catalyst::View::TT> and using the create script that Catalyst set
278 up as part of the skeleton application:
279
280     $ script/myapp_create.pl view TT TT
281     
282      exists "MyApp/lib/MyApp/View"
283      exists "MyApp/t/View"
284     created "MyApp/lib/MyApp/View/TT.pm"
285     created "MyApp/t/View/TT.t"
286
287 this generates a view component named C<MyApp::View::TT>, which you 
288 might use by forwarding from your C<end> action:
289
290     # In MyApp or MyApp::Controller::SomeController
291
292     sub end : Private {
293         my($self, $c) = @_;
294         $c->forward('MyApp::V::TT');
295     }
296
297 The generated TT view component simply subclasses the 
298 C<Catalyst::View::TT> class.  It looks like this (with the POD 
299 stripped out): 
300
301     package My::App::V::TT;
302
303     use strict;
304     use base 'Catalyst::View::TT';
305
306     1;
307
308 C<Catalyst::View::TT> initializes a Template Toolkit object with an 
309 options hash initialized with built-in default settings followed by 
310 the contents of the hash C<<%{__PACKAGE__->config()}>>.  You can
311 configure TT more to your needs by adding a C<new> method to the 
312 generated TT component:
313
314     sub new {
315         my $self = shift;
316         $self->config->{PRE_PROCESS} = 'config/main';
317         $self->config->{WRAPPER}     = 'site/wrapper';
318         return $self->SUPER::new(@_);
319     }
320
321 =head1 AUTHOR
322
323 Andrew Ford, C<A.Ford@ford-mason.co.uk>
324 Marcus Ramberg, C<mramberg@cpan.org>
325
326 As noted above, this document is at an alpha stage.  My plan for this 
327 document is as follows:
328
329 =over 4
330
331 =item 1
332
333 Expand this document fairly rapidly to cover topics relevant to
334 a newcomer to Catalyst, in an order that can be read sequentially
335
336 =item 2
337
338 Incorporate feedback 
339
340 =item 3
341
342 Revise the text 
343
344 =back
345
346 Placeholders are indicated by the words: TODO or CHECK 
347
348 Please send comments, corrections and suggestions for improvements to
349 A.Ford@ford-mason.co.uk
350
351 =head1 COPYRIGHT
352
353 This program is free software, you can redistribute it and/or modify 
354 it under the same terms as Perl itself.