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