ca49cf3c534b30be4743512db943531e855dedc1
[catagits/Catalyst-Manual.git] / lib / Catalyst / Manual / Cookbook.pod
1 =head1 NAME
2
3 Catalyst::Manual::Cookbook - Cooking with Catalyst
4
5 =head1 DESCRIPTION
6
7 Yummy code like your mum used to bake!
8
9 =head1 RECIPES
10
11 =head1 Basics
12
13 These recipes cover some basic stuff that is worth knowing for
14 catalyst developers.
15
16 =head2 Delivering a Custom Error Page
17
18 By default, Catalyst will display its own error page whenever it
19 encounters an error in your application. When running under C<-Debug>
20 mode, the error page is a useful screen including the error message
21 and L<Data::Dump> output of the relevant parts of the C<$c> context
22 object.  When not in C<-Debug>, users see a simple "Please come back
23 later" screen.
24
25 To use a custom error page, use a special C<end> method to
26 short-circuit the error processing. The following is an example; you
27 might want to adjust it further depending on the needs of your
28 application (for example, any calls to C<fillform> will probably need
29 to go into this C<end> method; see L<Catalyst::Plugin::FillInForm>).
30
31     sub end : Private {
32         my ( $self, $c ) = @_;
33
34         if ( scalar @{ $c->error } ) {
35             $c->stash->{errors}   = $c->error;
36             $c->stash->{template} = 'errors.tt';
37             $c->forward('MyApp::View::TT');
38             $c->error(0);
39         }
40
41         return 1 if $c->response->status =~ /^3\d\d$/;
42         return 1 if $c->response->body;
43
44         unless ( $c->response->content_type ) {
45             $c->response->content_type('text/html; charset=utf-8');
46         }
47
48         $c->forward('MyApp::View::TT');
49     }
50
51 You can manually set errors in your code to trigger this page by calling
52
53     $c->error( 'You broke me!' );
54
55 =head2 Disable statistics
56
57 Just add this line to your application class if you don't want those
58 nifty statistics in your debug messages.
59
60     sub Catalyst::Log::info { }
61
62 =head2 Enable debug status in the environment
63
64 Normally you enable the debugging info by adding the C<-Debug> flag to
65 your C<use Catalyst> statement . However, you can also enable it using
66 environment variable, so you can (for example) get debug info without
67 modifying your application scripts. Just set C<CATALYST_DEBUG> or
68 C<E<lt>MYAPPE<gt>_DEBUG> to a true value.
69
70 =head2 Sessions
71
72 When you have your users identified, you will want to somehow remember
73 that fact, to save them from having to identify themselves for every
74 single page. One way to do this is to send the username and password
75 parameters in every single page, but that's ugly, and won't work for
76 static pages.
77
78 Sessions are a method of saving data related to some transaction, and
79 giving the whole collection a single ID. This ID is then given to the
80 user to return to us on every page they visit while logged in. The
81 usual way to do this is using a browser cookie.
82
83 Catalyst uses two types of plugins to represent sessions:
84
85 =head3 State
86
87 A State module is used to keep track of the state of the session
88 between the users browser, and your application.
89
90 A common example is the Cookie state module, which sends the browser a
91 cookie containing the session ID. It will use default value for the
92 cookie name and domain, so will "just work" when used.
93
94 =head3 Store
95
96 A Store module is used to hold all the data relating to your session,
97 for example the users ID, or the items for their shopping cart. You
98 can store data in memory (FastMmap), in a file (File) or in a database
99 (DBI).
100
101 =head3 Authentication magic
102
103 If you have included the session modules in your application, the
104 Authentication modules will automagically use your session to save and
105 retrieve the user data for you.
106
107 =head3 Using a session
108
109 Once the session modules are loaded, the session is available as C<<
110 $c->session >>, and can be writen to and read from as a simple hash
111 reference.
112
113 =head3 EXAMPLE
114
115   use parent qw/Catalyst/;
116   use Catalyst  qw/
117                          Session
118                          Session::Store::FastMmap
119                          Session::State::Cookie
120                    /;
121
122
123   ## Write data into the session
124
125   sub add_item : Local {
126      my ( $self, $c ) = @_;
127
128      my $item_id = $c->req->param("item");
129
130      push @{ $c->session->{items} }, $item_id;
131
132   }
133
134   ## A page later we retrieve the data from the session:
135
136   sub get_items : Local {
137      my ( $self, $c ) = @_;
138
139      $c->stash->{items_to_display} = $c->session->{items};
140
141   }
142
143
144 =head3 More information
145
146 L<http://search.cpan.org/dist/Catalyst-Plugin-Session>
147
148 L<http://search.cpan.org/dist/Catalyst-Plugin-Session-State-Cookie>
149
150 L<http://search.cpan.org/dist/Catalyst-Plugin-Session-State-URI>
151
152 L<http://search.cpan.org/dist/Catalyst-Plugin-Session-Store-FastMmap>
153
154 L<http://search.cpan.org/dist/Catalyst-Plugin-Session-Store-File>
155
156 L<http://search.cpan.org/dist/Catalyst-Plugin-Session-Store-DBI>
157
158 =head2 Configure your application
159
160 You configure your application with the C<config> method in your
161 application class. This can be hard-coded, or brought in from a
162 separate configuration file.
163
164 =head3 Using Config::General
165
166 L<Config::General|Config::General> is a method for creating flexible
167 and readable configuration files. It's a great way to keep your
168 Catalyst application configuration in one easy-to-understand location.
169
170 Now create C<myapp.conf> in your application home:
171
172   name     MyApp
173
174   # session; perldoc Catalyst::Plugin::Session::FastMmap
175   <Session>
176     expires 3600
177     rewrite 0
178     storage /tmp/myapp.session
179   </Session>
180
181   # emails; perldoc Catalyst::Plugin::Email
182   # this passes options as an array :(
183   Mail SMTP
184   Mail localhost
185
186 This is equivalent to:
187
188   # configure base package
189   __PACKAGE__->config( name => MyApp );
190   # configure authentication
191   __PACKAGE__->config->{authentication} = {
192     user_class => 'MyApp::Model::MyDB::Customer',
193     ...
194   };
195   # configure sessions
196   __PACKAGE__->config->{session} = {
197     expires => 3600,
198     ...
199   };
200   # configure email sending
201   __PACKAGE__->config->{email} = [qw/SMTP localhost/];
202
203 See also L<Config::General|Config::General>.
204
205 =head1 Skipping your VCS's directories
206
207 Catalyst uses Module::Pluggable to load Models, Views and Controllers.
208 Module::Pluggable will scan through all directories and load modules
209 it finds.  Sometimes you might want to skip some of these directories,
210 for example when your version control system makes a subdirectory with
211 meta-information in every version-controlled directory.  While
212 Catalyst skips subversion and CVS directories already, there are other
213 source control systems.  Here is the configuration you need to add
214 their directories to the list to skip.
215
216 You can make catalyst skip these directories using the Catalyst config:
217
218   # Configure the application
219   __PACKAGE__->config(
220       name => 'MyApp',
221       setup_components => { except => qr/SCCS/ },
222   );
223
224 See the Module::Pluggable manual page for more information on B<except>
225 and other options.
226
227 =head1 Users and Access Control
228
229 Most multiuser, and some single user web applications require that
230 users identify themselves, and the application is often required to
231 define those roles.  The recipes below describe some ways of doing
232 this.
233
234 =head2 Authentication (logging in)
235
236 This is extensively covered in other documentation; see in particular
237 L<Catalyst::Plugin::Authentication> and the Authentication chapter
238 of the Tutorial at L<Catalyst::Manual::Tutorial::Authorization>.
239
240 =head2 Pass-through login (and other actions)
241
242 An easy way of having assorted actions that occur during the processing
243 of a request that are orthogonal to its actual purpose - logins, silent
244 commands etc. Provide actions for these, but when they're required for
245 something else fill e.g. a form variable __login and have a sub begin
246 like so:
247
248     sub begin : Private {
249       my ($self, $c) = @_;
250       foreach my $action (qw/login docommand foo bar whatever/) {
251         if ($c->req->params->{"__${action}"}) {
252           $c->forward($action);
253         }
254       }
255     }
256
257
258 =head2 Role-based Authorization
259
260 For more advanced access control, you may want to consider using role-based
261 authorization. This means you can assign different roles to each user, e.g.
262 "user", "admin", etc.
263
264 The C<login> and C<logout> methods and view template are exactly the same as
265 in the previous example.
266
267 The L<Catalyst::Plugin::Authorization::Roles> plugin is required when
268 implementing roles:
269
270  use parent qw/Catalyst/;
271  use Catalyst qw/
272      Authentication
273      Authentication::Credential::Password
274      Authentication::Store::Htpasswd
275      Authorization::Roles/;
276
277 Roles are implemented automatically when using
278 L<Catalyst::Authentication::Store::Htpasswd>:
279
280   # no additional role configuration required
281   __PACKAGE__->config->{authentication}{htpasswd} = "passwdfile";
282
283 Or can be set up manually when using L<Catalyst::Authentication::Store::DBIC>:
284
285   # Authorization using a many-to-many role relationship
286   __PACKAGE__->config->{authorization}{dbic} = {
287     'role_class'           => 'My::Model::DBIC::Role',
288     'role_field'           => 'name',
289     'user_role_user_field' => 'user',
290
291     # DBIx::Class only (omit if using Class::DBI)
292     'role_rel'             => 'user_role',
293
294     # Class::DBI only, (omit if using DBIx::Class)
295     'user_role_class'      => 'My::Model::CDBI::UserRole'
296     'user_role_role_field' => 'role',
297   };
298
299 To restrict access to any action, you can use the C<check_user_roles> method:
300
301   sub restricted : Local {
302      my ( $self, $c ) = @_;
303
304      $c->detach("unauthorized")
305        unless $c->check_user_roles( "admin" );
306
307      # do something restricted here
308   }
309
310 You can also use the C<assert_user_roles> method. This just gives an
311 error if the current user does not have one of the required roles:
312
313   sub also_restricted : Global {
314     my ( $self, $c ) = @_;
315     $c->assert_user_roles( qw/ user admin / );
316   }
317   
318 =head2 Authentication/Authorization
319
320 This is done in several steps:
321
322 =over 4
323
324 =item Verification
325
326 Getting the user to identify themselves, by giving you some piece of
327 information known only to you and the user. Then you can assume that
328 the user is who they say they are. This is called B<credential
329 verification>.
330
331 =item Authorization
332
333 Making sure the user only accesses functions you want them to
334 access. This is done by checking the verified users data against your
335 internal list of groups, or allowed persons for the current page.
336
337 =back
338
339 =head3 Modules
340
341 The Catalyst Authentication system is made up of many interacting
342 modules, to give you the most flexibility possible.
343
344 =head4 Credential verifiers
345
346 A Credential module tables the user input, and passes it to a Store,
347 or some other system, for verification. Typically, a user object is
348 created by either this module or the Store and made accessible by a
349 C<< $c->user >> call.
350
351 Examples:
352
353  Password - Simple username/password checking.
354  HTTPD    - Checks using basic HTTP auth.
355  TypeKey  - Check using the typekey system.
356
357 =head3 Storage backends
358
359 A Storage backend contains the actual data representing the users. It
360 is queried by the credential verifiers. Updating the store is not done
361 within this system, you will need to do it yourself.
362
363 Examples:
364
365  DBIC     - Storage using a database.
366  Minimal  - Storage using a simple hash (for testing).
367
368 =head3 User objects
369
370 A User object is created by either the storage backend or the
371 credential verifier, and filled with the retrieved user information.
372
373 Examples:
374
375  Hash     - A simple hash of keys and values.
376
377 =head3 ACL authorization
378
379 ACL stands for Access Control List. The ACL plugin allows you to
380 regulate access on a path by path basis, by listing which users, or
381 roles, have access to which paths.
382
383 =head3 Roles authorization
384
385 Authorization by roles is for assigning users to groups, which can
386 then be assigned to ACLs, or just checked when needed.
387
388 =head3 Logging in
389
390 When you have chosen your modules, all you need to do is call the C<<
391 $c->login >> method. If called with no parameters, it will try to find
392 suitable parameters, such as B<username> and B<password>, or you can
393 pass it these values.
394
395 =head3 Checking roles
396
397 Role checking is done by using the C<< $c->check_user_roles >> method,
398 this will check using the currently logged in user (via C<< $c->user
399 >>). You pass it the name of a role to check, and it returns true if
400 the user is a member.
401
402 =head3 EXAMPLE
403
404  use parent qw/Catalyst/;
405  use Catalyst qw/Authentication
406                  Authentication::Credential::Password
407                  Authentication::Store::Htpasswd
408                  Authorization::Roles/;
409
410  __PACKAGE__->config->{authentication}{htpasswd} = "passwdfile";
411
412   sub login : Local {
413      my ($self, $c) = @_;
414
415      if (    my $user = $c->req->param("user")
416          and my $password = $c->req->param("password") )
417      {
418          if ( $c->login( $user, $password ) ) {
419               $c->res->body( "hello " . $c->user->name );
420          } else {
421             # login incorrect
422          }
423      }
424      else {
425          # invalid form input
426      }
427   }
428
429   sub restricted : Local {
430      my ( $self, $c ) = @_;
431
432      $c->detach("unauthorized")
433        unless $c->check_user_roles( "admin" );
434
435      # do something restricted here
436   }
437
438 =head3 Using authentication in a testing environment
439
440 Ideally, to write tests for authentication/authorization code one
441 would first set up a test database with known data, then use
442 L<Test::WWW::Mechanize::Catalyst> to simulate a user logging
443 in. Unfortunately the former can be rather awkward, which is why it's
444 a good thing that the authentication framework is so flexible.
445
446 Instead of using a test database, one can simply change the
447 authentication store to something a bit easier to deal with in a
448 testing environment. Additionally, this has the advantage of not
449 modifying one's database, which can be problematic if one forgets to
450 use the testing instead of production database.
451
452 e.g.,
453
454   use Catalyst::Plugin::Authentication::Store::Minimal::Backend;
455
456   # Sets up the user `test_user' with password `test_pass'
457   MyApp->default_auth_store(
458     Catalyst::Plugin::Authentication::Store::Minimal::Backend->new({
459       test_user => { password => 'test_pass' },
460     })
461   );
462
463 Now, your test code can call C<$c->login('test_user', 'test_pass')> and
464 successfully login, without messing with the database at all.
465
466 =head3 More information
467
468 L<http://search.cpan.org/perldoc?Catalyst::Plugin::Authentication> has a longer explanation.
469
470 =head2 Authorization
471
472 =head3 Introduction
473
474 Authorization is the step that comes after
475 authentication. Authentication establishes that the user agent is
476 really representing the user we think it's representing, and then
477 authorization determines what this user is allowed to do.
478
479 =head3 Role Based Access Control
480
481 Under role based access control each user is allowed to perform any
482 number of roles. For example, at a zoo no one but specially trained
483 personnel can enter the moose cage (Mynd you, møøse bites kan be
484 pretty nasti!). For example:
485
486     package Zoo::Controller::MooseCage;
487
488     sub feed_moose : Local {
489         my ( $self, $c ) = @_;
490
491         $c->model( "Moose" )->eat( $c->req->param("food") );
492     }
493
494 With this action, anyone can just come into the moose cage and feed
495 the moose, which is a very dangerous thing. We need to restrict this
496 action, so that only a qualified moose feeder can perform that action.
497
498 The Authorization::Roles plugin let's us perform role based access
499 control checks. Let's load it:
500
501     use parent qw/Catalyst/;
502     use Catalyst qw/
503                     Authentication # yadda yadda
504                     Authorization::Roles
505                   /;
506
507 And now our action should look like this:
508
509     sub feed_moose : Local {
510         my ( $self, $c ) = @_;
511
512         if ( $c->check_roles( "moose_feeder" ) ) {
513             $c->model( "Moose" )->eat( $c->req->param("food") );
514         } else {
515             $c->stash->{error} = "unauthorized";
516         }
517     }
518
519 This checks C<< $c->user >>, and only if the user has B<all> the roles
520 in the list, a true value is returned.
521
522 C<check_roles> has a sister method, C<assert_roles>, which throws an
523 exception if any roles are missing.
524
525 Some roles that might actually make sense in, say, a forum application:
526
527 =over 4
528
529 =item *
530
531 administrator
532
533 =item *
534
535 moderator
536
537 =back
538
539 each with a distinct task (system administration versus content
540 administration).
541
542 =head3 Access Control Lists
543
544 Checking for roles all the time can be tedious and error prone.
545
546 The Authorization::ACL plugin let's us declare where we'd like checks
547 to be done automatically for us.
548
549 For example, we may want to completely block out anyone who isn't a
550 C<moose_feeder> from the entire C<MooseCage> controller:
551
552     Zoo->deny_access_unless( "/moose_cage", [qw/moose_feeder/] );
553
554 The role list behaves in the same way as C<check_roles>. However, the
555 ACL plugin isn't limited to just interacting with the Roles plugin. We
556 can use a code reference instead. For example, to allow either moose
557 trainers or moose feeders into the moose cage, we can create a more
558 complex check:
559
560     Zoo->deny_access_unless( "/moose_cage", sub {
561         my $c = shift;
562         $c->check_roles( "moose_trainer" ) || $c->check_roles( "moose_feeder" );
563     });
564
565 The more specific a role, the earlier it will be checked. Let's say
566 moose feeders are now restricted to only the C<feed_moose> action,
567 while moose trainers get access everywhere:
568
569     Zoo->deny_access_unless( "/moose_cage", [qw/moose_trainer/] );
570     Zoo->allow_access_if( "/moose_cage/feed_moose", [qw/moose_feeder/]);
571
572 When the C<feed_moose> action is accessed the second check will be
573 made. If the user is a C<moose_feeder>, then access will be
574 immediately granted. Otherwise, the next rule in line will be tested -
575 the one checking for a C<moose_trainer>.  If this rule is not
576 satisfied, access will be immediately denied.
577
578 Rules applied to the same path will be checked in the order they were
579 added.
580
581 Lastly, handling access denial events is done by creating an
582 C<access_denied> private action:
583
584     sub access_denied : Private {
585         my ( $self, $c, $action ) = @_;
586     }
587
588 This action works much like auto, in that it is inherited across
589 namespaces (not like object oriented code). This means that the
590 C<access_denied> action which is B<nearest> to the action which was
591 blocked will be triggered.
592
593 If this action does not exist, an error will be thrown, which you can
594 clean up in your C<end> private action instead.
595
596 Also, it's important to note that if you restrict access to "/" then
597 C<end>, C<default>, etc will also be restricted.
598
599    MyApp->acl_allow_root_internals;
600
601 will create rules that permit access to C<end>, C<begin>, and C<auto> in the
602 root of your app (but not in any other controller).
603
604 =head1 Models
605
606 Models are where application data belongs.  Catalyst is exteremely
607 flexible with the kind of models that it can use.  The recipes here
608 are just the start.
609
610 =head2 Using existing DBIC (etc.) classes with Catalyst
611
612 Many people have existing Model classes that they would like to use
613 with Catalyst (or, conversely, they want to write Catalyst models that
614 can be used outside of Catalyst, e.g.  in a cron job). It's trivial to
615 write a simple component in Catalyst that slurps in an outside Model:
616
617     package MyApp::Model::DB;
618     use base qw/Catalyst::Model::DBIC::Schema/;
619     __PACKAGE__->config(
620         schema_class => 'Some::DBIC::Schema',
621         connect_info => ['dbi:SQLite:foo.db', '', '', {AutoCommit=>1}];
622     );
623     1;
624
625 and that's it! Now C<Some::DBIC::Schema> is part of your
626 Cat app as C<MyApp::Model::DB>.
627
628 =head2 DBIx::Class as a Catalyst Model
629
630 See L<Catalyst::Model::DBIC::Schema>.
631
632 =head2 Create accessors to preload static data once per server instance
633
634 When you have data that you want to load just once from the model at
635 server load instead of for each request, use mk_group_accessors to
636 create accessors and tie them to resultsets in your package that
637 inherits from DBIx::Class::Schema
638
639     package My::Schema;
640     use base qw/DBIx::Class::Schema/;
641     __PACKAGE__->register_class('RESULTSOURCEMONIKER',
642                                 'My::Schema::RESULTSOURCE');
643     __PACKAGE__->mk_group_accessors('simple' =>
644                                 qw(ACCESSORNAME1 ACCESSORNAME2 ACCESSORNAMEn));
645
646     sub connection {
647         my ($self, @rest) = @_;
648         $self->next::method(@rest);
649         # $self is now a live My::Schema object, complete with DB connection 
650
651         $self->ACCESSORNAME1([ $self->resultset('RESULTSOURCEMONIKER')->all ]);
652         $self->ACCESSORNAME2([ $self->resultset('RESULTSOURCEMONIKER')->search({ COLUMN => { '<' => '30' } })->all ]);
653         $self->ACCESSORNAMEn([ $self->resultset('RESULTSOURCEMONIKER')->find(1) ]);
654     }
655
656     1;
657
658 and now in the controller, you can now access any of these without a
659 per-request fetch:
660
661     $c->stash->{something} = $c->model('My::Schema')->schema->ACCESSORNAMEn;
662
663
664 =head2 XMLRPC
665
666 Unlike SOAP, XMLRPC is a very simple (and imo elegant) web-services
667 protocol, exchanging small XML messages like these:
668
669 Request:
670
671     POST /api HTTP/1.1
672     TE: deflate,gzip;q=0.3
673     Connection: TE, close
674     Accept: text/xml
675     Accept: multipart/*
676     Host: 127.0.0.1:3000
677     User-Agent: SOAP::Lite/Perl/0.60
678     Content-Length: 192
679     Content-Type: text/xml
680
681     <?xml version="1.0" encoding="UTF-8"?>
682     <methodCall>
683         <methodName>add</methodName>
684         <params>
685             <param><value><int>1</int></value></param>
686             <param><value><int>2</int></value></param>
687         </params>
688     </methodCall>
689
690 Response:
691
692     Connection: close
693     Date: Tue, 20 Dec 2005 07:45:55 GMT
694     Content-Length: 133
695     Content-Type: text/xml
696     Status: 200
697     X-Catalyst: 5.70
698
699     <?xml version="1.0" encoding="us-ascii"?>
700     <methodResponse>
701         <params>
702             <param><value><int>3</int></value></param>
703         </params>
704     </methodResponse>
705
706 Now follow these few steps to implement the application:
707
708 1. Install Catalyst (5.61 or later), Catalyst::Plugin::XMLRPC (0.06 or
709 later) and SOAP::Lite (for XMLRPCsh.pl).
710
711 2. Create an application framework:
712
713     % catalyst.pl MyApp
714     ...
715     % cd MyApp
716
717 3. Add the XMLRPC plugin to MyApp.pm
718
719     use Catalyst qw/-Debug Static::Simple XMLRPC/;
720
721 4. Add an API controller
722
723     % ./script/myapp_create.pl controller API
724
725 5. Add a XMLRPC redispatch method and an add method with Remote
726 attribute to lib/MyApp/Controller/API.pm
727
728     sub default :Path {
729         my ( $self, $c ) = @_;
730         $c->xmlrpc;
731     }
732
733     sub add : Remote {
734         my ( $self, $c, $a, $b ) = @_;
735         return $a + $b;
736     }
737
738 The default action is the entry point for each XMLRPC request. It will
739 redispatch every request to methods with Remote attribute in the same
740 class.
741
742 The C<add> method is not a traditional action; it has no private or
743 public path. Only the XMLRPC dispatcher knows it exists.
744
745 6. That's it! You have built your first web service. Let's test it with
746 XMLRPCsh.pl (part of SOAP::Lite):
747
748     % ./script/myapp_server.pl
749     ...
750     % XMLRPCsh.pl http://127.0.0.1:3000/api
751     Usage: method[(parameters)]
752     > add( 1, 2 )
753     --- XMLRPC RESULT ---
754     '3'
755
756 =head3 Tip
757
758 Your return data type is usually auto-detected, but you can easily
759 enforce a specific one.
760
761     sub add : Remote {
762         my ( $self, $c, $a, $b ) = @_;
763         return RPC::XML::int->new( $a + $b );
764     }
765     
766
767
768 =head1 Views
769
770 Views pertain to the display of your application.  As with models,
771 catalyst is uncommonly flexible.  The recipes below are just a start.
772
773 =head2 Catalyst::View::TT
774
775 One of the first things you probably want to do when starting a new
776 Catalyst application is set up your View. Catalyst doesn't care how you
777 display your data; you can choose to generate HTML, PDF files, or plain
778 text if you wanted.
779
780 Most Catalyst applications use a template system to generate their HTML,
781 and though there are several template systems available, Template
782 Toolkit is probably the most popular.
783
784 Once again, the Catalyst developers have done all the hard work, and
785 made things easy for the rest of us. Catalyst::View::TT provides the
786 interface to Template Toolkit, and provides Helpers which let us set it
787 up that much more easily.
788
789 =head3 Creating your View
790
791 Catalyst::View::TT provides two different helpers for us to use: TT and
792 TTSite.
793
794 =head4 TT
795
796 Create a basic Template Toolkit View using the provided helper script:
797
798     script/myapp_create.pl view TT TT
799
800 This will create lib/MyApp/View/MyView.pm, which is going to be pretty
801 empty to start. However, it sets everything up that you need to get
802 started. You can now define which template you want and forward to your
803 view. For instance:
804
805     sub hello : Local {
806         my ( $self, $c ) = @_;
807
808         $c->stash->{template} = 'hello.tt';
809
810         $c->forward( $c->view('TT') );
811     }
812
813 In practice you wouldn't do the forwarding manually, but would
814 use L<Catalyst::Action::RenderView>.
815
816 =head4 TTSite
817
818 Although the TT helper does create a functional, working view, you may
819 find yourself having to create the same template files and changing the
820 same options every time you create a new application. The TTSite helper
821 saves us even more time by creating the basic templates and setting some
822 common options for us.
823
824 Once again, you can use the helper script:
825
826     script/myapp_create.pl view TT TTSite
827
828 This time, the helper sets several options for us in the generated View.
829
830     __PACKAGE__->config({
831         CATALYST_VAR => 'Catalyst',
832         INCLUDE_PATH => [
833             MyApp->path_to( 'root', 'src' ),
834             MyApp->path_to( 'root', 'lib' )
835         ],
836         PRE_PROCESS  => 'config/main',
837         WRAPPER      => 'site/wrapper',
838         ERROR        => 'error.tt2',
839         TIMER        => 0
840     });
841
842 =over
843
844 =item 
845
846 INCLUDE_PATH defines the directories that Template Toolkit should search
847 for the template files.
848
849 =item
850
851 PRE_PROCESS is used to process configuration options which are common to
852 every template file.
853
854 =item
855
856 WRAPPER is a file which is processed with each template, usually used to
857 easily provide a common header and footer for every page.
858
859 =back
860
861 In addition to setting these options, the TTSite helper also created the
862 template and config files for us! In the 'root' directory, you'll notice
863 two new directories: src and lib.
864
865 Several configuration files in root/lib/config are called by PRE_PROCESS.
866
867 The files in root/lib/site are the site-wide templates, called by
868 WRAPPER, and display the html framework, control the layout, and provide
869 the templates for the header and footer of your page. Using the template
870 organization provided makes it much easier to standardize pages and make
871 changes when they are (inevitably) needed.
872
873 The template files that you will create for your application will go
874 into root/src, and you don't need to worry about putting the the <html>
875 or <head> sections; just put in the content. The WRAPPER will the rest
876 of the page around your template for you.
877
878
879 =head3 $c->stash
880
881 Of course, having the template system include the header and footer for
882 you isn't all that we want our templates to do. We need to be able to
883 put data into our templates, and have it appear where and how we want
884 it, right? That's where the stash comes in.
885
886 In our controllers, we can add data to the stash, and then access it
887 from the template. For instance:
888
889     sub hello : Local {
890         my ( $self, $c ) = @_;
891
892         $c->stash->{name} = 'Adam';
893
894         $c->stash->{template} = 'hello.tt';
895
896         $c->forward( $c->view('TT') );
897     }
898
899 Then, in hello.tt:
900
901     <strong>Hello, [% name %]!</strong>
902
903 When you view this page, it will display "Hello, Adam!"
904
905 All of the information in your stash is available, by its name/key, in
906 your templates. And your data don't have to be plain, old, boring
907 scalars. You can pass array references and hash references, too.
908
909 In your controller:
910
911     sub hello : Local {
912         my ( $self, $c ) = @_;
913
914         $c->stash->{names} = [ 'Adam', 'Dave', 'John' ];
915
916         $c->stash->{template} = 'hello.tt';
917
918         $c->forward( $c->view('TT') );
919     }
920
921 In hello.tt:
922
923     [% FOREACH name IN names %]
924         <strong>Hello, [% name %]!</strong><br />
925     [% END %]
926
927 This allowed us to loop through each item in the arrayref, and display a
928 line for each name that we have.
929
930 This is the most basic usage, but Template Toolkit is quite powerful,
931 and allows you to truly keep your presentation logic separate from the
932 rest of your application.
933
934 =head3 $c->uri_for()
935
936 One of my favorite things about Catalyst is the ability to move an
937 application around without having to worry that everything is going to
938 break. One of the areas that used to be a problem was with the http
939 links in your template files. For example, suppose you have an
940 application installed at http://www.domain.com/Calendar. The links point
941 to "/Calendar", "/Calendar/2005", "/Calendar/2005/10", etc.  If you move
942 the application to be at http://www.mydomain.com/Tools/Calendar, then
943 all of those links will suddenly break.
944
945 That's where $c->uri_for() comes in. This function will merge its
946 parameters with either the base location for the app, or its current
947 namespace. Let's take a look at a couple of examples.
948
949 In your template, you can use the following:
950
951     <a href="[% c.uri_for('/login') %]">Login Here</a>
952
953 Although the parameter starts with a forward slash, this is relative
954 to the application root, not the webserver root. This is important to
955 remember. So, if your application is installed at
956 http://www.domain.com/Calendar, then the link would be
957 http://www.mydomain.com/Calendar/Login. If you move your application
958 to a different domain or path, then that link will still be correct.
959
960 Likewise,
961
962     <a href="[% c.uri_for('2005','10', '24') %]">October, 24 2005</a>
963
964 The first parameter does NOT have a forward slash, and so it will be
965 relative to the current namespace. If the application is installed at
966 http://www.domain.com/Calendar. and if the template is called from
967 MyApp::Controller::Display, then the link would become
968 http://www.domain.com/Calendar/Display/2005/10/24.
969
970 If you want to link to a parent uri of your current namespace you can
971 prefix the arguments with multiple '../':
972
973     <a href="[% c.uri_for('../../view', stashed_object.id) %]">User view</a>
974
975 Once again, this allows you to move your application around without
976 having to worry about broken links. But there's something else, as
977 well. Since the links are generated by uri_for, you can use the same
978 template file by several different controllers, and each controller
979 will get the links that its supposed to. Since we believe in Don't
980 Repeat Yourself, this is particularly helpful if you have common
981 elements in your site that you want to keep in one file.
982
983 Further Reading:
984
985 L<http://search.cpan.org/perldoc?Catalyst>
986
987 L<http://search.cpan.org/perldoc?Catalyst%3A%3AView%3A%3ATT>
988
989 L<http://search.cpan.org/perldoc?Template>
990
991 =head2 Adding RSS feeds 
992
993 Adding RSS feeds to your Catalyst applications is simple. We'll see two
994 different aproaches here, but the basic premise is that you forward to
995 the normal view action first to get the objects, then handle the output
996 differently.
997
998 =head3 Using TT templates
999
1000 This is the aproach used in Agave (L<http://dev.rawmode.org/>).
1001
1002     sub rss : Local {
1003         my ($self,$c) = @_;
1004         $c->forward('view');
1005         $c->stash->{template}='rss.tt';
1006     }
1007
1008 Then you need a template. Here's the one from Agave: 
1009
1010     <?xml version="1.0" encoding="UTF-8"?>
1011     <rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/">
1012       <channel>
1013         <title>[ [% blog.name || c.config.name || "Agave" %] ] RSS Feed</title>
1014         <link>[% base %]</link>
1015         <description>Recent posts</description>
1016         <language>en-us</language>
1017         <ttl>40</ttl>
1018      [% WHILE (post = posts.next) %]
1019       <item>
1020         <title>[% post.title %]</title>
1021         <description>[% post.formatted_teaser|html%]</description>    
1022         <pubDate>[% post.pub_date %]</pubDate>
1023         <guid>[% post.full_uri %]</guid>
1024         <link>[% post.full_uri %]</link>
1025         <dc:creator>[% post.author.screenname %]</dc:creator>
1026       </item>
1027     [% END %]
1028       </channel>
1029     </rss> 
1030
1031 =head3 Using XML::Feed
1032
1033 A more robust solution is to use XML::Feed, as was done in the Catalyst
1034 Advent Calendar. Assuming we have a C<view> action that populates
1035 'entries' with some DBIx::Class iterator, the code would look something
1036 like this:
1037
1038     sub rss : Local {
1039         my ($self,$c) = @_;
1040         $c->forward('view'); # get the entries
1041
1042         my $feed = XML::Feed->new('RSS');
1043         $feed->title( $c->config->{name} . ' RSS Feed' );
1044         $feed->link( $c->req->base ); # link to the site.
1045         $feed->description('Catalyst advent calendar'); Some description
1046
1047         # Process the entries
1048         while( my $entry = $c->stash->{entries}->next ) {
1049             my $feed_entry = XML::Feed::Entry->new('RSS');
1050             $feed_entry->title($entry->title);
1051             $feed_entry->link( $c->uri_for($entry->link) );
1052             $feed_entry->issued( DateTime->from_epoch(epoch => $entry->created) );
1053             $feed->add_entry($feed_entry);
1054         }
1055         $c->res->body( $feed->as_xml );
1056    }
1057
1058 A little more code in the controller, but with this approach you're
1059 pretty sure to get something that validates. 
1060
1061 Note that for both of the above aproaches, you'll need to set the
1062 content type like this:
1063
1064     $c->res->content_type('application/rss+xml');
1065
1066 =head3 Final words
1067
1068 You could generalize the second variant easily by replacing 'RSS' with a
1069 variable, so you can generate Atom feeds with the same code.
1070
1071 Now, go ahead and make RSS feeds for all your stuff. The world *needs*
1072 updates on your goldfish!
1073
1074 =head2 Forcing the browser to download content
1075
1076 Sometimes you need your application to send content for download. For
1077 example, you can generate a comma-separated values (CSV) file for your
1078 users to download and import into their spreadsheet program.
1079
1080 Let's say you have an C<Orders> controller which generates a CSV file
1081 in the C<export> action (i.e., C<http://localhost:3000/orders/export>):
1082
1083     sub export : Local Args(0) {
1084         my ( $self, $c ) = @_;
1085
1086         # In a real application, you'd generate this from the database
1087         my $csv = "1,5.99\n2,29.99\n3,3.99\n";
1088
1089         $c->res->content_type('text/comma-separated-values');
1090         $c->res->body($csv);
1091     }
1092
1093 Normally the browser uses the last part of the URI to generate a
1094 filename for data it cannot display. In this case your browser would
1095 likely ask you to save a file named C<export>.
1096
1097 Luckily you can have the browser download the content with a specific
1098 filename by setting the C<Content-Disposition> header:
1099
1100     my $filename = 'Important Orders.csv';
1101     $c->res->header('Content-Disposition', qq[attachment; filename="$filename"]);
1102
1103 Note the use of quotes around the filename; this ensures that any
1104 spaces in the filename are handled by the browser.
1105
1106 Put this right before calling C<< $c->res->body >> and your browser
1107 will download a file named C<Important Orders.csv> instead of
1108 C<export>.
1109
1110 You can also use this to have the browser download content which it
1111 normally displays, such as JPEG images or even HTML. Just be sure to
1112 set the appropriate content type and disposition.
1113
1114
1115 =head1 Controllers
1116
1117 Controllers are the main point of communication between the web server
1118 and your application.  Here we explore some aspects of how they work.
1119
1120 =head2 Extending RenderView (formerly DefaultEnd)
1121
1122 The recommended approach for an C<end> action is to use
1123 L<Catalyst::Action::RenderView> (taking the place of
1124 L<Catalyst::Plugin::DefaultEnd>), which does what you usually need.
1125 However there are times when you need to add a bit to it, but don't want
1126 to write your own C<end> action.
1127
1128 You can extend it like this:
1129
1130 To add something to an C<end> action that is called before rendering
1131 (this is likely to be what you want), simply place it in the C<end>
1132 method:
1133
1134     sub end : ActionClass('RenderView') {
1135       my ( $self, $c ) = @_;
1136       # do stuff here; the RenderView action is called afterwards
1137     }
1138
1139 To add things to an C<end> action that are called I<after> rendering,
1140 you can set it up like this:
1141
1142     sub render : ActionClass('RenderView') { }
1143
1144     sub end : Private { 
1145       my ( $self, $c ) = @_;
1146       $c->forward('render');
1147       # do stuff here
1148     }
1149   
1150 =head2 Action Types
1151
1152 =head3 Introduction
1153
1154 A Catalyst application is driven by one or more Controller
1155 modules. There are a number of ways that Catalyst can decide which of
1156 the methods in your controller modules it should call. Controller
1157 methods are also called actions, because they determine how your
1158 catalyst application should (re-)act to any given URL. When the
1159 application is started up, catalyst looks at all your actions, and
1160 decides which URLs they map to.
1161
1162 =head3 Type attributes
1163
1164 Each action is a normal method in your controller, except that it has an
1165 L<attribute|http://search.cpan.org/~nwclark/perl-5.8.7/lib/attributes.pm>
1166 attached. These can be one of several types.
1167
1168 Assume our Controller module starts with the following package declaration:
1169
1170  package MyApp::Controller::Buckets;
1171
1172 and we are running our application on localhost, port 3000 (the test
1173 server default).
1174
1175 =over 4
1176
1177 =item Path
1178
1179 A Path attribute also takes an argument, this can be either a relative
1180 or an absolute path. A relative path will be relative to the
1181 controller namespace, an absolute path will represent an exact
1182 matching URL.
1183
1184  sub my_handles : Path('handles') { .. }
1185
1186 becomes
1187
1188  http://localhost:3000/buckets/handles
1189
1190 and
1191
1192  sub my_handles : Path('/handles') { .. }
1193
1194 becomes 
1195
1196  http://localhost:3000/handles
1197
1198 See also: L<Catalyst::DispatchType::Path>
1199
1200 =item Local
1201
1202 When using a Local attribute, no parameters are needed, instead, the
1203 name of the action is matched in the URL. The namespaces created by
1204 the name of the controller package is always part of the URL.
1205
1206  sub my_handles : Local { .. }
1207
1208 becomes
1209
1210  http://localhost:3000/buckets/my_handles
1211
1212 =item Global
1213
1214 A Global attribute is similar to a Local attribute, except that the
1215 namespace of the controller is ignored, and matching starts at root.
1216
1217  sub my_handles : Global { .. }
1218
1219 becomes
1220
1221  http://localhost:3000/my_handles
1222
1223 =item Regex
1224
1225 By now you should have figured that a Regex attribute is just what it
1226 sounds like. This one takes a regular expression, and matches starting
1227 from root. These differ from the rest as they can match multiple URLs.
1228
1229  sub my_handles : Regex('^handles') { .. }
1230
1231 matches
1232
1233  http://localhost:3000/handles
1234
1235 and 
1236
1237  http://localhost:3000/handles_and_other_parts
1238
1239 etc.
1240
1241 See also: L<Catalyst::DispatchType::Regex>
1242
1243 =item LocalRegex
1244
1245 A LocalRegex is similar to a Regex, except it only matches below the current
1246 controller namespace.
1247
1248  sub my_handles : LocalRegex(^handles') { .. }
1249
1250 matches
1251
1252  http://localhost:3000/buckets/handles
1253
1254 and
1255
1256  http://localhost:3000/buckets/handles_and_other_parts
1257
1258 etc.
1259
1260 =item Chained
1261
1262 See L<Catalyst::DispatchType::Chained> for a description of how the chained
1263 dispatch type works.
1264
1265 =item Private
1266
1267 Last but not least, there is the Private attribute, which allows you
1268 to create your own internal actions, which can be forwarded to, but
1269 won't be matched as URLs.
1270
1271  sub my_handles : Private { .. }
1272
1273 becomes nothing at all..
1274
1275 Catalyst also predefines some special Private actions, which you can
1276 override, these are:
1277
1278 =over 4
1279
1280 =item default
1281
1282 The default action will be called, if no other matching action is
1283 found. If you don't have one of these in your namespace, or any sub
1284 part of your namespace, you'll get an error page instead. If you want
1285 to find out where it was the user was trying to go, you can look in
1286 the request object using C<< $c->req->path >>.
1287
1288  sub default :Path { .. }
1289
1290 works for all unknown URLs, in this controller namespace, or every one
1291 if put directly into MyApp.pm.
1292
1293 =item index 
1294
1295 The index action is called when someone tries to visit the exact
1296 namespace of your controller. If index, default and matching Path
1297 actions are defined, then index will be used instead of default and
1298 Path.
1299
1300  sub index :Path :Args(0) { .. }
1301
1302 becomes
1303
1304  http://localhost:3000/buckets
1305
1306 =item begin
1307
1308 The begin action is called at the beginning of every request involving
1309 this namespace directly, before other matching actions are called. It
1310 can be used to set up variables/data for this particular part of your
1311 app. A single begin action is called, its always the one most relevant
1312 to the current namespace.
1313
1314  sub begin : Private { .. }
1315
1316 is called once when 
1317
1318  http://localhost:3000/bucket/(anything)?
1319
1320 is visited.
1321
1322 =item end
1323
1324 Like begin, this action is always called for the namespace it is in,
1325 after every other action has finished. It is commonly used to forward
1326 processing to the View component. A single end action is called, its
1327 always the one most relevant to the current namespace.
1328
1329
1330  sub end : Private { .. }
1331
1332 is called once after any actions when
1333
1334  http://localhost:3000/bucket/(anything)?
1335
1336 is visited.
1337
1338 =item auto
1339
1340 Lastly, the auto action is magic in that B<every> auto action in the
1341 chain of paths up to and including the ending namespace, will be
1342 called. (In contrast, only one of the begin/end/default actions will
1343 be called, the relevant one).
1344
1345  package MyApp.pm;
1346  sub auto : Private { .. }
1347
1348 and 
1349
1350  sub auto : Private { .. }
1351
1352 will both be called when visiting 
1353
1354  http://localhost:3000/bucket/(anything)?
1355
1356 =back
1357
1358 =back
1359
1360 =head3 A word of warning
1361
1362 Due to possible namespace conflicts with Plugins, it is advised to
1363 only put the pre-defined Private actions in your main MyApp.pm file,
1364 all others should go in a Controller module.
1365
1366 =head3 More Information
1367
1368 L<http://search.cpan.org/author/SRI/Catalyst-5.61/lib/Catalyst/Manual/Intro.pod>
1369
1370 L<http://dev.catalyst.perl.org/wiki/FlowChart>
1371
1372 =head2 DRY Controllers with Chained actions.
1373
1374 Imagine that you would like the following paths in your application:
1375
1376 =over
1377
1378 =item B</cd/<ID>/track/<ID>>
1379
1380 Displays info on a particular track.
1381                                        
1382 In the case of a multi-volume CD, this is the track sequence.
1383
1384 =item B</cd/<ID>/volume/<ID>/track/<ID>>
1385
1386 Displays info on a track on a specific volume.
1387
1388 =back
1389
1390 Here is some example code, showing how to do this with chained controllers:
1391
1392     package CD::Controller;
1393     use base qw/Catalyst::Controller/;
1394     
1395     sub root : Chained('/') PathPart('/cd') CaptureArgs(1) {
1396         my ($self, $c, $cd_id) = @_;
1397         $c->stash->{cd_id} = $cd_id;
1398         $c->stash->{cd} = $self->model('CD')->find_by_id($cd_id);
1399     }
1400     
1401     sub trackinfo : Chained('track') PathPart('') Args(0) RenderView {
1402         my ($self, $c) = @_;
1403     }
1404     
1405     package CD::Controller::ByTrackSeq;
1406     use base qw/CD::Controller/;
1407     
1408     sub track : Chained('root') PathPart('track') CaptureArgs(1) {
1409         my ($self, $c, $track_seq) = @_;
1410         $c->stash->{track} = $self->stash->{cd}->find_track_by_seq($track_seq);
1411     }
1412     
1413     package CD::Controller::ByTrackVolNo;
1414     use base qw/CD::Controller/;
1415     
1416     sub volume : Chained('root') PathPart('volume') CaptureArgs(1) {
1417         my ($self, $c, $volume) = @_;
1418         $c->stash->{volume} = $volume;
1419     }
1420     
1421     sub track : Chained('volume') PathPart('track') CaptureArgs(1) {
1422         my ($self, $c, $track_no) = @_;
1423         $c->stash->{track} = $self->stash->{cd}->find_track_by_vol_and_track_no(
1424             $c->stash->{volume}, $track_no
1425         );
1426     }
1427     
1428 Note that adding other actions (i.e. chain endpoints) which operate on a track 
1429 is simply a matter of adding a new sub to CD::Controller - no code is duplicated,
1430 even though there are two different methods of looking up a track.
1431
1432 This technique can be expanded as needed to fulfil your requirements - for example,
1433 if you inherit the first action of a chain from a base class, then mixing in a
1434 different base class can be used to duplicate an entire URL hieratchy at a different
1435 point within your application.
1436
1437 =head2 Component-based Subrequests
1438
1439 See L<Catalyst::Plugin::SubRequest>.
1440
1441 =head2 File uploads
1442
1443 =head3 Single file upload with Catalyst
1444
1445 To implement uploads in Catalyst, you need to have a HTML form similar to
1446 this:
1447
1448     <form action="/upload" method="post" enctype="multipart/form-data">
1449       <input type="hidden" name="form_submit" value="yes">
1450       <input type="file" name="my_file">
1451       <input type="submit" value="Send">
1452     </form>
1453
1454 It's very important not to forget C<enctype="multipart/form-data"> in
1455 the form.
1456
1457 Catalyst Controller module 'upload' action:
1458
1459     sub upload : Global {
1460         my ($self, $c) = @_;
1461
1462         if ( $c->request->parameters->{form_submit} eq 'yes' ) {
1463
1464             if ( my $upload = $c->request->upload('my_file') ) {
1465
1466                 my $filename = $upload->filename;
1467                 my $target   = "/tmp/upload/$filename";
1468
1469                 unless ( $upload->link_to($target) || $upload->copy_to($target) ) {
1470                     die( "Failed to copy '$filename' to '$target': $!" );
1471                 }
1472             }
1473         }
1474
1475         $c->stash->{template} = 'file_upload.html';
1476     }
1477
1478 =head3 Multiple file upload with Catalyst
1479
1480 Code for uploading multiple files from one form needs a few changes:
1481
1482 The form should have this basic structure:
1483
1484     <form action="/upload" method="post" enctype="multipart/form-data">
1485       <input type="hidden" name="form_submit" value="yes">
1486       <input type="file" name="file1" size="50"><br>
1487       <input type="file" name="file2" size="50"><br>
1488       <input type="file" name="file3" size="50"><br>
1489       <input type="submit" value="Send">
1490     </form>
1491
1492 And in the controller:
1493
1494     sub upload : Local {
1495         my ($self, $c) = @_;
1496
1497         if ( $c->request->parameters->{form_submit} eq 'yes' ) {
1498
1499             for my $field ( $c->req->upload ) {
1500
1501                 my $upload   = $c->req->upload($field);
1502                 my $filename = $upload->filename;
1503                 my $target   = "/tmp/upload/$filename";
1504
1505                 unless ( $upload->link_to($target) || $upload->copy_to($target) ) {
1506                     die( "Failed to copy '$filename' to '$target': $!" );
1507                 }
1508             }
1509         }
1510
1511         $c->stash->{template} = 'file_upload.html';
1512     }
1513
1514 C<for my $field ($c-E<gt>req->upload)> loops automatically over all file
1515 input fields and gets input names. After that is basic file saving code,
1516 just like in single file upload.
1517
1518 Notice: C<die>ing might not be what you want to do, when an error
1519 occurs, but it works as an example. A better idea would be to store
1520 error C<$!> in $c->stash->{error} and show a custom error template
1521 displaying this message.
1522
1523 For more information about uploads and usable methods look at
1524 L<Catalyst::Request::Upload> and L<Catalyst::Request>.
1525
1526 =head2 Forwarding with arguments
1527
1528 Sometimes you want to pass along arguments when forwarding to another
1529 action. As of version 5.30, arguments can be passed in the call to
1530 C<forward>; in earlier versions, you can manually set the arguments in
1531 the Catalyst Request object:
1532
1533   # version 5.30 and later:
1534   $c->forward('/wherever', [qw/arg1 arg2 arg3/]);
1535
1536   # pre-5.30
1537   $c->req->args([qw/arg1 arg2 arg3/]);
1538   $c->forward('/wherever');
1539
1540 (See the L<Catalyst::Manual::Intro> Flow_Control section for more 
1541 information on passing arguments via C<forward>.)
1542
1543 =head2 Chained dispatch using base classes, and inner packages.
1544
1545   package MyApp::Controller::Base;
1546   use base qw/Catalyst::Controller/;
1547
1548   sub key1 : Chained('/') 
1549
1550 =head1 Deployment
1551
1552 The recipes below describe aspects of the deployment process,
1553 including web server engines and tips to improve application efficiency.
1554
1555 =head2 mod_perl Deployment
1556
1557 mod_perl is the best solution for many applications, but we'll list some pros
1558 and cons so you can decide for yourself.  The other production deployment
1559 option is FastCGI, for which see below.
1560
1561 =head3 Pros
1562
1563 =head4 Speed
1564
1565 mod_perl is very fast and your app will benefit from being loaded in memory
1566 within each Apache process.
1567
1568 =head4 Shared memory for multiple apps
1569
1570 If you need to run several Catalyst apps on the same server, mod_perl will
1571 share the memory for common modules.
1572
1573 =head3 Cons
1574
1575 =head4 Memory usage
1576
1577 Since your application is fully loaded in memory, every Apache process will
1578 be rather large.  This means a large Apache process will be tied up while
1579 serving static files, large files, or dealing with slow clients.  For this
1580 reason, it is best to run a two-tiered web architecture with a lightweight
1581 frontend server passing dynamic requests to a large backend mod_perl
1582 server.
1583
1584 =head4 Reloading
1585
1586 Any changes made to the core code of your app require a full Apache restart.
1587 Catalyst does not support Apache::Reload or StatINC.  This is another good
1588 reason to run a frontend web server where you can set up an
1589 C<ErrorDocument 502> page to report that your app is down for maintenance.
1590
1591 =head4 Cannot run multiple versions of the same app
1592
1593 It is not possible to run two different versions of the same application in
1594 the same Apache instance because the namespaces will collide.
1595
1596 =head4 Setup
1597
1598 Now that we have that out of the way, let's talk about setting up mod_perl
1599 to run a Catalyst app.
1600
1601 =head4 1. Install Catalyst::Engine::Apache
1602
1603 You should install the latest versions of both Catalyst and 
1604 Catalyst::Engine::Apache.  The Apache engines were separated from the
1605 Catalyst core in version 5.50 to allow for updates to the engine without
1606 requiring a new Catalyst release.
1607
1608 =head4 2. Install Apache with mod_perl
1609
1610 Both Apache 1.3 and Apache 2 are supported, although Apache 2 is highly
1611 recommended.  With Apache 2, make sure you are using the prefork MPM and not
1612 the worker MPM.  The reason for this is that many Perl modules are not
1613 thread-safe and may have problems running within the threaded worker
1614 environment.  Catalyst is thread-safe however, so if you know what you're
1615 doing, you may be able to run using worker.
1616
1617 In Debian, the following commands should get you going.
1618
1619     apt-get install apache2-mpm-prefork
1620     apt-get install libapache2-mod-perl2
1621
1622 =head4 3. Configure your application
1623
1624 Every Catalyst application will automagically become a mod_perl handler
1625 when run within mod_perl.  This makes the configuration extremely easy.
1626 Here is a basic Apache 2 configuration.
1627
1628     PerlSwitches -I/var/www/MyApp/lib
1629     PerlModule MyApp
1630     
1631     <Location />
1632         SetHandler          modperl
1633         PerlResponseHandler MyApp
1634     </Location>
1635
1636 The most important line here is C<PerlModule MyApp>.  This causes mod_perl
1637 to preload your entire application into shared memory, including all of your
1638 controller, model, and view classes and configuration.  If you have -Debug
1639 mode enabled, you will see the startup output scroll by when you first
1640 start Apache.
1641
1642 For an example Apache 1.3 configuration, please see the documentation for
1643 L<Catalyst::Engine::Apache::MP13>.
1644
1645 =head3 Test It
1646
1647 That's it, your app is now a full-fledged mod_perl application!  Try it out
1648 by going to http://your.server.com/.
1649
1650 =head3 Other Options
1651
1652 =head4 Non-root location
1653
1654 You may not always want to run your app at the root of your server or virtual
1655 host.  In this case, it's a simple change to run at any non-root location
1656 of your choice.
1657
1658     <Location /myapp>
1659         SetHandler          modperl
1660         PerlResponseHandler MyApp
1661     </Location>
1662     
1663 When running this way, it is best to make use of the C<uri_for> method in
1664 Catalyst for constructing correct links.
1665
1666 =head4 Static file handling
1667
1668 Static files can be served directly by Apache for a performance boost.
1669
1670     DocumentRoot /var/www/MyApp/root
1671     <Location /static>
1672         SetHandler default-handler
1673     </Location>
1674     
1675 This will let all files within root/static be handled directly by Apache.  In
1676 a two-tiered setup, the frontend server should handle static files.
1677 The configuration to do this on the frontend will vary.
1678
1679 The same is accomplished in lighttpd with the following snippet:
1680
1681    $HTTP["url"] !~ "^/(?:img/|static/|css/|favicon.ico$)" {
1682          fastcgi.server = (
1683              "" => (
1684                  "MyApp" => (
1685                      "socket"       => "/tmp/myapp.socket",
1686                      "check-local"  => "disable",
1687                  )
1688              )
1689          )
1690     }
1691
1692 Which serves everything in the img, static, css directories
1693 statically, as well as the favicon file.
1694
1695 Note the path of the application needs to be stated explicitly in the
1696 web server configuration for both these recipes.
1697
1698 =head2 Catalyst on shared hosting
1699
1700 So, you want to put your Catalyst app out there for the whole world to
1701 see, but you don't want to break the bank. There is an answer - if you
1702 can get shared hosting with FastCGI and a shell, you can install your
1703 Catalyst app in a local directory on your shared host. First, run
1704
1705     perl -MCPAN -e shell
1706
1707 and go through the standard CPAN configuration process. Then exit out
1708 without installing anything. Next, open your .bashrc and add
1709
1710     export PATH=$HOME/local/bin:$HOME/local/script:$PATH
1711     perlversion=`perl -v | grep 'built for' | awk '{print $4}' | sed -e 's/v//;'`
1712     export PERL5LIB=$HOME/local/share/perl/$perlversion:$HOME/local/lib/perl/$perlversion:$HOME/local/lib:$PERL5LIB
1713
1714 and log out, then back in again (or run C<". .bashrc"> if you
1715 prefer). Finally, edit C<.cpan/CPAN/MyConfig.pm> and add
1716
1717     'make_install_arg' => qq[SITEPREFIX=$ENV{HOME}/local],
1718     'makepl_arg' => qq[INSTALLDIRS=site install_base=$ENV{HOME}/local],
1719
1720 Now you can install the modules you need using CPAN as normal; they
1721 will be installed into your local directory, and perl will pick them
1722 up. Finally, change directory into the root of your virtual host and
1723 symlink your application's script directory in:
1724
1725     cd path/to/mydomain.com
1726     ln -s ~/lib/MyApp/script script
1727
1728 And add the following lines to your .htaccess file (assuming the server
1729 is setup to handle .pl as fcgi - you may need to rename the script to
1730 myapp_fastcgi.fcgi and/or use a SetHandler directive):
1731
1732   RewriteEngine On
1733   RewriteCond %{REQUEST_URI} !^/?script/myapp_fastcgi.pl
1734   RewriteRule ^(.*)$ script/myapp_fastcgi.pl/$1 [PT,L]
1735
1736 Now C<http://mydomain.com/> should now Just Work. Congratulations, now
1737 you can tell your friends about your new website (or in our case, tell
1738 the client it's time to pay the invoice :) )
1739
1740 =head2 FastCGI Deployment
1741
1742 FastCGI is a high-performance extension to CGI. It is suitable
1743 for production environments.
1744
1745 =head3 Pros
1746
1747 =head4 Speed
1748
1749 FastCGI performs equally as well as mod_perl.  Don't let the 'CGI' fool you;
1750 your app runs as multiple persistent processes ready to receive connections
1751 from the web server.
1752
1753 =head4 App Server
1754
1755 When using external FastCGI servers, your application runs as a standalone
1756 application server.  It may be restarted independently from the web server.
1757 This allows for a more robust environment and faster reload times when
1758 pushing new app changes.  The frontend server can even be configured to
1759 display a friendly "down for maintenance" page while the application is
1760 restarting.
1761
1762 =head4 Load-balancing
1763
1764 You can launch your application on multiple backend servers and allow the
1765 frontend web server to load-balance between all of them.  And of course, if
1766 one goes down, your app continues to run fine.
1767
1768 =head4 Multiple versions of the same app
1769
1770 Each FastCGI application is a separate process, so you can run different
1771 versions of the same app on a single server.
1772
1773 =head4 Can run with threaded Apache
1774
1775 Since your app is not running inside of Apache, the faster mpm_worker module
1776 can be used without worrying about the thread safety of your application.
1777
1778 =head3 Cons
1779
1780 You may have to disable mod_deflate.  If you experience page hangs with
1781 mod_fastcgi then remove deflate.load and deflate.conf from mods-enabled/
1782
1783 =head4 More complex environment
1784
1785 With FastCGI, there are more things to monitor and more processes running
1786 than when using mod_perl.
1787
1788 =head3 Setup
1789
1790 =head4 1. Install Apache with mod_fastcgi
1791
1792 mod_fastcgi for Apache is a third party module, and can be found at
1793 L<http://www.fastcgi.com/>.  It is also packaged in many distributions,
1794 for example, libapache2-mod-fastcgi in Debian.
1795
1796 =head4 2. Configure your application
1797
1798     # Serve static content directly
1799     DocumentRoot  /var/www/MyApp/root
1800     Alias /static /var/www/MyApp/root/static
1801
1802     FastCgiServer /var/www/MyApp/script/myapp_fastcgi.pl -processes 3
1803     Alias /myapp/ /var/www/MyApp/script/myapp_fastcgi.pl/
1804     
1805     # Or, run at the root
1806     Alias / /var/www/MyApp/script/myapp_fastcgi.pl/
1807     
1808 The above commands will launch 3 app processes and make the app available at
1809 /myapp/
1810
1811 =head3 Standalone server mode
1812
1813 While not as easy as the previous method, running your app as an external
1814 server gives you much more flexibility.
1815
1816 First, launch your app as a standalone server listening on a socket.
1817
1818     script/myapp_fastcgi.pl -l /tmp/myapp.socket -n 5 -p /tmp/myapp.pid -d
1819     
1820 You can also listen on a TCP port if your web server is not on the same
1821 machine.
1822
1823     script/myapp_fastcgi.pl -l :8080 -n 5 -p /tmp/myapp.pid -d
1824     
1825 You will probably want to write an init script to handle starting/stopping
1826 of the app using the pid file.
1827
1828 Now, we simply configure Apache to connect to the running server.
1829
1830     # 502 is a Bad Gateway error, and will occur if the backend server is down
1831     # This allows us to display a friendly static page that says "down for
1832     # maintenance"
1833     Alias /_errors /var/www/MyApp/root/error-pages
1834     ErrorDocument 502 /_errors/502.html
1835
1836     FastCgiExternalServer /tmp/myapp.fcgi -socket /tmp/myapp.socket
1837     Alias /myapp/ /tmp/myapp.fcgi/
1838     
1839     # Or, run at the root
1840     Alias / /tmp/myapp.fcgi/
1841     
1842 =head3 More Info
1843
1844 L<Catalyst::Engine::FastCGI>.
1845
1846 =head2 Development server deployment
1847
1848 The development server is a mini web server written in perl.  If you
1849 expect a low number of hits or you don't need mod_perl/FastCGI speed,
1850 you could use the development server as the application server with a
1851 lightweight proxy web server at the front.  However, consider using
1852 L<Catalyst::Engine::HTTP::Prefork> for this kind of deployment instead, since
1853 it can better handle multiple concurrent requests without forking, or can
1854 prefork a set number of servers for improved performance.
1855
1856 =head3 Pros
1857
1858 As this is an application server setup, the pros are the same as
1859 FastCGI (with the exception of speed).
1860 It is also:
1861
1862 =head4 Simple
1863
1864 The development server is what you create your code on, so if it works
1865 here, it should work in production!
1866
1867 =head3 Cons
1868
1869 =head4 Speed
1870
1871 Not as fast as mod_perl or FastCGI. Needs to fork for each request
1872 that comes in - make sure static files are served by the web server to
1873 save forking.
1874
1875 =head3 Setup
1876
1877 =head4 Start up the development server
1878
1879    script/myapp_server.pl -p 8080 -k  -f -pidfile=/tmp/myapp.pid
1880
1881 You will probably want to write an init script to handle stop/starting
1882 the app using the pid file.
1883
1884 =head4 Configuring Apache
1885
1886 Make sure mod_proxy is enabled and add:
1887
1888     # Serve static content directly
1889     DocumentRoot /var/www/MyApp/root
1890     Alias /static /var/www/MyApp/root/static
1891
1892     ProxyRequests Off
1893     <Proxy *>
1894         Order deny,allow
1895         Allow from all
1896     </Proxy>
1897
1898     # Need to specifically stop these paths from being passed to proxy
1899     ProxyPass /static !
1900     ProxyPass /favicon.ico !
1901
1902     ProxyPass / http://localhost:8080/
1903     ProxyPassReverse / http://localhost:8080/
1904
1905     # This is optional if you'd like to show a custom error page 
1906     # if the proxy is not available
1907     ErrorDocument 502 /static/error_pages/http502.html
1908
1909 You can wrap the above within a VirtualHost container if you want
1910 different apps served on the same host.
1911
1912 =head2 Quick deployment: Building PAR Packages
1913
1914 You have an application running on your development box, but then you
1915 have to quickly move it to another one for
1916 demonstration/deployment/testing...
1917
1918 PAR packages can save you from a lot of trouble here. They are usual Zip
1919 files that contain a blib tree; you can even include all prereqs and a
1920 perl interpreter by setting a few flags!
1921
1922 =head3 Follow these few points to try it out!
1923
1924 1. Install Catalyst and PAR 0.89 (or later)
1925
1926     % perl -MCPAN -e 'install Catalyst'
1927     ...
1928     % perl -MCPAN -e 'install PAR'
1929     ...
1930
1931 2. Create a application
1932
1933     % catalyst.pl MyApp
1934     ...
1935     % cd MyApp
1936
1937 Recent versions of Catalyst (5.62 and up) include
1938 L<Module::Install::Catalyst>, which simplifies the process greatly.  From the shell in your application directory:
1939
1940     % perl Makefile.PL
1941     % make catalyst_par
1942
1943 Congratulations! Your package "myapp.par" is ready, the following
1944 steps are just optional.
1945
1946 3. Test your PAR package with "parl" (no typo)
1947
1948     % parl myapp.par
1949     Usage:
1950         [parl] myapp[.par] [script] [arguments]
1951
1952       Examples:
1953         parl myapp.par myapp_server.pl -r
1954         myapp myapp_cgi.pl
1955
1956       Available scripts:
1957         myapp_cgi.pl
1958         myapp_create.pl
1959         myapp_fastcgi.pl
1960         myapp_server.pl
1961         myapp_test.pl
1962
1963     % parl myapp.par myapp_server.pl
1964     You can connect to your server at http://localhost:3000
1965
1966 Yes, this nifty little starter application gets automatically included.
1967 You can also use "catalyst_par_script('myapp_server.pl')" to set a
1968 default script to execute.
1969
1970 6. Want to create a binary that includes the Perl interpreter?
1971
1972     % pp -o myapp myapp.par
1973     % ./myapp myapp_server.pl
1974     You can connect to your server at http://localhost:3000
1975
1976 =head2 Serving static content
1977
1978 Serving static content in Catalyst used to be somewhat tricky; the use
1979 of L<Catalyst::Plugin::Static::Simple> makes everything much easier.
1980 This plugin will automatically serve your static content during development,
1981 but allows you to easily switch to Apache (or other server) in a
1982 production environment.
1983
1984 =head3 Introduction to Static::Simple
1985
1986 Static::Simple is a plugin that will help to serve static content for your
1987 application. By default, it will serve most types of files, excluding some
1988 standard Template Toolkit extensions, out of your B<root> file directory. All
1989 files are served by path, so if B<images/me.jpg> is requested, then
1990 B<root/images/me.jpg> is found and served.
1991
1992 =head3 Usage
1993
1994 Using the plugin is as simple as setting your use line in MyApp.pm to include:
1995
1996  use Catalyst qw/Static::Simple/;
1997
1998 and already files will be served.
1999
2000 =head3 Configuring
2001
2002 Static content is best served from a single directory within your root
2003 directory. Having many different directories such as C<root/css> and
2004 C<root/images> requires more code to manage, because you must separately
2005 identify each static directory--if you decide to add a C<root/js>
2006 directory, you'll need to change your code to account for it. In
2007 contrast, keeping all static directories as subdirectories of a main
2008 C<root/static> directory makes things much easier to manage. Here's an
2009 example of a typical root directory structure:
2010
2011     root/
2012     root/content.tt
2013     root/controller/stuff.tt
2014     root/header.tt
2015     root/static/
2016     root/static/css/main.css
2017     root/static/images/logo.jpg
2018     root/static/js/code.js
2019
2020
2021 All static content lives under C<root/static>, with everything else being
2022 Template Toolkit files.
2023
2024 =over 4
2025
2026 =item Include Path
2027
2028 You may of course want to change the default locations, and make
2029 Static::Simple look somewhere else, this is as easy as:
2030
2031  MyApp->config->{static}->{include_path} = [
2032   MyApp->config->{root},
2033   '/path/to/my/files' 
2034  ];
2035
2036 When you override include_path, it will not automatically append the
2037 normal root path, so you need to add it yourself if you still want
2038 it. These will be searched in order given, and the first matching file
2039 served.
2040
2041 =item Static directories
2042
2043 If you want to force some directories to be only static, you can set
2044 them using paths relative to the root dir, or regular expressions:
2045
2046  MyApp->config->{static}->{dirs} = [
2047    'static',
2048    qr/^(images|css)/,
2049  ];
2050
2051 =item File extensions
2052
2053 By default, the following extensions are not served (that is, they will
2054 be processed by Catalyst): B<tmpl, tt, tt2, html, xhtml>. This list can
2055 be replaced easily:
2056
2057  MyApp->config->{static}->{ignore_extensions} = [
2058     qw/tmpl tt tt2 html xhtml/ 
2059  ];
2060
2061 =item Ignoring directories
2062
2063 Entire directories can be ignored. If used with include_path,
2064 directories relative to the include_path dirs will also be ignored:
2065
2066  MyApp->config->{static}->{ignore_dirs} = [ qw/tmpl css/ ];
2067
2068 =back
2069
2070 =head3 More information
2071
2072 L<http://search.cpan.org/dist/Catalyst-Plugin-Static-Simple/>
2073
2074 =head3 Serving manually with the Static plugin with HTTP::Daemon (myapp_server.pl)
2075
2076 In some situations you might want to control things more directly,
2077 using L<Catalyst::Plugin::Static>.
2078
2079 In your main application class (MyApp.pm), load the plugin:
2080
2081     use Catalyst qw/-Debug FormValidator Static OtherPlugin/;
2082
2083 You will also need to make sure your end method does I<not> forward
2084 static content to the view, perhaps like this:
2085
2086     sub end : Private {
2087         my ( $self, $c ) = @_;
2088
2089         $c->forward( 'MyApp::View::TT' ) 
2090           unless ( $c->res->body || !$c->stash->{template} );
2091     }
2092
2093 This code will only forward to the view if a template has been
2094 previously defined by a controller and if there is not already data in
2095 C<$c-E<gt>res-E<gt>body>.
2096
2097 Next, create a controller to handle requests for the /static path. Use
2098 the Helper to save time. This command will create a stub controller as
2099 C<lib/MyApp/Controller/Static.pm>.
2100
2101     $ script/myapp_create.pl controller Static
2102
2103 Edit the file and add the following methods:
2104
2105     # serve all files under /static as static files
2106     sub default : Path('/static') {
2107         my ( $self, $c ) = @_;
2108
2109         # Optional, allow the browser to cache the content
2110         $c->res->headers->header( 'Cache-Control' => 'max-age=86400' );
2111
2112         $c->serve_static; # from Catalyst::Plugin::Static
2113     }
2114
2115     # also handle requests for /favicon.ico
2116     sub favicon : Path('/favicon.ico') {
2117         my ( $self, $c ) = @_;
2118
2119         $c->serve_static;
2120     }
2121
2122 You can also define a different icon for the browser to use instead of
2123 favicon.ico by using this in your HTML header:
2124
2125     <link rel="icon" href="/static/myapp.ico" type="image/x-icon" />
2126
2127 =head3 Common problems with the Static plugin
2128
2129 The Static plugin makes use of the C<shared-mime-info> package to
2130 automatically determine MIME types. This package is notoriously
2131 difficult to install, especially on win32 and OS X. For OS X the easiest
2132 path might be to install Fink, then use C<apt-get install
2133 shared-mime-info>. Restart the server, and everything should be fine.
2134
2135 Make sure you are using the latest version (>= 0.16) for best
2136 results. If you are having errors serving CSS files, or if they get
2137 served as text/plain instead of text/css, you may have an outdated
2138 shared-mime-info version. You may also wish to simply use the following
2139 code in your Static controller:
2140
2141     if ($c->req->path =~ /css$/i) {
2142         $c->serve_static( "text/css" );
2143     } else {
2144         $c->serve_static;
2145     }
2146
2147 =head3 Serving Static Files with Apache
2148
2149 When using Apache, you can bypass Catalyst and any Static
2150 plugins/controllers controller by intercepting requests for the
2151 C<root/static> path at the server level. All that is required is to
2152 define a DocumentRoot and add a separate Location block for your static
2153 content. Here is a complete config for this application under mod_perl
2154 1.x:
2155
2156     <Perl>
2157         use lib qw(/var/www/MyApp/lib);
2158     </Perl>
2159     PerlModule MyApp
2160
2161     <VirtualHost *>
2162         ServerName myapp.example.com
2163         DocumentRoot /var/www/MyApp/root
2164         <Location />
2165             SetHandler perl-script
2166             PerlHandler MyApp
2167         </Location>
2168         <LocationMatch "/(static|favicon.ico)">
2169             SetHandler default-handler
2170         </LocationMatch>
2171     </VirtualHost>
2172
2173 And here's a simpler example that'll get you started:
2174
2175     Alias /static/ "/my/static/files/"
2176     <Location "/static">
2177         SetHandler none
2178     </Location>
2179
2180 =head2 Caching
2181
2182 Catalyst makes it easy to employ several different types of caching to
2183 speed up your applications.
2184
2185 =head3 Cache Plugins
2186
2187 There are three wrapper plugins around common CPAN cache modules:
2188 Cache::FastMmap, Cache::FileCache, and Cache::Memcached.  These can be
2189 used to cache the result of slow operations.
2190
2191 The Catalyst Advent Calendar uses the FileCache plugin to cache the
2192 rendered XHTML version of the source POD document.  This is an ideal
2193 application for a cache because the source document changes
2194 infrequently but may be viewed many times.
2195
2196     use Catalyst qw/Cache::FileCache/;
2197     
2198     ...
2199     
2200     use File::stat;
2201     sub render_pod : Local {
2202         my ( self, $c ) = @_;
2203         
2204         # the cache is keyed on the filename and the modification time
2205         # to check for updates to the file.
2206         my $file  = $c->path_to( 'root', '2005', '11.pod' );
2207         my $mtime = ( stat $file )->mtime;
2208         
2209         my $cached_pod = $c->cache->get("$file $mtime");
2210         if ( !$cached_pod ) {
2211             $cached_pod = do_slow_pod_rendering();
2212             # cache the result for 12 hours
2213             $c->cache->set( "$file $mtime", $cached_pod, '12h' );
2214         }
2215         $c->stash->{pod} = $cached_pod;
2216     }
2217     
2218 We could actually cache the result forever, but using a value such as 12 hours
2219 allows old entries to be automatically expired when they are no longer needed.
2220
2221 =head3 Page Caching
2222
2223 Another method of caching is to cache the entire HTML page.  While this is
2224 traditionally handled by a front-end proxy server like Squid, the Catalyst
2225 PageCache plugin makes it trivial to cache the entire output from
2226 frequently-used or slow actions.
2227
2228 Many sites have a busy content-filled front page that might look something
2229 like this.  It probably takes a while to process, and will do the exact same
2230 thing for every single user who views the page.
2231
2232     sub front_page : Path('/') {
2233         my ( $self, $c ) = @_;
2234         
2235         $c->forward( 'get_news_articles' );
2236         $c->forward( 'build_lots_of_boxes' );
2237         $c->forward( 'more_slow_stuff' );
2238         
2239         $c->stash->{template} = 'index.tt';
2240     }
2241
2242 We can add the PageCache plugin to speed things up.
2243
2244     use Catalyst qw/Cache::FileCache PageCache/;
2245     
2246     sub front_page : Path ('/') {
2247         my ( $self, $c ) = @_;
2248         
2249         $c->cache_page( 300 );
2250         
2251         # same processing as above
2252     }
2253     
2254 Now the entire output of the front page, from <html> to </html>, will be
2255 cached for 5 minutes.  After 5 minutes, the next request will rebuild the
2256 page and it will be re-cached.
2257
2258 Note that the page cache is keyed on the page URI plus all parameters, so
2259 requests for / and /?foo=bar will result in different cache items.  Also,
2260 only GET requests will be cached by the plugin.
2261
2262 You can even get that front-end Squid proxy to help out by enabling HTTP
2263 headers for the cached page.
2264
2265     MyApp->config->{page_cache}->{set_http_headers} = 1;
2266     
2267 This would now set the following headers so proxies and browsers may cache
2268 the content themselves.
2269
2270     Cache-Control: max-age=($expire_time - time)
2271     Expires: $expire_time
2272     Last-Modified: $cache_created_time
2273     
2274 =head3 Template Caching
2275
2276 Template Toolkit provides support for caching compiled versions of your
2277 templates.  To enable this in Catalyst, use the following configuration.
2278 TT will cache compiled templates keyed on the file mtime, so changes will
2279 still be automatically detected.
2280
2281     package MyApp::View::TT;
2282     
2283     use strict;
2284     use warnings;
2285     use base 'Catalyst::View::TT';
2286     
2287     __PACKAGE__->config(
2288         COMPILE_DIR => '/tmp/template_cache',
2289     );
2290     
2291     1;
2292     
2293 =head3 More Info
2294
2295 See the documentation for each cache plugin for more details and other
2296 available configuration options.
2297
2298 L<Catalyst::Plugin::Cache::FastMmap>
2299 L<Catalyst::Plugin::Cache::FileCache>
2300 L<Catalyst::Plugin::Cache::Memcached>
2301 L<Catalyst::Plugin::PageCache>
2302 L<http://search.cpan.org/dist/Template-Toolkit/lib/Template/Manual/Config.pod#Caching_and_Compiling_Options>
2303
2304 =head1 Testing
2305
2306 Testing is an integral part of the web application development
2307 process.  Tests make multi developer teams easier to coordinate, and
2308 they help ensure that there are no nasty surprises after upgrades or
2309 alterations.
2310
2311 =head2 Testing
2312
2313 Catalyst provides a convenient way of testing your application during 
2314 development and before deployment in a real environment.
2315
2316 C<Catalyst::Test> makes it possible to run the same tests both locally 
2317 (without an external daemon) and against a remote server via HTTP.
2318
2319 =head3 Tests
2320
2321 Let's examine a skeleton application's C<t/> directory:
2322
2323     mundus:~/MyApp chansen$ ls -l t/
2324     total 24
2325     -rw-r--r--  1 chansen  chansen   95 18 Dec 20:50 01app.t
2326     -rw-r--r--  1 chansen  chansen  190 18 Dec 20:50 02pod.t
2327     -rw-r--r--  1 chansen  chansen  213 18 Dec 20:50 03podcoverage.t
2328
2329 =over 4
2330
2331 =item C<01app.t>
2332
2333 Verifies that the application loads, compiles, and returns a successful
2334 response.
2335
2336 =item C<02pod.t>
2337
2338 Verifies that all POD is free from errors. Only executed if the C<TEST_POD> 
2339 environment variable is true.
2340
2341 =item C<03podcoverage.t>
2342
2343 Verifies that all methods/functions have POD coverage. Only executed if the
2344 C<TEST_POD> environment variable is true.
2345
2346 =back
2347
2348 =head3 Creating tests
2349
2350     mundus:~/MyApp chansen$ cat t/01app.t | perl -ne 'printf( "%2d  %s", $., $_ )'
2351     1  use Test::More tests => 2;
2352     2  use_ok( Catalyst::Test, 'MyApp' );
2353     3
2354     4  ok( request('/')->is_success );
2355
2356 The first line declares how many tests we are going to run, in this case
2357 two. The second line tests and loads our application in test mode. The
2358 fourth line verifies that our application returns a successful response.
2359
2360 C<Catalyst::Test> exports two functions, C<request> and C<get>. Each can
2361 take three different arguments:
2362
2363 =over 4
2364
2365 =item A string which is a relative or absolute URI.
2366
2367     request('/my/path');
2368     request('http://www.host.com/my/path');
2369
2370 =item An instance of C<URI>.
2371
2372     request( URI->new('http://www.host.com/my/path') );
2373
2374 =item An instance of C<HTTP::Request>.
2375
2376     request( HTTP::Request->new( GET => 'http://www.host.com/my/path') );
2377
2378 =back
2379
2380 C<request> returns an instance of C<HTTP::Response> and C<get> returns the 
2381 content (body) of the response.
2382
2383 =head3 Running tests locally
2384
2385     mundus:~/MyApp chansen$ CATALYST_DEBUG=0 TEST_POD=1 prove --lib lib/ t/
2386     t/01app............ok                                                        
2387     t/02pod............ok                                                        
2388     t/03podcoverage....ok                                                        
2389     All tests successful.
2390     Files=3, Tests=4,  2 wallclock secs ( 1.60 cusr +  0.36 csys =  1.96 CPU)
2391  
2392 C<CATALYST_DEBUG=0> ensures that debugging is off; if it's enabled you
2393 will see debug logs between tests.
2394
2395 C<TEST_POD=1> enables POD checking and coverage.
2396
2397 C<prove> A command-line tool that makes it easy to run tests. You can
2398 find out more about it from the links below.
2399
2400 =head3 Running tests remotely
2401
2402     mundus:~/MyApp chansen$ CATALYST_SERVER=http://localhost:3000/ prove --lib lib/ t/01app.t
2403     t/01app....ok                                                                
2404     All tests successful.
2405     Files=1, Tests=2,  0 wallclock secs ( 0.40 cusr +  0.01 csys =  0.41 CPU)
2406
2407 C<CATALYST_SERVER=http://localhost:3000/> is the absolute deployment URI of 
2408 your application. In C<CGI> or C<FastCGI> it should be the host and path 
2409 to the script.
2410
2411 =head3 C<Test::WWW::Mechanize> and Catalyst
2412
2413 Be sure to check out C<Test::WWW::Mechanize::Catalyst>. It makes it easy to
2414 test HTML, forms and links. A short example of usage:
2415
2416     use Test::More tests => 6;
2417     use_ok( Test::WWW::Mechanize::Catalyst, 'MyApp' );
2418
2419     my $mech = Test::WWW::Mechanize::Catalyst->new;
2420     $mech->get_ok("http://localhost/", 'Got index page');
2421     $mech->title_like( qr/^MyApp on Catalyst/, 'Got right index title' );
2422     ok( $mech->find_link( text_regex => qr/^Wiki/i ), 'Found link to Wiki' );
2423     ok( $mech->find_link( text_regex => qr/^Mailing-List/i ), 'Found link to Mailing-List' );
2424     ok( $mech->find_link( text_regex => qr/^IRC channel/i ), 'Found link to IRC channel' );
2425
2426 =head3 Further Reading
2427
2428 =over 4
2429
2430 =item Catalyst::Test
2431
2432 L<http://search.cpan.org/dist/Catalyst/lib/Catalyst/Test.pm>
2433
2434 =item Test::WWW::Mechanize::Catalyst
2435
2436 L<http://search.cpan.org/dist/Test-WWW-Mechanize-Catalyst/lib/Test/WWW/Mechanize/Catalyst.pm>
2437
2438 =item Test::WWW::Mechanize
2439
2440 L<http://search.cpan.org/dist/Test-WWW-Mechanize/Mechanize.pm>
2441
2442 =item WWW::Mechanize
2443
2444 L<http://search.cpan.org/dist/WWW-Mechanize/lib/WWW/Mechanize.pm>
2445
2446 =item LWP::UserAgent
2447
2448 L<http://search.cpan.org/dist/libwww-perl/lib/LWP/UserAgent.pm>
2449
2450 =item HTML::Form
2451
2452 L<http://search.cpan.org/dist/libwww-perl/lib/HTML/Form.pm>
2453
2454 =item HTTP::Message
2455
2456 L<http://search.cpan.org/dist/libwww-perl/lib/HTTP/Message.pm>
2457
2458 =item HTTP::Request
2459
2460 L<http://search.cpan.org/dist/libwww-perl/lib/HTTP/Request.pm>
2461
2462 =item HTTP::Request::Common
2463
2464 L<http://search.cpan.org/dist/libwww-perl/lib/HTTP/Request/Common.pm>
2465
2466 =item HTTP::Response
2467
2468 L<http://search.cpan.org/dist/libwww-perl/lib/HTTP/Response.pm>
2469
2470 =item HTTP::Status
2471
2472 L<http://search.cpan.org/dist/libwww-perl/lib/HTTP/Status.pm>
2473
2474 =item URI
2475
2476 L<http://search.cpan.org/dist/URI/URI.pm>
2477
2478 =item Test::More
2479
2480 L<http://search.cpan.org/dist/Test-Simple/lib/Test/More.pm>
2481
2482 =item Test::Pod
2483
2484 L<http://search.cpan.org/dist/Test-Pod/Pod.pm>
2485
2486 =item Test::Pod::Coverage
2487
2488 L<http://search.cpan.org/dist/Test-Pod-Coverage/Coverage.pm>
2489
2490 =item prove (Test::Harness)
2491
2492 L<http://search.cpan.org/dist/Test-Harness/bin/prove>
2493
2494 =back
2495
2496 =head3 More Information
2497
2498 L<http://search.cpan.org/perldoc?Catalyst::Plugin::Authorization::Roles>
2499 L<http://search.cpan.org/perldoc?Catalyst::Plugin::Authorization::ACL>
2500
2501 =head1 AUTHORS
2502
2503 Sebastian Riedel C<sri@oook.de>
2504
2505 Danijel Milicevic C<me@danijel.de>
2506
2507 Viljo Marrandi C<vilts@yahoo.com>  
2508
2509 Marcus Ramberg C<mramberg@cpan.org>
2510
2511 Jesse Sheidlower C<jester@panix.com>
2512
2513 Andy Grundman C<andy@hybridized.org> 
2514
2515 Chisel Wright C<pause@herlpacker.co.uk>
2516
2517 Will Hawes C<info@whawes.co.uk>
2518
2519 Gavin Henry C<ghenry@perl.me.uk>
2520
2521 Kieren Diment C<kd@totaldatasolution.com>
2522
2523 =head1 COPYRIGHT
2524
2525 This document is free, you can redistribute it and/or modify it
2526 under the same terms as Perl itself.
2527