fix methods and action names to match the next example (which is supposed to be equiv...
[catagits/Catalyst-Manual.git] / lib / Catalyst / Manual / Intro.pod
index 3538185..a5acd72 100644 (file)
@@ -23,7 +23,7 @@ possible to do things in a different way. Other web frameworks are
 I<initially> simpler to use, 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.  For
-example, this leads to Catalyst being more suited to system integration
+example, this leads to Catalyst being better suited to system integration
 tasks than other web frameworks.
 
 =head3 MVC
@@ -53,7 +53,7 @@ L<Mason|HTML::Mason>, L<HTML::Template>...
 =item * B<Controller>
 
 Control the whole request phase, check parameters, dispatch actions, flow
-control. Catalyst itself!
+control. This is the meat of where Catalyst works.
 
 =back
 
@@ -104,7 +104,7 @@ example:
 
 Now http://localhost:3000/hello prints "Hello World!".
 
-Note that actions with the C< :Global > attribute are equivalent to
+Note that actions with the C< :Local > attribute are equivalent to
 using a C<:Path('action_name') > attribute, so our action could be
 equivalently:
 
@@ -122,6 +122,12 @@ separately - which will turn the built server into a fully fledged production
 ready server (although you'll probably want to run it behind a front end proxy
 if you end up using it).
 
+=item * PSGI Support
+
+Starting with Catalyst version 5.9 Catalyst ships with L<PSGI> integration
+for even more powerful and flexible testing and deployment options.  See
+L<Catalyst::PSGI> for details.
+
 =back
 
 =head3 Simplicity
@@ -171,16 +177,9 @@ running, using the helper scripts described above.
 
 =head3 Install
 
-Installation of Catalyst can be a time-consuming effort, due to its
-large number of dependencies. Although most of the frustrations
-associated with this are now ironed out and a simple C<cpan
-Catalyst::Devel> or C<cpan Catalyst::Runtime> are now usually
-straightforward, if you still have problems, you can use use Matt
-Trout's C<cat-install> script, from
-L<http://www.shadowcatsystems.co.uk/static/cat-install>, and then
-install L<Catalyst::Devel>.
+Installation of Catalyst should be straightforward:
 
-    # perl cat-install
+    # perl -MCPAN -e 'install Catalyst::Runtime'
     # perl -MCPAN -e 'install Catalyst::Devel'
 
 =head3 Setup
@@ -230,7 +229,7 @@ Catalyst has an uncommonly flexible component system. You can define as
 many L</Models>, L</Views>, and L</Controllers> as you like. As discussed
 previously, the general idea is that the View is responsible for the
 output of data to the user (typically via a web browser, but a View can
-also generate PDFs or e-mails, for example); the Model is responsible 
+also generate PDFs or e-mails, for example); the Model is responsible
 for providing data (typically from a relational database); and the
 Controller is responsible for interacting with the user and deciding
 how user input determines what actions the application takes.
@@ -238,7 +237,7 @@ how user input determines what actions the application takes.
 In the world of MVC, there are frequent discussions and disagreements
 about the nature of each element - whether certain types of logic
 belong in the Model or the Controller, etc. Catalyst's flexibility
-means that this decision is entirely up to you, the programmer; 
+means that this decision is entirely up to you, the programmer;
 Catalyst doesn't enforce anything. See L<Catalyst::Manual::About> for
 a general discussion of these issues.
 
@@ -248,9 +247,10 @@ from L<Catalyst::Component> which provides a simple class structure and some
 common class methods like C<config> and C<new> (constructor).
 
     package MyApp::Controller::Catalog;
+    use Moose;
+    use namespace::autoclean;
 
-    use strict;
-    use base 'Catalyst::Controller';
+    BEGIN { extends 'Catalyst::Controller' }
 
     __PACKAGE__->config( foo => 'bar' );
 
@@ -264,7 +264,7 @@ short alias for each one.
 
 =over 4
 
