Expand roles section to contain specific docs on caveats, and version numbers when...
[catagits/Catalyst-Manual.git] / lib / Catalyst / Manual / Cookbook.pod
index 3aed940..ca49cf3 100644 (file)
@@ -62,11 +62,10 @@ nifty statistics in your debug messages.
 =head2 Enable debug status in the environment
 
 Normally you enable the debugging info by adding the C<-Debug> flag to
-your C<use Catalyst> statement (or C<__PACKAGE__->setup(qw/-Debug/)
-). However, you can also enable it using environment variable, so you
-can (for example) get debug info without modifying your application
-scripts. Just set C<CATALYST_DEBUG> or C<E<lt>MYAPPE<gt>_DEBUG> to a
-true value.
+your C<use Catalyst> statement . However, you can also enable it using
+environment variable, so you can (for example) get debug info without
+modifying your application scripts. Just set C<CATALYST_DEBUG> or
+C<E<lt>MYAPPE<gt>_DEBUG> to a true value.
 
 =head2 Sessions
 
@@ -114,11 +113,11 @@ reference.
 =head3 EXAMPLE
 
   use parent qw/Catalyst/;
-  __PACKAGE__->setup( qw/
+  use Catalyst  qw/
                          Session
                          Session::Store::FastMmap
                          Session::State::Cookie
-                   /;)
+                   /;
 
 
   ## Write data into the session
@@ -269,12 +268,11 @@ The L<Catalyst::Plugin::Authorization::Roles> plugin is required when
 implementing roles:
 
  use parent qw/Catalyst/;
- __PACKAGE__->setup (qw/
+ use Catalyst qw/
      Authentication
      Authentication::Credential::Password
      Authentication::Store::Htpasswd
-     Authorization::Roles
-  /);
+     Authorization::Roles/;
 
 Roles are implemented automatically when using
 L<Catalyst::Authentication::Store::Htpasswd>:
@@ -404,10 +402,10 @@ the user is a member.
 =head3 EXAMPLE
 
  use parent qw/Catalyst/;
- __PACKAGE__->setup( qw/Authentication
-                        Authentication::Credential::Password
-                        Authentication::Store::Htpasswd
-                        Authorization::Roles/);
+ use Catalyst qw/Authentication
+                 Authentication::Credential::Password
+                 Authentication::Store::Htpasswd
+                 Authorization::Roles/;
 
  __PACKAGE__->config->{authentication}{htpasswd} = "passwdfile";
 
@@ -501,10 +499,10 @@ The Authorization::Roles plugin let's us perform role based access
 control checks. Let's load it:
 
     use parent qw/Catalyst/;
-    __PACKAGE__->setup(qw/
-        Authentication # yadda yadda
-        Authorization::Roles
-    /);
+    use Catalyst qw/
+                    Authentication # yadda yadda
+                    Authorization::Roles
+                  /;
 
 And now our action should look like this:
 
@@ -718,7 +716,7 @@ later) and SOAP::Lite (for XMLRPCsh.pl).
 
 3. Add the XMLRPC plugin to MyApp.pm
 
-    __PACKAGE__->setup( qw/-Debug Static::Simple XMLRPC/);
+    use Catalyst qw/-Debug Static::Simple XMLRPC/;
 
 4. Add an API controller
 
@@ -1197,6 +1195,8 @@ becomes
 
  http://localhost:3000/handles
 
+See also: L<Catalyst::DispatchType::Path>
+
 =item Local
 
 When using a Local attribute, no parameters are needed, instead, the
@@ -1238,6 +1238,8 @@ and
 
 etc.
 
+See also: L<Catalyst::DispatchType::Regex>
+
 =item LocalRegex
 
 A LocalRegex is similar to a Regex, except it only matches below the current
@@ -1255,6 +1257,11 @@ and
 
 etc.
 
+=item Chained
+
+See L<Catalyst::DispatchType::Chained> for a description of how the chained
+dispatch type works.
+
 =item Private
 
 Last but not least, there is the Private attribute, which allows you
@@ -1362,6 +1369,71 @@ L<http://search.cpan.org/author/SRI/Catalyst-5.61/lib/Catalyst/Manual/Intro.pod>
 
 L<http://dev.catalyst.perl.org/wiki/FlowChart>
 
