Captures -> CapureArgs
[catagits/Catalyst-Runtime.git] / lib / Catalyst / Manual / Intro.pod
index c446014..32e2ba1 100644 (file)
@@ -4,15 +4,26 @@ Catalyst::Manual::Intro - Introduction to Catalyst
 
 =head1 DESCRIPTION
 
-This is a brief overview of why and how to use Catalyst. It explains how
-Catalyst works and shows how to get a simple application up and running
-quickly.
+This is a brief introduction to Catalyst. It explains the most important
+features of how Catalyst works and shows how to get a simple application
+up and running quickly. For an introduction (without code) to Catalyst
+itself, and why you should be using it, see L<Catalyst::Manual::About>.
+For a systematic step-by-step introduction to writing an application
+with Catalyst, see L<Catalyst::Manual::Tutorial>.
 
 =head2 What is Catalyst?
 
 Catalyst is an elegant web application framework, extremely flexible yet
-extremely simple. It's similar to Ruby on Rails, Spring (Java) and
-L<Maypole>, upon which it was originally based.
+extremely simple. It's similar to Ruby on Rails, Spring (Java), and
+L<Maypole>, upon which it was originally based. Its most important
+design philosphy is to provide easy access to all the tools you need to
+develop web applications, with few restrictions on how you need to use
+these tools. Under Catalyst, it is always possible to do things in a
+different way. However, this does mean that it is always possible to do
+things in a different way. Other web frameworks are simpler to use and
+easy to get up and running, but achieve this by locking the programmer
+into a single set of tools. Catalyst's emphasis on flexibility means
+that you have to think more to use it. We view this as a feature.
 
 =head3 MVC
 
@@ -30,7 +41,8 @@ well-known Perl modules you may want to use for each.
 
 =item * B<Model>
 
-Access and modify content (data). L<Class::DBI>, L<Plucene>, L<Net::LDAP>...
+Access and modify content (data). L<DBIx::Class>, L<Class::DBI>,
+L<Xapian>, L<Net::LDAP>...
 
 =item * B<View>
 
@@ -40,15 +52,15 @@ L<Mason|HTML::Mason>, L<HTML::Template>...
 =item * B<Controller>
 
 Control the whole request phase, check parameters, dispatch actions, flow
-control. Catalyst!
+control. Catalyst itself!
 
 =back
 
-If you're unfamiliar with MVC and design patterns, you may want to check
-out the original book on the subject, I<Design Patterns>, by Gamma,
-Helm, Johnson, and Vlissides, also known as the Gang of Four (GoF). You
-can also just Google it.  Many, many web application frameworks are
-based on MVC, including all those listed above.
+If you're unfamiliar with MVC and design patterns, you may want to
+check out the original book on the subject, I<Design Patterns>, by
+Gamma, Helm, Johnson, and Vlissides, also known as the Gang of Four
+(GoF).  Many, many web application frameworks are based on MVC, which
+is becoming a popular design method for web applications.
 
 =head3 Flexibility
 
@@ -78,7 +90,7 @@ multiple Catalyst applications.
 
 =item * B<Unrestrained URL-to-Action Dispatching>
 
-Catalyst allows you to dispatch any URLs to any application L<Actions>,
+Catalyst allows you to dispatch any URLs to any application L</Actions>,
 even through regular expressions! Unlike most other frameworks, it
 doesn't require mod_rewrite or class and method names in URLs.
 
@@ -108,7 +120,7 @@ simple way.
 =item * B<Building Block Interface>
 
 Components interoperate very smoothly. For example, Catalyst
-automatically makes a L<Context> object available to every
+automatically makes a L</Context> object available to every
 component. Via the context, you can access the request object, share
 data between components, and control the flow of your
 application. Building a Catalyst application feels a lot like snapping
@@ -121,8 +133,8 @@ and loads them.
 
 =item * B<Pre-Built Components for Popular Modules>
 
-See L<Catalyst::Model::CDBI> for L<Class::DBI>, or L<Catalyst::View::TT>
-for L<Template Toolkit|Template>.
+See L<Catalyst::Model::DBIC::Schema> for L<DBIx::Class>, or
+L<Catalyst::View::TT> for L<Template Toolkit|Template>.
 
 =item * B<Built-in Test Framework>
 
@@ -143,7 +155,7 @@ running, using the helper scripts described above.
 
 =head3 Install
 
-    $ perl -MCPAN -e 'install Bundle::Catalyst'
+    $ perl -MCPAN -e 'install Task::Catalyst'
 
 =head3 Setup
 
