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