clean up logging and debug output, minor doc fixes
[catagits/Catalyst-Runtime.git] / lib / Catalyst / Manual / Tutorial.pod
index fe92823..ef0db08 100644 (file)
@@ -6,92 +6,59 @@ Catalyst::Manual::Tutorial - Getting started with Catalyst
 
 This document aims to get you up and running with Catalyst.
 
-NOTE: THIS DOCUMENT IS STILL VERY MUCH IN AN EARLY DRAFT STATE.  SEE 
-THE NOTES AT THE BOTTOM OF THE DOCUMENT.
-
 =head2 Installation
 
 The first step is to install Catalyst, and the simplest way to do this 
 is to install the Catalyst bundle from CPAN:
 
-    $ perl -MCPAN -e 'install Bundle::Catalyst'
+    $ perl -MCPAN -e 'install Task::Catalyst'
 
 This will retrieve Catalyst and a number of useful extensions and 
-install them for you.
+install them for you. This process might not be totally painless
+though, and you might want to look at CatInABox at
+L<http://use.perl.org/~jk2addict/journal/28071>, especially if you are
+on a system that lacks a compiler.
 
 
-=head2 Setting up your application
+=head2 The very basics - Setting up the skeleton application.
 
 Catalyst includes a helper script, C<catalyst.pl>, that will set up a 
 skeleton application for you:
 
-    $ catalyst MyApp
-    
-    created "MyApp"
-    created "MyApp/script"
-    created "MyApp/lib"
-    created "MyApp/root"
-    created "MyApp/root/static"
-    created "MyApp/root/static/images"
-    created "MyApp/t"
-    created "MyApp/t/Model"
-    created "MyApp/t/View"
-    created "MyApp/t/Controller"
-    created "MyApp/lib/MyApp"
-    created "MyApp/lib/MyApp/Model"
-    created "MyApp/lib/MyApp/View"
-    created "MyApp/lib/MyApp/Controller"
-    created "MyApp/lib/MyApp.pm"
-    created "MyApp/Build.PL"
-    created "MyApp/Makefile.PL"
-    created "MyApp/README"
-    created "MyApp/Changes"
-    created "MyApp/t/01app.t"
-    created "MyApp/t/02pod.t"
-    created "MyApp/t/03podcoverage.t"
-    created "MyApp/root/static/images/catalyst_logo.png"
-    created "MyApp/root/static/images/btn_120x50_built.png"
-    created "MyApp/root/static/images/btn_120x50_built_shadow.png"
-    created "MyApp/root/static/images/btn_120x50_powered.png"
-    created "MyApp/root/static/images/btn_120x50_powered_shadow.png"
-    created "MyApp/root/static/images/btn_88x31_built.png"
-    created "MyApp/root/static/images/btn_88x31_built_shadow.png"
-    created "MyApp/root/static/images/btn_88x31_powered.png"
-    created "MyApp/root/static/images/btn_88x31_powered_shadow.png"
-    created "MyApp/root/favicon.ico"
-    created "MyApp/script/myapp_cgi.pl"
-    created "MyApp/script/myapp_fastcgi.pl"
-    created "MyApp/script/myapp_server.pl"
-    created "MyApp/script/myapp_test.pl"
-    created "MyApp/script/myapp_create.pl"
-
-This creates the directory structure shown, populated with skeleton 
+    $ catalyst.pl tutorial
+
+    created "tutorial"
+    created "tutorial/script"
+    ... output snipped
+    created "tutorial/script/tutorial_create.pl"
+
+This creates the directory structure, populated with skeleton 
 files.
 
-=head2 Testing out the sample application
+=head2 Testing out the skeleton application
 
 You can test out your new application by running the server script that
 Catalyst provides:
 
-    $ cd MyApp
-    $ script/myapp_server.pl 
+    $ cd tutorial
+    $ script/tutorial_server.pl 
 
-    [...] [catalyst] [debug] Debug messages enabled
-    [...] [catalyst] [debug] Loaded plugins:
+    [debug] Debug messages enabled
+    [debug] Loaded plugins:
     .------------------------------------------------------------------------------.
     | Catalyst::Plugin::Static::Simple                                             |
     '------------------------------------------------------------------------------'
-    [...] [catalyst] [debug] Loaded dispatcher "Catalyst::Dispatcher"
-    [...] [catalyst] [debug] Loaded engine "Catalyst::Engine::HTTP"
-    [...] [catalyst] [debug] Found home "/home/users/me/MyApp"
-    [...] [catalyst] [debug] Loaded Private actions:
+    [debug] Loaded dispatcher "Catalyst::Dispatcher"
+    [debug] Loaded engine "Catalyst::Engine::HTTP"
+    [debug] Found home "/home/users/me/tutorial"
+    [debug] Loaded Private actions:
     .--------------------------------------+---------------------------------------.
     | Private                              | Class                                 |
     +--------------------------------------+---------------------------------------+
-    | /default                             | MyApp                                 |
+    | /default                             | tutorial                              |
     '--------------------------------------+---------------------------------------'