-=item * B<MyApp/Model/> 
+=item * B<MyApp/Model/>
 
 =item * B<MyApp/M/>
 
@@ -280,8 +280,8 @@ short alias for each one.
 
 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.
+C<M/>, C<V/>, and C<C/>. Though these still work, they are deprecated
+and we now recommend the use of the full names.
 
 =head4 Views
 
@@ -363,7 +363,7 @@ Now we can create a DBIC::Schema model for this database.
 
     script/myapp_create.pl model MyModel DBIC::Schema MySchema create=static 'dbi:SQLite:/tmp/myapp.db'
 
-L<DBIx::Class::Schema::Loader> can automaticall load table layouts and
+L<DBIx::Class::Schema::Loader> can automatically load table layouts and
 relationships, and convert them into a static schema definition
 C<MySchema>, which you can edit later.
 
@@ -373,15 +373,15 @@ We add the following to MyApp/Controller/Root.pm
 
     sub view : Global {
         my ( $self, $c, $id ) = @_;
-        
+
         $c->stash->{item} = $c->model('MyModel::Foo')->find($id);
     }
 
     1;
-    
+
     sub end : Private {
         my ( $self, $c ) = @_;
-        
+
         $c->stash->{template} ||= 'index.tt';
         $c->forward( $c->view('TT') );
     }
@@ -396,14 +396,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::Database::Module;
       my @records = Some::Outside::Database::Module->search({
         artist => 'Led Zeppelin',
         });
-      
+
       $c->stash->{records} = \@records;
     }
 
@@ -482,9 +482,9 @@ application.
 
     use base qw/Catalyst::Controller/;
 
-    sub login : Path("login") { }
+    sub sign_in : Path("sign-in") { }
     sub new_password : Path("new-password") { }
-    sub logout : Path("logout") { }
+    sub sign_out : Path("sign-out") { }
 
     package MyApp::Controller::Catalog;
 
@@ -765,7 +765,7 @@ will look at the URL it is processing, and the actions that it has
 found, and automatically call the actions it finds that match the
 circumstances of the request.
 
