Intro.pod formatting
[catagits/Catalyst-Runtime.git] / lib / Catalyst / Manual / Intro.pod
index fe9ac8d..6bbebde 100644 (file)
@@ -211,8 +211,8 @@ configure your application, load plugins, and extend Catalyst.
 
 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.
+to place such actions in a special Root controller (see L</Actions>,
+below), to avoid namespace collisions.
 
 =over 4
 
@@ -228,8 +228,6 @@ 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
@@ -266,6 +264,7 @@ query parameters, cookies, uploads, headers, and more.
     $c->req->cookies->{sessionid};
     $c->req->headers->content_type;
     $c->req->base;
+    $c->req->uri_with( { page = $pager->next_page } );
 
 =item * L<Catalyst::Response>
 
@@ -318,7 +317,9 @@ application components. For an example, we return to our 'hello' action:
 
 Note that the stash should be used only for passing data in an
 individual request cycle; it gets cleared at a new request. If you need
-to maintain more persistent data, use a session.
+to maintain persistent data, use a session. See
+L<Catalyst::Plugin::Session> for a comprehensive set of
+Catalyst-friendly session-handling tools.
 
 =head3 Actions
 
@@ -417,249 +418,6 @@ 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<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<Captures> 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('/') Captures(1) {
-      my ( $self, $c, $integer ) = @_;
-      $c->stash->{ message } = "Hello ";
-      $c->stash->{ arg_sum } = $integer;
-  }
-
-  #   this is our endpoint, because it has no :Captures
-  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<:Captures>.
-
-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<:Captures(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<:Captures> 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('/') Captures(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') Captures(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<:Captures(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 Captures(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 Captures
-
-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<:Captures(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<:Captures> 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<:Captures>. 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<:Captures>, 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.
-
-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;
@@ -687,6 +445,24 @@ Catalyst ("MyApp::Controller" in the above example), replaces "::" with
 explanation of the pre-defined meaning of Catalyst component class
 names.
 
+=item * B<Chained>
+
+Catalyst also provides a method to build and dispatch chains of actions,
+like
+
+    sub foo : Chained : CaptureArgs(1) {
+        my ( $self, $c, $arg ) = @_;
+        ...
+    }
+
+    sub bar : Chained('foo') : Args(1) {
+        my ( $self, $c, $arg ) = @_;
+        ...
+    }
+
+to handle a C</foo/*/bar/*> path. For extensive information about this
+dispatch type, please see L<Catalyst::DispatchType::Chained>.
+
 =item * B<Private>
 
     sub foo : Private { }
@@ -740,10 +516,12 @@ 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
-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.
+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. Indeed, this is now the recommended way of
+handling default situations; the C<default> private controller should
+be considered deprecated.
 
 =item * B<index : Private>
 
@@ -1056,11 +834,12 @@ C<$c-E<gt>forward(qw/MyApp::View::TT process/)>.
     }
 
 You normally render templates at the end of a request, so it's a perfect
-use for the global C<end> action.
+use for the global C<end> action. (In practice, however, you would use a
+default C<end> action as supplied by L<Catalyst::Action::RenderView>.)
 
 Also, be sure to put the template under the directory specified in
-C<$c-E<gt>config-E<gt>{root}>, or you'll be forced to look at our
-eyecandy debug screen. ;)
+C<$c-E<gt>config-E<gt>{root}>, or you'll end up looking at the debug
+screen.
 
 =head4 Models
 
@@ -1124,9 +903,9 @@ can always call an outside module that serves as your Model:
       
       $c->stash->{template} = 'list.tt';
       
-      use Some::Outside::DBIC::Module;
-      my @records = Some::Outside::DBIC::Module->search({
-        artist => 'sri',
+      use Some::Outside::Database::Module;
+      my @records = Some::Outside::Database::Module->search({
+        artist => 'Led Zeppelin',
         });
       
       $c->stash->{records} = \@records;
@@ -1288,18 +1067,18 @@ 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;
-               }
-       }
+    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