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