-    
-    [...] [catalyst] [info] MyApp powered by Catalyst 5.5
+
+    [...] [catalyst] [info] tutorial powered by Catalyst 5.67
     You can connect to your server at http://localhost:3000
 
 (Note that each line logged by Catalyst begins with a timestamp, which has
@@ -107,29 +74,27 @@ and hit return twice):
     Connected to localhost.
     Escape character is '^]'.
     GET / HTTP/1.0
-    
+
     HTTP/1.0 200 OK
     Date: Mon, 07 Nov 2005 14:57:39 GMT
     Content-Length: 5525
     Content-Type: text/html; charset=utf-8
     Status: 200
-    X-Catalyst: 5.5
+    X-Catalyst: 5.67
 
     [...]
     Connection closed by foreign host.
     $
 
-You can see the full welcome message by visting
+You can see the full welcome message by visiting
 http://localhost:3000/ with your browser.
 
 More trace messages will appear in the original terminal window:
 
-    [...] [catalyst] [debug] **********************************
-    [...] [catalyst] [debug] * Request 1 (0.063/s) [2148]
-    [...] [catalyst] [debug] **********************************
-    [...] [catalyst] [debug] Arguments are ""
-    [...] [catalyst] [debug] "GET" request for "" from localhost
-    [...] [catalyst] [info] Request took 0.046883s (21.330/s)
+    [debug] *** Request 1 (0.063/s) [2148]
+    [debug] Arguments are ""
+    [debug] "GET" request for "/" from localhost
+    [info] Request took 0.046883s (21.330/s)
     .------------------------------------------------------------------+-----------.
     | Action                                                           | Time      |
     +------------------------------------------------------------------+-----------+
@@ -139,214 +104,742 @@ More trace messages will appear in the original terminal window:
 The server will continue running until you interrupt it.
 
 The application can also be tested from the command line using the generated
-helper script, C<script/myapp_test.pl>.
+helper script, C<script/tutorial_test.pl>.
 
-=head2 Getting your application invoked
+=head2 Getting started
 
-Catalyst applications are usually run from mod_perl, but can also be
-run as CGI or FastCGI scripts.  Running under mod_perl gives better 
-performance, but for development purposes you may want to run your 
-application as a CGI script, especially as changes to your application 
-code take effect under CGI without having to restart the web server.
+So you picked Catalyst. Good choice. We assume you have installed it as
+well. For this tutorial you will also need the following modules:
 
-To run from mod_perl you need to add something like this to your Apache
-configuration file:
+L<Catalyst::Plugin::Session>
 
-    <Location /MyApp>
-        SetHandler  perl-script
-        PerlHandler MyApp
-    </Location>
+L<Catalyst::Plugin::Session::Store::File>
 
-To run as a CGI script you need a wrapper script like:
+L<Catalyst::Plugin::Session::State::Cookie>
 
-    #!/usr/bin/perl -w
-    
-    use strict;
-    use lib '/path/to/MyApp/lib';
-    use MyApp;
-    
-    MyApp->run;
+L<Catalyst::Plugin::Authentication>
 
-=head2 Examining the generated code
+L<Catalyst::Plugin::Authentication::Store::Minimal>
 
-The generated application code is quite simple and looks something 
-like this (comments removed):
+L<Catalyst::Plugin::Authentication::::Minimal>
 
-    package MyApp;
-    
-    use strict;
-    use warnings;
-    
-    use Catalyst qw/-Debug Static::Simple/;
+L<Catalyst::Plugin::Authentication::Credential::Password>
+
+L<Catalyst::Plugin::Authorization::Roles>
+
+L<DBD::SQLite>
+
+...
+
+If you have not already done this following the example above, then to get 
+started all you need to do is type:
+
+    catalyst.pl tutorial
+
+=for commentary
+Poor choice of application name - searching for "tutorial" in the docs
+also results in discussion of the tutorial process, which is probably
+not what the reader wants.
+
+=cut
+
+This should create a directory called F<tutorial> and fill it with the
+default (standard) Catalyst installation. Change to this directory
+because we will be running all further commands from inside the
+F<tutorial> directory.
+
+If you now run the built-in mini-server with:
     
