=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, Johson 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). You
+can also just Google it. Many, many web application frameworks are
+based on MVC, including all those listed above.
=head3 Flexibility
sub hello : Global {
my ( $self, $context ) = @_;
- $context->response->output('Hello World!');
+ $context->response->body('Hello World!');
}
Now http://localhost:3000/hello prints "Hello World!".
MyApp->config(
name => 'My Application',
- root => '/home/joeuser/myapp/root',
# You can put anything else you want in here:
my_configuration_variable => 'something',
sub default : Private {
my ( $self, $context ) = @_;
- $context->response->output('Catalyst rockz!');
+ $context->response->body('Catalyst rockz!');
}
1;
-For most applications, Catalyst requires you to define only two config
-parameters:
+For most applications, Catalyst requires you to define only one config
+parameter:
=over 4
Name of your application.
-=item * B<root>
-
-Path to additional files such as templates, images, or other static data.
-
=back
-However, 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}>.
+Optionally, you can specify a B<root> parameter for templates and static data.
+If omitted, Catalyst will try to auto-detect the directory's 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}>.
=head3 Context
sub hello : Global {
my ( $self, $c ) = @_;
- $c->res->output('Hello World!');
+ $c->res->body('Hello World!');
}
The Context contains several important objects:
The response is like the request, but contains just response-specific
information.
- $c->res->output('Hello World');
+ $c->res->body('Hello World');
$c->res->status(404);
$c->res->redirect('http://oook.de');
sub show_message : Private {
my ( $self, $c ) = @_;
- $c->res->output( $c->stash->{message} );
+ $c->res->body( $c->stash->{message} );
}
Note that the stash should be used only for passing data in an individual
=item * B<Literal>
+ package MyApp::C::My::Controller;
sub bar : Path('foo/bar') { }
+Literal C<Path> actions will act relative to their current namespace. The above
+example matches only http://localhost:3000/my/controller/foo/bar. If you start
+your path with a forward slash, it will match from the root. Example:
+
+ package MyApp::C::My::Controller;
+ sub bar : Path('/foo/bar') { }
+
Matches only http://localhost:3000/foo/bar.
+ package MyApp::C::My::Controller;
+ sub bar : Path { }
+
+By leaving the C<Path> definition empty, it will match on the namespace root.
+The above code matches http://localhost:3000/my/controller.
+
=item * B<Regex>
sub bar : Regex('^item(\d+)/order(\d+)$') { }
it is called, so that a C<bar> method in the
C<MyApp::Controller::Catalog::Order::Process> namespace won't match any form of
C<bar>, C<Catalog>, C<Order>, or C<Process> unless you explicitly put this in
-the regex.
+the regex. To achieve the above, you should consider using a C<LocalRegex> action.
+
+=item * B<LocalRegex>
-If you use capturing parentheses to extract values within the matching URL (23,
-42 in the above example), those values are available in the $c->req->snippets
+ sub bar : LocalRegex('^widget(\d+)$') { }
+
+LocalRegex actions act locally. If you were to use C<bar> in
+C<MyApp::Controller::Catalog>, the above example would match urls like
+http://localhost:3000/catalog/widget23.
+
+If you omit the "C<^>" from your regex, then it will match any depth from the
+controller and not immediately off of the controller name. The following example
+differes from the above code in that it will match
+http://localhost:3000/catalog/foo/widget23 as well.
+
+ package MyApp::Controller::Catalog;
+ sub bar : LocalRegex('widget(\d+)$') { }
+
+For both LocalRegex and Regex actions, if you use capturing parentheses to
+extract values within the matching URL ("widget23" would capture "23" in the
+above example), those values are available in the $c->req->snippets
array. If you want to pass arguments at the end of your URL, you must use regex
action keys. See L</URL Argument Handling> below.
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
+being that C<Path> takes arguments relative from the namespace and
+C<default> takes arguments relative from the root.
+
+=item * B<index : Private>
+
+C<index> is much like C<default> except that it takes no arguments
+and it is weighted slightly higher in the matching process.
+
=item * B<begin : Private>
Called at the beginning of a request, before any matching actions are
sub show_message : Private {
my ( $self, $c ) = @_;
- $c->res->output( $c->stash->{message} );
+ $c->res->body( $c->stash->{message} );
}
A C<forward> does not create a new request, so your request
sub say_hello {
my ( $self, $c ) = @_;
- $c->res->output('Hello World!');
+ $c->res->body('Hello World!');
}
sub process {
my ( $self, $c ) = @_;
- $c->res->output('Goodbye World!');
+ $c->res->body('Goodbye World!');
}
Note that C<forward> returns to the calling action and continues
script/myapp_create.pl view TT TT
-where the first C<TT> tells the script to create a Template Toolkit
-view, and the second tells the script that its name should be C<TT>.)
+where the first C<TT> tells the script that the name of the view should
+be C<TT>, and the second that it should be a Template Toolkit view.)
This gives us a process() method and we can now just do
$c->forward('MyApp::V::TT') to render our templates. The base class makes
But by using a Model that is part of your Catalyst application, you gain
several things: you don't have to C<use> each component, Catalyst will
find and load it automatically at compile-time; you can C<forward> to
-the module, which can only be done to Catalyst componenents; and only
+the module, which can only be done to Catalyst components; and only
Catalyst components can be fetched with
C<$c-E<gt>comp('MyApp::M::SomeModel')>.
package MyApp::C::Login;
- sign-in : Local { }
- new-password : Local { }
- sign-out : Local { }
+ sub sign-in : Local { }
+ sub new-password : Local { }
+ sub sign-out : Local { }
package MyApp::C::Catalog;