f8bcdab3a4b136e8c26e378404d9e2f1fd75a453
[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 =head3 Using authentication in a testing environment
1547
1548 Ideally, to write tests for authentication/authorization code one would first
1549 set up a test database with known data, then use
1550 L<Test::WWW::Mechanize::Catalyst> to simulate a user logging in. Unfortunately
1551 the former can be rather awkward, which is why it's a good thing that the
1552 authentication framework is so flexible.
1553
1554 Instead of using a test database, one can simply change the authentication
1555 store to something a bit easier to deal with in a testing
1556 environment. Additionally, this has the advantage of not modifying one's
1557 database, which can be problematic if one forgets to use the testing instead of
1558 production database.
1559
1560 e.g.,
1561
1562   use Catalyst::Plugin::Authentication::Store::Minimal::Backend;
1563
1564   # Sets up the user `test_user' with password `test_pass'
1565   MyApp->default_auth_store(
1566     Catalyst::Plugin::Authentication::Store::Minimal::Backend->new({
1567       test_user => { password => 'test_pass' },
1568     })
1569   );
1570
1571 Now, your test code can call C<$c->login('test_user', 'test_pass')> and
1572 successfully login, without messing with the database at all.
1573
1574 =head3 More information
1575
1576 L<http://search.cpan.org/perldoc?Catalyst::Plugin::Authentication> has a longer explanation.
1577
1578 =head2 Sessions
1579
1580 When you have your users identified, you will want to somehow remember that
1581 fact, to save them from having to identify themselves for every single
1582 page. One way to do this is to send the username and password parameters in
1583 every single page, but that's ugly, and won't work for static pages. 
1584
1585 Sessions are a method of saving data related to some transaction, and giving
1586 the whole collection a single ID. This ID is then given to the user to return
1587 to us on every page they visit while logged in. The usual way to do this is
1588 using a browser cookie.
1589
1590 Catalyst uses two types of plugins to represent sessions:
1591
1592 =head3 State
1593
1594 A State module is used to keep track of the state of the session between the
1595 users browser, and your application.  
1596
1597 A common example is the Cookie state module, which sends the browser a cookie
1598 containing the session ID. It will use default value for the cookie name and
1599 domain, so will "just work" when used. 
1600
1601 =head3 Store
1602
1603 A Store module is used to hold all the data relating to your session, for
1604 example the users ID, or the items for their shopping cart. You can store data
1605 in memory (FastMmap), in a file (File) or in a database (DBI).
1606
1607 =head3 Authentication magic
1608
1609 If you have included the session modules in your application, the
1610 Authentication modules will automagically use your session to save and
1611 retrieve the user data for you.
1612
1613 =head3 Using a session
1614
1615 Once the session modules are loaded, the session is available as C<<
1616 $c->session >>, and can be writen to and read from as a simple hash reference.
1617
1618 =head3 EXAMPLE
1619
1620   use Catalyst qw/
1621                  Session
1622                  Session::Store::FastMmap
1623                  Session::State::Cookie
1624                  /;
1625
1626
1627   ## Write data into the session
1628
1629   sub add_item : Local {
1630      my ( $self, $c ) = @_;
1631
1632      my $item_id = $c->req->param("item");
1633
1634      push @{ $c->session->{items} }, $item_id;
1635
1636   }
1637
1638   ## A page later we retrieve the data from the session:
1639
1640   sub get_items : Local {
1641      my ( $self, $c ) = @_;
1642
1643      $c->stash->{items_to_display} = $c->session->{items};
1644
1645   }
1646
1647
1648 =head3 More information
1649
1650 L<http://search.cpan.org/dist/Catalyst-Plugin-Session>
1651
1652 L<http://search.cpan.org/dist/Catalyst-Plugin-Session-State-Cookie>
1653
1654 L<http://search.cpan.org/dist/Catalyst-Plugin-Session-State-URI>
1655
1656 L<http://search.cpan.org/dist/Catalyst-Plugin-Session-Store-FastMmap>
1657
1658 L<http://search.cpan.org/dist/Catalyst-Plugin-Session-Store-File>
1659
1660 L<http://search.cpan.org/dist/Catalyst-Plugin-Session-Store-DBI>
1661
1662 =head2 Adding RSS feeds 
1663
1664 Adding RSS feeds to your stuff in Catalyst is really simple. I'll show two
1665 different aproaches here, but the basic premise is that you forward to the
1666 normal view action first to get the objects, then handle the output differently
1667
1668 =head3 Using TT templates
1669
1670 This is the aproach we chose in Agave (L<http://dev.rawmode.org/>).
1671
1672     sub rss : Local {
1673         my ($self,$c) = @_;
1674         $c->forward('view');
1675         $c->stash->{template}='rss.tt';
1676     }
1677
1678 Then you need a template. Here's the one from Agave: 
1679 L<http://svn.rawmode.org/repos/Agave/trunk/root/base/blog/rss.tt>
1680
1681 As you can see, it's pretty simple. 
1682
1683 =head3 Using XML::Feed
1684
1685 However, a more robust solution is to use XML::Feed, as we've done in this 
1686 Advent Calendar. Assuming we have a 'view' action that populates 'entries' 
1687 with some DBIx::Class/Class::DBI iterator, the code would look something like 
1688 this:
1689
1690     sub rss : Local {
1691         my ($self,$c) = @_;
1692         $c->forward('view'); # get the entries
1693
1694         my $feed = XML::Feed->new('RSS');
1695         $feed->title( $c->config->{name} . ' RSS Feed' );
1696         $feed->link( $c->req->base ); # link to the site.
1697         $feed->description('Catalyst advent calendar'); Some description
1698
1699         # Process the entries
1700         while( my $entry=$c->stash->{entries}->next ) {
1701             my $feed_entry = XML::Feed::Entry->new('RSS');
1702             $feed_entry->title($entry->title);
1703             $feed_entry->link( $c->uri_for($entry->link) );
1704             $feed_entry->issued( DateTime->from_epoch(epoch   => $entry->created) );
1705             $feed->add_entry($feed_entry);
1706         }
1707         $c->res->body( $feed->as_xml );
1708    }
1709
1710
1711 A little more code in the controller, but with this approach you're pretty sure
1712 to get something that validates. One little note regarding that tho, for both
1713 of the above aproaches, you'll need to set the content type like this:
1714
1715     $c->res->content_type('application/rss+xml');
1716
1717 =head2 Final words
1718
1719 Note that you could generalize the second variant easily by replacing 'RSS' 
1720 with a variable, so you can generate Atom feeds with the same code.
1721
1722 Now, go ahead and make RSS feeds for all your stuff. The world *needs* updates
1723 on your goldfish!
1724
1725 =head2 FastCGI Deployment
1726
1727 As a companion to Day 7's mod_perl article, today's article is about
1728 production FastCGI deployment.
1729
1730 =head3 Pros
1731
1732 =head4 Speed
1733
1734 FastCGI performs equally as well as mod_perl.  Don't let the 'CGI' fool you;
1735 your app runs as multiple persistent processes ready to receive connections
1736 from the web server.
1737
1738 =head4 App Server
1739
1740 When using external FastCGI servers, your application runs as a standalone
1741 application server.  It may be restarted independently from the web server.
1742 This allows for a more robust environment and faster reload times when
1743 pushing new app changes.  The frontend server can even be configured to
1744 display a friendly "down for maintenance" page while the application is
1745 restarting.
1746
1747 =head4 Load-balancing
1748
1749 You can launch your application on multiple backend servers and allow the
1750 frontend web server to load-balance between all of them.  And of course, if
1751 one goes down, your app continues to run fine.
1752
1753 =head4 Multiple versions of the same app
1754
1755 Each FastCGI application is a separate process, so you can run different
1756 versions of the same app on a single server.
1757
1758 =head4 Can run with threaded Apache
1759
1760 Since your app is not running inside of Apache, the faster mpm_worker module
1761 can be used without worrying about the thread safety of your application.
1762
1763 =head3 Cons
1764
1765 =head4 More complex environment
1766
1767 With FastCGI, there are more things to monitor and more processes running
1768 than when using mod_perl.
1769
1770 =head3 Setup
1771
1772 =head4 1. Install Apache with mod_fastcgi
1773
1774 mod_fastcgi for Apache is a third party module, and can be found at
1775 L<http://www.fastcgi.com/>.  It is also packaged in many distributions, for
1776 example, libapache2-mod-fastcgi in Debian.
1777
1778 =head4 2. Configure your application
1779
1780     # Serve static content directly
1781     DocumentRoot  /var/www/MyApp/root
1782     Alias /static /var/www/MyApp/root/static
1783
1784     FastCgiServer /var/www/MyApp/script/myapp_fastcgi.pl -processes 3
1785     Alias /myapp/ /var/www/MyApp/script/myapp_fastcgi.pl/
1786     
1787     # Or, run at the root
1788     Alias / /var/www/MyApp/script/myapp_fastcgi.pl/
1789     
1790 The above commands will launch 3 app processes and make the app available at
1791 /myapp/
1792
1793 =head3 Standalone server mode
1794
1795 While not as easy as the previous method, running your app as an external
1796 server gives you much more flexibility.
1797
1798 First, launch your app as a standalone server listening on a socket.
1799
1800     script/myapp_fastcgi.pl -l /tmp/myapp.socket -n 5 -p /tmp/myapp.pid -d
1801     
1802 You can also listen on a TCP port if your web server is not on the same
1803 machine.
1804
1805     script/myapp_fastcgi.pl -l :8080 -n 5 -p /tmp/myapp.pid -d
1806     
1807 You will probably want to write an init script to handle starting/stopping
1808 of the app using the pid file.
1809
1810 Now, we simply configure Apache to connect to the running server.
1811
1812     # 502 is a Bad Gateway error, and will occur if the backend server is down
1813     # This allows us to display a friendly static page that says "down for
1814     # maintenance"
1815     Alias /_errors /var/www/MyApp/root/error-pages
1816     ErrorDocument 502 /_errors/502.html
1817
1818     FastCgiExternalServer /tmp/myapp -socket /tmp/myapp.socket
1819     Alias /myapp/ /tmp/myapp/
1820     
1821     # Or, run at the root
1822     Alias / /tmp/myapp/
1823     
1824 =head3 More Info
1825
1826 Lots more information is available in the new and expanded FastCGI docs that
1827 will be part of Catalyst 5.62.  For now you may read them here:
1828 L<http://dev.catalyst.perl.org/file/trunk/Catalyst/lib/Catalyst/Engine/FastCGI.pm>
1829
1830 =head2 Catalyst::View::TT
1831
1832 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.
1833
1834 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.
1835
1836 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.
1837
1838 =head3 Creating your View
1839
1840 Catalyst::View::TT provides two different helpers for use to use: TT and TTSite.
1841
1842 =head4 TT
1843
1844 Create a basic Template Toolkit View using the provided helper script:
1845
1846     script/myapp_create.pl view TT TT
1847
1848 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:
1849
1850     sub hello : Local {
1851         my ( $self, $c ) = @_;
1852
1853         $c->stash->{template} = 'hello.tt';
1854
1855         $c->forward( $c->view('TT') );
1856     }
1857
1858 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.
1859
1860 =head4 TTSite
1861
1862 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.
1863
1864 Once again, you can use the helper script:
1865
1866     script/myapp_create.pl view TT TTSite
1867
1868 This time, the helper sets several options for us in the generated View.
1869
1870     __PACKAGE__->config({
1871         CATALYST_VAR => 'Catalyst',
1872         INCLUDE_PATH => [
1873             MyApp->path_to( 'root', 'src' ),
1874             MyApp->path_to( 'root', 'lib' )
1875         ],
1876         PRE_PROCESS  => 'config/main',
1877         WRAPPER      => 'site/wrapper',
1878         ERROR        => 'error.tt2',
1879         TIMER        => 0
1880     });
1881
1882 =over
1883
1884 =item
1885 INCLUDE_PATH defines the directories that Template Toolkit should search for the template files.
1886
1887 =item
1888 PRE_PROCESS is used to process configuration options which are common to every template file.
1889
1890 =item
1891 WRAPPER is a file which is processed with each template, usually used to easily provide a common header and footer for every page.
1892
1893 =back
1894
1895 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. 
1896
1897 Several configuration files in root/lib/config are called by PRE_PROCESS.
1898
1899 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.
1900
1901 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.
1902
1903 =head2 $c->stash
1904
1905 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.
1906
1907 In our controllers, we can add data to the stash, and then access it from the template. For instance:
1908
1909     sub hello : Local {
1910         my ( $self, $c ) = @_;
1911
1912         $c->stash->{name} = 'Adam';
1913
1914         $c->stash->{template} = 'hello.tt';
1915
1916         $c->forward( $c->view('TT') );
1917     }
1918
1919 Then, in hello.tt:
1920
1921     <strong>Hello, [% name %]!</strong>
1922
1923 When you view this page, it will display "Hello, Adam!"
1924
1925 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.
1926
1927 In your controller:
1928
1929     sub hello : Local {
1930         my ( $self, $c ) = @_;
1931
1932         $c->stash->{names} = [ 'Adam', 'Dave', 'John' ];
1933
1934         $c->stash->{template} = 'hello.tt';
1935
1936         $c->forward( $c->view('TT') );
1937     }
1938
1939 In hello.tt:
1940
1941     [% FOREACH name IN names %]
1942         <strong>Hello, [% name %]!</strong><br />
1943     [% END %]
1944
1945 This allowed us to loop through each item in the arrayref, and display a line for each name that we have.
1946
1947 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.
1948
1949 =head3 $c->uri_for()
1950
1951 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.
1952
1953 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.
1954
1955 In your template, you can use the following:
1956
1957     <a href="[% c.uri_for('/login') %]">Login Here</a>
1958
1959 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.
1960
1961 Likewise,
1962
1963     <a href="[% c.uri_for('2005','10', '24') %]">October, 24 2005</a>
1964
1965 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.
1966
1967 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.
1968
1969 Further Reading:
1970
1971 L<http://search.cpan.org/perldoc?Catalyst>
1972
1973 L<http://search.cpan.org/perldoc?Catalyst%3A%3AView%3A%3ATT>
1974
1975 L<http://search.cpan.org/perldoc?Template>
1976
1977 =head2 Testing
1978
1979 Catalyst provides a convenient way of testing your application during 
1980 development and before deployment in a real environment.
1981
1982 C<Catalyst::Test> makes it possible to run the same tests both locally 
1983 (without an external daemon) and against a remote server via HTTP.
1984
1985 =head3 Tests
1986
1987 Let's examine a skeleton application's C<t/> directory:
1988
1989     mundus:~/MyApp chansen$ ls -l t/
1990     total 24
1991     -rw-r--r--  1 chansen  chansen   95 18 Dec 20:50 01app.t
1992     -rw-r--r--  1 chansen  chansen  190 18 Dec 20:50 02pod.t
1993     -rw-r--r--  1 chansen  chansen  213 18 Dec 20:50 03podcoverage.t
1994
1995 =over 4
1996
1997 =item C<01app.t>
1998
1999 Verifies that the application loads, compiles, and returns a successful
2000 response.
2001
2002 =item C<02pod.t>
2003
2004 Verifies that all POD is free from errors. Only executed if the C<TEST_POD> 
2005 environment variable is true.
2006
2007 =item C<03podcoverage.t>
2008
2009 Verifies that all methods/functions have POD coverage. Only executed if the
2010 C<TEST_POD> environment variable is true.
2011
2012 =back
2013
2014 =head3 Creating tests
2015
2016     mundus:~/MyApp chansen$ cat t/01app.t | perl -ne 'printf( "%2d  %s", $., $_ )'
2017     1  use Test::More tests => 2;
2018     2  use_ok( Catalyst::Test, 'MyApp' );
2019     3
2020     4  ok( request('/')->is_success );
2021
2022 The first line declares how many tests we are going to run, in this case
2023 two. The second line tests and loads our application in test mode. The
2024 fourth line verifies that our application returns a successful response.
2025
2026 C<Catalyst::Test> exports two functions, C<request> and C<get>. Each can
2027 take three different arguments:
2028
2029 =over 4
2030
2031 =item A string which is a relative or absolute URI.
2032
2033     request('/my/path');
2034     request('http://www.host.com/my/path');
2035
2036 =item An instance of C<URI>.
2037
2038     request( URI->new('http://www.host.com/my/path') );
2039
2040 =item An instance of C<HTTP::Request>.
2041
2042     request( HTTP::Request->new( GET => 'http://www.host.com/my/path') );
2043
2044 =back
2045
2046 C<request> returns an instance of C<HTTP::Response> and C<get> returns the 
2047 content (body) of the response.
2048
2049 =head3 Running tests locally
2050
2051     mundus:~/MyApp chansen$ CATALYST_DEBUG=0 TEST_POD=1 prove --lib lib/ t/
2052     t/01app............ok                                                        
2053     t/02pod............ok                                                        
2054     t/03podcoverage....ok                                                        
2055     All tests successful.
2056     Files=3, Tests=4,  2 wallclock secs ( 1.60 cusr +  0.36 csys =  1.96 CPU)
2057  
2058 C<CATALYST_DEBUG=0> ensures that debugging is off; if it's enabled you
2059 will see debug logs between tests.
2060
2061 C<TEST_POD=1> enables POD checking and coverage.
2062
2063 C<prove> A command-line tool that makes it easy to run tests. You can
2064 find out more about it from the links below.
2065
2066 =head3 Running tests remotely
2067
2068     mundus:~/MyApp chansen$ CATALYST_SERVER=http://localhost:3000/ prove --lib lib/ t/01app.t
2069     t/01app....ok                                                                
2070     All tests successful.
2071     Files=1, Tests=2,  0 wallclock secs ( 0.40 cusr +  0.01 csys =  0.41 CPU)
2072
2073 C<CATALYST_SERVER=http://localhost:3000/> is the absolute deployment URI of 
2074 your application. In C<CGI> or C<FastCGI> it should be the host and path 
2075 to the script.
2076
2077 =head3 C<Test::WWW::Mechanize> and Catalyst
2078
2079 Be sure to check out C<Test::WWW::Mechanize::Catalyst>. It makes it easy to
2080 test HTML, forms and links. A short example of usage:
2081
2082     use Test::More tests => 6;
2083     use_ok( Test::WWW::Mechanize::Catalyst, 'MyApp' );
2084
2085     my $mech = Test::WWW::Mechanize::Catalyst->new;
2086     $mech->get_ok("http://localhost/", 'Got index page');
2087     $mech->title_like( qr/^MyApp on Catalyst/, 'Got right index title' );
2088     ok( $mech->find_link( text_regex => qr/^Wiki/i ), 'Found link to Wiki' );
2089     ok( $mech->find_link( text_regex => qr/^Mailing-List/i ), 'Found link to Mailing-List' );
2090     ok( $mech->find_link( text_regex => qr/^IRC channel/i ), 'Found link to IRC channel' );
2091
2092 =head3 Further Reading
2093
2094 =over 4
2095
2096 =item Catalyst::Test
2097
2098 L<http://search.cpan.org/dist/Catalyst/lib/Catalyst/Test.pm>
2099
2100 =item Test::WWW::Mechanize::Catalyst
2101
2102 L<http://search.cpan.org/dist/Test-WWW-Mechanize-Catalyst/lib/Test/WWW/Mechanize/Catalyst.pm>
2103
2104 =item Test::WWW::Mechanize
2105
2106 L<http://search.cpan.org/dist/Test-WWW-Mechanize/Mechanize.pm>
2107
2108 =item WWW::Mechanize
2109
2110 L<http://search.cpan.org/dist/WWW-Mechanize/lib/WWW/Mechanize.pm>
2111
2112 =item LWP::UserAgent
2113
2114 L<http://search.cpan.org/dist/libwww-perl/lib/LWP/UserAgent.pm>
2115
2116 =item HTML::Form
2117
2118 L<http://search.cpan.org/dist/libwww-perl/lib/HTML/Form.pm>
2119
2120 =item HTTP::Message
2121
2122 L<http://search.cpan.org/dist/libwww-perl/lib/HTTP/Message.pm>
2123
2124 =item HTTP::Request
2125
2126 L<http://search.cpan.org/dist/libwww-perl/lib/HTTP/Request.pm>
2127
2128 =item HTTP::Request::Common
2129
2130 L<http://search.cpan.org/dist/libwww-perl/lib/HTTP/Request/Common.pm>
2131
2132 =item HTTP::Response
2133
2134 L<http://search.cpan.org/dist/libwww-perl/lib/HTTP/Response.pm>
2135
2136 =item HTTP::Status
2137
2138 L<http://search.cpan.org/dist/libwww-perl/lib/HTTP/Status.pm>
2139
2140 =item URI
2141
2142 L<http://search.cpan.org/dist/URI/URI.pm>
2143
2144 =item Test::More
2145
2146 L<http://search.cpan.org/dist/Test-Simple/lib/Test/More.pm>
2147
2148 =item Test::Pod
2149
2150 L<http://search.cpan.org/dist/Test-Pod/Pod.pm>
2151
2152 =item Test::Pod::Coverage
2153
2154 L<http://search.cpan.org/dist/Test-Pod-Coverage/Coverage.pm>
2155
2156 =item prove (Test::Harness)
2157
2158 L<http://search.cpan.org/dist/Test-Harness/bin/prove>
2159
2160 =back
2161
2162 =head2 XMLRPC
2163
2164 Today we'll discover the wonderful world of web services.
2165 XMLRPC is unlike SOAP a very simple (and imo elegant) protocol,
2166 exchanging small XML messages like these.
2167
2168 Request:
2169
2170     POST /api HTTP/1.1
2171     TE: deflate,gzip;q=0.3
2172     Connection: TE, close
2173     Accept: text/xml
2174     Accept: multipart/*
2175     Host: 127.0.0.1:3000
2176     User-Agent: SOAP::Lite/Perl/0.60
2177     Content-Length: 192
2178     Content-Type: text/xml
2179
2180     <?xml version="1.0" encoding="UTF-8"?>
2181     <methodCall>
2182         <methodName>add</methodName>
2183         <params>
2184             <param><value><int>1</int></value></param>
2185             <param><value><int>2</int></value></param>
2186         </params>
2187     </methodCall>
2188
2189 Response:
2190
2191     Connection: close
2192     Date: Tue, 20 Dec 2005 07:45:55 GMT
2193     Content-Length: 133
2194     Content-Type: text/xml
2195     Status: 200
2196     X-Catalyst: 5.62
2197
2198     <?xml version="1.0" encoding="us-ascii"?>
2199     <methodResponse>
2200         <params>
2201             <param><value><int>3</int></value></param>
2202         </params>
2203     </methodResponse>
2204
2205 Sweet little protocol, isn't it? :)
2206
2207 Now follow these few steps to implement the application.
2208
2209 1. Install Catalyst (5.61 or later), Catalyst::Plugin::XMLRPC (0.06 or later) and SOAP::Lite (for XMLRPCsh.pl)
2210
2211     % perl -MCPAN -e'install Catalyst'
2212     ...
2213     % perl -MCPAN -e'install Catalyst::Plugin::XMLRPC'
2214     ...
2215
2216 2. Create a myapp
2217
2218     % catalyst.pl MyApp
2219     ...
2220     % cd MyApp
2221
2222 3. Add the XMLRPC plugin to MyApp.pm
2223
2224     use Catalyst qw/-Debug Static::Simple XMLRPC/;
2225
2226 4. Add a api controller
2227
2228     % ./script/myapp_create.pl controller API
2229
2230 5. Add a XMLRPC redispatch method and a add method with Remote attribute
2231 to lib/MyApp/Controller/API.pm
2232
2233     sub default : Private {
2234         my ( $self, $c ) = @_;
2235         $c->xmlrpc;
2236     }
2237
2238     sub add : Remote {
2239         my ( $self, $c, $a, $b ) = @_;
2240         return $a + $b;
2241     }
2242
2243 The default action is the entry point for each XMLRPC request, it will
2244 redispatch every request to methods with Remote attribute in the same class.
2245
2246 The add method is no traditional action, it has no private or public path.
2247 Only the XMLRPC dispatcher knows it exists.
2248
2249 6. Thats it! You have built your first web service, lets test it with
2250 XMLRPCsh.pl (part of SOAP::Lite)
2251
2252     % ./script/myapp_server.pl
2253     ...
2254     % XMLRPCsh.pl http://127.0.0.1:3000/api
2255     Usage: method[(parameters)]
2256     > add( 1, 2 )
2257     --- XMLRPC RESULT ---
2258     '3'
2259
2260 =head3 Tip Of The Day
2261
2262 Your return data type is usually auto-detected, but you can easily
2263 enforce a specific one.
2264
2265     sub add : Remote {
2266         my ( $self, $c, $a, $b ) = @_;
2267         return RPC::XML::int->new( $a + $b );
2268     }
2269     
2270 =head2 Action Types
2271
2272 =head3 Introduction
2273
2274 A Catalyst application is driven by one or more Controller modules. There are
2275 a number of ways that Catalyst can decide which of the methods in your
2276 controller modules it should call. Controller methods are also called actions,
2277 because they determine how your catalyst application should (re-)act to any
2278 given URL. When the application is started up, catalyst looks at all your
2279 actions, and decides which URLs they map to.
2280
2281 =head3 Type attributes
2282
2283 Each action is a normal method in your controller, except that it has an
2284 L<attribute|http://search.cpan.org/~nwclark/perl-5.8.7/lib/attributes.pm>
2285 attached. These can be one of several types.
2286
2287 Assume our Controller module starts with the following package declaration:
2288
2289  package MyApp::Controller::Buckets;
2290
2291 and we are running our application on localhost, port 3000 (the test server default).
2292
2293 =over 4
2294
2295 =item Path
2296
2297 A Path attribute also takes an argument, this can be either a relative or an
2298 absolute path. A relative path will be relative to the controller namespace,
2299 an absolute path will represent an exact matching URL.
2300
2301  sub my_handles : Path('handles') { .. }
2302
2303 becomes
2304
2305  http://localhost:3000/buckets/handles
2306
2307 and
2308
2309  sub my_handles : Path('/handles') { .. }
2310
2311 becomes 
2312
2313  http://localhost:3000/handles
2314
2315 =item Local
2316
2317 When using a Local attribute, no parameters are needed, instead, the name of
2318 the action is matched in the URL. The namespaces created by the name of the
2319 controller package is always part of the URL.
2320
2321  sub my_handles : Local { .. }
2322
2323 becomes
2324
2325  http://localhost:3000/buckets/my_handles
2326
2327 =item Global
2328
2329 A Global attribute is similar to a Local attribute, except that the namespace
2330 of the controller is ignored, and matching starts at root.
2331
2332  sub my_handles : Global { .. }
2333
2334 becomes
2335
2336  http://localhost:3000/my_handles
2337
2338 =item Regex
2339
2340 By now you should have figured that a Regex attribute is just what it sounds
2341 like. This one takes a regular expression, and matches starting from
2342 root. These differ from the rest as they can match multiple URLs.
2343
2344  sub my_handles : Regex('^handles') { .. }
2345
2346 matches
2347
2348  http://localhost:3000/handles
2349
2350 and 
2351
2352  http://localhost:3000/handles_and_other_parts
2353
2354 etc.
2355
2356 =item LocalRegex
2357
2358 A LocalRegex is similar to a Regex, except it only matches below the current
2359 controller namespace.
2360
2361  sub my_handles : LocalRegex(^handles') { .. }
2362
2363 matches
2364
2365  http://localhost:3000/buckets/handles
2366
2367 and
2368
2369  http://localhost:3000/buckets/handles_and_other_parts
2370
2371 etc.
2372
2373 =item Private
2374
2375 Last but not least, there is the Private attribute, which allows you to create
2376 your own internal actions, which can be forwarded to, but won't be matched as
2377 URLs.
2378
2379  sub my_handles : Private { .. }
2380
2381 becomes nothing at all..
2382
2383 Catalyst also predefines some special Private actions, which you can override,
2384 these are:
2385
2386 =over 4
2387
2388 =item default
2389
2390 The default action will be called, if no other matching action is found. If
2391 you don't have one of these in your namespace, or any sub part of your
2392 namespace, you'll get an error page instead. If you want to find out where it
2393 was the user was trying to go, you can look in the request object using 
2394 C<< $c->req->path >>.
2395
2396  sub default : Private { .. }
2397
2398 works for all unknown URLs, in this controller namespace, or every one if put
2399 directly into MyApp.pm.
2400
2401 =item index 
2402
2403 The index action is called when someone tries to visit the exact namespace of
2404 your controller. If index, default and matching Path actions are defined, then
2405 index will be used instead of default and Path.
2406
2407  sub index : Private { .. }
2408
2409 becomes
2410
2411  http://localhost:3000/buckets
2412
2413 =item begin
2414
2415 The begin action is called at the beginning of every request involving this
2416 namespace directly, before other matching actions are called. It can be used
2417 to set up variables/data for this particular part of your app. A single begin
2418 action is called, its always the one most relevant to the current namespace.
2419
2420  sub begin : Private { .. }
2421
2422 is called once when 
2423
2424  http://localhost:3000/bucket/(anything)?
2425
2426 is visited.
2427
2428 =item end
2429
2430 Like begin, this action is always called for the namespace it is in, after
2431 every other action has finished. It is commonly used to forward processing to
2432 the View component. A single end action is called, its always the one most
2433 relevant to the current namespace. 
2434
2435
2436  sub end : Private { .. }
2437
2438 is called once after any actions when
2439
2440  http://localhost:3000/bucket/(anything)?
2441
2442 is visited.
2443
2444 =item auto
2445
2446 Lastly, the auto action is magic in that B<every> auto action in
2447 the chain of paths up to and including the ending namespace, will be
2448 called. (In contrast, only one of the begin/end/default actions will be
2449 called, the relevant one).
2450
2451  package MyApp.pm;
2452  sub auto : Private { .. }
2453
2454 and 
2455
2456  sub auto : Private { .. }
2457
2458 will both be called when visiting 
2459
2460  http://localhost:3000/bucket/(anything)?
2461
2462 =back
2463
2464 =back
2465
2466 =head3 A word of warning
2467
2468 Due to possible namespace conflicts with Plugins, it is advised to only put the
2469 pre-defined Private actions in your main MyApp.pm file, all others should go
2470 in a Controller module.
2471
2472 =head3 More Information
2473
2474 L<http://search.cpan.org/author/SRI/Catalyst-5.61/lib/Catalyst/Manual/Intro.pod>
2475
2476 L<http://dev.catalyst.perl.org/wiki/FlowChart>
2477
2478 =head2 Static::Simple
2479
2480 =head3 Introduction
2481
2482 Static::Simple is a plugin that will help to serve static content for your
2483 application. By default, it will serve most types of files, excluding some
2484 standard Template Toolkit extensions, out of your B<root> file directory. All
2485 files are served by path, so if B<images/me.jpg> is requested, then
2486 B<root/images/me.jpg> is found and served.
2487
2488 =head3 Usage
2489
2490 Using the plugin is as simple as setting your use line in MyApp.pm to:
2491
2492  use Catalyst qw/Static::Simple/;
2493
2494 and already files will be served.
2495
2496 =head3 Configuring
2497
2498 =over 4
2499
2500 =item Include Path
2501
2502 You may of course want to change the default locations, and make
2503 Static::Simple look somewhere else, this is as easy as:
2504
2505  MyApp->config->{static}->{include_path} = [
2506   MyApp->config->{root},
2507   '/path/to/my/files' 
2508  ];
2509
2510 When you override include_path, it will not automatically append the normal
2511 root path, so you need to add it yourself if you still want it. These will be
2512 searched in order given, and the first matching file served.
2513
2514 =item Static directories
2515
2516 If you want to force some directories to be only static, you can set them
2517 using paths relative to the root dir, or regular expressions:
2518
2519  MyApp->config->{static}->{dirs} = [
2520    'static',
2521    qr/^(images|css)/,
2522  ];
2523
2524 =item File extensions
2525
2526 By default, the following extensions are not served: B<tmpl, tt, tt2, html,
2527 xhtml>. This list can be replaced easily:
2528
2529  MyApp->config->{static}->{ignore_extensions} = [
2530     qw/tmpl tt tt2 html xhtml/ 
2531  ];
2532
2533 =item Ignoring directories
2534
2535 Entire directories can be ignored. If used with include_path, directories
2536 relative to the include_path dirs will also be ignored:
2537
2538  MyApp->config->{static}->{ignore_dirs} = [ qw/tmpl css/ ];
2539
2540 =back
2541
2542 =head3 More information
2543
2544 L<http://search.cpan.org/dist/Catalyst-Plugin-Static-Simple/>
2545
2546 =head2 Authorization
2547
2548 =head3 Introduction
2549
2550 Authorization is the step that comes after authentication. Authentication
2551 establishes that the user agent is really representing the user we think it's
2552 representing, and then authorization determines what this user is allowed to
2553 do.
2554
2555 =head3 Role Based Access Control
2556
2557 Under role based access control each user is allowed to perform any number of
2558 roles. For example, at a zoo no one but specially trained personnel can enter
2559 the moose cage (Mynd you, møøse bites kan be pretty nasti!). For example: 
2560
2561     package Zoo::Controller::MooseCage;
2562
2563     sub feed_moose : Local {
2564         my ( $self, $c ) = @_;
2565
2566         $c->model( "Moose" )->eat( $c->req->param("food") );
2567     }
2568
2569 With this action, anyone can just come into the moose cage and feed the moose,
2570 which is a very dangerous thing. We need to restrict this action, so that only
2571 a qualified moose feeder can perform that action.
2572
2573 The Authorization::Roles plugin let's us perform role based access control
2574 checks. Let's load it:
2575
2576     use Catalyst qw/
2577         Authentication # yadda yadda
2578         Authorization::Roles
2579     /;
2580
2581 And now our action should look like this:
2582
2583     sub feed_moose : Local {
2584         my ( $self, $c ) = @_;
2585
2586         if ( $c->check_roles( "moose_feeder" ) ) {
2587             $c->model( "Moose" )->eat( $c->req->param("food") );
2588         } else {
2589             $c->stash->{error} = "unauthorized";
2590         }
2591     }
2592
2593 This checks C<< $c->user >>, and only if the user has B<all> the roles in the
2594 list, a true value is returned.
2595
2596 C<check_roles> has a sister method, C<assert_roles>, which throws an exception
2597 if any roles are missing.
2598
2599 Some roles that might actually make sense in, say, a forum application:
2600
2601 =over 4
2602
2603 =item *
2604
2605 administrator
2606
2607 =item *
2608
2609 moderator
2610
2611 =back
2612
2613 each with a distinct task (system administration versus content administration).
2614
2615 =head3 Access Control Lists
2616
2617 Checking for roles all the time can be tedious and error prone.
2618
2619 The Authorization::ACL plugin let's us declare where we'd like checks to be
2620 done automatically for us.
2621
2622 For example, we may want to completely block out anyone who isn't a
2623 C<moose_feeder> from the entire C<MooseCage> controller:
2624
2625     Zoo->deny_access_unless( "/moose_cage", [qw/moose_feeder/] );
2626
2627 The role list behaves in the same way as C<check_roles>. However, the ACL
2628 plugin isn't limited to just interacting with the Roles plugin. We can use a
2629 code reference instead. For example, to allow either moose trainers or moose
2630 feeders into the moose cage, we can create a more complex check:
2631
2632     Zoo->deny_access_unless( "/moose_cage", sub {
2633         my $c = shift;
2634         $c->check_roles( "moose_trainer" ) || $c->check_roles( "moose_feeder" );
2635     });
2636
2637 The more specific a role, the earlier it will be checked. Let's say moose
2638 feeders are now restricted to only the C<feed_moose> action, while moose
2639 trainers get access everywhere:
2640
2641     Zoo->deny_access_unless( "/moose_cage", [qw/moose_trainer/] );
2642     Zoo->allow_access_if( "/moose_cage/feed_moose", [qw/moose_feeder/]);
2643
2644 When the C<feed_moose> action is accessed the second check will be made. If the
2645 user is a C<moose_feeder>, then access will be immediately granted. Otherwise,
2646 the next rule in line will be tested - the one checking for a C<moose_trainer>.
2647 If this rule is not satisfied, access will be immediately denied.
2648
2649 Rules applied to the same path will be checked in the order they were added.
2650
2651 Lastly, handling access denial events is done by creating an C<access_denied>
2652 private action:
2653
2654     sub access_denied : Private {
2655         my ( $self, $c, $action ) = @_;
2656
2657         
2658     }
2659
2660 This action works much like auto, in that it is inherited across namespaces
2661 (not like object oriented code). This means that the C<access_denied> action
2662 which is B<nearest> to the action which was blocked will be triggered.
2663
2664 If this action does not exist, an error will be thrown, which you can clean up
2665 in your C<end> private action instead.
2666
2667 Also, it's important to note that if you restrict access to "/" then C<end>,
2668 C<default>, etc will also be restricted.
2669
2670    MyApp->acl_allow_root_internals;
2671
2672 will create rules that permit access to C<end>, C<begin>, and C<auto> in the
2673 root of your app (but not in any other controller).
2674
2675 =head3 More Information
2676
2677 L<http://search.cpan.org/perldoc?Catalyst::Plugin::Authorization::Roles>
2678 L<http://search.cpan.org/perldoc?Catalyst::Plugin::Authorization::ACL>
2679
2680 =head1 AUTHORS
2681
2682 Sebastian Riedel, C<sri@oook.de>
2683 Danijel Milicevic, C<me@danijel.de>
2684 Viljo Marrandi, C<vilts@yahoo.com>  
2685 Marcus Ramberg, C<mramberg@cpan.org>
2686 Jesse Sheidlower, C<jester@panix.com>
2687 Andy Grundman, C<andy@hybridized.org> 
2688 Chisel Wright, C<pause@herlpacker.co.uk>
2689 Will Hawes, C<info@whawes.co.uk>
2690 Gavin Henry, C<ghenry@perl.me.uk>
2691
2692
2693 =head1 COPYRIGHT
2694
2695 This program is free software, you can redistribute it and/or modify it
2696 under the same terms as Perl itself.