Moved Chained intro to dispatch type and made recursion test more sane.
[catagits/Catalyst-Runtime.git] / lib / Catalyst / Manual / Intro.pod
index 8e0211c..44a80b4 100644 (file)
@@ -8,12 +8,22 @@ 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.
+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
 
@@ -32,7 +42,7 @@ well-known Perl modules you may want to use for each.
 =item * B<Model>
 
 Access and modify content (data). L<DBIx::Class>, L<Class::DBI>,
-L<Plucene>, L<Net::LDAP>...
+L<Xapian>, L<Net::LDAP>...
 
 =item * B<View>
 
@@ -46,11 +56,11 @@ 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).
-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
 
@@ -184,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;
 
@@ -198,16 +207,12 @@ 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
 
@@ -223,6 +228,8 @@ 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
@@ -288,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
 
@@ -319,6 +330,29 @@ http://localhost.3000/foo/bar) consists of two parts, the base
 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
@@ -385,11 +419,15 @@ L</URL Path Handling> below.
 
 =item * B<Top-level> (B<Global>)
 
-    package MyApp; 
+    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> (B<Local>)
 
@@ -406,6 +444,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 more information about this dispatch
+type, please read L<Catalyst::DispatchType::Chained>.
+
 =item * B<Private>
 
     sub foo : Private { }
@@ -632,10 +688,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>
@@ -717,7 +772,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
 
@@ -735,6 +790,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
@@ -920,11 +980,108 @@ controller above
     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...
 
@@ -956,6 +1113,8 @@ 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