add =encoding to make pod tests happy
[catagits/Catalyst-Manual.git] / lib / Catalyst / Manual / Cookbook.pod
index 104ab74..6b5d47a 100644 (file)
@@ -1,3 +1,5 @@
+=encoding utf8
+
 =head1 NAME
 
 Catalyst::Manual::Cookbook - Cooking with Catalyst
@@ -33,9 +35,12 @@ to go into this C<end> method; see L<Catalyst::Plugin::FillInForm>).
 
         if ( scalar @{ $c->error } ) {
             $c->stash->{errors}   = $c->error;
+            for my $error ( @{ $c->error } ) {
+                $c->log->error($error);
+            }
             $c->stash->{template} = 'errors.tt';
             $c->forward('MyApp::View::TT');
-            $c->error(0);
+            $c->clear_errors;
         }
 
         return 1 if $c->response->status =~ /^3\d\d$/;
@@ -133,7 +138,7 @@ reference.
   sub add_item : Local {
      my ( $self, $c ) = @_;
 
-     my $item_id = $c->req->param("item");
+     my $item_id = $c->req->params->{item};
 
      push @{ $c->session->{items} }, $item_id;
 
@@ -196,17 +201,25 @@ This is equivalent to:
   # configure base package
   __PACKAGE__->config( name => MyApp );
   # configure authentication
-  __PACKAGE__->config->{authentication} = {
-    user_class => 'MyApp::Model::MyDB::Customer',
-    ...
-  };
+  __PACKAGE__->config(
+        'Plugin::Authentication' => {
+            user_class => 'MyApp::Model::MyDB::Customer',
+            ...
+        },
+  _;
   # configure sessions
-  __PACKAGE__->config->{session} = {
-    expires => 3600,
-    ...
-  };
+  __PACKAGE__->config(
+    session => {
+        expires => 3600,
+        ...
+    },
+  );
   # configure email sending
-  __PACKAGE__->config->{email} = [qw/SMTP localhost/];
+  __PACKAGE__->config( email => [qw/SMTP localhost/] );
+
+L<Catalyst> explains precedence of multiple sources for configuration
+values, how to access the values in your components, and many 'base'
+config variables used internally.
 
 See also L<Config::General|Config::General>.
 
@@ -243,7 +256,7 @@ this.
 
 This is extensively covered in other documentation; see in particular
 L<Catalyst::Plugin::Authentication> and the Authentication chapter
-of the Tutorial at L<Catalyst::Manual::Tutorial::Authorization>.
+of the Tutorial at L<Catalyst::Manual::Tutorial::06_Authorization>.
 
 =head2 Pass-through login (and other actions)
 
@@ -373,22 +386,22 @@ the user is a member.
                  },
              },
          },
-     },   
+     },
   );
 
   package MyApp::Controller::Root;
   use Moose;
   use namespace::autoclean;
-  
+
   BEGIN { extends 'Catalyst::Controller' }
-  
+
   __PACKAGE__->config(namespace => '');
