Commit | Line | Data |
fc7ec1d9 |
1 | =head1 NAME |
2 | |
3 | Catalyst::Manual::Intro - Introduction to Catalyst |
4 | |
5 | =head1 DESCRIPTION |
6 | |
670b3d78 |
7 | This is a brief introduction to Catalyst. It explains the most important |
aa2b0d97 |
8 | features of how Catalyst works and shows how to get a simple application |
9 | up and running quickly. For an introduction (without code) to Catalyst |
10 | itself, and why you should be using it, see L<Catalyst::Manual::About>. |
6c5c02ba |
11 | For a systematic step-by-step introduction to writing an application |
12 | with Catalyst, see L<Catalyst::Manual::Tutorial>. |
fc7ec1d9 |
13 | |
14 | =head2 What is Catalyst? |
15 | |
d708fed4 |
16 | Catalyst is an elegant web application framework, extremely flexible |
17 | yet extremely simple. It's similar to Ruby on Rails, Spring (Java), |
18 | and L<Maypole>, upon which it was originally based. Its most important |
19 | design philosphy is to provide easy access to all the tools you need |
20 | to develop web applications, with few restrictions on how you need to |
21 | use these tools. However, this does mean that it is always possible to |
22 | do things in a different way. Other web frameworks are B<initially> |
23 | simpler to use, but achieve this by locking the programmer into a |
24 | single set of tools. Catalyst's emphasis on flexibility means that you |
25 | have to think more to use it. We view this as a feature. For example, |
26 | this leads to Catalyst being more suited to system integration tasks |
27 | than other web frameworks. |
fc7ec1d9 |
28 | |
29 | =head3 MVC |
30 | |
e178a66a |
31 | Catalyst follows the Model-View-Controller (MVC) design pattern, |
32 | allowing you to easily separate concerns, like content, presentation, |
33 | and flow control, into separate modules. This separation allows you to |
34 | modify code that handles one concern without affecting code that handles |
35 | the others. Catalyst promotes the re-use of existing Perl modules that |
36 | already handle common web application concerns well. |
fc7ec1d9 |
37 | |
7f71afbe |
38 | Here's how the Model, View, and Controller map to those concerns, with |
39 | examples of well-known Perl modules you may want to use for each. |
fc7ec1d9 |
40 | |
41 | =over 4 |
42 | |
4a6895ce |
43 | =item * B<Model> |
fc7ec1d9 |
44 | |
e112461a |
45 | Access and modify content (data). L<DBIx::Class>, L<Class::DBI>, |
6c5c02ba |
46 | L<Xapian>, L<Net::LDAP>... |
fc7ec1d9 |
47 | |
4a6895ce |
48 | =item * B<View> |
fc7ec1d9 |
49 | |
e178a66a |
50 | Present content to the user. L<Template Toolkit|Template>, |
51 | L<Mason|HTML::Mason>, L<HTML::Template>... |
fc7ec1d9 |
52 | |
4a6895ce |
53 | =item * B<Controller> |
fc7ec1d9 |
54 | |
129cfe74 |
55 | Control the whole request phase, check parameters, dispatch actions, flow |
56d8daeb |
56 | control. Catalyst itself! |
fc7ec1d9 |
57 | |
58 | =back |
59 | |
d4ef4999 |
60 | If you're unfamiliar with MVC and design patterns, you may want to |
61 | check out the original book on the subject, I<Design Patterns>, by |
62 | Gamma, Helm, Johnson, and Vlissides, also known as the Gang of Four |
63 | (GoF). Many, many web application frameworks are based on MVC, which |
d708fed4 |
64 | is becoming a popular design paradigm for the world wide web. |
fc7ec1d9 |
65 | |
66 | =head3 Flexibility |
67 | |
7f71afbe |
68 | Catalyst is much more flexible than many other frameworks. Rest assured |
69 | you can use your favorite Perl modules with Catalyst. |
fc7ec1d9 |
70 | |
71 | =over 4 |
72 | |
72d9bfc7 |
73 | =item * B<Multiple Models, Views, and Controllers> |
fc7ec1d9 |
74 | |
e178a66a |
75 | To build a Catalyst application, you handle each type of concern inside |
76 | special modules called L</Components>. Often this code will be very |
77 | simple, just calling out to Perl modules like those listed above under |
78 | L</MVC>. Catalyst handles these components in a very flexible way. Use |
79 | as many Models, Views, and Controllers as you like, using as many |
80 | different Perl modules as you like, all in the same application. Want to |
81 | manipulate multiple databases, and retrieve some data via LDAP? No |
82 | problem. Want to present data from the same Model using L<Template |
83 | Toolkit|Template> and L<PDF::Template>? Easy. |
fc7ec1d9 |
84 | |
cda8d1ac |
85 | =item * B<Reuseable Components> |
fc7ec1d9 |
86 | |
e178a66a |
87 | Not only does Catalyst promote the re-use of already existing Perl |
88 | modules, it also allows you to re-use your Catalyst components in |
89 | multiple Catalyst applications. |
fc7ec1d9 |
90 | |
4a6895ce |
91 | =item * B<Unrestrained URL-to-Action Dispatching> |
fc7ec1d9 |
92 | |
cccc887d |
93 | Catalyst allows you to dispatch any URLs to any application L</Actions>, |
e178a66a |
94 | even through regular expressions! Unlike most other frameworks, it |
95 | doesn't require mod_rewrite or class and method names in URLs. |
fc7ec1d9 |
96 | |
e178a66a |
97 | With Catalyst you register your actions and address them directly. For |
98 | example: |
fc7ec1d9 |
99 | |
e3dc9d78 |
100 | sub hello : Global { |
fc7ec1d9 |
101 | my ( $self, $context ) = @_; |
66f6e959 |
102 | $context->response->body('Hello World!'); |
5a8ed4fe |
103 | } |
fc7ec1d9 |
104 | |
105 | Now http://localhost:3000/hello prints "Hello World!". |
106 | |
7f71afbe |
107 | =item * B<Support for CGI, mod_perl, Apache::Request, FastCGI> |
fc7ec1d9 |
108 | |
7f71afbe |
109 | Use L<Catalyst::Engine::Apache> or L<Catalyst::Engine::CGI>. Other |
110 | engines are also available. |
fc7ec1d9 |
111 | |
112 | =back |
113 | |
114 | =head3 Simplicity |
115 | |
e178a66a |
116 | The best part is that Catalyst implements all this flexibility in a very |
117 | simple way. |
fc7ec1d9 |
118 | |
6f4e1683 |
119 | =over 4 |
120 | |
4a6895ce |
121 | =item * B<Building Block Interface> |
fc7ec1d9 |
122 | |
e178a66a |
123 | Components interoperate very smoothly. For example, Catalyst |
cccc887d |
124 | automatically makes a L</Context> object available to every |
e178a66a |
125 | component. Via the context, you can access the request object, share |
126 | data between components, and control the flow of your |
127 | application. Building a Catalyst application feels a lot like snapping |
129cfe74 |
128 | together toy building blocks, and everything just works. |
fc7ec1d9 |
129 | |
4a6895ce |
130 | =item * B<Component Auto-Discovery> |
fc7ec1d9 |
131 | |
e178a66a |
132 | No need to C<use> all of your components. Catalyst automatically finds |
133 | and loads them. |
fc7ec1d9 |
134 | |
4a6895ce |
135 | =item * B<Pre-Built Components for Popular Modules> |
fc7ec1d9 |
136 | |
e112461a |
137 | See L<Catalyst::Model::DBIC::Schema> for L<DBIx::Class>, or |
138 | L<Catalyst::View::TT> for L<Template Toolkit|Template>. |
fc7ec1d9 |
139 | |
72d9bfc7 |
140 | =item * B<Built-in Test Framework> |
fc7ec1d9 |
141 | |
e178a66a |
142 | Catalyst comes with a built-in, lightweight http server and test |
d708fed4 |
143 | framework, making it easy to test applications from the web browser, |
144 | and the command line. |
fc7ec1d9 |
145 | |
4a6895ce |
146 | =item * B<Helper Scripts> |
fc7ec1d9 |
147 | |
e178a66a |
148 | Catalyst provides helper scripts to quickly generate running starter |
7f71afbe |
149 | code for components and unit tests. Install L<Catalyst::Devel> and see |
150 | L<Catalyst::Helper>. |
fc7ec1d9 |
151 | |
6f4e1683 |
152 | =back |
153 | |
fc7ec1d9 |
154 | =head2 Quickstart |
155 | |
e178a66a |
156 | Here's how to install Catalyst and get a simple application up and |
157 | running, using the helper scripts described above. |
fc7ec1d9 |
158 | |
159 | =head3 Install |
160 | |
7f71afbe |
161 | Installation of Catalyst can be a time-consuming and frustrating |
162 | effort, due to its large number of dependencies. The easiest way |
163 | to get up and running is to use Matt Trout's C<cat-install> |
164 | script, from L<http://www.shadowcatsystems.co.uk/static/cat-install>, |
165 | and then install L<Catalyst::Devel>. |
166 | |
167 | # perl cat-install |
168 | # perl -MCPAN -e 'install Catalyst::Devel' |
fc7ec1d9 |
169 | |
170 | =head3 Setup |
171 | |
2feb6632 |
172 | $ catalyst.pl MyApp |
b33ed88c |
173 | # output omitted |
2feb6632 |
174 | $ cd MyApp |
ac4a0ae0 |
175 | $ script/myapp_create.pl controller Library::Login |
fc7ec1d9 |
176 | |
177 | =head3 Run |
178 | |
b33ed88c |
179 | $ script/myapp_server.pl |
fc7ec1d9 |
180 | |
129cfe74 |
181 | Now visit these locations with your favorite browser or user agent to see |
182 | Catalyst in action: |
fc7ec1d9 |
183 | |
51aec62b |
184 | (NOTE: Although we create a controller here, we don't actually use it. |
185 | Both of these URLs should take you to the welcome page.) |
186 | |
187 | |
fc7ec1d9 |
188 | =over 4 |
189 | |
190 | =item http://localhost:3000/ |
191 | |
ac4a0ae0 |
192 | =item http://localhost:3000/library/login/ |
fc7ec1d9 |
193 | |
194 | =back |
195 | |
fc7ec1d9 |
196 | =head2 How It Works |
197 | |
e178a66a |
198 | Let's see how Catalyst works, by taking a closer look at the components |
199 | and other parts of a Catalyst application. |
fc7ec1d9 |
200 | |
75c0ec03 |
201 | =head3 Components |
fc7ec1d9 |
202 | |
75c0ec03 |
203 | Catalyst has an uncommonly flexible component system. You can define as |
204 | many L</Models>, L</Views>, and L</Controllers> as you like. As discussed |
205 | previously, the general idea is that the View is responsible for the |
206 | output of data to the user (typically via a web browser, but a View can |
207 | also generate PDFs or e-mails, for example); the Model is responsible |
208 | for providing data (typically from a relational database); and the |
209 | Controller is responsible for interacting with the user and deciding |
210 | how user input determines what actions the application takes. |
211 | |
212 | In the world of MVC, there are frequent discussions and disagreements |
213 | about the nature of each element - whether certain types of logic |
214 | belong in the Model or the Controller, etc. Catalyst's flexibility |
215 | means that this decision is entirely up to you, the programmer; |
216 | Catalyst doesn't enforce anything. See L<Catalyst::Manual::About> for |
d708fed4 |
217 | a general discussion of these issues. |
fc7ec1d9 |
218 | |
75c0ec03 |
219 | All components must inherit from L<Catalyst::Base>, which provides a |
220 | simple class structure and some common class methods like C<config> and |
221 | C<new> (constructor). |
222 | |
223 | package MyApp::Controller::Catalog; |
fc7ec1d9 |
224 | |
225 | use strict; |
75c0ec03 |
226 | use base 'Catalyst::Base'; |
fc7ec1d9 |
227 | |
75c0ec03 |
228 | __PACKAGE__->config( foo => 'bar' ); |
fc7ec1d9 |
229 | |
fc7ec1d9 |
230 | 1; |
231 | |
75c0ec03 |
232 | You don't have to C<use> or otherwise register Models, Views, and |
233 | Controllers. Catalyst automatically discovers and instantiates them |
234 | when you call C<setup> in the main application. All you need to do is |
235 | put them in directories named for each Component type. You can use a |
236 | short alias for each one. |
6c5c02ba |
237 | |
fc7ec1d9 |
238 | =over 4 |
239 | |
75c0ec03 |
240 | =item * B<MyApp/Model/> |
fc7ec1d9 |
241 | |
75c0ec03 |
242 | =item * B<MyApp/M/> |
243 | |
244 | =item * B<MyApp/View/> |
245 | |
246 | =item * B<MyApp/V/> |
247 | |
248 | =item * B<MyApp/Controller/> |
249 | |
250 | =item * B<MyApp/C/> |
fc7ec1d9 |
251 | |
fc7ec1d9 |
252 | =back |
253 | |
75c0ec03 |
254 | In older versions of Catalyst, the recommended practice (and the one |
255 | automatically created by helper scripts) was to name the directories |
256 | C<M/>, C<V/>, and C<C/>. Though these still work, we now recommend |
257 | the use of the full names. |
fc7ec1d9 |
258 | |
75c0ec03 |
259 | =head4 Views |
fc7ec1d9 |
260 | |
75c0ec03 |
261 | To show how to define views, we'll use an already-existing base class for the |
262 | L<Template Toolkit|Template>, L<Catalyst::View::TT>. All we need to do is |
263 | inherit from this class: |
c42f5bbf |
264 | |
75c0ec03 |
265 | package MyApp::View::TT; |
fc7ec1d9 |
266 | |
75c0ec03 |
267 | use strict; |
268 | use base 'Catalyst::View::TT'; |
fc7ec1d9 |
269 | |
75c0ec03 |
270 | 1; |
fc7ec1d9 |
271 | |
75c0ec03 |
272 | (You can also generate this automatically by using the helper script: |
fc7ec1d9 |
273 | |
75c0ec03 |
274 | script/myapp_create.pl view TT TT |
fc7ec1d9 |
275 | |
75c0ec03 |
276 | where the first C<TT> tells the script that the name of the view should |
277 | be C<TT>, and the second that it should be a Template Toolkit view.) |
fc7ec1d9 |
278 | |
75c0ec03 |
279 | This gives us a process() method and we can now just do |
280 | $c->forward('MyApp::View::TT') to render our templates. The base class |
281 | makes process() implicit, so we don't have to say |
282 | C<$c-E<gt>forward(qw/MyApp::View::TT process/)>. |
fc7ec1d9 |
283 | |
75c0ec03 |
284 | sub hello : Global { |
285 | my ( $self, $c ) = @_; |
286 | $c->stash->{template} = 'hello.tt'; |
287 | } |
fc7ec1d9 |
288 | |
75c0ec03 |
289 | sub end : Private { |
290 | my ( $self, $c ) = @_; |
291 | $c->forward( $c->view('TT') ); |
292 | } |
fc7ec1d9 |
293 | |
75c0ec03 |
294 | You normally render templates at the end of a request, so it's a perfect |
295 | use for the global C<end> action. |
fc7ec1d9 |
296 | |
75c0ec03 |
297 | In practice, however, you would use a default C<end> action as supplied |
298 | by L<Catalyst::Action::RenderView>. |
fc7ec1d9 |
299 | |
75c0ec03 |
300 | Also, be sure to put the template under the directory specified in |
301 | C<$c-E<gt>config-E<gt>{root}>, or you'll end up looking at the debug |
302 | screen. |
fc7ec1d9 |
303 | |
75c0ec03 |
304 | =head4 Models |
fc7ec1d9 |
305 | |
75c0ec03 |
306 | Models are providers of data. This data could come from anywhere - a |
d708fed4 |
307 | search engine index, a spreadsheet, the file system - but typically a |
308 | Model represents a database table. The data source does not |
309 | intrinsically have much to do with web applications or Catalyst - it |
310 | could just as easily be used to write an offline report generator or a |
311 | command-line tool. |
fc7ec1d9 |
312 | |
75c0ec03 |
313 | To show how to define models, again we'll use an already-existing base |
314 | class, this time for L<DBIx::Class>: L<Catalyst::Model::DBIC::Schema>. |
315 | We'll also need L<DBIx::Class::Schema::Loader>. |
fc7ec1d9 |
316 | |
75c0ec03 |
317 | But first, we need a database. |
fc7ec1d9 |
318 | |
75c0ec03 |
319 | -- myapp.sql |
320 | CREATE TABLE foo ( |
321 | id INTEGER PRIMARY KEY, |
322 | data TEXT |
323 | ); |
fc7ec1d9 |
324 | |
75c0ec03 |
325 | CREATE TABLE bar ( |
326 | id INTEGER PRIMARY KEY, |
327 | foo INTEGER REFERENCES foo, |
328 | data TEXT |
329 | ); |
fc7ec1d9 |
330 | |
75c0ec03 |
331 | INSERT INTO foo (data) VALUES ('TEST!'); |
d4ef4999 |
332 | |
75c0ec03 |
333 | % sqlite /tmp/myapp.db < myapp.sql |
fc7ec1d9 |
334 | |
75c0ec03 |
335 | Now we can create a DBIC::SchemaLoader component for this database. |
fc7ec1d9 |
336 | |
75c0ec03 |
337 | script/myapp_create.pl model DBIC DBIC::SchemaLoader 'dbi:SQLite:/tmp/myapp.db' |
fc7ec1d9 |
338 | |
75c0ec03 |
339 | L<DBIx::Class::Schema::Loader> automatically loads table layouts and |
340 | relationships. Use the stash to pass data to your templates. |
341 | |
342 | We add the following to MyApp/Controller/Root.pm |
343 | |
344 | sub view : Global { |
345 | my ( $self, $c, $id ) = @_; |
346 | |
347 | $c->stash->{item} = $c->model('DBIC::Foo')->find($id); |
5a8ed4fe |
348 | } |
fc7ec1d9 |
349 | |
75c0ec03 |
350 | 1; |
351 | |
352 | sub end : Private { |
5a8ed4fe |
353 | my ( $self, $c ) = @_; |
75c0ec03 |
354 | |
355 | $c->stash->{template} ||= 'index.tt'; |
356 | $c->forward( $c->view('TT') ); |
5a8ed4fe |
357 | } |
fc7ec1d9 |
358 | |
75c0ec03 |
359 | We then create a new template file "root/index.tt" containing: |
dd25a192 |
360 | |
75c0ec03 |
361 | The Id's data is [% item.data %] |
fc7ec1d9 |
362 | |
75c0ec03 |
363 | Models do not have to be part of your Catalyst application; you |
364 | can always call an outside module that serves as your Model: |
cda8d1ac |
365 | |
75c0ec03 |
366 | # in a Controller |
367 | sub list : Local { |
368 | my ( $self, $c ) = @_; |
369 | |
370 | $c->stash->{template} = 'list.tt'; |
371 | |
372 | use Some::Outside::Database::Module; |
373 | my @records = Some::Outside::Database::Module->search({ |
374 | artist => 'Led Zeppelin', |
375 | }); |
376 | |
377 | $c->stash->{records} = \@records; |
378 | } |
c37916b0 |
379 | |
d708fed4 |
380 | But by using a Model that is part of your Catalyst application, you |
381 | gain several things: you don't have to C<use> each component, Catalyst |
382 | will find and load it automatically at compile-time; you can |
383 | C<forward> to the module, which can only be done to Catalyst |
384 | components. Only Catalyst components can be fetched with |
75c0ec03 |
385 | C<$c-E<gt>model('SomeModel')>. |
c37916b0 |
386 | |
75c0ec03 |
387 | Happily, since many people have existing Model classes that they |
388 | would like to use with Catalyst (or, conversely, they want to |
389 | write Catalyst models that can be used outside of Catalyst, e.g. |
390 | in a cron job), it's trivial to write a simple component in |
391 | Catalyst that slurps in an outside Model: |
c37916b0 |
392 | |
75c0ec03 |
393 | package MyApp::Model::DB; |
394 | use base qw/Catalyst::Model::DBIC::Schema/; |
395 | __PACKAGE__->config( |
396 | schema_class => 'Some::DBIC::Schema', |
397 | connect_info => ['dbi:SQLite:foo.db', '', '', {AutoCommit=>1}] |
398 | ); |
c37916b0 |
399 | 1; |
400 | |
75c0ec03 |
401 | and that's it! Now C<Some::DBIC::Schema> is part of your |
402 | Cat app as C<MyApp::Model::DB>. |
c37916b0 |
403 | |
75c0ec03 |
404 | Within Catalyst, the common approach to writing a model for your |
405 | application is wrapping a generic model (e.g. L<DBIx::Class::Schema>, a |
406 | bunch of XMLs, or anything really) with an object that contains |
407 | configuration data, convenience methods, and so forth. Thus you |
408 | will in effect have two models - a wrapper model that knows something |
409 | about Catalyst and your web application, and a generic model that is |
410 | totally independent of these needs. |
c37916b0 |
411 | |
75c0ec03 |
412 | Technically, within Catalyst a model is a B<component> - an instance of |
413 | the model's class belonging to the application. It is important to |
414 | stress that the lifetime of these objects is per application, not per |
415 | request. |
416 | |
417 | While the model base class (L<Catalyst::Model>) provides things like |
418 | C<config> to better integrate the model into the application, sometimes |
419 | this is not enough, and the model requires access to C<$c> itself. |
420 | |
421 | Situations where this need might arise include: |
fc7ec1d9 |
422 | |
423 | =over 4 |
424 | |
75c0ec03 |
425 | =item * |
fc7ec1d9 |
426 | |
75c0ec03 |
427 | Interacting with another model |
fc7ec1d9 |
428 | |
75c0ec03 |
429 | =item * |
0cf56dbc |
430 | |
75c0ec03 |
431 | Using per-request data to control behavior |
0cf56dbc |
432 | |
75c0ec03 |
433 | =item * |
fc7ec1d9 |
434 | |
75c0ec03 |
435 | Using plugins from a Model (for example L<Catalyst::Plugin::Cache>). |
0cf56dbc |
436 | |
75c0ec03 |
437 | =back |
0cf56dbc |
438 | |
75c0ec03 |
439 | From a style perspective it's usually considered bad form to make your |
440 | model "too smart" about things - it should worry about business logic |
441 | and leave the integration details to the controllers. If, however, you |
442 | find that it does not make sense at all to use an auxillary controller |
443 | around the model, and the model's need to access C<$c> cannot be |
444 | sidestepped, there exists a power tool called L</ACCEPT_CONTEXT>. |
fc7ec1d9 |
445 | |
75c0ec03 |
446 | =head4 Controllers |
fc7ec1d9 |
447 | |
75c0ec03 |
448 | Multiple controllers are a good way to separate logical domains of your |
449 | application. |
b33ed88c |
450 | |
75c0ec03 |
451 | package MyApp::Controller::Login; |
66f6e959 |
452 | |
75c0ec03 |
453 | use base qw/Catalyst::Controller/; |
66f6e959 |
454 | |
75c0ec03 |
455 | sub login : Path("login") { } |
456 | sub new_password : Path("new-password") { } |
457 | sub logout : Path("logout") { } |
fc7ec1d9 |
458 | |
75c0ec03 |
459 | package MyApp::Controller::Catalog; |
0cf56dbc |
460 | |
75c0ec03 |
461 | use base qw/Catalyst::Controller/; |
0cf56dbc |
462 | |
75c0ec03 |
463 | sub view : Local { } |
464 | sub list : Local { } |
66f6e959 |
465 | |
75c0ec03 |
466 | package MyApp::Controller::Cart; |
fc7ec1d9 |
467 | |
75c0ec03 |
468 | use base qw/Catalyst::Controller/; |
cda8d1ac |
469 | |
75c0ec03 |
470 | sub add : Local { } |
471 | sub update : Local { } |
472 | sub order : Local { } |
cda8d1ac |
473 | |
75c0ec03 |
474 | Note that you can also supply attributes via the Controller's config so |
475 | long as you have at least one attribute on a subref to be exported |
476 | (:Action is commonly used for this) - for example the following is |
477 | equivalent to the same controller above: |
c37916b0 |
478 | |
75c0ec03 |
479 | package MyApp::Controller::Login; |
cda8d1ac |
480 | |
75c0ec03 |
481 | use base qw/Catalyst::Controller/; |
fc7ec1d9 |
482 | |
75c0ec03 |
483 | __PACKAGE__->config( |
484 | actions => { |
485 | 'sign_in' => { Path => 'sign-in' }, |
486 | 'new_password' => { Path => 'new-password' }, |
487 | 'sign_out' => { Path => 'sign-out' }, |
488 | }, |
489 | ); |
fc7ec1d9 |
490 | |
75c0ec03 |
491 | sub sign_in : Action { } |
492 | sub new_password : Action { } |
493 | sub sign_out : Action { } |
fc7ec1d9 |
494 | |
75c0ec03 |
495 | =head3 ACCEPT_CONTEXT |
fc7ec1d9 |
496 | |
75c0ec03 |
497 | Whenever you call $c->component("Foo") you get back an object - the |
498 | instance of the model. If the component supports the C<ACCEPT_CONTEXT> |
499 | method instead of returning the model itself, the return value of C<< |
500 | $model->ACCEPT_CONTEXT( $c ) >> will be used. |
05a90578 |
501 | |
75c0ec03 |
502 | This means that whenever your model/view/controller needs to talk to C<$c> it |
503 | gets a chance to do this when it's needed. |
05a90578 |
504 | |
75c0ec03 |
505 | A typical C<ACCEPT_CONTEXT> method will either clone the model and return one |
506 | with the context object set, or it will return a thin wrapper that contains |
507 | C<$c> and delegates to the per-application model object. |
05a90578 |
508 | |
75c0ec03 |
509 | A typical C<ACCEPT_CONTEXT> method could look like this: |
510 | |
511 | sub ACCEPT_CONTEXT { |
512 | my ( $self, $c, @extra_arguments ) = @_; |
513 | bless { %$self, c => $c }, ref($self); |
05a90578 |
514 | } |
515 | |
75c0ec03 |
516 | effectively treating $self as a B<prototype object> that gets a new parameter. |
517 | C<@extra_arguments> comes from any trailing arguments to |
518 | C<< $c->component( $bah, @extra_arguments ) >> (or C<< $c->model(...) >>, |
519 | C<< $c->view(...) >> etc). |
05a90578 |
520 | |
75c0ec03 |
521 | The life time of this value is B<per usage>, and not per request. To make this |
522 | per request you can use the following technique: |
fc7ec1d9 |
523 | |
75c0ec03 |
524 | Add a field to C<$c>, like C<my_model_instance>. Then write your |
525 | C<ACCEPT_CONTEXT> method to look like this: |
fc7ec1d9 |
526 | |
75c0ec03 |
527 | sub ACCEPT_CONTEXT { |
528 | my ( $self, $c ) = @_; |
fc7ec1d9 |
529 | |
75c0ec03 |
530 | if ( my $per_request = $c->my_model_instance ) { |
531 | return $per_request; |
532 | } else { |
533 | my $new_instance = bless { %$self, c => $c }, ref($self); |
534 | Scalar::Util::weaken($new_instance->{c}); # or we have a circular reference |
535 | $c->my_model_instance( $new_instance ); |
536 | return $new_instance; |
537 | } |
538 | } |
fc7ec1d9 |
539 | |
75c0ec03 |
540 | =head3 Application Class |
fc7ec1d9 |
541 | |
75c0ec03 |
542 | In addition to the Model, View, and Controller components, there's a |
543 | single class that represents your application itself. This is where you |
544 | configure your application, load plugins, and extend Catalyst. |
baf5120b |
545 | |
75c0ec03 |
546 | package MyApp; |
baf5120b |
547 | |
75c0ec03 |
548 | use strict; |
549 | use Catalyst qw/-Debug/; # Add other plugins here, e.g. |
550 | # for session support |
baf5120b |
551 | |
75c0ec03 |
552 | MyApp->config( |
553 | name => 'My Application', |
baf5120b |
554 | |
75c0ec03 |
555 | # You can put anything else you want in here: |
556 | my_configuration_variable => 'something', |
557 | ); |
558 | 1; |
baf5120b |
559 | |
75c0ec03 |
560 | In older versions of Catalyst, the application class was where you put |
561 | global actions. However, as of version 5.66, the recommended practice is |
562 | to place such actions in a special Root controller (see L</Actions>, |
563 | below), to avoid namespace collisions. |
564 | |
565 | =over 4 |
566 | |
567 | =item * B<name> |
568 | |
569 | The name of your application. |
baf5120b |
570 | |
fc7ec1d9 |
571 | =back |
572 | |
75c0ec03 |
573 | Optionally, you can specify a B<root> parameter for templates and static |
574 | data. If omitted, Catalyst will try to auto-detect the directory's |
575 | location. You can define as many parameters as you want for plugins or |
576 | whatever you need. You can access them anywhere in your application via |
577 | C<$context-E<gt>config-E<gt>{$param_name}>. |
cda8d1ac |
578 | |
75c0ec03 |
579 | =head3 Context |
fc7ec1d9 |
580 | |
75c0ec03 |
581 | Catalyst automatically blesses a Context object into your application |
582 | class and makes it available everywhere in your application. Use the |
583 | Context to directly interact with Catalyst and glue your L</Components> |
584 | together. For example, if you need to use the Context from within a |
585 | Template Toolkit template, it's already there: |
fc7ec1d9 |
586 | |
75c0ec03 |
587 | <h1>Welcome to [% c.config.name %]!</h1> |
fc7ec1d9 |
588 | |
75c0ec03 |
589 | As illustrated in our URL-to-Action dispatching example, the Context is |
590 | always the second method parameter, behind the Component object |
591 | reference or class name itself. Previously we called it C<$context> for |
592 | clarity, but most Catalyst developers just call it C<$c>: |
fc7ec1d9 |
593 | |
75c0ec03 |
594 | sub hello : Global { |
595 | my ( $self, $c ) = @_; |
596 | $c->res->body('Hello World!'); |
597 | } |
fc7ec1d9 |
598 | |
75c0ec03 |
599 | The Context contains several important objects: |
0cf56dbc |
600 | |
75c0ec03 |
601 | =over 4 |
66f6e959 |
602 | |
75c0ec03 |
603 | =item * L<Catalyst::Request> |
66f6e959 |
604 | |
75c0ec03 |
605 | $c->request |
606 | $c->req # alias |
fc7ec1d9 |
607 | |
75c0ec03 |
608 | The request object contains all kinds of request-specific information, like |
609 | query parameters, cookies, uploads, headers, and more. |
fc7ec1d9 |
610 | |
75c0ec03 |
611 | $c->req->params->{foo}; |
612 | $c->req->cookies->{sessionid}; |
613 | $c->req->headers->content_type; |
614 | $c->req->base; |
615 | $c->req->uri_with( { page = $pager->next_page } ); |
4a6895ce |
616 | |
75c0ec03 |
617 | =item * L<Catalyst::Response> |
fc7ec1d9 |
618 | |
75c0ec03 |
619 | $c->response |
620 | $c->res # alias |
fc9c8698 |
621 | |
75c0ec03 |
622 | The response is like the request, but contains just response-specific |
623 | information. |
fc7ec1d9 |
624 | |
75c0ec03 |
625 | $c->res->body('Hello World'); |
626 | $c->res->status(404); |
627 | $c->res->redirect('http://oook.de'); |
fc7ec1d9 |
628 | |
75c0ec03 |
629 | =item * L<Catalyst::Config> |
cda8d1ac |
630 | |
75c0ec03 |
631 | $c->config |
632 | $c->config->root; |
633 | $c->config->name; |
80ef2e6d |
634 | |
75c0ec03 |
635 | =item * L<Catalyst::Log> |
80ef2e6d |
636 | |
75c0ec03 |
637 | $c->log |
638 | $c->log->debug('Something happened'); |
639 | $c->log->info('Something you should know'); |
80ef2e6d |
640 | |
75c0ec03 |
641 | =item * B<Stash> |
80ef2e6d |
642 | |
75c0ec03 |
643 | $c->stash |
644 | $c->stash->{foo} = 'bar'; |
645 | $c->stash->{baz} = {baz => 'qox'}; |
646 | $c->stash->{fred} = [qw/wilma pebbles/]; |
80ef2e6d |
647 | |
75c0ec03 |
648 | and so on. |
cda8d1ac |
649 | |
650 | =back |
4a6895ce |
651 | |
75c0ec03 |
652 | The last of these, the stash, is a universal hash for sharing data among |
653 | application components. For an example, we return to our 'hello' action: |
fc7ec1d9 |
654 | |
e3dc9d78 |
655 | sub hello : Global { |
5a8ed4fe |
656 | my ( $self, $c ) = @_; |
657 | $c->stash->{message} = 'Hello World!'; |
4c6807d2 |
658 | $c->forward('show_message'); |
5a8ed4fe |
659 | } |
fc7ec1d9 |
660 | |
4c6807d2 |
661 | sub show_message : Private { |
5a8ed4fe |
662 | my ( $self, $c ) = @_; |
66f6e959 |
663 | $c->res->body( $c->stash->{message} ); |
5a8ed4fe |
664 | } |
3323f920 |
665 | |
75c0ec03 |
666 | Note that the stash should be used only for passing data in an |
667 | individual request cycle; it gets cleared at a new request. If you need |
668 | to maintain persistent data, use a session. See |
669 | L<Catalyst::Plugin::Session> for a comprehensive set of |
670 | Catalyst-friendly session-handling tools. |
3323f920 |
671 | |
75c0ec03 |
672 | =head3 Actions |
3323f920 |
673 | |
75c0ec03 |
674 | A Catalyst controller is defined by its actions. An action is a |
675 | subroutine with a special attribute. You've already seen some examples |
676 | of actions in this document. The URL (for example |
677 | http://localhost.3000/foo/bar) consists of two parts, the base |
678 | (http://localhost:3000/ in this example) and the path (foo/bar). Please |
679 | note that the trailing slash after the hostname[:port] always belongs to |
680 | base and not to the action. |
b248fa4a |
681 | |
75c0ec03 |
682 | =over 4 |
cda8d1ac |
683 | |
75c0ec03 |
684 | =item * B<Application Wide Actions> |
fc7ec1d9 |
685 | |
75c0ec03 |
686 | Actions which are called at the root level of the application |
687 | (e.g. http://localhost:3000/ ) go in MyApp::Controller::Root, like |
688 | this: |
fc7ec1d9 |
689 | |
75c0ec03 |
690 | package MyApp::Controller::Root; |
691 | use base 'Catalyst::Controller'; |
692 | # Sets the actions in this controller to be registered with no prefix |
693 | # so they function identically to actions created in MyApp.pm |
694 | __PACKAGE__->config->{namespace} = ''; |
695 | sub default : Private { |
696 | my ( $self, $context ) = @_; |
697 | $context->response->body('Catalyst rocks!'); |
5a8ed4fe |
698 | } |
75c0ec03 |
699 | 1; |
fc7ec1d9 |
700 | |
75c0ec03 |
701 | =back |
fc7ec1d9 |
702 | |
75c0ec03 |
703 | =head4 Action types |
fc7ec1d9 |
704 | |
75c0ec03 |
705 | Catalyst supports several types of actions: |
fc7ec1d9 |
706 | |
75c0ec03 |
707 | =over 4 |
fc7ec1d9 |
708 | |
75c0ec03 |
709 | =item * B<Literal> (B<Path> actions) |
fc7ec1d9 |
710 | |
75c0ec03 |
711 | package MyApp::Controller::My::Controller; |
712 | sub bar : Path('foo/bar') { } |
fc7ec1d9 |
713 | |
75c0ec03 |
714 | Literal C<Path> actions will act relative to their current |
715 | namespace. The above example matches only |
716 | http://localhost:3000/my/controller/foo/bar. If you start your path with |
717 | a forward slash, it will match from the root. Example: |
fc7ec1d9 |
718 | |
75c0ec03 |
719 | package MyApp::Controller::My::Controller; |
720 | sub bar : Path('/foo/bar') { } |
fc7ec1d9 |
721 | |
75c0ec03 |
722 | Matches only http://localhost:3000/foo/bar. |
fc7ec1d9 |
723 | |
75c0ec03 |
724 | package MyApp::Controller::My::Controller; |
725 | sub bar : Path { } |
fc7ec1d9 |
726 | |
75c0ec03 |
727 | By leaving the C<Path> definition empty, it will match on the namespace |
728 | root. The above code matches http://localhost:3000/my/controller. |
fc7ec1d9 |
729 | |
75c0ec03 |
730 | =item * B<Regex> |
fc7ec1d9 |
731 | |
75c0ec03 |
732 | sub bar : Regex('^item(\d+)/order(\d+)$') { } |
fc7ec1d9 |
733 | |
75c0ec03 |
734 | Matches any URL that matches the pattern in the action key, e.g. |
735 | http://localhost:3000/item23/order42. The '' around the regexp is |
736 | optional, but perltidy likes it. :) |
fc7ec1d9 |
737 | |
75c0ec03 |
738 | Regex matches act globally, i.e. without reference to the namespace from |
739 | which it is called, so that a C<bar> method in the |
740 | C<MyApp::Controller::Catalog::Order::Process> namespace won't match any |
741 | form of C<bar>, C<Catalog>, C<Order>, or C<Process> unless you |
742 | explicitly put this in the regex. To achieve the above, you should |
743 | consider using a C<LocalRegex> action. |
fc7ec1d9 |
744 | |
75c0ec03 |
745 | =item * B<LocalRegex> |
fc7ec1d9 |
746 | |
75c0ec03 |
747 | sub bar : LocalRegex('^widget(\d+)$') { } |
fc7ec1d9 |
748 | |
75c0ec03 |
749 | LocalRegex actions act locally. If you were to use C<bar> in |
750 | C<MyApp::Controller::Catalog>, the above example would match urls like |
751 | http://localhost:3000/catalog/widget23. |
fc7ec1d9 |
752 | |
75c0ec03 |
753 | If you omit the "C<^>" from your regex, then it will match any depth |
754 | from the controller and not immediately off of the controller name. The |
755 | following example differs from the above code in that it will match |
756 | http://localhost:3000/catalog/foo/widget23 as well. |
fc7ec1d9 |
757 | |
75c0ec03 |
758 | package MyApp::Controller::Catalog; |
759 | sub bar : LocalRegex('widget(\d+)$') { } |
fc7ec1d9 |
760 | |
75c0ec03 |
761 | For both LocalRegex and Regex actions, if you use capturing parentheses |
762 | to extract values within the matching URL, those values are available in |
763 | the C<$c-E<gt>req-E<gt>captures> array. In the above example, "widget23" |
764 | would capture "23" in the above example, and |
765 | C<$c-E<gt>req-E<gt>captures-E<gt>[0]> would be "23". If you want to pass |
766 | arguments at the end of your URL, you must use regex action keys. See |
767 | L</URL Path Handling> below. |
fc7ec1d9 |
768 | |
75c0ec03 |
769 | =item * B<Top-level> (B<Global>) |
6c5c02ba |
770 | |
75c0ec03 |
771 | package MyApp::Controller::Foo; |
772 | sub foo : Global { } |
fc7ec1d9 |
773 | |
75c0ec03 |
774 | Matches http://localhost:3000/foo. The function name is mapped |
775 | directly to the application base. You can provide an equivalent |
776 | function in this case by doing the following: |
fc7ec1d9 |
777 | |
75c0ec03 |
778 | package MyApp::Controller::Root |
779 | sub foo : Local { } |
fc7ec1d9 |
780 | |
75c0ec03 |
781 | =item * B<Namespace-Prefixed> (B<Local>) |
fc7ec1d9 |
782 | |
75c0ec03 |
783 | package MyApp::Controller::My::Controller; |
784 | sub foo : Local { } |
fc7ec1d9 |
785 | |
75c0ec03 |
786 | Matches http://localhost:3000/my/controller/foo. |
b33ed88c |
787 | |
75c0ec03 |
788 | This action type indicates that the matching URL must be prefixed with a |
789 | modified form of the component's class (package) name. This modified |
790 | class name excludes the parts that have a pre-defined meaning in |
791 | Catalyst ("MyApp::Controller" in the above example), replaces "::" with |
792 | "/", and converts the name to lower case. See L</Components> for a full |
793 | explanation of the pre-defined meaning of Catalyst component class |
794 | names. |
b33ed88c |
795 | |
75c0ec03 |
796 | =item * B<Chained> |
b33ed88c |
797 | |
75c0ec03 |
798 | Catalyst also provides a method to build and dispatch chains of actions, |
799 | like |
fc7ec1d9 |
800 | |
75c0ec03 |
801 | sub catalog : Chained : CaptureArgs(1) { |
802 | my ( $self, $c, $arg ) = @_; |
803 | ... |
5a8ed4fe |
804 | } |
fc7ec1d9 |
805 | |
75c0ec03 |
806 | sub item : Chained('catalog') : Args(1) { |
807 | my ( $self, $c, $arg ) = @_; |
808 | ... |
5a8ed4fe |
809 | } |
fc7ec1d9 |
810 | |
d708fed4 |
811 | to handle a C</catalog/*/item/*> path. For further information about this |
75c0ec03 |
812 | dispatch type, please see L<Catalyst::DispatchType::Chained>. |
7f71afbe |
813 | |
75c0ec03 |
814 | =item * B<Private> |
fc7ec1d9 |
815 | |
75c0ec03 |
816 | sub foo : Private { } |
fc7ec1d9 |
817 | |
75c0ec03 |
818 | Matches no URL, and cannot be executed by requesting a URL that |
819 | corresponds to the action key. Private actions can be executed only |
820 | inside a Catalyst application, by calling the C<forward> method: |
fc7ec1d9 |
821 | |
75c0ec03 |
822 | $c->forward('foo'); |
fc7ec1d9 |
823 | |
75c0ec03 |
824 | See L</Flow Control> for a full explanation of C<forward>. Note that, as |
825 | discussed there, when forwarding from another component, you must use |
826 | the absolute path to the method, so that a private C<bar> method in your |
827 | C<MyApp::Controller::Catalog::Order::Process> controller must, if called |
828 | from elsewhere, be reached with |
829 | C<$c-E<gt>forward('/catalog/order/process/bar')>. |
fc7ec1d9 |
830 | |
75c0ec03 |
831 | =item * B<Args> |
fc7ec1d9 |
832 | |
75c0ec03 |
833 | Args is not an action type per se, but an action modifier - it adds a |
834 | match restriction to any action it's provided to, requiring only as many |
835 | path parts as are specified for the action to be valid - for example in |
836 | MyApp::Controller::Foo, |
fc7ec1d9 |
837 | |
75c0ec03 |
838 | sub bar :Local |
fc7ec1d9 |
839 | |
75c0ec03 |
840 | would match any URL starting /foo/bar/. To restrict this you can do |
fc7ec1d9 |
841 | |
75c0ec03 |
842 | sub bar :Local :Args(1) |
fc7ec1d9 |
843 | |
75c0ec03 |
844 | to only match /foo/bar/*/ |
fc7ec1d9 |
845 | |
75c0ec03 |
846 | =back |
fc7ec1d9 |
847 | |
75c0ec03 |
848 | B<Note:> After seeing these examples, you probably wonder what the point |
849 | is of defining names for regex and path actions. Every public action is |
850 | also a private one, so you have one unified way of addressing components |
851 | in your C<forward>s. |
fc7ec1d9 |
852 | |
75c0ec03 |
853 | =head4 Built-in Private Actions |
b248fa4a |
854 | |
75c0ec03 |
855 | In response to specific application states, Catalyst will automatically |
856 | call these built-in private actions in your application class: |
fc7ec1d9 |
857 | |
75c0ec03 |
858 | =over 4 |
fc7ec1d9 |
859 | |
75c0ec03 |
860 | =item * B<default : Private> |
fc7ec1d9 |
861 | |
75c0ec03 |
862 | Called when no other action matches. Could be used, for example, for |
863 | displaying a generic frontpage for the main app, or an error page for |
864 | individual controllers. |
fc7ec1d9 |
865 | |
75c0ec03 |
866 | If C<default> isn't acting how you would expect, look at using a |
867 | L</Literal> C<Path> action (with an empty path string). The difference |
868 | is that C<Path> takes arguments relative from the namespace and |
869 | C<default> I<always> takes arguments relative from the root, regardless |
870 | of what controller it's in. Indeed, this is now the recommended way of |
871 | handling default situations; the C<default> private controller should |
872 | be considered deprecated. |
6b10c72b |
873 | |
75c0ec03 |
874 | =item * B<index : Private> |
875 | |
876 | C<index> is much like C<default> except that it takes no arguments |
877 | and it is weighted slightly higher in the matching process. It is |
878 | useful as a static entry point to a controller, e.g. to have a static |
879 | welcome page. Note that it's also weighted higher than Path. |
880 | |
881 | =item * B<begin : Private> |
882 | |
883 | Called at the beginning of a request, before any matching actions are |
884 | called. |
885 | |
886 | =item * B<end : Private> |
887 | |
888 | Called at the end of a request, after all matching actions are called. |
889 | |
890 | =back |
891 | |
892 | =head4 Built-in actions in controllers/autochaining |
893 | |
894 | Package MyApp::Controller::Foo; |
895 | sub begin : Private { } |
896 | sub default : Private { } |
897 | sub auto : Private { } |
898 | |
899 | You can define built-in private actions within your controllers as |
900 | well. The actions will override the ones in less-specific controllers, |
901 | or your application class. In other words, for each of the three |
902 | built-in private actions, only one will be run in any request |
903 | cycle. Thus, if C<MyApp::Controller::Catalog::begin> exists, it will be |
904 | run in place of C<MyApp::begin> if you're in the C<catalog> namespace, |
905 | and C<MyApp::Controller::Catalog::Order::begin> would override this in |
906 | turn. |
6b10c72b |
907 | |
75c0ec03 |
908 | =item * B<auto : Private> |
6b10c72b |
909 | |
75c0ec03 |
910 | In addition to the normal built-in actions, you have a special action |
911 | for making chains, C<auto>. Such C<auto> actions will be run after any |
912 | C<begin>, but before your action is processed. Unlike the other |
913 | built-ins, C<auto> actions I<do not> override each other; they will be |
914 | called in turn, starting with the application class and going through to |
915 | the I<most> specific class. I<This is the reverse of the order in which |
916 | the normal built-ins override each other>. |
6b10c72b |
917 | |
75c0ec03 |
918 | Here are some examples of the order in which the various built-ins |
919 | would be called: |
6b10c72b |
920 | |
75c0ec03 |
921 | =over 4 |
6b10c72b |
922 | |
75c0ec03 |
923 | =item for a request for C</foo/foo> |
fc7ec1d9 |
924 | |
75c0ec03 |
925 | MyApp::begin |
926 | MyApp::auto |
927 | MyApp::Controller::Foo::default # in the absence of MyApp::Controller::Foo::Foo |
928 | MyApp::end |
fc7ec1d9 |
929 | |
75c0ec03 |
930 | =item for a request for C</foo/bar/foo> |
fc7ec1d9 |
931 | |
75c0ec03 |
932 | MyApp::Controller::Foo::Bar::begin |
933 | MyApp::auto |
934 | MyApp::Controller::Foo::auto |
935 | MyApp::Controller::Foo::Bar::auto |
936 | MyApp::Controller::Foo::Bar::default # for MyApp::Controller::Foo::Bar::foo |
937 | MyApp::Controller::Foo::Bar::end |
c02f7490 |
938 | |
75c0ec03 |
939 | =back |
fc7ec1d9 |
940 | |
75c0ec03 |
941 | The C<auto> action is also distinguished by the fact that you can break |
942 | out of the processing chain by returning 0. If an C<auto> action returns |
943 | 0, any remaining actions will be skipped, except for C<end>. So, for the |
944 | request above, if the first auto returns false, the chain would look |
945 | like this: |
fc7ec1d9 |
946 | |
75c0ec03 |
947 | =over 4 |
c02f7490 |
948 | |
75c0ec03 |
949 | =item for a request for C</foo/bar/foo> where first C<auto> returns |
950 | false |
fc7ec1d9 |
951 | |
75c0ec03 |
952 | MyApp::Controller::Foo::Bar::begin |
953 | MyApp::auto |
954 | MyApp::Controller::Foo::Bar::end |
fc7ec1d9 |
955 | |
75c0ec03 |
956 | =back |
c02f7490 |
957 | |
75c0ec03 |
958 | An example of why one might use this is an authentication action: you |
959 | could set up a C<auto> action to handle authentication in your |
960 | application class (which will always be called first), and if |
961 | authentication fails, returning 0 would skip any remaining methods |
962 | for that URL. |
fc7ec1d9 |
963 | |
75c0ec03 |
964 | B<Note:> Looking at it another way, C<auto> actions have to return a |
965 | true value to continue processing! You can also C<die> in the auto |
966 | action; in that case, the request will go straight to the finalize |
967 | stage, without processing further actions. |
c02f7490 |
968 | |
75c0ec03 |
969 | =head4 URL Path Handling |
c02f7490 |
970 | |
75c0ec03 |
971 | You can pass variable arguments as part of the URL path, separated with |
972 | forward slashes (/). If the action is a Regex or LocalRegex, the '$' anchor |
973 | must be used. For example, suppose you want to handle C</foo/$bar/$baz>, |
974 | where C<$bar> and C<$baz> may vary: |
c02f7490 |
975 | |
75c0ec03 |
976 | sub foo : Regex('^foo$') { my ($self, $context, $bar, $baz) = @_; } |
c02f7490 |
977 | |
75c0ec03 |
978 | But what if you also defined actions for C</foo/boo> and C</foo/boo/hoo>? |
c02f7490 |
979 | |
75c0ec03 |
980 | sub boo : Path('foo/boo') { .. } |
981 | sub hoo : Path('foo/boo/hoo') { .. } |
24cda51b |
982 | |
75c0ec03 |
983 | Catalyst matches actions in most specific to least specific order: |
24cda51b |
984 | |
75c0ec03 |
985 | /foo/boo/hoo |
986 | /foo/boo |
987 | /foo # might be /foo/bar/baz but won't be /foo/boo/hoo |
24cda51b |
988 | |
75c0ec03 |
989 | So Catalyst would never mistakenly dispatch the first two URLs to the |
990 | '^foo$' action. |
24cda51b |
991 | |
75c0ec03 |
992 | If a Regex or LocalRegex action doesn't use the '$' anchor, the action will |
993 | still match a URL containing arguments, however the arguments won't be |
994 | available via C<@_>. |
24cda51b |
995 | |
75c0ec03 |
996 | =head4 Parameter Processing |
24cda51b |
997 | |
75c0ec03 |
998 | Parameters passed in the URL query string are handled with methods in |
999 | the L<Catalyst::Request> class. The C<param> method is functionally |
1000 | equivalent to the C<param> method of C<CGI.pm> and can be used in |
1001 | modules that require this. |
24cda51b |
1002 | |
75c0ec03 |
1003 | # http://localhost:3000/catalog/view/?category=hardware&page=3 |
1004 | my $category = $c->req->param('category'); |
1005 | my $current_page = $c->req->param('page') || 1; |
24cda51b |
1006 | |
75c0ec03 |
1007 | # multiple values for single parameter name |
1008 | my @values = $c->req->param('scrolling_list'); |
24cda51b |
1009 | |
75c0ec03 |
1010 | # DFV requires a CGI.pm-like input hash |
1011 | my $results = Data::FormValidator->check($c->req->params, \%dfv_profile); |
24cda51b |
1012 | |
75c0ec03 |
1013 | =head3 Flow Control |
24cda51b |
1014 | |
75c0ec03 |
1015 | You control the application flow with the C<forward> method, which |
1016 | accepts the key of an action to execute. This can be an action in the |
1017 | same or another Catalyst controller, or a Class name, optionally |
1018 | followed by a method name. After a C<forward>, the control flow will |
1019 | return to the method from which the C<forward> was issued. |
24cda51b |
1020 | |
75c0ec03 |
1021 | A C<forward> is similar to a method call. The main differences are that |
1022 | it wraps the call in an C<eval> to allow exception handling; it |
1023 | automatically passes along the context object (C<$c> or C<$context>); |
1024 | and it allows profiling of each call (displayed in the log with |
1025 | debugging enabled). |
24cda51b |
1026 | |
75c0ec03 |
1027 | sub hello : Global { |
1028 | my ( $self, $c ) = @_; |
1029 | $c->stash->{message} = 'Hello World!'; |
1030 | $c->forward('check_message'); # $c is automatically included |
1031 | } |
24cda51b |
1032 | |
75c0ec03 |
1033 | sub check_message : Private { |
1034 | my ( $self, $c ) = @_; |
1035 | return unless $c->stash->{message}; |
1036 | $c->forward('show_message'); |
1037 | } |
24cda51b |
1038 | |
75c0ec03 |
1039 | sub show_message : Private { |
1040 | my ( $self, $c ) = @_; |
1041 | $c->res->body( $c->stash->{message} ); |
1042 | } |
24cda51b |
1043 | |
75c0ec03 |
1044 | A C<forward> does not create a new request, so your request object |
1045 | (C<$c-E<gt>req>) will remain unchanged. This is a key difference between |
1046 | using C<forward> and issuing a redirect. |
24cda51b |
1047 | |
75c0ec03 |
1048 | You can pass new arguments to a C<forward> by adding them |
1049 | in an anonymous array. In this case C<$c-E<gt>req-E<gt>args> |
1050 | will be changed for the duration of the C<forward> only; upon |
1051 | return, the original value of C<$c-E<gt>req-E<gt>args> will |
1052 | be reset. |
24cda51b |
1053 | |
75c0ec03 |
1054 | sub hello : Global { |
1055 | my ( $self, $c ) = @_; |
1056 | $c->stash->{message} = 'Hello World!'; |
1057 | $c->forward('check_message',[qw/test1/]); |
1058 | # now $c->req->args is back to what it was before |
1059 | } |
24cda51b |
1060 | |
75c0ec03 |
1061 | sub check_message : Private { |
1062 | my ( $self, $c ) = @_; |
1063 | my $first_argument = $c->req->args->[0]; # now = 'test1' |
1064 | # do something... |
1065 | } |
24cda51b |
1066 | |
75c0ec03 |
1067 | As you can see from these examples, you can just use the method name as |
1068 | long as you are referring to methods in the same controller. If you want |
1069 | to forward to a method in another controller, or the main application, |
1070 | you will have to refer to the method by absolute path. |
24cda51b |
1071 | |
75c0ec03 |
1072 | $c->forward('/my/controller/action'); |
1073 | $c->forward('/default'); # calls default in main application |
24cda51b |
1074 | |
75c0ec03 |
1075 | Here are some examples of how to forward to classes and methods. |
24cda51b |
1076 | |
75c0ec03 |
1077 | sub hello : Global { |
1078 | my ( $self, $c ) = @_; |
1079 | $c->forward(qw/MyApp::Model::Hello say_hello/); |
1080 | } |
24cda51b |
1081 | |
75c0ec03 |
1082 | sub bye : Global { |
1083 | my ( $self, $c ) = @_; |
1084 | $c->forward('MyApp::Model::Hello'); # no method: will try 'process' |
1085 | } |
24cda51b |
1086 | |
75c0ec03 |
1087 | package MyApp::Model::Hello; |
24cda51b |
1088 | |
75c0ec03 |
1089 | sub say_hello { |
1090 | my ( $self, $c ) = @_; |
1091 | $c->res->body('Hello World!'); |
1092 | } |
5403ad42 |
1093 | |
75c0ec03 |
1094 | sub process { |
1095 | my ( $self, $c ) = @_; |
1096 | $c->res->body('Goodbye World!'); |
5403ad42 |
1097 | } |
24cda51b |
1098 | |
75c0ec03 |
1099 | Note that C<forward> returns to the calling action and continues |
1100 | processing after the action finishes. If you want all further processing |
1101 | in the calling action to stop, use C<detach> instead, which will execute |
1102 | the C<detach>ed action and not return to the calling sub. In both cases, |
1103 | Catalyst will automatically try to call process() if you omit the |
1104 | method. |
1105 | |
24cda51b |
1106 | |
fc7ec1d9 |
1107 | =head3 Testing |
1108 | |
75c0ec03 |
1109 | Catalyst has a built-in http server for testing or local |
1110 | deployment. (Later, you can easily use a more powerful server, for |
1111 | example Apache/mod_perl or FastCGI, in a production environment.) |
fc7ec1d9 |
1112 | |
1113 | Start your application on the command line... |
1114 | |
b33ed88c |
1115 | script/myapp_server.pl |
fc7ec1d9 |
1116 | |
1117 | ...then visit http://localhost:3000/ in a browser to view the output. |
1118 | |
1119 | You can also do it all from the command line: |
1120 | |
b33ed88c |
1121 | script/myapp_test.pl http://localhost/ |
fc7ec1d9 |
1122 | |
75c0ec03 |
1123 | Catalyst has a number of tools for actual regression testing of |
1124 | applications. The helper scripts will automatically generate basic tests |
1125 | that can be extended as you develop your project. To write your own |
1126 | comprehensive test scripts, L<Test::WWW::Mechanize::Catalyst> is an |
1127 | invaluable tool. |
1128 | |
1129 | For more testing ideas, see L<Catalyst::Manual::Tutorial::Testing>. |
1130 | |
fc7ec1d9 |
1131 | Have fun! |
1132 | |
75c0ec03 |
1133 | =head1 SEE ALSO |
1134 | |
1135 | =item * L<Catalyst::Manual::About> |
1136 | |
1137 | =item * L<Catalyst::Manual::Tutorial> |
1138 | |
1139 | =item * L<Catalyst> |
1140 | |
3cb1db8c |
1141 | =head1 SUPPORT |
1142 | |
1143 | IRC: |
1144 | |
1145 | Join #catalyst on irc.perl.org. |
75c0ec03 |
1146 | Join #catalyst-dev on irc.perl.org to help with development. |
3cb1db8c |
1147 | |
75c0ec03 |
1148 | Mailing lists: |
3cb1db8c |
1149 | |
1150 | http://lists.rawmode.org/mailman/listinfo/catalyst |
1151 | http://lists.rawmode.org/mailman/listinfo/catalyst-dev |
1152 | |
fc7ec1d9 |
1153 | =head1 AUTHOR |
1154 | |
cda8d1ac |
1155 | Sebastian Riedel, C<sri@oook.de> |
1156 | David Naughton, C<naughton@umn.edu> |
1157 | Marcus Ramberg, C<mramberg@cpan.org> |
f531dd37 |
1158 | Jesse Sheidlower, C<jester@panix.com> |
129cfe74 |
1159 | Danijel Milicevic, C<me@danijel.de> |
c37916b0 |
1160 | Kieren Diment, C<kd@totaldatasolution.com> |
24cda51b |
1161 | Yuval Kogman, C<nothingmuch@woobling.org> |
fc7ec1d9 |
1162 | |
1163 | =head1 COPYRIGHT |
1164 | |
75c0ec03 |
1165 | This program is free software. You can redistribute it and/or modify it |
aa2b0d97 |
1166 | under the same terms as Perl itself. |