Commit | Line | Data |
fc7ec1d9 |
1 | =head1 NAME |
2 | |
3 | Catalyst::Manual::Intro - Introduction to Catalyst |
4 | |
5 | =head1 DESCRIPTION |
6 | |
129cfe74 |
7 | This is a brief overview of why and how to use Catalyst. It explains how |
e178a66a |
8 | Catalyst works and shows how to get a simple application up and running |
9 | quickly. |
fc7ec1d9 |
10 | |
11 | =head2 What is Catalyst? |
12 | |
129cfe74 |
13 | Catalyst is an elegant web application framework, extremely flexible yet |
e178a66a |
14 | extremely simple. It's similar to Ruby on Rails, Spring (Java) and |
15 | L<Maypole>, upon which it was originally based. |
fc7ec1d9 |
16 | |
17 | =head3 MVC |
18 | |
e178a66a |
19 | Catalyst follows the Model-View-Controller (MVC) design pattern, |
20 | allowing you to easily separate concerns, like content, presentation, |
21 | and flow control, into separate modules. This separation allows you to |
22 | modify code that handles one concern without affecting code that handles |
23 | the others. Catalyst promotes the re-use of existing Perl modules that |
24 | already handle common web application concerns well. |
fc7ec1d9 |
25 | |
e178a66a |
26 | Here's how the M, V, and C map to those concerns, with examples of |
27 | well-known Perl modules you may want to use for each. |
fc7ec1d9 |
28 | |
29 | =over 4 |
30 | |
4a6895ce |
31 | =item * B<Model> |
fc7ec1d9 |
32 | |
33 | Access and modify content (data). L<Class::DBI>, L<Plucene>, L<Net::LDAP>... |
34 | |
4a6895ce |
35 | =item * B<View> |
fc7ec1d9 |
36 | |
e178a66a |
37 | Present content to the user. L<Template Toolkit|Template>, |
38 | L<Mason|HTML::Mason>, L<HTML::Template>... |
fc7ec1d9 |
39 | |
4a6895ce |
40 | =item * B<Controller> |
fc7ec1d9 |
41 | |
129cfe74 |
42 | Control the whole request phase, check parameters, dispatch actions, flow |
43 | control. Catalyst! |
fc7ec1d9 |
44 | |
45 | =back |
46 | |
26e73131 |
47 | If you're unfamiliar with MVC and design patterns, you may want to check |
48 | out the original book on the subject, I<Design Patterns>, by Gamma, |
49 | Helm, Johnson, and Vlissides, also known as the Gang of Four (GoF). You |
50 | can also just Google it. Many, many web application frameworks are |
51 | based on MVC, including all those listed above. |
fc7ec1d9 |
52 | |
53 | =head3 Flexibility |
54 | |
e178a66a |
55 | Catalyst is much more flexible than many other frameworks. We'll talk |
56 | more about this later, but rest assured you can use your favorite Perl |
57 | modules with Catalyst. |
fc7ec1d9 |
58 | |
59 | =over 4 |
60 | |
72d9bfc7 |
61 | =item * B<Multiple Models, Views, and Controllers> |
fc7ec1d9 |
62 | |
e178a66a |
63 | To build a Catalyst application, you handle each type of concern inside |
64 | special modules called L</Components>. Often this code will be very |
65 | simple, just calling out to Perl modules like those listed above under |
66 | L</MVC>. Catalyst handles these components in a very flexible way. Use |
67 | as many Models, Views, and Controllers as you like, using as many |
68 | different Perl modules as you like, all in the same application. Want to |
69 | manipulate multiple databases, and retrieve some data via LDAP? No |
70 | problem. Want to present data from the same Model using L<Template |
71 | Toolkit|Template> and L<PDF::Template>? Easy. |
fc7ec1d9 |
72 | |
cda8d1ac |
73 | =item * B<Reuseable Components> |
fc7ec1d9 |
74 | |
e178a66a |
75 | Not only does Catalyst promote the re-use of already existing Perl |
76 | modules, it also allows you to re-use your Catalyst components in |
77 | multiple Catalyst applications. |
fc7ec1d9 |
78 | |
4a6895ce |
79 | =item * B<Unrestrained URL-to-Action Dispatching> |
fc7ec1d9 |
80 | |
e178a66a |
81 | Catalyst allows you to dispatch any URLs to any application L<Actions>, |
82 | even through regular expressions! Unlike most other frameworks, it |
83 | doesn't require mod_rewrite or class and method names in URLs. |
fc7ec1d9 |
84 | |
e178a66a |
85 | With Catalyst you register your actions and address them directly. For |
86 | example: |
fc7ec1d9 |
87 | |
e3dc9d78 |
88 | sub hello : Global { |
fc7ec1d9 |
89 | my ( $self, $context ) = @_; |
66f6e959 |
90 | $context->response->body('Hello World!'); |
5a8ed4fe |
91 | } |
fc7ec1d9 |
92 | |
93 | Now http://localhost:3000/hello prints "Hello World!". |
94 | |
4a6895ce |
95 | =item * B<Support for CGI, mod_perl, Apache::Request> |
fc7ec1d9 |
96 | |
97 | Use L<Catalyst::Engine::Apache> or L<Catalyst::Engine::CGI>. |
98 | |
99 | =back |
100 | |
101 | =head3 Simplicity |
102 | |
e178a66a |
103 | The best part is that Catalyst implements all this flexibility in a very |
104 | simple way. |
fc7ec1d9 |
105 | |
6f4e1683 |
106 | =over 4 |
107 | |
4a6895ce |
108 | =item * B<Building Block Interface> |
fc7ec1d9 |
109 | |
e178a66a |
110 | Components interoperate very smoothly. For example, Catalyst |
111 | automatically makes a L<Context> object available to every |
112 | component. Via the context, you can access the request object, share |
113 | data between components, and control the flow of your |
114 | application. Building a Catalyst application feels a lot like snapping |
129cfe74 |
115 | together toy building blocks, and everything just works. |
fc7ec1d9 |
116 | |
4a6895ce |
117 | =item * B<Component Auto-Discovery> |
fc7ec1d9 |
118 | |
e178a66a |
119 | No need to C<use> all of your components. Catalyst automatically finds |
120 | and loads them. |
fc7ec1d9 |
121 | |
4a6895ce |
122 | =item * B<Pre-Built Components for Popular Modules> |
fc7ec1d9 |
123 | |
e178a66a |
124 | See L<Catalyst::Model::CDBI> for L<Class::DBI>, or L<Catalyst::View::TT> |
125 | for L<Template Toolkit|Template>. |
fc7ec1d9 |
126 | |
72d9bfc7 |
127 | =item * B<Built-in Test Framework> |
fc7ec1d9 |
128 | |
e178a66a |
129 | Catalyst comes with a built-in, lightweight http server and test |
130 | framework, making it easy to test applications from the command line. |
fc7ec1d9 |
131 | |
4a6895ce |
132 | =item * B<Helper Scripts> |
fc7ec1d9 |
133 | |
e178a66a |
134 | Catalyst provides helper scripts to quickly generate running starter |
135 | code for components and unit tests. See L<Catalyst::Helper>. |
fc7ec1d9 |
136 | |
6f4e1683 |
137 | =back |
138 | |
fc7ec1d9 |
139 | =head2 Quickstart |
140 | |
e178a66a |
141 | Here's how to install Catalyst and get a simple application up and |
142 | running, using the helper scripts described above. |
fc7ec1d9 |
143 | |
144 | =head3 Install |
145 | |
146 | $ perl -MCPAN -e 'install Bundle::Catalyst' |
147 | |
148 | =head3 Setup |
149 | |
2feb6632 |
150 | $ catalyst.pl MyApp |
b33ed88c |
151 | # output omitted |
2feb6632 |
152 | $ cd MyApp |
ac4a0ae0 |
153 | $ script/myapp_create.pl controller Library::Login |
fc7ec1d9 |
154 | |
155 | =head3 Run |
156 | |
b33ed88c |
157 | $ script/myapp_server.pl |
fc7ec1d9 |
158 | |
129cfe74 |
159 | Now visit these locations with your favorite browser or user agent to see |
160 | Catalyst in action: |
fc7ec1d9 |
161 | |
162 | =over 4 |
163 | |
164 | =item http://localhost:3000/ |
165 | |
ac4a0ae0 |
166 | =item http://localhost:3000/library/login/ |
fc7ec1d9 |
167 | |
168 | =back |
169 | |
170 | Dead easy! |
171 | |
172 | =head2 How It Works |
173 | |
e178a66a |
174 | Let's see how Catalyst works, by taking a closer look at the components |
175 | and other parts of a Catalyst application. |
fc7ec1d9 |
176 | |
177 | =head3 Application Class |
178 | |
e178a66a |
179 | In addition to the Model, View, and Controller components, there's a |
180 | single class that represents your application itself. This is where you |
181 | configure your application, load plugins, define application-wide |
182 | actions, and extend Catalyst. |
fc7ec1d9 |
183 | |
184 | package MyApp; |
185 | |
186 | use strict; |
187 | use Catalyst qw/-Debug/; |
188 | |
189 | MyApp->config( |
190 | name => 'My Application', |
fc7ec1d9 |
191 | |
b33ed88c |
192 | # You can put anything else you want in here: |
193 | my_configuration_variable => 'something', |
fc7ec1d9 |
194 | ); |
195 | |
5a8ed4fe |
196 | sub default : Private { |
fc7ec1d9 |
197 | my ( $self, $context ) = @_; |
e178a66a |
198 | $context->response->body('Catalyst rocks!'); |
5a8ed4fe |
199 | } |
fc7ec1d9 |
200 | |
201 | 1; |
202 | |
66f6e959 |
203 | For most applications, Catalyst requires you to define only one config |
204 | parameter: |
fc7ec1d9 |
205 | |
206 | =over 4 |
207 | |
4a6895ce |
208 | =item * B<name> |
fc7ec1d9 |
209 | |
210 | Name of your application. |
211 | |
fc7ec1d9 |
212 | =back |
213 | |
e178a66a |
214 | Optionally, you can specify a B<root> parameter for templates and static |
215 | data. If omitted, Catalyst will try to auto-detect the directory's |
216 | location. You can define as many parameters as you want for plugins or |
217 | whatever you need. You can access them anywhere in your application via |
218 | C<$context-E<gt>config-E<gt>{$param_name}>. |
fc7ec1d9 |
219 | |
220 | =head3 Context |
221 | |
e178a66a |
222 | Catalyst automatically blesses a Context object into your application |
223 | class and makes it available everywhere in your application. Use the |
224 | Context to directly interact with Catalyst and glue your L<Components> |
225 | together. For example, if you need to use the Context from within a |
226 | Template Toolkit template, it's already there: |
c42f5bbf |
227 | |
228 | <h1>Welcome to [% c.config.name %]!</h1> |
fc7ec1d9 |
229 | |
e178a66a |
230 | As illustrated in our URL-to-Action dispatching example, the Context is |
231 | always the second method parameter, behind the Component object |
232 | reference or class name itself. Previously we called it C<$context> for |
233 | clarity, but most Catalyst developers just call it C<$c>: |
fc7ec1d9 |
234 | |
e3dc9d78 |
235 | sub hello : Global { |
fc7ec1d9 |
236 | my ( $self, $c ) = @_; |
66f6e959 |
237 | $c->res->body('Hello World!'); |
5a8ed4fe |
238 | } |
fc7ec1d9 |
239 | |
240 | The Context contains several important objects: |
241 | |
242 | =over 4 |
243 | |
244 | =item * L<Catalyst::Request> |
245 | |
246 | $c->request |
247 | $c->req # alias |
248 | |
129cfe74 |
249 | The request object contains all kinds of request-specific information, like |
250 | query parameters, cookies, uploads, headers, and more. |
fc7ec1d9 |
251 | |
252 | $c->req->params->{foo}; |
253 | $c->req->cookies->{sessionid}; |
254 | $c->req->headers->content_type; |
255 | $c->req->base; |
256 | |
afdca3a3 |
257 | =item * L<Catalyst::Response> |
fc7ec1d9 |
258 | |
259 | $c->response |
260 | $c->res # alias |
261 | |
129cfe74 |
262 | The response is like the request, but contains just response-specific |
263 | information. |
fc7ec1d9 |
264 | |
66f6e959 |
265 | $c->res->body('Hello World'); |
fc7ec1d9 |
266 | $c->res->status(404); |
267 | $c->res->redirect('http://oook.de'); |
268 | |
269 | =item * L<Catalyst::Config> |
270 | |
271 | $c->config |
fc7ec1d9 |
272 | $c->config->root; |
273 | $c->config->name; |
274 | |
275 | =item * L<Catalyst::Log> |
276 | |
277 | $c->log |
278 | |
279 | $c->log->debug('Something happened'); |
280 | $c->log->info('Something you should know'); |
281 | |
4a6895ce |
282 | =item * B<Stash> |
fc7ec1d9 |
283 | |
284 | $c->stash |
fc7ec1d9 |
285 | $c->stash->{foo} = 'bar'; |
286 | |
287 | =back |
288 | |
129cfe74 |
289 | The last of these, the stash, is a universal hash for sharing data among |
290 | application components. For an example, we return to our 'hello' action: |
fc7ec1d9 |
291 | |
e3dc9d78 |
292 | sub hello : Global { |
5a8ed4fe |
293 | my ( $self, $c ) = @_; |
294 | $c->stash->{message} = 'Hello World!'; |
4c6807d2 |
295 | $c->forward('show_message'); |
5a8ed4fe |
296 | } |
fc7ec1d9 |
297 | |
4c6807d2 |
298 | sub show_message : Private { |
5a8ed4fe |
299 | my ( $self, $c ) = @_; |
66f6e959 |
300 | $c->res->body( $c->stash->{message} ); |
5a8ed4fe |
301 | } |
fc7ec1d9 |
302 | |
e178a66a |
303 | Note that the stash should be used only for passing data in an |
304 | individual request cycle; it gets cleared at a new request. If you need |
305 | to maintain more persistent data, use a session. |
dd25a192 |
306 | |
fc7ec1d9 |
307 | =head3 Actions |
308 | |
e178a66a |
309 | A Catalyst controller is defined by its actions. An action is a sub with |
310 | a special attribute. You've already seen some examples of actions in |
311 | this document. The URL (for example http://localhost.3000/foo/bar) |
312 | consists of two parts, the base (http://localhost:3000/ in this example) |
313 | and the path (foo/bar). Please note that the trailing slash after the |
314 | hostname[:port] always belongs to base and not to the action. |
cda8d1ac |
315 | |
316 | Catalyst supports several types of actions: |
fc7ec1d9 |
317 | |
318 | =over 4 |
319 | |
4a6895ce |
320 | =item * B<Literal> |
fc7ec1d9 |
321 | |
e178a66a |
322 | package MyApp::Controller::My::Controller; |
f29c48dd |
323 | sub bar : Path('foo/bar') { } |
fc7ec1d9 |
324 | |
e178a66a |
325 | Literal C<Path> actions will act relative to their current |
326 | namespace. The above example matches only |
327 | http://localhost:3000/my/controller/foo/bar. If you start your path with |
328 | a forward slash, it will match from the root. Example: |
0cf56dbc |
329 | |
e178a66a |
330 | package MyApp::Controller::My::Controller; |
0cf56dbc |
331 | sub bar : Path('/foo/bar') { } |
332 | |
fc7ec1d9 |
333 | Matches only http://localhost:3000/foo/bar. |
334 | |
e178a66a |
335 | package MyApp::Controller::My::Controller; |
0cf56dbc |
336 | sub bar : Path { } |
337 | |
e178a66a |
338 | By leaving the C<Path> definition empty, it will match on the namespace |
339 | root. The above code matches http://localhost:3000/my/controller. |
0cf56dbc |
340 | |
4a6895ce |
341 | =item * B<Regex> |
fc7ec1d9 |
342 | |
b33ed88c |
343 | sub bar : Regex('^item(\d+)/order(\d+)$') { } |
fc7ec1d9 |
344 | |
129cfe74 |
345 | Matches any URL that matches the pattern in the action key, e.g. |
e178a66a |
346 | http://localhost:3000/item23/order42. The '' around the regexp is |
347 | optional, but perltidy likes it. :) |
b33ed88c |
348 | |
e178a66a |
349 | Regex matches act globally, i.e. without reference to the namespace from |
350 | which it is called, so that a C<bar> method in the |
351 | C<MyApp::Controller::Catalog::Order::Process> namespace won't match any |
352 | form of C<bar>, C<Catalog>, C<Order>, or C<Process> unless you |
353 | explicitly put this in the regex. To achieve the above, you should |
354 | consider using a C<LocalRegex> action. |
66f6e959 |
355 | |
356 | =item * B<LocalRegex> |
357 | |
358 | sub bar : LocalRegex('^widget(\d+)$') { } |
fc7ec1d9 |
359 | |
66f6e959 |
360 | LocalRegex actions act locally. If you were to use C<bar> in |
0cf56dbc |
361 | C<MyApp::Controller::Catalog>, the above example would match urls like |
362 | http://localhost:3000/catalog/widget23. |
363 | |
e178a66a |
364 | If you omit the "C<^>" from your regex, then it will match any depth |
365 | from the controller and not immediately off of the controller name. The |
366 | following example differs from the above code in that it will match |
0cf56dbc |
367 | http://localhost:3000/catalog/foo/widget23 as well. |
368 | |
369 | package MyApp::Controller::Catalog; |
370 | sub bar : LocalRegex('widget(\d+)$') { } |
66f6e959 |
371 | |
e178a66a |
372 | For both LocalRegex and Regex actions, if you use capturing parentheses |
373 | to extract values within the matching URL, those values are available in |
374 | the C<$c-E<gt>req-E<gt>snippets> array. In the above example, "widget23" |
375 | would capture "23" in the above example, and |
376 | C<$c-E<gt>req-E<gt>snippets-E<gt>[0]> would be "23". If you want to pass |
377 | arguments at the end of your URL, you must use regex action keys. See |
378 | L</URL Path Handling> below. |
fc7ec1d9 |
379 | |
72d9bfc7 |
380 | =item * B<Top-level> |
cda8d1ac |
381 | |
382 | package MyApp; |
383 | sub foo : Global { } |
384 | |
b33ed88c |
385 | Matches http://localhost:3000/foo. The function name is mapped directly |
386 | to the application base. |
cda8d1ac |
387 | |
4a6895ce |
388 | =item * B<Namespace-Prefixed> |
fc7ec1d9 |
389 | |
e178a66a |
390 | package MyApp::Controller::My::Controller; |
e3dc9d78 |
391 | sub foo : Local { } |
fc7ec1d9 |
392 | |
cda8d1ac |
393 | Matches http://localhost:3000/my/controller/foo. |
fc7ec1d9 |
394 | |
129cfe74 |
395 | This action type indicates that the matching URL must be prefixed with a |
e178a66a |
396 | modified form of the component's class (package) name. This modified |
397 | class name excludes the parts that have a pre-defined meaning in |
398 | Catalyst ("MyApp::Controller" in the above example), replaces "::" with |
399 | "/", and converts the name to lower case. See L</Components> for a full |
400 | explanation of the pre-defined meaning of Catalyst component class |
401 | names. |
fc7ec1d9 |
402 | |
4a6895ce |
403 | =item * B<Private> |
fc7ec1d9 |
404 | |
5a8ed4fe |
405 | sub foo : Private { } |
fc7ec1d9 |
406 | |
e178a66a |
407 | Matches no URL, and cannot be executed by requesting a URL that |
408 | corresponds to the action key. Private actions can be executed only |
409 | inside a Catalyst application, by calling the C<forward> method: |
fc7ec1d9 |
410 | |
5a8ed4fe |
411 | $c->forward('foo'); |
fc7ec1d9 |
412 | |
129cfe74 |
413 | See L</Flow Control> for a full explanation of C<forward>. Note that, as |
fc9c8698 |
414 | discussed there, when forwarding from another component, you must use |
415 | the absolute path to the method, so that a private C<bar> method in your |
416 | C<MyApp::Controller::Catalog::Order::Process> controller must, if called |
417 | from elsewhere, be reached with |
418 | C<$c-E<gt>forward('/catalog/order/process/bar')>. |
fc7ec1d9 |
419 | |
420 | =back |
421 | |
b33ed88c |
422 | B<Note:> After seeing these examples, you probably wonder what the point |
423 | is of defining names for regex and path actions. Actually, every public |
424 | action is also a private one, so you have one unified way of addressing |
425 | components in your C<forward>s. |
cda8d1ac |
426 | |
72d9bfc7 |
427 | =head4 Built-in Private Actions |
fc7ec1d9 |
428 | |
fc9c8698 |
429 | In response to specific application states, Catalyst will automatically |
430 | call these built-in private actions in your application class: |
fc7ec1d9 |
431 | |
432 | =over 4 |
433 | |
cda8d1ac |
434 | =item * B<default : Private> |
fc7ec1d9 |
435 | |
fc9c8698 |
436 | Called when no other action matches. Could be used, for example, for |
437 | displaying a generic frontpage for the main app, or an error page for |
438 | individual controllers. |
fc7ec1d9 |
439 | |
0cf56dbc |
440 | If C<default> isn't acting how you would expect, look at using a |
e178a66a |
441 | L<Literal> C<Path> action (with an empty path string). The difference is |
442 | that C<Path> takes arguments relative from the namespace and C<default> |
443 | I<always> takes arguments relative from the root, regardless of what |
444 | controller it's in. |
0cf56dbc |
445 | |
66f6e959 |
446 | =item * B<index : Private> |
447 | |
448 | C<index> is much like C<default> except that it takes no arguments |
e178a66a |
449 | and it is weighted slightly higher in the matching process. It is |
450 | useful as a static entry point to a controller, e.g. to have a static |
451 | welcome page. |
66f6e959 |
452 | |
cda8d1ac |
453 | =item * B<begin : Private> |
fc7ec1d9 |
454 | |
fc9c8698 |
455 | Called at the beginning of a request, before any matching actions are |
456 | called. |
fc7ec1d9 |
457 | |
cda8d1ac |
458 | =item * B<end : Private> |
4a6895ce |
459 | |
fc7ec1d9 |
460 | Called at the end of a request, after all matching actions are called. |
461 | |
fc9c8698 |
462 | =back |
463 | |
6b10c72b |
464 | =head4 Built-in actions in controllers/autochaining |
fc7ec1d9 |
465 | |
e178a66a |
466 | Package MyApp::Controller::Foo; |
cda8d1ac |
467 | sub begin : Private { } |
5a8ed4fe |
468 | sub default : Private { } |
eff5f524 |
469 | sub auto : Private { } |
fc7ec1d9 |
470 | |
fc9c8698 |
471 | You can define built-in private actions within your controllers as |
472 | well. The actions will override the ones in less-specific controllers, |
473 | or your application class. In other words, for each of the three |
474 | built-in private actions, only one will be run in any request |
e178a66a |
475 | cycle. Thus, if C<MyApp::Controller::Catalog::begin> exists, it will be |
476 | run in place of C<MyApp::begin> if you're in the C<catalog> namespace, |
477 | and C<MyApp::Controller::Catalog::Order::begin> would override this in |
478 | turn. |
fc9c8698 |
479 | |
eff5f524 |
480 | In addition to the normal built-in actions, you have a special action |
481 | for making chains, C<auto>. Such C<auto> actions will be run after any |
fc9c8698 |
482 | C<begin>, but before your action is processed. Unlike the other |
eff5f524 |
483 | built-ins, C<auto> actions I<do not> override each other; they will be |
484 | called in turn, starting with the application class and going through to |
485 | the I<most> specific class. I<This is the reverse of the order in which |
486 | the normal built-ins override each other>. |
fc9c8698 |
487 | |
488 | Here are some examples of the order in which the various built-ins |
489 | would be called: |
cda8d1ac |
490 | |
491 | =over 4 |
492 | |
fc9c8698 |
493 | =item for a request for C</foo/foo> |
cda8d1ac |
494 | |
495 | MyApp::begin |
80ef2e6d |
496 | MyApp::auto |
e178a66a |
497 | MyApp::Controller::Foo::default # in the absence of MyApp::Controller::Foo::Foo |
cda8d1ac |
498 | MyApp::end |
499 | |
fc9c8698 |
500 | =item for a request for C</foo/bar/foo> |
cda8d1ac |
501 | |
e178a66a |
502 | MyApp::Controller::Foo::Bar::begin |
80ef2e6d |
503 | MyApp::auto |
e178a66a |
504 | MyApp::Controller::Foo::auto |
505 | MyApp::Controller::Foo::Bar::auto |
506 | MyApp::Controller::Foo::Bar::default # for MyApp::Controller::Foo::Bar::foo |
507 | MyApp::Controller::Foo::Bar::end |
80ef2e6d |
508 | |
509 | =back |
510 | |
fc9c8698 |
511 | The C<auto> action is also distinguished by the fact that you can break |
512 | out of the processing chain by returning 0. If an C<auto> action returns |
513 | 0, any remaining actions will be skipped, except for C<end>. So, for the |
514 | request above, if the first auto returns false, the chain would look |
515 | like this: |
80ef2e6d |
516 | |
517 | =over 4 |
518 | |
fc9c8698 |
519 | =item for a request for C</foo/bar/foo> where first C<auto> returns |
520 | false |
80ef2e6d |
521 | |
e178a66a |
522 | MyApp::Controller::Foo::Bar::begin |
80ef2e6d |
523 | MyApp::auto |
e178a66a |
524 | MyApp::Controller::Foo::Bar::end |
cda8d1ac |
525 | |
526 | =back |
4a6895ce |
527 | |
fc9c8698 |
528 | An example of why one might use this is an authentication action: you |
529 | could set up a C<auto> action to handle authentication in your |
530 | application class (which will always be called first), and if |
531 | authentication fails, returning 0 would skip any remaining methods |
532 | for that URL. |
03805733 |
533 | |
fc9c8698 |
534 | B<Note:> Looking at it another way, C<auto> actions have to return a |
535 | true value to continue processing! You can also C<die> in the autochain |
536 | action; in that case, the request will go straight to the finalize |
537 | stage, without processing further actions. |
03805733 |
538 | |
6b10c72b |
539 | =head4 URL Path Handling |
4a6895ce |
540 | |
fc9c8698 |
541 | You can pass variable arguments as part of the URL path. In this case, |
542 | you must use regex action keys with '^' and '$' anchors, and the |
543 | arguments must be separated with forward slashes (/) in the URL. For |
544 | example, suppose you want to handle C</foo/$bar/$baz>, where C<$bar> and |
545 | C<$baz> may vary: |
4a6895ce |
546 | |
cda8d1ac |
547 | sub foo : Regex('^foo$') { my ($self, $context, $bar, $baz) = @_; } |
4a6895ce |
548 | |
fc9c8698 |
549 | But what if you also defined actions for C</foo/boo> and C</foo/boo/hoo>? |
4a6895ce |
550 | |
f29c48dd |
551 | sub boo : Path('foo/boo') { .. } |
552 | sub hoo : Path('foo/boo/hoo') { .. } |
4a6895ce |
553 | |
554 | Catalyst matches actions in most specific to least specific order: |
555 | |
556 | /foo/boo/hoo |
557 | /foo/boo |
fc9c8698 |
558 | /foo # might be /foo/bar/baz but won't be /foo/boo/hoo |
4a6895ce |
559 | |
fc9c8698 |
560 | So Catalyst would never mistakenly dispatch the first two URLs to the |
561 | '^foo$' action. |
fc7ec1d9 |
562 | |
6b10c72b |
563 | =head4 Parameter Processing |
2ef2fb0f |
564 | |
fc9c8698 |
565 | Parameters passed in the URL query string are handled with methods in |
566 | the L<Catalyst::Request> class. The C<param> method is functionally |
567 | equivalent to the C<param> method of C<CGI.pm> and can be used in |
568 | modules that require this. |
2ef2fb0f |
569 | |
570 | # http://localhost:3000/catalog/view/?category=hardware&page=3 |
571 | my $category = $c->req->param('category'); |
572 | my $current_page = $c->req->param('page') || 1; |
573 | |
574 | # multiple values for single parameter name |
575 | my @values = $c->req->param('scrolling_list'); |
576 | |
577 | # DFV requires a CGI.pm-like input hash |
578 | my $results = Data::FormValidator->check($c->req->params, \%dfv_profile); |
579 | |
fc7ec1d9 |
580 | =head3 Flow Control |
581 | |
d08ced28 |
582 | You control the application flow with the C<forward> method, which |
583 | accepts the key of an action to execute. This can be an action in the |
584 | same or another Catalyst controller, or a Class name, optionally |
585 | followed by a method name. After a C<forward>, the control flow will |
586 | return to the method from which the C<forward> was issued. |
587 | |
588 | A C<forward> is similar to a method call. The main differences are that |
589 | it wraps the call in an C<eval> to allow exception handling; it |
590 | automatically passes along the context object (C<$c> or C<$context>); |
591 | and it allows profiling of each call (displayed in the log with |
592 | debugging enabled). |
fc7ec1d9 |
593 | |
e3dc9d78 |
594 | sub hello : Global { |
5a8ed4fe |
595 | my ( $self, $c ) = @_; |
596 | $c->stash->{message} = 'Hello World!'; |
d08ced28 |
597 | $c->forward('check_message'); # $c is automatically included |
5a8ed4fe |
598 | } |
fc7ec1d9 |
599 | |
4c6807d2 |
600 | sub check_message : Private { |
5a8ed4fe |
601 | my ( $self, $c ) = @_; |
602 | return unless $c->stash->{message}; |
4c6807d2 |
603 | $c->forward('show_message'); |
5a8ed4fe |
604 | } |
fc7ec1d9 |
605 | |
4c6807d2 |
606 | sub show_message : Private { |
5a8ed4fe |
607 | my ( $self, $c ) = @_; |
66f6e959 |
608 | $c->res->body( $c->stash->{message} ); |
5a8ed4fe |
609 | } |
3323f920 |
610 | |
d08ced28 |
611 | A C<forward> does not create a new request, so your request |
612 | object (C<$c-E<gt>req>) will remain unchanged. This is a |
613 | key difference between using C<forward> and issuing a |
614 | redirect. |
3323f920 |
615 | |
d08ced28 |
616 | You can pass new arguments to a C<forward> by adding them |
617 | in an anonymous array. In this case C<$c-E<gt>req-E<gt>args> |
618 | will be changed for the duration of the C<forward> only; upon |
619 | return, the original value of C<$c-E<gt>req-E<gt>args> will |
620 | be reset. |
3323f920 |
621 | |
622 | sub hello : Global { |
623 | my ( $self, $c ) = @_; |
624 | $c->stash->{message} = 'Hello World!'; |
d08ced28 |
625 | $c->forward('check_message',[qw/test1/]); |
626 | # now $c->req->args is back to what it was before |
3323f920 |
627 | } |
628 | |
d08ced28 |
629 | sub check_message : Private { |
630 | my ( $self, $c ) = @_; |
631 | my $first_argument = $c->req->args[0]; # now = 'test1' |
632 | # do something... |
633 | } |
cda8d1ac |
634 | |
d08ced28 |
635 | As you can see from these examples, you can just use the method name as |
636 | long as you are referring to methods in the same controller. If you want |
637 | to forward to a method in another controller, or the main application, |
638 | you will have to refer to the method by absolute path. |
cda8d1ac |
639 | |
640 | $c->forward('/my/controller/action'); |
d08ced28 |
641 | $c->forward('/default'); # calls default in main application |
fc7ec1d9 |
642 | |
d08ced28 |
643 | Here are some examples of how to forward to classes and methods. |
fc7ec1d9 |
644 | |
e3dc9d78 |
645 | sub hello : Global { |
5a8ed4fe |
646 | my ( $self, $c ) = @_; |
e178a66a |
647 | $c->forward(qw/MyApp::Model::Hello say_hello/); |
5a8ed4fe |
648 | } |
fc7ec1d9 |
649 | |
e3dc9d78 |
650 | sub bye : Global { |
5a8ed4fe |
651 | my ( $self, $c ) = @_; |
e178a66a |
652 | $c->forward('MyApp::Model::Hello'); # no method: will try 'process' |
5a8ed4fe |
653 | } |
fc7ec1d9 |
654 | |
e178a66a |
655 | package MyApp::Model::Hello; |
fc7ec1d9 |
656 | |
657 | sub say_hello { |
658 | my ( $self, $c ) = @_; |
66f6e959 |
659 | $c->res->body('Hello World!'); |
fc7ec1d9 |
660 | } |
661 | |
662 | sub process { |
663 | my ( $self, $c ) = @_; |
66f6e959 |
664 | $c->res->body('Goodbye World!'); |
fc7ec1d9 |
665 | } |
666 | |
d08ced28 |
667 | Note that C<forward> returns to the calling action and continues |
13436c14 |
668 | processing after the action finishes. If you want all further processing |
669 | in the calling action to stop, use C<detach> instead, which will execute |
670 | the C<detach>ed action and not return to the calling sub. In both cases, |
671 | Catalyst will automatically try to call process() if you omit the |
672 | method. |
fc7ec1d9 |
673 | |
674 | =head3 Components |
675 | |
129cfe74 |
676 | Catalyst has an uncommonly flexible component system. You can define as many |
677 | L<Models>, L<Views>, and L<Controllers> as you like. |
fc7ec1d9 |
678 | |
129cfe74 |
679 | All components must inherit from L<Catalyst::Base>, which provides a simple |
680 | class structure and some common class methods like C<config> and C<new> |
681 | (constructor). |
fc7ec1d9 |
682 | |
e178a66a |
683 | package MyApp::Controller::Catalog; |
fc7ec1d9 |
684 | |
685 | use strict; |
686 | use base 'Catalyst::Base'; |
687 | |
688 | __PACKAGE__->config( foo => 'bar' ); |
689 | |
690 | 1; |
691 | |
6b10c72b |
692 | You don't have to C<use> or otherwise register Models, Views, and |
693 | Controllers. Catalyst automatically discovers and instantiates them |
694 | when you call C<setup> in the main application. All you need to do is |
695 | put them in directories named for each Component type. Notice that you |
696 | can use some very terse aliases for each one. |
fc7ec1d9 |
697 | |
698 | =over 4 |
699 | |
4a6895ce |
700 | =item * B<MyApp/Model/> |
fc7ec1d9 |
701 | |
4a6895ce |
702 | =item * B<MyApp/M/> |
fc7ec1d9 |
703 | |
4a6895ce |
704 | =item * B<MyApp/View/> |
fc7ec1d9 |
705 | |
4a6895ce |
706 | =item * B<MyApp/V/> |
fc7ec1d9 |
707 | |
4a6895ce |
708 | =item * B<MyApp/Controller/> |
fc7ec1d9 |
709 | |
4a6895ce |
710 | =item * B<MyApp/C/> |
fc7ec1d9 |
711 | |
712 | =back |
713 | |
714 | =head4 Views |
715 | |
129cfe74 |
716 | To show how to define views, we'll use an already-existing base class for the |
717 | L<Template Toolkit|Template>, L<Catalyst::View::TT>. All we need to do is |
718 | inherit from this class: |
fc7ec1d9 |
719 | |
e178a66a |
720 | package MyApp::View::TT; |
fc7ec1d9 |
721 | |
722 | use strict; |
723 | use base 'Catalyst::View::TT'; |
724 | |
725 | 1; |
726 | |
b33ed88c |
727 | (You can also generate this automatically by using the helper script: |
728 | |
729 | script/myapp_create.pl view TT TT |
730 | |
fb9257c1 |
731 | where the first C<TT> tells the script that the name of the view should |
732 | be C<TT>, and the second that it should be a Template Toolkit view.) |
b33ed88c |
733 | |
129cfe74 |
734 | This gives us a process() method and we can now just do |
e178a66a |
735 | $c->forward('MyApp::View::TT') to render our templates. The base class |
736 | makes process() implicit, so we don't have to say |
737 | C<$c-E<gt>forward(qw/MyApp::View::TT process/)>. |
fc7ec1d9 |
738 | |
e3dc9d78 |
739 | sub hello : Global { |
5a8ed4fe |
740 | my ( $self, $c ) = @_; |
741 | $c->stash->{template} = 'hello.tt'; |
742 | } |
fc7ec1d9 |
743 | |
5a8ed4fe |
744 | sub end : Private { |
745 | my ( $self, $c ) = @_; |
e178a66a |
746 | $c->forward('MyApp::View::TT'); |
5a8ed4fe |
747 | } |
fc7ec1d9 |
748 | |
6b10c72b |
749 | You normally render templates at the end of a request, so it's a perfect |
750 | use for the global C<end> action. |
fc7ec1d9 |
751 | |
129cfe74 |
752 | Also, be sure to put the template under the directory specified in |
6b10c72b |
753 | C<$c-E<gt>config-E<gt>{root}>, or you'll be forced to look at our |
754 | eyecandy debug screen. ;) |
fc7ec1d9 |
755 | |
756 | =head4 Models |
757 | |
e178a66a |
758 | To show how to define models, again we'll use an already-existing base |
759 | class, this time for L<Class::DBI>: L<Catalyst::Model::CDBI>. |
fc7ec1d9 |
760 | |
761 | But first, we need a database. |
762 | |
763 | -- myapp.sql |
764 | CREATE TABLE foo ( |
765 | id INTEGER PRIMARY KEY, |
766 | data TEXT |
767 | ); |
768 | |
769 | CREATE TABLE bar ( |
770 | id INTEGER PRIMARY KEY, |
771 | foo INTEGER REFERENCES foo, |
772 | data TEXT |
773 | ); |
774 | |
775 | INSERT INTO foo (data) VALUES ('TEST!'); |
776 | |
777 | |
778 | % sqlite /tmp/myapp.db < myapp.sql |
779 | |
780 | Now we can create a CDBI component for this database. |
781 | |
e178a66a |
782 | package MyApp::Model::CDBI; |
fc7ec1d9 |
783 | |
784 | use strict; |
785 | use base 'Catalyst::Model::CDBI'; |
786 | |
787 | __PACKAGE__->config( |
788 | dsn => 'dbi:SQLite:/tmp/myapp.db', |
789 | relationships => 1 |
790 | ); |
791 | |
792 | 1; |
793 | |
e178a66a |
794 | Catalyst automatically loads table layouts and relationships. Use the |
795 | stash to pass data to your templates. |
fc7ec1d9 |
796 | |
797 | package MyApp; |
798 | |
799 | use strict; |
800 | use Catalyst '-Debug'; |
801 | |
802 | __PACKAGE__->config( |
803 | name => 'My Application', |
804 | root => '/home/joeuser/myapp/root' |
805 | ); |
cda8d1ac |
806 | |
807 | __PACKAGE__->setup; |
fc7ec1d9 |
808 | |
5a8ed4fe |
809 | sub end : Private { |
810 | my ( $self, $c ) = @_; |
811 | $c->stash->{template} ||= 'index.tt'; |
e178a66a |
812 | $c->forward('MyApp::View::TT'); |
5a8ed4fe |
813 | } |
fc7ec1d9 |
814 | |
e3dc9d78 |
815 | sub view : Global { |
5a8ed4fe |
816 | my ( $self, $c, $id ) = @_; |
e178a66a |
817 | $c->stash->{item} = MyApp::Model::CDBI::Foo->retrieve($id); |
5a8ed4fe |
818 | } |
fc7ec1d9 |
819 | |
820 | 1; |
821 | |
6b10c72b |
822 | # Then, in a TT template: |
fc7ec1d9 |
823 | The id is [% item.data %] |
824 | |
6b10c72b |
825 | Models do not have to be part of your Catalyst application; you |
826 | can always call an outside module that serves as your Model: |
827 | |
828 | # in a Controller |
829 | sub list : Local { |
830 | my ( $self, $c ) = @_; |
831 | $c->stash->{template} = 'list.tt'; |
832 | use Some::Outside::CDBI::Module; |
833 | my @records = Some::Outside::CDBI::Module->retrieve_all; |
834 | $c->stash->{records} = \@records; |
835 | } |
836 | |
837 | But by using a Model that is part of your Catalyst application, you gain |
838 | several things: you don't have to C<use> each component, Catalyst will |
839 | find and load it automatically at compile-time; you can C<forward> to |
26e73131 |
840 | the module, which can only be done to Catalyst components; and only |
6b10c72b |
841 | Catalyst components can be fetched with |
e178a66a |
842 | C<$c-E<gt>model('SomeModel')>. |
6b10c72b |
843 | |
844 | Happily, since many people have existing Model classes that they |
845 | would like to use with Catalyst (or, conversely, they want to |
846 | write Catalyst models that can be used outside of Catalyst, e.g. |
847 | in a cron job), it's trivial to write a simple component in |
848 | Catalyst that slurps in an outside Model: |
849 | |
e178a66a |
850 | package MyApp::Model::Catalog; |
6b10c72b |
851 | use base qw/Catalyst::Base Some::Other::CDBI::Module::Catalog/; |
852 | 1; |
853 | |
854 | and that's it! Now C<Some::Other::CDBI::Module::Catalog> is part of your |
e178a66a |
855 | Cat app as C<MyApp::Model::Catalog>. |
6b10c72b |
856 | |
fc7ec1d9 |
857 | =head4 Controllers |
858 | |
129cfe74 |
859 | Multiple controllers are a good way to separate logical domains of your |
860 | application. |
fc7ec1d9 |
861 | |
e178a66a |
862 | package MyApp::Controller::Login; |
fc7ec1d9 |
863 | |
fb9257c1 |
864 | sub sign-in : Local { } |
865 | sub new-password : Local { } |
866 | sub sign-out : Local { } |
fc7ec1d9 |
867 | |
e178a66a |
868 | package MyApp::Controller::Catalog; |
fc7ec1d9 |
869 | |
e3dc9d78 |
870 | sub view : Local { } |
871 | sub list : Local { } |
fc7ec1d9 |
872 | |
e178a66a |
873 | package MyApp::Controller::Cart; |
fc7ec1d9 |
874 | |
e3dc9d78 |
875 | sub add : Local { } |
876 | sub update : Local { } |
877 | sub order : Local { } |
fc7ec1d9 |
878 | |
879 | =head3 Testing |
880 | |
e178a66a |
881 | Catalyst has a built-in http server for testing! (Later, you can easily |
882 | use a more powerful server, e.g. Apache/mod_perl, in a production |
883 | environment.) |
fc7ec1d9 |
884 | |
885 | Start your application on the command line... |
886 | |
b33ed88c |
887 | script/myapp_server.pl |
fc7ec1d9 |
888 | |
889 | ...then visit http://localhost:3000/ in a browser to view the output. |
890 | |
891 | You can also do it all from the command line: |
892 | |
b33ed88c |
893 | script/myapp_test.pl http://localhost/ |
fc7ec1d9 |
894 | |
895 | Have fun! |
896 | |
3cb1db8c |
897 | =head1 SUPPORT |
898 | |
899 | IRC: |
900 | |
901 | Join #catalyst on irc.perl.org. |
902 | |
72d9bfc7 |
903 | Mailing-lists: |
3cb1db8c |
904 | |
905 | http://lists.rawmode.org/mailman/listinfo/catalyst |
906 | http://lists.rawmode.org/mailman/listinfo/catalyst-dev |
907 | |
fc7ec1d9 |
908 | =head1 AUTHOR |
909 | |
cda8d1ac |
910 | Sebastian Riedel, C<sri@oook.de> |
911 | David Naughton, C<naughton@umn.edu> |
912 | Marcus Ramberg, C<mramberg@cpan.org> |
f531dd37 |
913 | Jesse Sheidlower, C<jester@panix.com> |
129cfe74 |
914 | Danijel Milicevic, C<me@danijel.de> |
fc7ec1d9 |
915 | |
916 | =head1 COPYRIGHT |
917 | |
918 | This program is free software, you can redistribute it and/or modify it under |
919 | the same terms as Perl itself. |