-  
+
   sub login : Local {
      my ($self, $c) = @_;
 
-     if (    my $user = $c->req->param("user")
-         and my $password = $c->req->param("password") )
+     if ( my $user = $c->req->params->{user}
+         and my $password = $c->req->param->{password} )
      {
          if ( $c->authenticate( username => $user, password => $password ) ) {
               $c->res->body( "hello " . $c->user->name );
@@ -446,7 +459,7 @@ determines what this user is allowed to do.
 
 Under role based access control each user is allowed to perform any
 number of roles. For example, at a zoo no one but specially trained
-personnel can enter the moose cage (Mynd you, møøse bites kan be
+personnel can enter the moose cage (Mynd you, møøse bites kan be
 pretty nasti!). For example:
 
     package Zoo::Controller::MooseCage;
@@ -454,7 +467,7 @@ pretty nasti!). For example:
     sub feed_moose : Local {
         my ( $self, $c ) = @_;
 
-        $c->model( "Moose" )->eat( $c->req->param("food") );
+        $c->model( "Moose" )->eat( $c->req->params->{food} );
     }
 
 With this action, anyone can just come into the moose cage and feed
@@ -476,7 +489,7 @@ And now our action should look like this:
         my ( $self, $c ) = @_;
 
         if ( $c->check_roles( "moose_feeder" ) ) {
-            $c->model( "Moose" )->eat( $c->req->param("food") );
+            $c->model( "Moose" )->eat( $c->req->params->{food} );
         } else {
             $c->stash->{error} = "unauthorized";
         }
@@ -569,7 +582,7 @@ root of your app (but not in any other controller).
 
 =head1 Models
 
-Models are where application data belongs.  Catalyst is exteremely
+Models are where application data belongs.  Catalyst is extremely
 flexible with the kind of models that it can use.  The recipes here
 are just the start.
 
@@ -586,7 +599,7 @@ write a simple component in Catalyst that slurps in an outside Model:
 
     __PACKAGE__->config(
         schema_class => 'Some::DBIC::Schema',
-        connect_info => ['dbi:SQLite:foo.db', '', '', {AutoCommit=>1}];
+        connect_info => ['dbi:SQLite:foo.db', '', '', {AutoCommit=>1}],
     );
 
     1;
@@ -745,8 +758,8 @@ display your data; you can choose to generate HTML, PDF files, or plain
 text if you wanted.
 
 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.
+and though there are several template systems available,
+L<Template Toolkit|Template> is probably the most popular.
 
 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
@@ -958,47 +971,13 @@ L<http://search.cpan.org/perldoc?Template>
 =head2 Adding RSS feeds
 
 Adding RSS feeds to your Catalyst applications is simple. We'll see two
-different aproaches here, but the basic premise is that you forward to
+different approaches here, but the basic premise is that you forward to
 the normal view action first to get the objects, then handle the output
 differently.
 
-=head3 Using TT templates
-
-This is the aproach used in Agave (L<http://dev.rawmode.org/>).
-
-    sub rss : Local {
-        my ($self,$c) = @_;
-        $c->forward('view');
-        $c->stash->{template}='rss.tt';
-    }
-
-Then you need a template. Here's the one from Agave:
-
-    <?xml version="1.0" encoding="UTF-8"?>
-    <rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/">
-      <channel>
-       <title>[ [% blog.name || c.config.name || "Agave" %] ] RSS Feed</title>
-        <link>[% base %]</link>
-        <description>Recent posts</description>
-        <language>en-us</language>
-        <ttl>40</ttl>
-     [% WHILE (post = posts.next) %]
-      <item>
-        <title>[% post.title %]</title>
-        <description>[% post.formatted_teaser|html%]</description>
-        <pubDate>[% post.pub_date %]</pubDate>
-        <guid>[% post.full_uri %]</guid>
-        <link>[% post.full_uri %]</link>
-        <dc:creator>[% post.author.screenname %]</dc:creator>
-      </item>
-    [% END %]
-      </channel>
-    </rss>
-
 =head3 Using XML::Feed
 
-A more robust solution is to use XML::Feed, as was done in the Catalyst
-Advent Calendar. Assuming we have a C<view> action that populates
+Assuming we have a C<view> action that populates
 'entries' with some DBIx::Class iterator, the code would look something
 like this:
 
@@ -1022,10 +1001,10 @@ like this:
         $c->res->body( $feed->as_xml );
    }
 
-A little more code in the controller, but with this approach you're
+With this approach you're
 pretty sure to get something that validates.
 
-Note that for both of the above aproaches, you'll need to set the
+Note that for both of the above approaches, you'll need to set the
 content type like this:
 
     $c->res->content_type('application/rss+xml');
@@ -1084,36 +1063,6 @@ set the appropriate content type and disposition.
 Controllers are the main point of communication between the web server
 and your application.  Here we explore some aspects of how they work.
 
-=head2 Extending RenderView (formerly DefaultEnd)
-
-The recommended approach for an C<end> action is to use
-L<Catalyst::Action::RenderView> (taking the place of
-L<Catalyst::Plugin::DefaultEnd>), which does what you usually need.
-However there are times when you need to add a bit to it, but don't want
-to write your own C<end> action.
-
-You can extend it like this:
-
-To add something to an C<end> action that is called before rendering
-(this is likely to be what you want), simply place it in the C<end>
-method:
-
-    sub end : ActionClass('RenderView') {
-      my ( $self, $c ) = @_;
-      # do stuff here; the RenderView action is called afterwards
-    }
-
-To add things to an C<end> action that are called I<after> rendering,
-you can set it up like this:
-
-    sub render : ActionClass('RenderView') { }
-
-    sub end : Private {
-      my ( $self, $c ) = @_;
-      $c->forward('render');
-      # do stuff here
-    }
-
 =head2 Action Types
 
 =head3 Introduction
@@ -1329,23 +1278,24 @@ will both be called when visiting
 You can put root actions in your main MyApp.pm file, but this is deprecated,
 please put your actions into your Root controller.
 
-=head3 More Information
+=head3 Flowchart
 
-L<http://dev.catalyst.perl.org/wiki/FlowChart>
+A graphical flowchart of how the dispatcher works can be found on the wiki at
+L<http://dev.catalyst.perl.org/attachment/wiki/WikiStart/catalyst-flow.png>.
 
-=head2 DRY Controllers with Chained actions.
+=head2 DRY Controllers with Chained actions
 
 Imagine that you would like the following paths in your application:
 
 =over
 
-=item B</cd/<ID>/track/<ID>>
+=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>>
+=item B<< /cd/<ID>/volume/<ID>/track/<ID> >>
 
 Displays info on a track on a specific volume.
 
@@ -1395,7 +1345,7 @@ 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
+different base class can be used to duplicate an entire URL hierarchy at a different
 point within your application.
 
 =head2 Component-based Subrequests
@@ -1511,458 +1461,36 @@ information on passing arguments via C<forward>.)
 
   sub key1 : Chained('/')
 
-=head1 Deployment
-
-The recipes below describe aspects of the deployment process,
-including web server engines and tips to improve application efficiency.
-
-=head2 mod_perl Deployment
-
-mod_perl is the best solution for many applications, but we'll list some pros
-and cons so you can decide for yourself.  The other production deployment
-option is FastCGI, for which see below.
-
-=head3 Pros
-
-=head4 Speed
-
-mod_perl is very fast and your app will benefit from being loaded in memory
-within each Apache process.
-
-=head4 Shared memory for multiple apps
-
-If you need to run several Catalyst apps on the same server, mod_perl will
-share the memory for common modules.
-
-=head3 Cons
-
-=head4 Memory usage
-
-Since your application is fully loaded in memory, every Apache process will
-be rather large.  This means a large Apache process will be tied up while
-serving static files, large files, or dealing with slow clients.  For this
-reason, it is best to run a two-tiered web architecture with a lightweight
-frontend server passing dynamic requests to a large backend mod_perl
-server.
-
-=head4 Reloading
-
-Any changes made to the core code of your app require a full Apache restart.
-Catalyst does not support Apache::Reload or StatINC.  This is another good
-reason to run a frontend web server where you can set up an
-C<ErrorDocument 502> page to report that your app is down for maintenance.
-
-=head4 Cannot run multiple versions of the same app
-
-It is not possible to run two different versions of the same application in
-the same Apache instance because the namespaces will collide.
-
-=head4 Setup
-
-Now that we have that out of the way, let's talk about setting up mod_perl
-to run a Catalyst app.
-
-=head4 1. Install Catalyst::Engine::Apache
-
-You should install the latest versions of both Catalyst and
-Catalyst::Engine::Apache.  The Apache engines were separated from the
-Catalyst core in version 5.50 to allow for updates to the engine without
-requiring a new Catalyst release.
-
-=head4 2. Install Apache with mod_perl
-
-Both Apache 1.3 and Apache 2 are supported, although Apache 2 is highly
-recommended.  With Apache 2, make sure you are using the prefork MPM and not
-the worker MPM.  The reason for this is that many Perl modules are not
-thread-safe and may have problems running within the threaded worker
-environment.  Catalyst is thread-safe however, so if you know what you're
-doing, you may be able to run using worker.
-
-In Debian, the following commands should get you going.
-
-    apt-get install apache2-mpm-prefork
-    apt-get install libapache2-mod-perl2
-
-=head4 3. Configure your application
-
-Every Catalyst application will automagically become a mod_perl handler
-when run within mod_perl.  This makes the configuration extremely easy.
-Here is a basic Apache 2 configuration.
-
-    PerlSwitches -I/var/www/MyApp/lib
-    PerlModule MyApp
-
-    <Location />
-        SetHandler          modperl
-        PerlResponseHandler MyApp
-    </Location>
-
-The most important line here is C<PerlModule MyApp>.  This causes mod_perl
-to preload your entire application into shared memory, including all of your
-controller, model, and view classes and configuration.  If you have -Debug
-mode enabled, you will see the startup output scroll by when you first
-start Apache.
-
-For an example Apache 1.3 configuration, please see the documentation for
-L<Catalyst::Engine::Apache::MP13>.
-
-=head3 Test It
-
-That's it, your app is now a full-fledged mod_perl application!  Try it out
-by going to http://your.server.com/.
-
-=head3 Other Options
-
-=head4 Non-root location
-
-You may not always want to run your app at the root of your server or virtual
-host.  In this case, it's a simple change to run at any non-root location
-of your choice.
-
-    <Location /myapp>
-        SetHandler          modperl
-        PerlResponseHandler MyApp
-    </Location>
-
-When running this way, it is best to make use of the C<uri_for> method in
-Catalyst for constructing correct links.
+=head2 Extending RenderView (formerly DefaultEnd)
 
-=head4 Static file handling
+The recommended approach for an C<end> action is to use
+L<Catalyst::Action::RenderView> (taking the place of
+L<Catalyst::Plugin::DefaultEnd>), which does what you usually need.
+However there are times when you need to add a bit to it, but don't want
+to write your own C<end> action.
 
-Static files can be served directly by Apache for a performance boost.
+You can extend it like this:
 
-    DocumentRoot /var/www/MyApp/root
-    <Location /static>
-        SetHandler default-handler
-    </Location>
+To add something to an C<end> action that is called before rendering
+(this is likely to be what you want), simply place it in the C<end>
+method:
 
-This will let all files within root/static be handled directly by Apache.  In
-a two-tiered setup, the frontend server should handle static files.
-The configuration to do this on the frontend will vary.
-
-The same is accomplished in lighttpd with the following snippet:
-
-   $HTTP["url"] !~ "^/(?:img/|static/|css/|favicon.ico$)" {
-         fastcgi.server = (
-             "" => (
-                 "MyApp" => (
-                     "socket"       => "/tmp/myapp.socket",
-                     "check-local"  => "disable",
-                 )
-             )
-         )
+    sub end : ActionClass('RenderView') {
+      my ( $self, $c ) = @_;
+      # do stuff here; the RenderView action is called afterwards
     }
 
-Which serves everything in the img, static, css directories
-statically, as well as the favicon file.
-
-Note the path of the application needs to be stated explicitly in the
-web server configuration for both these recipes.
-
-=head2 Catalyst on shared hosting
-
-So, you want to put your Catalyst app out there for the whole world to
-see, but you don't want to break the bank. There is an answer - if you
-can get shared hosting with FastCGI and a shell, you can install your
-Catalyst app in a local directory on your shared host. First, run
-
-    perl -MCPAN -e shell
-
-and go through the standard CPAN configuration process. Then exit out
-without installing anything. Next, open your .bashrc and add
-
-    export PATH=$HOME/local/bin:$HOME/local/script:$PATH
-    perlversion=`perl -v | grep 'built for' | awk '{print $4}' | sed -e 's/v//;'`
-    export PERL5LIB=$HOME/local/share/perl/$perlversion:$HOME/local/lib/perl/$perlversion:$HOME/local/lib:$PERL5LIB
-
-and log out, then back in again (or run C<". .bashrc"> if you
-prefer). Finally, edit C<.cpan/CPAN/MyConfig.pm> and add
-
-    'make_install_arg' => qq[SITEPREFIX=$ENV{HOME}/local],
-    'makepl_arg' => qq[INSTALLDIRS=site install_base=$ENV{HOME}/local],
-
-Now you can install the modules you need using CPAN as normal; they
-will be installed into your local directory, and perl will pick them
-up. Finally, change directory into the root of your virtual host and
-symlink your application's script directory in:
-
-    cd path/to/mydomain.com
-    ln -s ~/lib/MyApp/script script
-
-And add the following lines to your .htaccess file (assuming the server
-is setup to handle .pl as fcgi - you may need to rename the script to
-myapp_fastcgi.fcgi and/or use a SetHandler directive):
-
-  RewriteEngine On
-  RewriteCond %{REQUEST_URI} !^/?script/myapp_fastcgi.pl
-  RewriteRule ^(.*)$ script/myapp_fastcgi.pl/$1 [PT,L]
-
-Now C<http://mydomain.com/> should now Just Work. Congratulations, now
-you can tell your friends about your new website (or in our case, tell
-the client it's time to pay the invoice :) )
-
-=head2 FastCGI Deployment
-
-FastCGI is a high-performance extension to CGI. It is suitable
-for production environments.
-
-=head3 Pros
-
-=head4 Speed
-
-FastCGI performs equally as well as mod_perl.  Don't let the 'CGI' fool you;
-your app runs as multiple persistent processes ready to receive connections
-from the web server.
-
-=head4 App Server
-
-When using external FastCGI servers, your application runs as a standalone
-application server.  It may be restarted independently from the web server.
-This allows for a more robust environment and faster reload times when
-pushing new app changes.  The frontend server can even be configured to
-display a friendly "down for maintenance" page while the application is
-restarting.
-
-=head4 Load-balancing
-
-You can launch your application on multiple backend servers and allow the
-frontend web server to load-balance between all of them.  And of course, if
-one goes down, your app continues to run fine.
-
-=head4 Multiple versions of the same app
-
-Each FastCGI application is a separate process, so you can run different
-versions of the same app on a single server.
-
-=head4 Can run with threaded Apache
-
-Since your app is not running inside of Apache, the faster mpm_worker module
-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
-than when using mod_perl.
-
-=head3 Setup
-
-=head4 1. Install Apache with mod_fastcgi
-
-mod_fastcgi for Apache is a third party module, and can be found at
-L<http://www.fastcgi.com/>.  It is also packaged in many distributions,
-for example, libapache2-mod-fastcgi in Debian.
-
-=head4 2. Configure your application
-
-    # Serve static content directly
-    DocumentRoot  /var/www/MyApp/root
-    Alias /static /var/www/MyApp/root/static
-
-    FastCgiServer /var/www/MyApp/script/myapp_fastcgi.pl -processes 3
-    Alias /myapp/ /var/www/MyApp/script/myapp_fastcgi.pl/
-
-    # Or, run at the root
-    Alias / /var/www/MyApp/script/myapp_fastcgi.pl/
-
-The above commands will launch 3 app processes and make the app available at
-/myapp/
-
-=head3 Standalone server mode
-
-While not as easy as the previous method, running your app as an external
-server gives you much more flexibility.
-
-First, launch your app as a standalone server listening on a socket.
-
-    script/myapp_fastcgi.pl -l /tmp/myapp.socket -n 5 -p /tmp/myapp.pid -d
-
-You can also listen on a TCP port if your web server is not on the same
-machine.
-
-    script/myapp_fastcgi.pl -l :8080 -n 5 -p /tmp/myapp.pid -d
-
-You will probably want to write an init script to handle starting/stopping
-of the app using the pid file.
-
-Now, we simply configure Apache to connect to the running server.
-
-    # 502 is a Bad Gateway error, and will occur if the backend server is down
-    # This allows us to display a friendly static page that says "down for
-    # maintenance"
-    Alias /_errors /var/www/MyApp/root/error-pages
-    ErrorDocument 502 /_errors/502.html
-
-    FastCgiExternalServer /tmp/myapp.fcgi -socket /tmp/myapp.socket
-    Alias /myapp/ /tmp/myapp.fcgi/
-
-    # Or, run at the root
-    Alias / /tmp/myapp.fcgi/
-
-=head3 More Info
-
-L<Catalyst::Engine::FastCGI>.
-
-=head2 Development server deployment
-
-The development server is a mini web server written in perl.  If you
-expect a low number of hits or you don't need mod_perl/FastCGI speed,
-you could use the development server as the application server with a
-lightweight proxy web server at the front.  However, consider using
-L<Catalyst::Engine::HTTP::Prefork> for this kind of deployment instead, since
-it can better handle multiple concurrent requests without forking, or can
-prefork a set number of servers for improved performance.
-
-=head3 Pros
-
-As this is an application server setup, the pros are the same as
-FastCGI (with the exception of speed).
-It is also:
-
-=head4 Simple
-
-The development server is what you create your code on, so if it works
-here, it should work in production!
-
-=head3 Cons
-
-=head4 Speed
-
-Not as fast as mod_perl or FastCGI. Needs to fork for each request
-that comes in - make sure static files are served by the web server to
-save forking.
-
-=head3 Setup
-
-=head4 Start up the development server
-
-   script/myapp_server.pl -p 8080 -k  -f -pidfile=/tmp/myapp.pid
-
-You will probably want to write an init script to handle stop/starting
-the app using the pid file.
-
-=head4 Configuring Apache
-
-Make sure mod_proxy is enabled and add:
-
-    # Serve static content directly
-    DocumentRoot /var/www/MyApp/root
-    Alias /static /var/www/MyApp/root/static
-
-    ProxyRequests Off
-    <Proxy *>
-        Order deny,allow
-        Allow from all
-    </Proxy>
-
-    # Need to specifically stop these paths from being passed to proxy
-    ProxyPass /static !
-    ProxyPass /favicon.ico !
-
-    ProxyPass / http://localhost:8080/
-    ProxyPassReverse / http://localhost:8080/
-
-    # This is optional if you'd like to show a custom error page
-    # if the proxy is not available
-    ErrorDocument 502 /static/error_pages/http502.html
-
-You can wrap the above within a VirtualHost container if you want
-different apps served on the same host.
-
-=head2 Quick deployment: Building PAR Packages
-
-You have an application running on your development box, but then you
-have to quickly move it to another one for
-demonstration/deployment/testing...
-
-PAR packages can save you from a lot of trouble here. They are usual Zip
-files that contain a blib tree; you can even include all prereqs and a
-perl interpreter by setting a few flags!
-
-=head3 Follow these few points to try it out!
-
-1. Install Catalyst and PAR 0.89 (or later)
-
-    % perl -MCPAN -e 'install Catalyst'
-    ...
-    % perl -MCPAN -e 'install PAR'
-    ...
-
-2. Create a application
-
-    % catalyst.pl MyApp
-    ...
-    % cd MyApp
-
-Recent versions of Catalyst (5.62 and up) include
-L<Module::Install::Catalyst>, which simplifies the process greatly.  From the shell in your application directory:
-
-    % perl Makefile.PL
-    % make catalyst_par
-
-You can customise the PAR creation process by special "catalyst_par_*" commands
-available from L<Module::Install::Catalyst>. You can add these commands in your
-Makefile.PL just before the line containing "catalyst;"
-
-    #Makefile.PL example with extra PAR options
-    use inc::Module::Install;
-
-    name 'MyApp';
-    all_from 'lib\MyApp.pm';
-
-    requires 'Catalyst::Runtime' => '5.80005';
-    <snip>
-    ...
-    <snip>
-
-    catalyst_par_core(1);      # bundle perl core modules in the resulting PAR
-    catalyst_par_multiarch(1); # build a multi-architecture PAR file
-    catalyst_par_classes(qw/
-      Some::Additional::Module
-      Some::Other::Module
-    /);          # specify additional modules you want to be included into PAR
-    catalyst;
-
-    install_script glob('script/*.pl');
-    auto_install;
-    WriteAll;
-
-Congratulations! Your package "myapp.par" is ready, the following
-steps are just optional.
-
-3. Test your PAR package with "parl" (no typo)
-
-    % parl myapp.par
-    Usage:
-        [parl] myapp[.par] [script] [arguments]
-
-      Examples:
-        parl myapp.par myapp_server.pl -r
-        myapp myapp_cgi.pl
-
-      Available scripts:
-        myapp_cgi.pl
-        myapp_create.pl
-        myapp_fastcgi.pl
-        myapp_server.pl
-        myapp_test.pl
-
-    % parl myapp.par myapp_server.pl
-    You can connect to your server at http://localhost:3000
+To add things to an C<end> action that are called I<after> rendering,
+you can set it up like this:
 
-Yes, this nifty little starter application gets automatically included.
-You can also use "catalyst_par_script('myapp_server.pl')" to set a
-default script to execute.
+    sub render : ActionClass('RenderView') { }
 
-6. Want to create a binary that includes the Perl interpreter?
+    sub end : Private {
+      my ( $self, $c ) = @_;
+      $c->forward('render');
+      # do stuff here
+    }
 
-    % pp -o myapp myapp.par
-    % ./myapp myapp_server.pl
-    You can connect to your server at http://localhost:3000
 
 =head2 Serving static content
 
@@ -2019,10 +1547,14 @@ Template Toolkit files.
 You may of course want to change the default locations, and make
 Static::Simple look somewhere else, this is as easy as:
 
- MyApp->config->{static}->{include_path} = [
-  MyApp->config->{root},
-  '/path/to/my/files'
- ];
+ MyApp->config(
+    static => {
+        include_path => [
+            MyApp->path_to('/'),
+            '/path/to/my/files',
+        ],
+    },
+  );
 
 When you override include_path, it will not automatically append the
 normal root path, so you need to add it yourself if you still want
@@ -2034,10 +1566,14 @@ served.
 If you want to force some directories to be only static, you can set
 them using paths relative to the root dir, or regular expressions:
 
- MyApp->config->{static}->{dirs} = [
-   'static',
-   qr/^(images|css)/,
- ];
+ MyApp->config(
+    static => {
+        dirs => [
+            'static',
+            qr/^(images|css)/,
+        ],
+    },
+  );
 
 =item File extensions
 
@@ -2045,16 +1581,22 @@ By default, the following extensions are not served (that is, they will
 be processed by Catalyst): B<tmpl, tt, tt2, html, xhtml>. This list can
 be replaced easily:
 
- MyApp->config->{static}->{ignore_extensions} = [
-    qw/tmpl tt tt2 html xhtml/
- ];
+ MyApp->config(
+        static => {
+            ignore_extensions => [
+                qw/tmpl tt tt2 html xhtml/
+            ],
+        },
+  );
 
 =item Ignoring directories
 
 Entire directories can be ignored. If used with include_path,
 directories relative to the include_path dirs will also be ignored:
 
- MyApp->config->{static}->{ignore_dirs} = [ qw/tmpl css/ ];
+  MyApp->config( static => {
+        ignore_dirs => [ qw/tmpl css/ ],
+  });
 
 =back
 
@@ -2212,7 +1754,7 @@ allows old entries to be automatically expired when they are no longer needed.
 =head3 Page Caching
 
 Another method of caching is to cache the entire HTML page.  While this is
-traditionally handled by a front-end proxy server like Squid, the Catalyst
+traditionally handled by a frontend proxy server like Squid, the Catalyst
 PageCache plugin makes it trivial to cache the entire output from
 frequently-used or slow actions.
 
@@ -2250,10 +1792,14 @@ Note that the page cache is keyed on the page URI plus all parameters, so
 requests for / and /?foo=bar will result in different cache items.  Also,
 only GET requests will be cached by the plugin.
 
-You can even get that front-end Squid proxy to help out by enabling HTTP
+You can even get that frontend Squid proxy to help out by enabling HTTP
 headers for the cached page.
 
-    MyApp->config->{page_cache}->{set_http_headers} = 1;
+    MyApp->config(
+        page_cache => {
+            set_http_headers => 1,
+        },
+    );
 
 This would now set the following headers so proxies and browsers may cache
 the content themselves.
@@ -2340,7 +1886,7 @@ C<TEST_POD> environment variable is true.
 
     mundus:~/MyApp chansen$ cat t/01app.t | perl -ne 'printf( "%2d  %s", $., $_ )'
     1  use Test::More tests => 2;
-    2  use_ok( Catalyst::Test, 'MyApp' );
+    2  BEGIN { use_ok( Catalyst::Test, 'MyApp' ) }
     3
     4  ok( request('/')->is_success );
 
@@ -2405,7 +1951,7 @@ Be sure to check out C<Test::WWW::Mechanize::Catalyst>. It makes it easy to
 test HTML, forms and links. A short example of usage:
 
     use Test::More tests => 6;
-    use_ok( Test::WWW::Mechanize::Catalyst, 'MyApp' );
+    BEGIN { use_ok( Test::WWW::Mechanize::Catalyst, 'MyApp' ) }
 
     my $mech = Test::WWW::Mechanize::Catalyst->new;
     $mech->get_ok("http://localhost/", 'Got index page');
@@ -2420,7 +1966,7 @@ test HTML, forms and links. A short example of usage:
 
 =item Catalyst::Test
 
-L<http://search.cpan.org/dist/Catalyst/lib/Catalyst/Test.pm>
+L<Catalyst::Test>
 
 =item Test::WWW::Mechanize::Catalyst