@@ -159,6 +171,10 @@ running, using the helper scripts described above.
 Now visit these locations with your favorite browser or user agent to see
 Catalyst in action:
 
+(NOTE: Although we create a controller here, we don't actually use it.
+Both of these URLs should take you to the welcome page.)
+
+
 =over 4
 
 =item http://localhost:3000/
@@ -167,7 +183,7 @@ Catalyst in action:
 
 =back
 
-Dead easy!
+Easy!
 
 =head2 How It Works
 
@@ -178,8 +194,7 @@ and other parts of a Catalyst application.
 
 In addition to the Model, View, and Controller components, there's a
 single class that represents your application itself. This is where you
-configure your application, load plugins, define application-wide
-actions, and extend Catalyst.
+configure your application, load plugins, and extend Catalyst.
 
     package MyApp;
 
@@ -192,22 +207,18 @@ actions, and extend Catalyst.
         # You can put anything else you want in here:
         my_configuration_variable => 'something',
     );
-
-    sub default : Private {
-        my ( $self, $context ) = @_;
-        $context->response->body('Catalyst rocks!');
-    }
-
     1;
 
-For most applications, Catalyst requires you to define only one config
-parameter:
+In older versions of Catalyst, the application class was where you put
+global actions. However, as of version 5.66, the recommended practice is
+to place such actions in a special Root controller (see #####, below),
+to avoid namespace collisions.
 
 =over 4
 
 =item * B<name>
 
-Name of your application.
+The name of your application.
 
 =back
 
@@ -217,11 +228,13 @@ location. You can define as many parameters as you want for plugins or
 whatever you need. You can access them anywhere in your application via
 C<$context-E<gt>config-E<gt>{$param_name}>.
 
+###### We need a short section on configuration here.
+
 =head3 Context
 
 Catalyst automatically blesses a Context object into your application
 class and makes it available everywhere in your application. Use the
-Context to directly interact with Catalyst and glue your L<Components>
+Context to directly interact with Catalyst and glue your L</Components>
 together. For example, if you need to use the Context from within a
 Template Toolkit template, it's already there:
 
@@ -275,7 +288,6 @@ information.
 =item * L<Catalyst::Log>
 
     $c->log
-
     $c->log->debug('Something happened');
     $c->log->info('Something you should know');
 
@@ -283,6 +295,10 @@ information.
 
     $c->stash
     $c->stash->{foo} = 'bar';
+    $c->stash->{baz} = {baz => 'qox'};
+    $c->stash->{fred} = [qw/ wilma pebbles/];
+
+and so on.
 
 =back
 
@@ -306,18 +322,42 @@ to maintain more persistent data, use a session.
 
 =head3 Actions
 
-A Catalyst controller is defined by its actions. An action is a sub with
-a special attribute. You've already seen some examples of actions in
-this document. The URL (for example http://localhost.3000/foo/bar)
-consists of two parts, the base (http://localhost:3000/ in this example)
-and the path (foo/bar).  Please note that the trailing slash after the
-hostname[:port] always belongs to base and not to the action.
+A Catalyst controller is defined by its actions. An action is a
+subroutine with a special attribute. You've already seen some examples
+of actions in this document. The URL (for example
+http://localhost.3000/foo/bar) consists of two parts, the base
+(http://localhost:3000/ in this example) and the path (foo/bar).  Please
+note that the trailing slash after the hostname[:port] always belongs to
+base and not to the action.
+
+=over 4
+
+=item * B<Application Wide Actions>
+
+Actions which are called at the root level of the application
+(e.g. http://localhost:3000/ ) go in MyApp::Controller::Root, like
+this:
+
+    package MyApp::Controller::Root;
+    use base 'Catalyst::Controller';
+    # Sets the actions in this controller to be registered with no prefix
+    # so they function identically to actions created in MyApp.pm
+    __PACKAGE__->config->{namespace} = '';
+    sub default : Private {
+        my ( $self, $context ) = @_;
+        $context->response->body('Catalyst rocks!');
+    }
+    1;
+
+=back
+
+=head4 Action types
 
 Catalyst supports several types of actions:
 
 =over 4
 
-=item * B<Literal>
+=item * B<Literal> (B<Path> actions)
 
     package MyApp::Controller::My::Controller;
     sub bar : Path('foo/bar') { }
@@ -371,21 +411,268 @@ http://localhost:3000/catalog/foo/widget23 as well.
 
 For both LocalRegex and Regex actions, if you use capturing parentheses
 to extract values within the matching URL, those values are available in
-the C<$c-E<gt>req-E<gt>snippets> array. In the above example, "widget23"
+the C<$c-E<gt>req-E<gt>captures> array. In the above example, "widget23"
 would capture "23" in the above example, and
-C<$c-E<gt>req-E<gt>snippets-E<gt>[0]> would be "23". If you want to pass
+C<$c-E<gt>req-E<gt>captures-E<gt>[0]> would be "23". If you want to pass
 arguments at the end of your URL, you must use regex action keys. See
 L</URL Path Handling> below.
 
-=item * B<Top-level>
+=item * B<Chained>
+
+The C<Chained> attribute allows you to chain public path parts together
+by their private names. A chain part's path can be specified with C<PathPart>
+and can be declared to expect an arbitrary number of arguments. The endpoint
+of the chain specifies how many arguments it gets through the C<Args>
+attribute. C<:Args(0)> would be none at all, C<:Args> without an integer
+would be unlimited. The path parts that aren't endpoints are using
+C<CaptureArgs> to specify how many parameters they expect to receive. As an
+example setup:
+
+  package MyApp::Controller::Greeting;
+  use base qw/ Catalyst::Controller /;
+
+  #   this is the beginning of our chain
+  sub hello : PathPart('hello') Chained('/') CaptureArgs(1) {
+      my ( $self, $c, $integer ) = @_;
+      $c->stash->{ message } = "Hello ";
+      $c->stash->{ arg_sum } = $integer;
+  }
+
+  #   this is our endpoint, because it has no :CaptureArgs
+  sub world : PathPart('world') Chained('hello') Args(1) {
+      my ( $self, $c, $integer ) = @_;
+      $c->stash->{ message } .= "World!";
+      $c->stash->{ arg_sum } += $integer;
+
+      $c->response->body( join "<br/>\n" =>
+          $c->stash->{ message }, $c->stash->{ arg_sum } );
+  }
+
+The debug output provides a separate table for chained actions, showing
+the whole chain as it would match and the actions it contains. Here's
+an example of the startup output with our actions above:
+
+  ...
+  [debug] Loaded Path Part actions:
+  .-----------------------+------------------------------.
+  | Path Spec             | Private                      |
+  +-----------------------+------------------------------+
+  | /hello/*/world/*      | /greeting/hello (1)          |
+  |                       | => /greeting/world           |
+  '-----------------------+------------------------------'
+  ...
+
+As you can see, Catalyst only deals with chains as whole path and 
+builds one for each endpoint, which are the actions with C<:Chained>
+but without C<:CaptureArgs>.
+
+Let's assume this application gets a request at the path
+C</hello/23/world/12>, what happens then? First, Catalyst will dispatch
+to the C<hello> action and pass the value C<23> as argument to it after
+the context. It does so because we have previously used C<:CaptureArgs(1)>
+to declare that it has one path part after itself as it's argument. We
+told Catalyst that this is the beginning of the chain by specifying
+C<:Chained('/')>. Also note that instead of saying C<:PathPart('hello')>
+we could also just have said C<:PathPart>, as it defaults to the name of
+the action.
+
+After C<hello> has run, Catalyst goes on to dispatch to the C<world>
+action. This is the last action to be called, as Catalyst knows this
+is an endpoint because we specified no C<:CaptureArgs> attribute. Nevertheless
+we specify that this action expects an argument, but at this point we're
+using C<:Args(1)> to do that. We could also have said C<:Args> or leave 
+it out alltogether, which would mean this action gets all arguments that
+are there. This action's C<:Chained> attribute says C<hello> and tells
+Catalyst that the C<hello> action in the current controller is it's 
+parent.
+
+With this we have built a chain consisting of two public path parts.
+C<hello> captures one part of the path as it's argument, and also specifies
+the path root as it's parent. So this part is C</hello/$arg>. The next part
+is the endpoint C<world>, expecting one argument. It sums up to the path
+part C<world/$arg>. This leads to a complete chain of 
+C</hello/$arg/world/$arg> which is matched against the requested paths.
+
+This example application would, if run and called by e.g. 
+C</hello/23/world/12>, set the stash value C<message> to C<Hello > and
+the value C<arg_sum> to C<23>. The C<world> action would then append
+C<World!> to C<message> and add C<12> to the stash's C<arg_sum> value.
+For the sake of simplicity no view is shown. Instead we just put the
+values of the stash into our body. So the output would look like:
+
+  Hello World!
+  35
+
+And our test server would've given us this debugging output for the
+request:
+
+  ...
+  [debug] "GET" request for "hello/23/world/12" from "127.0.0.1"
+  [debug] Path is "/greeting/world"
+  [debug] Arguments are "12"
+  [info] Request took 0.164113s (6.093/s)
+  .------------------------------------------+-----------.
+  | Action                                   | Time      |
+  +------------------------------------------+-----------+
+  | /greeting/hello                          | 0.000029s |
+  | /greeting/world                          | 0.000024s |
+  '------------------------------------------+-----------'
+  ...
+
+What would be common usecases of this dispatching technique? It gives the
+possibility to split up logic that contains steps that each depend on each
+other. An example would be, for example, a wiki path like
+C</wiki/FooBarPage/rev/23/view>. This chain can be easily built with
+these actions:
+
+  sub wiki : PathPart('wiki') Chained('/') CaptureArgs(1) {
+      my ( $self, $c, $page_name ) = @_;
+      #  load the page named $page_name and put the object
+      #  into the stash
+  }
+
+  sub rev : PathPart('rev') Chained('wiki') CaptureArgs(1) {
+      my ( $self, $c, $revision_id ) = @_;
+      #  use the page object in the stash to get at it's
+      #  revision with number $revision_id
+  }
+
+  sub view : PathPart Chained('rev') Args(0) {
+      my ( $self, $c ) = @_;
+      #  display the revision in our stash. An other option
+      #  would be to forward a compatible object to the action
+      #  that displays the default wiki pages, unless we want
+      #  a different interface here, for example restore
+      #  functionality.
+  }
+
+It would now be possible to add other endpoints. For example C<restore> to
+restore this specific revision as current state.
+
+Also, you of course don't have to put all the chained actions in one
+controller. The specification of the parent through C<:Chained> also takes
+an absolute action path as it's argument. Just specify it with a leading
+C</>.
+
+If you want, for example, to have actions for the public paths
+C</foo/12/edit> and C</foo/12>, just specify two actions with 
+C<:PathPart('foo')> and C<:Chained('/')>. The handler for the former
+path needs a C<:CaptureArgs(1)> attribute and a endpoint with 
+C<:PathPart('edit')> and C<:Chained('foo')>. For the latter path give
+the action just a C<:Args(1)> to mark it as endpoint. This sums up to
+this debugging output:
+
+  ...
+  [debug] Loaded Path Part actions:
+  .-----------------------+------------------------------.
+  | Path Spec             | Private                      |
+  +-----------------------+------------------------------+
+  | /foo/*                | /controller/foo_view         |
+  | /foo/*/edit           | /controller/foo_load (1)     |
+  |                       | => /controller/edit          |
+  '-----------------------+------------------------------'
+  ...
+
+Here's a more detailed specification of the attributes belonging to 
+C<:Chained>:
+
+=over 8
+
+=item PathPart
+
+Sets the name of this part of the chain. If it is specified without
+arguments, it takes the name of the action as default. So basically
+C<sub foo :PathPart> and C<sub foo :PathPart('foo')> are identical.
+This can also contain slashes to bind to a deeper level. An action
+with C<sub bar :PathPart('foo/bar') :Chained('/')> would bind to
+C</foo/bar/...>. If you don't specify C<:PathPart> it has the same
+effect as using C<:PathPart>, it would default to the action name.
+
+=item Chained
+
+Has to be specified for every child in the chain. Possible values are
+absolute and relative private action paths, with the relatives pointing
+to the current controller, or a single slash C</> to tell Catalyst that
+this is the root of a chain. The attribute C<:Chained> without aguments
+also defaults to the C</> behaviour.
+
+Due to the fact that you can specify an absolute path to the parent
+action, it doesn't matter to Catalyst where that parent is located. So,
+if your design requests it, you can redispatch a chain through every
+controller or namespace you want.
+
+Another interesting possibility gives C<:Chained('.')>, which chains
+itself to an action with the path of the current controllers namespace.
+For example:
+
+  #   in MyApp::Controller::Foo
+  sub bar : Chained CaptureArgs(1) { ... }
+
+  #   in MyApp::Controller::Foo::Bar
+  sub baz : Chained('.') Args(1) { ... }
+
+This builds up a chain like C</bar/*/baz/*>. The specification of C<.>
+as argument to Chained here chains the C<baz> action to an action with
+the path of the current controller namespace, namely C</foo/bar>. That
+action chains directly to C</>, so the above chain comes out as end
+product.
+
+=item CaptureArgs
+
+Also has to be specified for every part of the chain that is not an
+endpoint. With this attribute Catalyst knows how many of the following
+parts of the path (separated by C</>) this action wants to captures as
+it's arguments. If it doesn't expect any, just specify C<:CaptureArgs(0)>.
+The captures get passed to the action's C<@_> right after the context,
+but you can also find them as array reference in 
+C<$c-E<gt>request-E<gt>captures-E<gt>[$level]>. The C<$level> is the
+level of the action in the chain that captured the parts of the path.
+
+An action that is part of a chain (read: that has a C<:Chained> attribute)
+but has no C<:CaptureArgs> attribute is treated by Catalyst as a chain end.
+
+=item Args
+
+By default, endpoints receive the rest of the arguments in the path. You
+can tell Catalyst through C<:Args> explicitly how many arguments your
+endpoint expects, just like you can with C<:CaptureArgs>. Note that this
+also influences if this chain is invoked on a request. A chain with an
+endpoint specifying one argument will only match if exactly one argument
+exists in the path.
+
+You can specify an exact number of arguments like C<:Args(3)>, including
+C<0>. If you just say C<:Args> without any arguments, it is the same as
+leaving it out alltogether: The chain is matched independent of the number
+of path parts after the endpoint.
+
+Just like with C<:CaptureArgs>, the arguments get passed to the action in
+C<@_> after the context object. They can also be reached through
+C<$c-E<gt>request-E<gt>arguments>.
+
+=back
+
+Note that the list of C<auto> actions called depends on the private path
+of the endpoint of the chain, not on the chained actions way. The C<auto>
+actions will be run before the chain dispatching begins. In every other
+aspect, C<auto> actions behave as documented.
 
-    package MyApp; 
+The C<forward>ing to other actions does just what you would expect. But if
+you C<detach> out of a chain, the rest of the chain will not get called
+after the C<detach> returned.
+
+=item * B<Top-level> (B<Global>)
+
+    package MyApp::Controller::Foo;
     sub foo : Global { }
 
-Matches http://localhost:3000/foo. The function name is mapped directly
-to the application base.
+Matches http://localhost:3000/foo. The function name is mapped
+directly to the application base.  You can provide an equivalent
+function in this case  by doing the following:
+
+    package MyApp::Controller::Root
+    sub foo : Local { }
 
-=item * B<Namespace-Prefixed>
+=item * B<Namespace-Prefixed> (B<Local>)
 
     package MyApp::Controller::My::Controller; 
     sub foo : Local { }
@@ -417,12 +704,27 @@ C<MyApp::Controller::Catalog::Order::Process> controller must, if called
 from elsewhere, be reached with
 C<$c-E<gt>forward('/catalog/order/process/bar')>.
 
+=item * B<Args>
+
+Args is not an action type per se, but an action modifier - it adds a match
+restriction to any action it's provided to, requiring only as many path parts
+as are specified for the action to be valid - for example in
+MyApp::Controller::Foo,
+
+  sub bar :Local
+
+would match any URL starting /foo/bar/. To restrict this you can do
+
+  sub bar :Local :Args(1)
+
+to only match /foo/bar/*/
+
 =back
 
 B<Note:> After seeing these examples, you probably wonder what the point
-is of defining names for regex and path actions. Actually, every public
-action is also a private one, so you have one unified way of addressing
-components in your C<forward>s.
+is of defining names for regex and path actions. Every public action is
+also a private one, so you have one unified way of addressing components
+in your C<forward>s.
 
 =head4 Built-in Private Actions
 
@@ -438,7 +740,7 @@ displaying a generic frontpage for the main app, or an error page for
 individual controllers.
 
 If C<default> isn't acting how you would expect, look at using a
-L<Literal> C<Path> action (with an empty path string). The difference is
+L</Literal> C<Path> action (with an empty path string). The difference is
 that C<Path> takes arguments relative from the namespace and C<default>
 I<always> takes arguments relative from the root, regardless of what
 controller it's in.
@@ -448,7 +750,7 @@ controller it's in.
 C<index> is much like C<default> except that it takes no arguments
 and it is weighted slightly higher in the matching process. It is
 useful as a static entry point to a controller, e.g. to have a static
-welcome page.
+welcome page. Note that it's also weighted higher than Path.
 
 =item * B<begin : Private>
 
@@ -538,11 +840,10 @@ stage, without processing further actions.
 
 =head4 URL Path Handling
 
-You can pass variable arguments as part of the URL path. In this case,
-you must use regex action keys with '^' and '$' anchors, and the
-arguments must be separated with forward slashes (/) in the URL. For
-example, suppose you want to handle C</foo/$bar/$baz>, where C<$bar> and
-C<$baz> may vary:
+You can pass variable arguments as part of the URL path, separated with 
+forward slashes (/). If the action is a Regex or LocalRegex, the '$' anchor 
+must be used. For example, suppose you want to handle C</foo/$bar/$baz>, 
+where C<$bar> and C<$baz> may vary:
 
     sub foo : Regex('^foo$') { my ($self, $context, $bar, $baz) = @_; }
 
@@ -560,6 +861,10 @@ Catalyst matches actions in most specific to least specific order:
 So Catalyst would never mistakenly dispatch the first two URLs to the
 '^foo$' action.
 
+If a Regex or LocalRegex action doesn't use the '$' anchor, the action will 
+still match a URL containing arguments, however the arguments won't be 
+available via C<@_>.
+
 =head4 Parameter Processing
 
 Parameters passed in the URL query string are handled with methods in
@@ -608,10 +913,9 @@ debugging enabled).
         $c->res->body( $c->stash->{message} );
     }
 
-A C<forward> does not create a new request, so your request
-object (C<$c-E<gt>req>) will remain unchanged. This is a
-key difference between using C<forward> and issuing a
-redirect.
+A C<forward> does not create a new request, so your request object
+(C<$c-E<gt>req>) will remain unchanged. This is a key difference between
+using C<forward> and issuing a redirect.
 
 You can pass new arguments to a C<forward> by adding them
 in an anonymous array. In this case C<$c-E<gt>req-E<gt>args>
@@ -628,10 +932,10 @@ be reset.
 
     sub check_message : Private {
         my ( $self, $c ) = @_;
-        my $first_argument = $c->req->args[0]; # now = 'test1'
+        my $first_argument = $c->req->args->[0]; # now = 'test1'
         # do something...
     }
-    
+
 As you can see from these examples, you can just use the method name as
 long as you are referring to methods in the same controller. If you want
 to forward to a method in another controller, or the main application,
@@ -673,12 +977,12 @@ method.
 
 =head3 Components
 
-Catalyst has an uncommonly flexible component system. You can define as many
-L<Models>, L<Views>, and L<Controllers> as you like.
+Catalyst has an uncommonly flexible component system. You can define as
+many L</Models>, L</Views>, and L</Controllers> as you like.
 
-All components must inherit from L<Catalyst::Base>, which provides a simple
-class structure and some common class methods like C<config> and C<new>
-(constructor).
+All components must inherit from L<Catalyst::Base>, which provides a
+simple class structure and some common class methods like C<config> and
+C<new> (constructor).
 
     package MyApp::Controller::Catalog;
 
@@ -693,7 +997,7 @@ You don't have to C<use> or otherwise register Models, Views, and
 Controllers.  Catalyst automatically discovers and instantiates them
 when you call C<setup> in the main application. All you need to do is
 put them in directories named for each Component type. Notice that you
-can use some very terse aliases for each one.
+can use a terse alias for each one.
 
 =over 4
 
@@ -711,6 +1015,11 @@ can use some very terse aliases for each one.
 
 =back
 
+In older versions of Catalyst, the recommended practice (and the one
+automatically created by helper scripts) was to name the directories
+C<M/>, C<V/>, and C<C/>. Though these still work, we now recommend
+the use of the full names.
+
 =head4 Views
 
 To show how to define views, we'll use an already-existing base class for the
@@ -756,7 +1065,8 @@ eyecandy debug screen. ;)
 =head4 Models
 
 To show how to define models, again we'll use an already-existing base
-class, this time for L<Class::DBI>: L<Catalyst::Model::CDBI>.
+class, this time for L<DBIx::Class>: L<Catalyst::Model::DBIC::Schema>.
+We'll also need L<DBIx::Class::Schema::Loader>.
 
 But first, we need a database.
 
@@ -777,50 +1087,33 @@ But first, we need a database.
 
     % sqlite /tmp/myapp.db < myapp.sql
 
-Now we can create a CDBI component for this database.
+Now we can create a DBIC::SchemaLoader component for this database.
 
-    package MyApp::Model::CDBI;
+    script/myapp_create.pl model DBIC DBIC::SchemaLoader 'dbi:SQLite:/tmp/myapp.db'
 
-    use strict;
-    use base 'Catalyst::Model::CDBI';
+L<DBIx::Class::Schema::Loader> automatically loads table layouts and
+relationships. Use the stash to pass data to your templates.
 
-    __PACKAGE__->config(
-        dsn           => 'dbi:SQLite:/tmp/myapp.db',
-        relationships => 1
-    );
+We add the following to MyApp/Controller/Root.pm
 
-    1;
-
-Catalyst automatically loads table layouts and relationships. Use the
-stash to pass data to your templates.
-
-    package MyApp;
-
-    use strict;
-    use Catalyst '-Debug';
+    sub view : Global {
+        my ( $self, $c, $id ) = @_;
+        
+        $c->stash->{item} = $c->model('DBIC::Foo')->find($id);
+    }
 
-    __PACKAGE__->config(
-        name => 'My Application',
-        root => '/home/joeuser/myapp/root'
-    );
+    1;
     
-    __PACKAGE__->setup;
-
     sub end : Private {
         my ( $self, $c ) = @_;
+        
         $c->stash->{template} ||= 'index.tt';
-        $c->forward('MyApp::View::TT');
-    }
-
-    sub view : Global {
-        my ( $self, $c, $id ) = @_;
-        $c->stash->{item} = MyApp::Model::CDBI::Foo->retrieve($id);
+        $c->forward( $c->view('TT') );
     }
 
-    1;
+We then create a new template file "root/index.tt" containing:
 
-    # Then, in a TT template:
-    The id is [% item.data %]
+    The Id's data is [% item.data %]
 
 Models do not have to be part of your Catalyst application; you
 can always call an outside module that serves as your Model:
@@ -828,9 +1121,14 @@ can always call an outside module that serves as your Model:
     # in a Controller
     sub list : Local {
       my ( $self, $c ) = @_;
+      
       $c->stash->{template} = 'list.tt';
-      use Some::Outside::CDBI::Module;
-      my @records = Some::Outside::CDBI::Module->retrieve_all;
+      
+      use Some::Outside::DBIC::Module;
+      my @records = Some::Outside::DBIC::Module->search({
+        artist => 'sri',
+        });
+      
       $c->stash->{records} = \@records;
     }
 
@@ -847,12 +1145,16 @@ write Catalyst models that can be used outside of Catalyst, e.g.
 in a cron job), it's trivial to write a simple component in
 Catalyst that slurps in an outside Model:
 
-    package MyApp::Model::Catalog;
-    use base qw/Catalyst::Base Some::Other::CDBI::Module::Catalog/;
+    package MyApp::Model::DB;
+    use base qw/Catalyst::Model::DBIC::Schema/;
+    __PACKAGE__->config(
+        schema_class => 'Some::DBIC::Schema',
+        connect_info => ['dbi:SQLite:foo.db', '', '', {AutoCommit=>1}]
+    );
     1;
 
-and that's it! Now C<Some::Other::CDBI::Module::Catalog> is part of your
-Cat app as C<MyApp::Model::Catalog>.
+and that's it! Now C<Some::DBIC::Schema> is part of your
+Cat app as C<MyApp::Model::DB>.
 
 =head4 Controllers
 
@@ -861,26 +1163,150 @@ application.
 
     package MyApp::Controller::Login;
 
-    sub sign-in : Local { }
-    sub new-password : Local { }
-    sub sign-out : Local { }
+    use base qw/Catalyst::Controller/;
+
+    sub sign_in : Path("sign-in") { }
+    sub new_password : Path("new-password") { }
+    sub sign_out : Path("sign-out") { }
 
     package MyApp::Controller::Catalog;
 
+    use base qw/Catalyst::Controller/;
+
     sub view : Local { }
     sub list : Local { }
 
     package MyApp::Controller::Cart;
 
+    use base qw/Catalyst::Controller/;
+
     sub add : Local { }
     sub update : Local { }
     sub order : Local { }
 
+Note that you can also supply attributes via the Controller's config so long
+as you have at least one attribute on a subref to be exported (:Action is
+commonly used for this) - for example the following is equivalent to the same
+controller above
+
+    package MyApp::Controller::Login;
+
+    use base qw/Catalyst::Controller/;
+
+    __PACKAGE__->config(
+      actions => {
+        'sign_in' => { Path => 'sign-in' },
+        'new_password' => { Path => 'new-password' },
+        'sign_out' => { Path => 'sign-out' },
+      },
+    );
+
+    sub sign_in : Action { }
+    sub new_password : Action { }
+    sub sign_out : Action { }
+
+=head3 Models
+
+Models are providers of data. This data could come from anywhere - a search
+engine index, a database table, etc. Typically the data source does not have
+much to do with web applications or Catalyst - it could be used to write an
+offline report generator or a command line tool just the same.
+
+The common approach to writing a Catalyst-style model for your application is
+wrapping a generic model (e.g. L<DBIx::Class::Schema>, a bunch of XMLs, or
+anything really) with an object that contains configuration data, convenience
+methods, and so forth.
+
+#### editor: move this part to =head3 Components somehow, right after this
+#### section - this will require deeply rephrasing this paragraph.
+
+Technically, within Catalyst a model is a B<component> - an instance of the
+model's class belonging to the application. It is important to stress that the
+lifetime of these objects is per application, not per request.
+
+While the model base class (L<Catalyst::Model>) provides things like C<config>
+and stuff to better integrate the model into the application, sometimes this is
+not enough, and the model requires access to C<$c> itself.
+
+Situations where this need might arise include:
+
+=over 4
+
+=item *
+
+Interacting with another model
+
+=item *
+
+Using per-request data to control behavior
+
+=item *
+
+Using plugins in (for example L<Catalyst::Plugin::Cache>).
+
+=back
+
+From a style perspective usually it's bad to make your model "too smart"
+about things - it should worry about business logic and leave the
+integration details to the controllers. If, however, you find that it
+does not make sense at all to use an auxillary controller around the
+model, and the model's need to access C<$c> cannot be sidestepped, there
+exists a power tool called C<ACCEPT_CONTEXT>.
+
+#### editor note: this part is "generic" - it also applies to views and
+#### controllers.
+
+=head3 ACCEPT_CONTEXT
+
+Whenever you call $c->component("Foo") you get back an object - the
+instance of the model. If the component supports the C<ACCEPT_CONTEXT>
+method instead of returning the model itself, the return value of C<<
+$model->ACCEPT_CONTEXT( $c ) >> will be used.
+
+This means that whenever your model/view/controller needs to talk to C<$c> it
+gets a chance to do this when it's needed.
+
+A typical C<ACCEPT_CONTEXT> method will either clone the model and return one
+with the context object set, or it will return a thin wrapper that contains
+C<$c> and delegates to the per-application model object.
+
+A typical C<ACCEPT_CONTEXT> method could look like this:
+
+       sub ACCEPT_CONTEXT {
+               my ( $self, $c, @extra_arguments ) = @_;
+               bless { %$self, c => $c }, ref($self);
+       }
+
+effectively treating $self as a B<prototype object> that gets a new parameter.
+C<@extra_arguments> comes from any trailing arguments to
+C<< $c->component( $bah, @extra_arguments ) >> (or C<< $c->model(...) >>,
+C<< $c->view(...) >> etc).
+
+The life time of this value is B<per usage>, and not per request. To make this
+per request you can use the following technique:
+
+Add a field to C<$c>, like C<my_model_instance>. Then write your
+C<ACCEPT_CONTEXT> method to look like this:
+
+       sub ACCEPT_CONTEXT {
+               my ( $self, $c ) = @_;
+
+               if ( my $per_request = $c->my_model_instance ) {
+                       return $per_request;
+               } else {
+                       my $new_instance = bless { %$self, c => $c }, ref($self);
+                       Scalar::Util::weaken($new_instance->{c}); # or we have a circular reference
+                       $c->my_model_instance( $new_instance );
+                       return $new_instance;
+               }
+       }
+
+
 =head3 Testing
 
-Catalyst has a built-in http server for testing! (Later, you can easily
-use a more powerful server, e.g. Apache/mod_perl, in a production
-environment.)
+Catalyst has a built-in http server for testing. (Later, you can easily
+use a more powerful server, e.g. Apache/mod_perl or FastCGI, in a
+production environment.)
 
 Start your application on the command line...
 
@@ -912,8 +1338,10 @@ David Naughton, C<naughton@umn.edu>
 Marcus Ramberg, C<mramberg@cpan.org>
 Jesse Sheidlower, C<jester@panix.com>
 Danijel Milicevic, C<me@danijel.de>
+Kieren Diment, C<kd@totaldatasolution.com>
+Yuval Kogman, C<nothingmuch@woobling.org>
 
 =head1 COPYRIGHT
 
-This program is free software, you can redistribute it and/or modify it under
-the same terms as Perl itself.
+This program is free software, you can redistribute it and/or modify it
+under the same terms as Perl itself.