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