+=head2 DRY Controllers with Chained actions.
+
+Imagine that you would like the following paths in your application:
+
+=over
+
+=item B</cd/<ID>/track/<ID>>
+
+Displays info on a particular track.
+                                       
+In the case of a multi-volume CD, this is the track sequence.
+
+=item B</cd/<ID>/volume/<ID>/track/<ID>>
+
+Displays info on a track on a specific volume.
+
+=back
+
+Here is some example code, showing how to do this with chained controllers:
+
+    package CD::Controller;
+    use base qw/Catalyst::Controller/;
+    
+    sub root : Chained('/') PathPart('/cd') CaptureArgs(1) {
+        my ($self, $c, $cd_id) = @_;
+        $c->stash->{cd_id} = $cd_id;
+        $c->stash->{cd} = $self->model('CD')->find_by_id($cd_id);
+    }
+    
+    sub trackinfo : Chained('track') PathPart('') Args(0) RenderView {
+        my ($self, $c) = @_;
+    }
+    
+    package CD::Controller::ByTrackSeq;
+    use base qw/CD::Controller/;
+    
+    sub track : Chained('root') PathPart('track') CaptureArgs(1) {
+        my ($self, $c, $track_seq) = @_;
+        $c->stash->{track} = $self->stash->{cd}->find_track_by_seq($track_seq);
+    }
+    
+    package CD::Controller::ByTrackVolNo;
+    use base qw/CD::Controller/;
+    
+    sub volume : Chained('root') PathPart('volume') CaptureArgs(1) {
+        my ($self, $c, $volume) = @_;
+        $c->stash->{volume} = $volume;
+    }
+    
+    sub track : Chained('volume') PathPart('track') CaptureArgs(1) {
+        my ($self, $c, $track_no) = @_;
+        $c->stash->{track} = $self->stash->{cd}->find_track_by_vol_and_track_no(
+            $c->stash->{volume}, $track_no
+        );
+    }
+    
+Note that adding other actions (i.e. chain endpoints) which operate on a track 
+is simply a matter of adding a new sub to CD::Controller - no code is duplicated,
+even though there are two different methods of looking up a track.
+
+This technique can be expanded as needed to fulfil your requirements - for example,
+if you inherit the first action of a chain from a base class, then mixing in a
+different base class can be used to duplicate an entire URL hieratchy at a different
+point within your application.
+
 =head2 Component-based Subrequests
 
 See L<Catalyst::Plugin::SubRequest>.
@@ -1468,6 +1540,12 @@ the Catalyst Request object:
 (See the L<Catalyst::Manual::Intro> Flow_Control section for more 
 information on passing arguments via C<forward>.)
 
+=head2 Chained dispatch using base classes, and inner packages.
+
+  package MyApp::Controller::Base;
+  use base qw/Catalyst::Controller/;
+
+  sub key1 : Chained('/') 
 
 =head1 Deployment
 
@@ -1699,6 +1777,9 @@ can be used without worrying about the thread safety of your application.
 
 =head3 Cons
 
+You may have to disable mod_deflate.  If you experience page hangs with
+mod_fastcgi then remove deflate.load and deflate.conf from mods-enabled/
+
 =head4 More complex environment
 
 With FastCGI, there are more things to monitor and more processes running
@@ -1912,7 +1993,7 @@ B<root/images/me.jpg> is found and served.
 
 Using the plugin is as simple as setting your use line in MyApp.pm to include:
 
- __PACKAGE__->setup( qw/Static::Simple/);
+ use Catalyst qw/Static::Simple/;
 
 and already files will be served.
 
@@ -1997,7 +2078,7 @@ using L<Catalyst::Plugin::Static>.
 
 In your main application class (MyApp.pm), load the plugin:
 
-    __PACKAGE__->setup( qw/-Debug FormValidator Static OtherPlugin/);
+    use Catalyst qw/-Debug FormValidator Static OtherPlugin/;
 
 You will also need to make sure your end method does I<not> forward
 static content to the view, perhaps like this:
@@ -2112,7 +2193,7 @@ rendered XHTML version of the source POD document.  This is an ideal
 application for a cache because the source document changes
 infrequently but may be viewed many times.
 
-    __PACKAGE__->setup( qw/Cache::FileCache/);
+    use Catalyst qw/Cache::FileCache/;
     
     ...
     
@@ -2160,7 +2241,7 @@ thing for every single user who views the page.
 
 We can add the PageCache plugin to speed things up.
 
-    __PACKAGE__->setup( qw/Cache::FileCache PageCache/);
+    use Catalyst qw/Cache::FileCache PageCache/;
     
     sub front_page : Path ('/') {
         my ( $self, $c ) = @_;