-    our $VERSION = '0.01';
+    script/tutorial_server.pl
+
+it will show some standard debug messages in the console screen 
+(more about those in a minute), and then inform you that you can now 
+connect to the test server on port 3000. Point your browser at 
+http://localhost:3000/ to see the built-in Catalyst welcome screen.
+
+The other important thing B<catalyst.pl> did was create your root
+controller. This file is a standard Perl module like all the other
+controllers that you might add to your application. It lives in the
+F<lib/> directory, and will have the same name as you supplied to the
+command above. In our case it is F<tutorial.pm>. Alongside this file is
+a directory of the same name, which is the top level namespace for the
+entire application. Thus every other module we create will be
+"tutorial::something".
+
+The root controller is used to load plugins, to configure the
+application and its plugins, and for generic private actions.  We will
+explain more about those later.
+
+=head2 Debugging
+
+The simplest way to debug your Catalyst application is to run it using
+the built-in mini-server as described in L<Getting started>. 
+
+If you want to output any debugging information to the console, then
+call C<< $c->log->debug() >>, passing it a string to output. For data
+structures, C<use> L<Data::Dumper> and call C<<
+$c->log->debug(Dumper($structure)) >>
+
+=head2 Model/View/Controller
+
+The recommended method for code organization in a Catalyst application
+is known as the "Model View Controller" design pattern (also referred to
+"MVC". See L<http://en.wikipedia.org/wiki/Model-view-controller>). 
+
+The point of the MVC pattern is to separate the dependencies of parts of
+the application from each other, and give them standard
+interfaces. Following this theory of organization should give your code
+all the benefits of modularity. The main benefits are interchangeability
+of parts and reusability of code.
+
+Thus you could replace your flat-file data storage with a relational
+database, or your MySQL database with an Oracle database, and not have
+to change any of your Controller or View logic. Or you could later
+decide to output information from your application as RSS instead of
+HTML just by adding a new View module.
+
+=head3 Model
+
+Models deal with the storage of data. For a complex website, you may
+need multiple data sources, each having its own model class that
+provides an abstracted interface to it. In this tutorial we are going to
+be using a simple database.
+
+=head3 View
+
+Views are used to display information to the user. In a web framework,
+the View is generally used to output HTML to the browser. As mentioned
+previously, Views can also be used to output RSS or any other kind of
+data. One easy way to do this with Catalyst is to use a templating
+system such as L<Template Toolkit|Template>. If outputting HTML is all
+you are going to do, then you will probably only need one View.
+
+=head3 Controller
+
+A controller is responsible for responding to user choices, and thus
+controls what the application does. Since this is a web framework,
+Catalyst controllers are frequently used to react directly to URLs
+requested by the user. This tutorial will describe the simplest way of
+using controllers, where each path or part of a path is assigned its own
+action (or subroutine). More complex controlling mechanisms will be
+mentioned briefly, and can be read about in detail elsewhere in the
+manual.
+
+
+=head2 Controlling
+
+Now let's write our first bit of application code. First, we would like
+our application to greet our users. We'll assume for now that our users
+will be sent to the I<users/greet> URL. To create a controller that
+serves the I<users> namespace, we run the following command in our
+F<tutorial> directory:
+
+    script/tutorial_create.pl controller Users
+
+This will create a Users.pm in F<lib/tutorial/Controller>. Open this
+file in an editor and take a look. You will notice there is some
+commented-out code which we will ignore for now. To make something
+happen when our URL is visited, we will write a "greet" action which
+looks like this:
+
+  sub greet : Local {
+    my ($self, $c) = @_;
+
+    my $name = $c->req->param('name');
+    $c->log->debug("Got name: $name\n");
+
+    if ($c->req->method eq 'POST') {
+       if(!$name) {
+            $c->stash->{message} = 'Please fill in a name!';
+        }
+        else {
+            $c->stash->{message} = "Hello $name!";     
+        }
+    }
+    $c->stash->{template} = 'greet.tt';
+  }
+
+Whew! So, what does all this do? Let's take it one step at a time. The
+subroutine declaration gives the action a name. To the right of the name
+there is an attribute type that looks like this:
+
+    : Local 
     
-    __PACKAGE__->config( name => 'MyApp' );
-    __PACKAGE__->setup;
+That defines which URIs will translate to this action. "Local" matches
+exactly one URI: 
+
+    /users/greet
     
-    sub default : Private {
-        my ( $self, $c ) = @_;
+The URI matched by "Local" is composed from the namespace minus the 
+tutorial::controller portion, that is common to all controllers, 
+and the action name itself.  Because it is a URI, we use forward slashes 
+instead of double colons.  So, in summary, when a user requests:
+    http://localhost:3000/users/greet
     
-        $c->response->body( $c->welcome_message );
+the "greet" action defined above in the Users controller will be executed.
+
+The second line retrieves the parameters Catalyst gives us when it calls
+our method. The first is the instance of our Users class, and the second
+is commonly called the "context", held in C<$context>, or abbreviated to
+C<$c>.  From now on, whenever we are talking about the context object,
+it will be represented as C<$c> in the code.
+
+The context is the magical object containing any information you need from 
+catalyst, or want to send to it, and is passed from action to action. 
+You will see it used frequently in Catalyst applications, and a list of all 
+its methods is available in the L<Catalyst> POD.
+
+On the third line we use the ->param method of the context's request object
+to retrieve one of the query parameters, just like in L<CGI>.
+
+On the fourth, we make a debug output of this object on the server console,
+or the error log if running under CGI or mod_perl.
+
+Next, if we have a post request, we check if the name field contains
+anything (or is "true"). If it isn't, we assign an error message to a
+"message" field in the stash. The stash is a special hash of the context
+object, which allows us to pass data on to other methods we call later,
+typically in the View.
+
+If the username did contain a value, then we just set our message to
+greet the user by name.
+
+Finally, we set the special "template" variable in the stash to the name
+of the template we want our View to use to display this page.
+
+=head2 Viewing
+
+OK, so reacting and checking the users data is all fine, but how do we
+actually display the page/form in the first place, and our results? In
+this tutorial, we'll use Template Toolkit for our viewing. To create our
+TT-based view, just run the following command:
+
+    script/tutorial_create.pl view TToolkit TT
+
+Notice that this time we not only gave it the type of module we wanted
+to create (a view), and a name, but also a third argument, "TT". This is
+a Catalyst helper module, which will make a standard Template Toolkit
+module for you. And that's all you need to do there.
+
+To use the view, the easiest way is to set up a standard "end" action.
+This is a special private action which will not be matched to a path
+like our "greet" action, but instead will be called after all other
+processing is done. Only one end action will be called in any request
+cycle. If there is one in a controller, it will be preferred over one in
+the application module, and so on.
+
+Since we're writing a simple application, just add an end action like
+this to F<tutorial.pm>:
+
+    sub end : Private {
+        my ($self, $c) = @_;
+        $c->forward('tutorial::View::TToolkit') unless $c->res->body();
     }
-    
-    1;
-
-When the C<Catalyst> module is imported by the application code, 
-Catalyst performs the first stage of its initialization.  This includes
-loading the appropriate Engine module for the environment in which the 
-application is running, loading any plugins and ensuring that the 
-calling module (the application module) inherits from C<Catalyst> 
-(which makes the Catalyst methods C<config> and C<setup> available to 
-the application module).
-
-The call to C<config> sets up configuration data for the application.  
-The C<name> parameter is the only required configuration parameter.
-You may also specificy a C<root> parameter, which is the path to the
-directory where documents, images, and templates can be found.
-
-Catalyst associates I<actions> with URLs and on receiving a request 
-dispatches to the action that matches to request URL.  The call to 
-C<setup> in the code above registers a default action.  With just 
-this action registered the application will respond to all requests 
-with the same welcome page.
-
-As you see, the default action is defined as a Private action. 
-Most private actions are not directly available from a web url. This
-also includes the built-in actions, 'default', 'begin', 'end', and
-'auto', although they will be called as part of some chains.  
-The rest can only be reached by using C<forward>.
-
-The call to the C<setup> method also triggers the second stage of 
-Catalyst's initialization process.  In this phase Catalyst searches 
-for any component modules, locating and registering any actions it 
-finds in those modules.
-
-Component modules have names prefixed with the application module name,
-followed by C<Model>, C<View> or C<Controller> (or the optional short
-forms: C<M>, C<V> or C<C>) followed by the component
-name, for example:
-
-    MyApp::Controller::ShoppingCart  # long (default) version
-    MyApp::C::ShoppingCart           # short version 
-
-    MyApp::Model::User               # long (default) version
-    MyApp::M::User                   # short version
-
-=head2 Extending the generated code
-
-You can start extending the application by adding new actions:
-
-    sub test1 : Global {
-        my ( $self, $c ) = @_;
-        $c->res->body('In a new test action #1');
+
+The first line declares the end sub, and marks it as a Private action.
+(This is the second and last attribute type we'll be using in this
+tutorial.) The second line collects our standard parameters as shown in
+the controller's greet action.
+
+The third line directs Catalyst to pass processing on to our TToolkit
+view. The forward method, when just passed a class name, calls
+C<process> on that class. The standard TT view's C<process> method
+renders the template named in the template variable in the stash, using
+all the other variables in the stash as values to fill it in.
+
+NB: This is such a common way to end your processing that there is a
+plugin which does it for you: L<Catalyst::Plugin::DefaultEnd>.
+
+Template Toolkit also has access to the entire context object via the
+special variable "c". For example, using C<[% c.config.name %]> in our
+template will output "tutorial", our project name.
+
+All that remains is to create a simple template called "greet.tt",
+containing a form with a text field called "name" like below.
+
+    <html><head><title> [% c.config.name %]</head><body>
+    <p>[% message %]</p>
+    <form action="[% c.req.uri %]" method="post">
+    <input type="text" name="name"/>
+    <input type="submit" value="Submit" name="submit"/>
+    </form>
+    </body></html>
+
+In the example above, we use C<[% c.req.uri %]>, since we're posting to
+ourself. If we post to another action, we commonly use the uri_for
+method, like this:
+
+    [% c.uri_for('/users/greet')%]
+
+Place this file in the F<root> directory. By default, templates are 
+searched for here, but we can change that, which brings us to...
+
+=head2 Configuring
+
+As previously mentioned, the configuration of modules, plugins, and so
+on is done in the main application file. This is especially true for
+bits which need to be done before an instance of them is created, for
+example Template Toolkit.
+
+The TT View looks for its templates in the F<root> directory by default.
+Since this is also the directory that static files go in, we'd rather
+have a separate F<templates> directory. To do this, change the config
+call in F<tutorial.pm> like this:
+
+ __PACKAGE__->config( name => 'tutorial',
+                      'View::TToolkit' => {
+                          'INCLUDE_PATH' => __PACKAGE__->path_to('templates')
+     }
+  );
+
+And move the F<greet.tt> file from F<root> to the F<templates> directory
+(after creating it).
+
+Now we can run our application again by killing (B<ctrl-c>) and restarting
+B<script/tutorial_server.pl>. Try connecting to
+I<localhost:3000/users/greet> with a browser and see what happens. What
+happens if you try to visit I<localhost:3000/users> ? 
+
+=head2 Users and Authenticating
+
+One of the many reasons to write dynamic websites instead of just using
+static HTML is to allow us to produce different content for different
+users, as well as restricting access to pages (which we could do with
+just Apache's htpasswd system).
+
+In this tutorial, we will just be using basic authentication. When
+writing a real application, you'll want to use a database or other
+secure store to contain your user data.
+
+To add authentication, all we need to do is add the
+L<Catalyst::Plugin::Authentication> module to our main application
+file. Then we need to pick a storage method (one of the
+L<Catalyst::Plugin::Authentication::Store> modules), and a method of
+verifying the user's credentials (one of the
+L<Catalyst::Plugin::Authentication::Credential> modules). Edit
+F<tutorial.pm> to look like this:
+
+ use Catalyst qw/-Debug Static::Simple Authentication 
+                Authentication::Store::Minimal 
+                Authentication::Credential::Password/;
+
+To configure, add some users to the config call. For example:
+
+ authentication => { 'users' =>
+                       { 'fred' =>
+                           { 'password' => 'fred1234',
+                           }
+                       }
+                   }
+
+Generally, setting up configuration data for plugins is done based on
+the type of plugin. Check the documentation of the plugin for exact
+details; in this example we should look in
+L<Catalyst::Plugin::Authentication::Store::Minimal>.
+
+Since our user data is in the config, we can update it at runtime, and
+thus add users dynamically. (Of course, to keep them permanently we'd
+need to save our data to disk and read it back into the config on
+startup.)
+
+To allow creation of new users we'll add a C<create> action to our Users
+controller.
+
+ sub create : Local {
+    my ($self, $c) = @_;
+    my ($username, $passwd1, $passwd2) = map { $c->req->param($_)} 
+       ('username', 'password', 'passwordverify');
+
+    if($username && $passwd1 && $passwd2) {
+       if($c->config->{authentication}{users}{$username}) {
+          $c->stash->{message} = 'Sorry, that user already exists';
+          $c->stash->{username} = $username;
+       }
+       elsif($passwd1 eq $passwd2) {
+            $c->config->{authentication}->{users}->{$username} =
+                {password => $passwd1};
+          $c->stash->{message} = 'User created!';
+       }
+       else {
+          $c->stash->{username} = $username;
+          $c->stash->{message} = 'Passwords do not match!';
+       }
     }
-    sub default : Private {
-        my ( $self, $c ) = @_;
-        $c->res->body('Congratulations, MyApp is on Catalyst!');
+    $c->stash->{template} = 'usercreate.tt';
+ }
+
+All this is doing is checking that all the appropriate fields are
+filled, and that the password fields contain the same data, and then
+adding the user to the config hash.  All the checks produce a message
+which can be displayed to the user via the View.
+
+The usercreate.tt template looks like this:
+
+ <html><head><title>[% c.config.name %]</title></head><body>
+ <h1>Create a new user</h1>
+ <h2>Current users are:</h2>
+ <p>
+    [% FOREACH key = c.config.authentication.users.keys %]
+        [% key %]<br/>
+    [% END %]
+ </p>
+ <p> [% message %] </p>
+ <form action="/users/create" method="post">
+ <p>User Name: <input type="text" name="username"/></p>
+ <p>Password: <input type="password" name="password"/></p>
+ <p>Confirm Password: <input type="password" name="passwordverify"/></p>
+ <p><input type="submit" name="submit" value="submit"></p>
+ </form>
+ </body></html>
+
+In order for our users to be able to login, we need a C<login> action
+which we put in the Users controller:
+
+ sub login : Local {
+     my ($self, $c) = @_;
+     $c->stash->{template} = 'userlogin.tt';
+     if(!$c->login()) {
+             $c->stash->{message} = 'Please login.';
+     }
+     else {
+         $c->stash->{message} = "Welcome " . $c->user->id;
+     }
+ }
+
+
+And the userlogin.tt template:
+
+ <html><head><title>[% c.config.name %]</title></head><body>
+ <p> [% message %] </p>
+ <form name='login' action='/users/login' method='post'>
+ <p>Username: <input type='text' name='user' /></p>
+ <p>Password: <input type='password' name='password' /></p>
+ <p><input type="submit" /></form>
+ </body></html>
+
+
+Very simple. Since Credential::Password's "login" call extracts the
+username/password data from the query itself (assuming we use a standard
+name for our form fields), we don't have to do anything but call it.
+
+To keep the user logged in, all we need to do is add the Session modules
+to our collection, and the Auth modules will automatically use them:
+
+ use Catalyst qw/-Debug Static::Simple Authentication 
+                 Authentication::Store::Minimal 
+                 Authentication::Credential::Password
+                 Session Session::Store::File Session::State::Cookie/;
+
+Magic!
+
+=head2 Exercise
+
+As an exercise for the reader, do the following:
+
+Change C<users/greet> and C<greet.tt> so that the welcome message greets
+the user by name.
+
+Enforce user logging in by adding an C<auto> action in tutorial.pm (see
+the L<Catalyst> documentation to find out about the C<auto> action).
+
+=head2 Authorizing
+
+Authentication is about verifying users, and authorization is about
+allowing them to do things. Catalyst currently has two Authorization
+modules, Roles and ACL. The Roles module allows you to define groups
+which you can assign your users to, and then allow access to areas of
+your website to the groups. The ACL module lets you do more fine grained
+access/restriction by allowing of denying access however you like. (It
+also supports Roles as done by the roles module.) This example uses
+L<Catalyst::Plugin::Authorization::Roles>. To use this add
+"Authorization::Roles" into the "use Catalyst" statement in tutorial.pm.
+
+Adding Roles via the Minimal store we are already using is quite simple,
+we just add a roles key to each user, defining the names of the roles
+they belong to.
+
+ authentication => { 'users' =>
+                            { 'fred' => 
+                               { 'password' => 'fred1234',
+                                 'roles'       => ['admin']
+                               }
+                            }
+                         }
+
+We need an interface for our admins to administer the roles, i.e. assign
+the users to groups. To restrict access to certain actions, we just need
+to call C<< $c->check_user_roles() >> in each action. So we can
+make a restricted I<http://localhost:3000/users/groups> page like this:
+
+ sub groups : Local {
+    my ($self, $c) = @_;
+    if($c->check_user_roles('admin')) {
+       # Now we can do things only an admin will see
+       if (my $params = $c->req->params) {
+          my $users = $c->config->{authentication}{users};
+          foreach my $u (keys %$params) {
+             $users->{$u}{roles} = $params->{$u} if($users->{$u});
+          }
+          $c->stash->{message} = 'Updated user roles!';
+       }
+       else {
+           $c->stash->{users} = $c->config->{authentication};
+       }
+       $c->stash->{template} = 'usersgroups.tt';
     }
+    else {
+        $c->stash->{message} = 'Admins Only!';
+        $c->stash->{template} = 'error.tt';
+    }
+ }
+
+What we are doing here is checking whether the logged-in user (used by
+default in the C<check_user_roles> method) is a member of the admin
+group. If it is, then we display the usergroups template, and update
+the users hash as required. Otherwise, we just show the user an error
+page.
+
+For this simple example, the usersgroups.tt and error.tt templates could
+both look like this:
+
+ <html><head><title>[% c.config.name %]</title></head><body>
+ <p>[% message %]</p>
+ <p>[% c.stash.users %]</p>
+ </body></html>
+
+And that's all there is to it.
+
+=for authors
+So it's not clear what the groups action is doing - and with the
+current template, nothing happens.  Running through the sample code,
+it's clear what's happening (which is very little), but the purpose,
+and how to display data is not clear.
+
+=cut
+
+So that you can test this out properly without having to go to the
+trouble of deleting browser cookies manually, we will add a logout
+action in the Users controller:
+
+ sub logout : Local {
+    my ($self, $c) = @_;
+    $c->stash->{message} = "You have successfully logged out";
+    $c->logout;
+ }
+
+
+=head2 Data Storage (Modelling)
+
+Whether we want our users to be able to contribute to our website, or
+just create it from changeable data, we need to store the data
+somewhere. Generally this is done using a database, but models can also
+use other data sources, for example another website, or an RSS feed.
+
+If you have or want a database, there are still choices to be
+made. There are several modules for accessing databases using an
+object-oriented wrapper. The best known are probably L<DBIx::Class> and
+L<Class::DBI>. Catalyst supports making models using either of these.
+
+For a simple example, we will allow our users to store their favorite
+greeting in our database. Create a table called "greetings" in a
+database, that contains a "user" field and a "greeting" field. The
+simplest way to create a model of your database is to use these helper
+modules, for example with L<DBIx::Class>:
+
+    script/tutorial_create.pl model UserData DBIC dbi:SQLite:/path/to/mydb.db
+
+This will cause the DBIx::Class Loader to inspect your database, and create a
+module in the Model::UserData namespace for each table in your database. 
+
+Now we need a form for our users to enter/edit their personal greetings
+in, so we'll make a I<http://localhost:3000/users/editgreeting> page:
+
+ sub editgreeting : Local {
+    my ($self, $c) = @_;
+    if($c->req->params->{greeting}) {
+       if(!$c->user_exists) {
+          $c->stash->{message} = "You're not logged in!";
+       }
+       else {
+          my $grtable = $c->model('UserData::Greetings');
+          my $record = $grtable->find_or_create(user => $c->user->id);
+          $record->greeting($c->req->params->{greeting});
+          $record->update;
+          $c->stash->{message} = 'Greeting updated';
+       }
+    }
+    $c->stash->{template} = 'usersgreeting.tt';
+ }
 
-    # called like '/article/2005/06'
-    sub archive_month : Regex('^article/(\d{4})/(\d{2})$') {
-        my ( $self, $c ) = @_;
+Using C<< $c->user_exists >> from the Authentication plugin, this checks
+whether the user is logged in already. If they are, and they have
+entered a new greeting, we use DBIx::Class' C<find_or_create> method to
+fetch or create a new record in the greetings table for the user. Once
+we have the record, we change the value of the greeting field, and call
+C<update> to store the new value in the database.
 
-        my $datetime = DateTime->new(
-            year  => $c->request->snippets->[0],
-            month => $c->request->snippets->[1]
-        );
-    }
+=head2 Engines (Apache and FastCGI)
 
-TODO: explain briefly about plugins, actions, and components
+Now that we have the basics together, we can try running our application on a
+"real" server instead of just using the test server that Catalyst comes
+with. L<Catalyst::Engine> is the module used to implement various types of
+servers to run it on. The current popular ones are Apache and FastCGI.
 
-If the action is a Regex type, you can use capturing parentheses to
-extract values within the matching URL (2005, 06 in the above
-example). Those values are available in the $c->req->snippets
-anonymous array. See L<Catalyst::Manual::Intro#Actions> for details.
+=head3 Apache
 
-=head2 Hooking in to Template Toolkit
+Apache needs to be configured: we need to tell it to load your
+application. You can either use Catalyst for your entire website, or
+subsections. Use the Location directive to choose a path to run your
+application under: 
 
-One of the first things you will probably want to add to your 
-application is a templating system for generating your output.  
-Catalyst works well with Template Toolkit.  If you are unfamiliar with 
-Template Toolkit then I suggest you look at L<http://tt2.org>, install 
-C<Template>, read the documentation and play around with it, and have 
-a look at the I<Badger Book> (I<Template Toolkit> by Darren 
-Chamberlain, Dave Cross, and Andy Wardley, O'Reilly & Associates, 2004).
+ <Location />
+   SetHandler           perl-script
+   PerlResponseHandler  tutorial
+ </Location>
 
-You can create a stub Template Toolkit view component by installing
-L<Catalyst::View::TT> and using the create script that Catalyst set
-up as part of the skeleton application:
+You will need to install the perl modules of your application into one
+of perl's library directories, as listed by B<perl -V>, so that Apache
+can find them. Alternatively you can use the C<PerlSwitches> directive
+to tell Apache where to look:
 
-    $ script/myapp_create.pl view TT TT
-    
-     exists "MyApp/lib/MyApp/View"
-     exists "MyApp/t/View"
-    created "MyApp/lib/MyApp/View/TT.pm"
-    created "MyApp/t/View/TT.t"
+ PerlSwitches -I/path/to/tutorial/
 
-this generates a view component named C<MyApp::View::TT>, which you 
-might use by forwarding from your C<end> action:
+These instructions are for using Apache2 and mod_perl 2.0. If you are
+using mod_perl 1.3 or 1.99, please refer to either
+L<Catalyst::Engine::Apache::MP13> or L<Catalyst::Engine::Apache2::MP19>
+for details of the slightly different ways to do it.
 
-    # In MyApp or MyApp::Controller::SomeController
+If you wish to ensure that Apache pre-loads your application, use the
+PerlModule directive. This means that there will be less of a delay when
+your application is accessed.
 
-    sub end : Private {
-        my($self, $c) = @_;
-        $c->forward('MyApp::V::TT');
-    }
+ PerlModule tutorial
 
-The generated TT view component simply subclasses the 
-C<Catalyst::View::TT> class.  It looks like this (with the POD 
-stripped out): 
+=head3 FastCGI
 
-    package My::App::V::TT;
+These instructions apply to the use of C<mod_fastcgi> under Apache
+(either 1 or 2 series).
 
-    use strict;
-    use base 'Catalyst::View::TT';
+There are 3 ways to attach a program to a URL with C<mod_fastcgi>;
+we'll examine all of them, and explain how to avoid having the
+C<tutorial_fastcgi.pl> substring in the user-visible URLs.
 
-    1;
+In all of these examples, we assume that the C<DocumentRoot> is
+C</var>, that our app is called C<tutorial> and is kept in C</usr>, that
+you want the users to access the app either from the root of the
+server-uri-space, or from C</theapp>. We also assume that the general
+FastCGI settings (C<FastCgiIpcDir>, loading the module) are already
+correct (they don't depend on Catalyst or your application layout).
 
-C<Catalyst::View::TT> initializes a Template Toolkit object with an 
-options hash initialized with built-in default settings followed by 
-the contents of the hash C<<%{__PACKAGE__->config()}>>.  You can
-configure TT more to your needs by adding a C<new> method to the 
-generated TT component:
+=head4 static application
 
-    sub new {
-        my $self = shift;
-        $self->config->{PRE_PROCESS} = 'config/main';
-        $self->config->{WRAPPER}     = 'site/wrapper';
-        return $self->SUPER::new(@_);
-    }
+In this setup, you tell C<mod_fastcgi> that a particular I<file> is to
+be run as a FastCGI handler. Put this somewhere in Apache's
+configuration:
 
-=head1 AUTHOR
+  FastCgiServer /usr/apps/tutorial/script/tutorial_fastcgi.pl
+  Alias / /usr/apps/tutorial/script/tutorial_fastcgi.pl/
 
-Andrew Ford, C<A.Ford@ford-mason.co.uk>
-Marcus Ramberg, C<mramberg@cpan.org>
+If you want your app under C</theapp>, change the C<Alias> line to:
+
+  Alias /theapp /usr/apps/tutorial/script/tutorial_fastcgi.pl
+
+Note the detail of the trailing C</ >: this is a general rule of the
+C<Alias> directive, both sides must end with C</ >, or both must not;
+you can't have one with C</ > and the other without, or strange things
+happen.
+
+=head4 dynamic application
+
+In this setup, you tell C<mod_fastcgi> that certain files are to be
+treated as FastCGI handlers, in the same way you have to tell
+C<mod_cgi>. Put this in the configuration:
 
-As noted above, this document is at an alpha stage.  My plan for this 
-document is as follows:
+  FastCgiConfig -autoUpdate
 
-=over 4
+  <Directory /usr/apps/tutorial/script>
+   Options +ExecCGI
+   <Files *_fastcgi.pl>
+    SetHandler fastcgi-script
+   </Files>
+  </Directory>
 
-=item 1
+  Alias / /usr/apps/tutorial/script/tutorial_fastcgi.pl/
 
-Expand this document fairly rapidly to cover topics relevant to
-a newcomer to Catalyst, in an order that can be read sequentially
+Again, if you want your app under C</theapp>, change the C<Alias> line to:
 
-=item 2
+  Alias /theapp /usr/apps/tutorial/script/tutorial_fastcgi.pl
 
-Incorporate feedback 
+=head4 external server
 
-=item 3
+In this setup, the application is started separately from Apache, and
+communicates via a socket with C<mod_fastcgi>. This can be useful if
+you need to have a particular environment for your application (maybe
+different between applications), or you want to run them on different
+machines, or under different users for security reasons.
 
-Revise the text 
+If you want to use a UNIX socket (on the filesystem), put this in
+Apache's configuration:
 
-=back
+  FastCgiExternalServer /tmp/somewhere -socket /tmp/tutorial-socket
+  Alias / /tmp/somewhere/
 
-Placeholders are indicated by the words: TODO or CHECK 
+Note that C</tmp> should I<not> exist: it's just a name to connect the
+two parts.
+
+Again, if you want your app under C</theapp>, change the C<Alias> line
+to:
+
+  Alias /theapp /tmp/somewhere
+
+Then start your Catalyst application:
+
+  $ cd /usr/apps/tutorial
+  $ ./script/tutorial_fastcgi -l /tmp/tutorial-socket
+
+If you want to use a TCP socket, simply change the C</tmp> to a
+C<host:port> pair, both in Apache's configuration and on the command
+line of your application.
+
+=head2 Upgrading
+
+Upgrading your application to newer Catalyst versions is quite
+simple. After installing the new Catalyst package, just run:
+
+    catalyst.pl -scripts
+
+One level above your application directory. This will update the scripts
+directory only, and leave the rest of your app alone. If you wish to
+make use of other parts of Catalyst that have been updated, leave off
+the B<-scripts> argument, this will cause .new files to appear, for each
+module that has either been updated, or is different to the original
+because you have changed it. To find out what these changes are, type:
+
+    diff tutorial/lib/tutorial/View/TT.pm tutorial/lib/tutorial/View/TT.pm.new
+
+for each of the changed files. (This is a Unix command; Windows users
+will need to find some equivalent.) Copy any changes you need into your
+original file, then remove the .new files. (This makes life less
+complicated when the next upgrade comes around.)
+
+=head1 AUTHORS
+
+Jess Robinson, C<jrobinson@cpan.org>
+Andrew Ford, C<A.Ford@ford-mason.co.uk>
+Marcus Ramberg, C<mramberg@cpan.org>
+Kieren Diment, C<kd@totaldatasolution.com>
+Gavin Henry, C<ghenry@cpan.org>
 
 Please send comments, corrections and suggestions for improvements to
-A.Ford@ford-mason.co.uk
+jrobinson@cpan.org, ghenry@cpan.org
+
+=head1 TODO
+
+Finish DBIC examples with templates and tested code. Make /users/groups
+do something "useful".
+
+Many other things....
 
 =head1 COPYRIGHT