-The URL (for example http://localhost.3000/foo/bar) consists of two
+The URL (for example http://localhost:3000/foo/bar) consists of two
 parts, the base, describing how to connect to the server
 (http://localhost:3000/ in this example) and the path, which the
 server uses to decide what to return (foo/bar).  Please note that the
@@ -790,7 +790,7 @@ of Catalyst component class names.
 
 =item * B<Overriding the namespace>
 
-Note that __PACKAGE__->config->{namespace} can be used to override the
+Note that I<< __PACKAGE__->config->(namespace => ... ) >> can be used to override the
 current namespace when matching.  So:
 
     package MyApp::Controller::Example;
@@ -798,7 +798,7 @@ current namespace when matching.  So:
 would normally use 'example' as its namespace for matching, but if
 this is specially overridden with
 
-    __PACKAGE__->config->{namespace}='thing';
+    __PACKAGE__->config( namespace => 'thing' );
 
 it matches using the namespace 'thing' instead.
 
@@ -810,25 +810,29 @@ application (e.g. http://localhost:3000/ ):
 
     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} = '';
+
+    __PACKAGE__->config( namespace => '');
+
     sub default : Path  {
         my ( $self, $context ) = @_;
         $context->response->status(404);
         $context->response->body('404 not found');
     }
+
     1;
 
 
 The code
 
-    __PACKAGE__->config->{namespace} = '';
+    __PACKAGE__->config( namespace => '' );
 
 makes the controller act as if its namespace is empty.  As you'll see
-below, an empty namespace makes many of the URL-matching attributes,
-such as :Path, :Local and :Global matches, match at the start of the
-URL path.
+below, an empty namespace makes many of the URL-matching attributes, such
+as :Path and :Local match at the start of the URL path (i.e. the
+application root).
 
 =back
 
@@ -847,30 +851,41 @@ of the path is passed as arguments.
 
 =item * Namespace-prefixed (C<:Local>)
 
-    package MyApp::Controller::My::Controller; 
+    package MyApp::Controller::My::Controller;
     sub foo : Local { }
 
 Matches any URL beginning with> http://localhost:3000/my/controller/foo. The namespace and
 subroutine name together determine the path.
 
-=item * Namespace-level (C<:Global>)
+=item * Root-level (C<:Global>)
 
     package MyApp::Controller::Foo;
-    sub foo : Global { }
 
-Matches http://localhost:3000/foo - that is, the action is mapped
-directly to the controller namespace, ignoring the function name.  
+    sub bar : Global {
+        my ($self, $c) = @_;
+        $c->res->body(
+          $c->res->body('sub bar in Controller::Foo triggered on a request for '
+                         . $c->req->uri));
+    }
 
-C<:Global> is equivalent C<:Local> one level higher in
-the namespace.  
+1;
 
-    package MyApp::Controller::Root;
-    __PACKAGE__->config->{namespace}='';
-    sub foo : Local { }
+Matches http://localhost:3000/bar - that is, the action is mapped
+directly to the method name, ignoring the controller namespace.
 
-Use whichever makes the most sense for your application.
+C<:Global> always matches from the application root: it is simply
+shorthandfor C<:Path('/methodname')>.  C<:Local> is shorthand for
+C<:Path('methodname')>, which takes the controller namespace as described
+above.
 
-=item * Changing handler behaviour: adding arguments (C<:Args>)
+Usage of the C<Global> handler is rare in all but very old Catalyst
+applications (e.g. before Catalyst 5.7).  The use cases where C<Global>
+used to make sense are now largely replaced by the C<Chained> dispatch
+type, or by empty C<Path> declarations on an controller action.  C<Global>
+is still included in Catalyst for backwards compatibility, although
+legitimate use-cases for it may still exist.
+
+=item * Changing handler behaviour: eating arguments (C<: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, additionally
@@ -886,6 +901,18 @@ would match any URL starting /foo/bar. To restrict this you can do
 to only match URLs starting /foo/bar/* - with one additional path
 element required after 'bar'.
 
+NOTE that adding C<:Args(0)> and missing out :Args completely are B<not>
+the same thing.
+
+C<:Args(0)> means that no arguments are taken.  Thus, the URL and path must
+match precisely.
+
+No :Args at all means that B<any number> of arguments are taken.  Thus, any
+URL that B<starts with> the controller's path will match. Obviously, this means
+you cannot chain from an action that does not specify args, as the next action
+in the chain will be swallowed as an arg to the first!
+
+
 =item * Literal match (C<:Path>)
 
 C<Path> actions match things starting with a precise specified path,
@@ -917,14 +944,14 @@ The above code matches http://localhost:3000/my/controller.
 Actions with the C<:Local> attribute are similarly equivalent to
 C<:Path('action_name')>:
 
-    sub foo : Local { } 
+    sub foo : Local { }
 
-is equivalent to 
+is equivalent to
 
     sub foo : Path('foo') { }
 
 =item * Pattern-match (C<:Regex> and C<:LocalRegex>)
+
     package MyApp::Controller::My::Controller;
     sub bar : Regex('^item(\d+)/order(\d+)$') { }
 
@@ -1092,7 +1119,7 @@ turn.
     sub auto : Private { }
 
 C<auto>, however, doesn't override like this: providing they exist,
-C<MyApp::auto>, C<MyApp::Controller::Catalog::auto> and
+C<MyApp::Controller::Root::auto>, C<MyApp::Controller::Catalog::auto> and
 C<MyApp::Catalog::Order::auto> would be called in turn.
 
 Here are some examples of the order in which the various built-ins
@@ -1147,7 +1174,7 @@ authentication fails, returning 0 would skip any remaining methods for
 that URL.
 
 B<Note:> Looking at it another way, C<auto> actions have to return a
-true value to continue processing! 
+true value to continue processing!
 
 =head4 URL Path Handling
 
@@ -1172,8 +1199,8 @@ Catalyst matches actions in most specific to least specific order - that is, wha
 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 
+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<@_>, because the Regex will 'eat' them.
 
 Beware!  If you write two matchers, that match the same path, with the
@@ -1205,7 +1232,7 @@ modules that require this.
     my $current_page = $c->req->param('page') || 1;
 
     # multiple values for single parameter name
-    my @values = $c->req->param('scrolling_list');         
+    my @values = $c->req->param('scrolling_list');
 
     # DFV requires a CGI.pm-like input hash
     my $results = Data::FormValidator->check($c->req->params, \%dfv_profile);
@@ -1258,9 +1285,9 @@ be reset.
         # now $c->req->args is back to what it was before
     }
 
-    sub check_message : Private {
-        my ( $self, $c ) = @_;
-        my $first_argument = $c->req->args->[0]; # now = 'test1'
+    sub check_message : Action {
+        my ( $self, $c, $first_argument ) = @_;
+        my $also_first_argument = $c->req->args->[0]; # now = 'test1'
         # do something...
     }
 
@@ -1272,11 +1299,11 @@ you will have to refer to the method by absolute path.
   $c->forward('/my/controller/action');
   $c->forward('/default'); # calls default in main application
 
-Here are some examples of how to forward to classes and methods.
+You can also forward to classes and methods.
 
     sub hello : Global {
         my ( $self, $c ) = @_;
-        $c->forward(qw/MyApp::Model::Hello say_hello/);
+        $c->forward(qw/MyApp::View:Hello say_hello/);
     }
 
     sub bye : Global {
@@ -1284,7 +1311,7 @@ Here are some examples of how to forward to classes and methods.
         $c->forward('MyApp::Model::Hello'); # no method: will try 'process'
     }
 
-    package MyApp::Model::Hello;
+    package MyApp::View::Hello;
 
     sub say_hello {
         my ( $self, $c ) = @_;
@@ -1296,6 +1323,28 @@ Here are some examples of how to forward to classes and methods.
         $c->res->body('Goodbye World!');
     }
 
+This mechanism is used by L<Catalyst::Action::RenderView> to forward
+to the C<process> method in a view class.
+
+It should be noted that whilst forward is useful, it is not the only way
+of calling other code in Catalyst. Forward just gives you stats in the debug
+screen, wraps the code you're calling in an exception handler and localises
+C<< $c->request->args >>.
+
+If you don't want or need these features then it's perfectly acceptable
+(and faster) to do something like this:
+
+    sub hello : Global {
+        my ( $self, $c ) = @_;
+        $c->stash->{message} = 'Hello World!';
+        $self->check_message( $c, 'test1' );
+    }
+    
+    sub check_message {
+        my ( $self, $c, $first_argument ) = @_;
+        # do something...
+    }
+
 Note that C<forward> returns to the calling action and continues
 processing after the action finishes. If you want all further processing
 in the calling action to stop, use C<detach> instead, which will execute
@@ -1303,7 +1352,6 @@ the C<detach>ed action and not return to the calling sub. In both cases,
 Catalyst will automatically try to call process() if you omit the
 method.
 
-
 =head3 Testing
 
 Catalyst has a built-in http server for testing or local
@@ -1362,17 +1410,13 @@ FAQ:
 
     http://dev.catalystframework.org/wiki/faq
 
-=head1 AUTHOR
+=head1 AUTHORS
 
-Sebastian Riedel, C<sri@oook.de> 
-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>
+Catalyst Contributors, see Catalyst.pm
 
 =head1 COPYRIGHT
 
-This program is free software. You can redistribute it and/or modify it
-under the same terms as Perl itself.
+This library is free software. You can redistribute it and/or modify it under
+the same terms as Perl itself.
+
+=cut