=head1 Basics
These recipes cover some basic stuff that is worth knowing for
-catalyst developers.
+Catalyst developers.
=head2 Delivering a Custom Error Page
package MyApp::Controller::Foo;
use Moose;
use namespace::autoclean;
- BEGIN { extends 'Catalyst::Controller';
+ BEGIN { extends 'Catalyst::Controller' };
## Write data into the session
sub add_item : Local {
=head1 Skipping your VCS's directories
-Catalyst uses Module::Pluggable to load Models, Views and Controllers.
+Catalyst uses Module::Pluggable to load Models, Views, and Controllers.
Module::Pluggable will scan through all directories and load modules
it finds. Sometimes you might want to skip some of these directories,
for example when your version control system makes a subdirectory with
source control systems. Here is the configuration you need to add
their directories to the list to skip.
-You can make catalyst skip these directories using the Catalyst config:
+You can make Catalyst skip these directories using the Catalyst config:
# Configure the application
__PACKAGE__->config(
=head1 Users and Access Control
-Most multiuser, and some single user web applications require that
+Most multiuser, and some single-user web applications require that
users identify themselves, and the application is often required to
define those roles. The recipes below describe some ways of doing
this.
=item Authorization
Making sure the user only accesses functions you want them to
-access. This is done by checking the verified users data against your
+access. This is done by checking the verified user's data against your
internal list of groups, or allowed persons for the current page.
=back
A Storage backend contains the actual data representing the users. It
is queried by the credential verifiers. Updating the store is not done
-within this system, you will need to do it yourself.
+within this system; you will need to do it yourself.
Examples:
- DBIC - Storage using a database.
+ DBIC - Storage using a database via DBIx::Class.
Minimal - Storage using a simple hash (for testing).
=head3 User objects
A User object is created by either the storage backend or the
-credential verifier, and filled with the retrieved user information.
+credential verifier, and is filled with the retrieved user information.
Examples:
=head3 ACL authorization
ACL stands for Access Control List. The ACL plugin allows you to
-regulate access on a path by path basis, by listing which users, or
+regulate access on a path-by-path basis, by listing which users, or
roles, have access to which paths.
=head3 Roles authorization
=head3 Checking roles
-Role checking is done by using the C<< $c->check_user_roles >> method,
-this will check using the currently logged in user (via C<< $c->user
+Role checking is done by using the C<< $c->check_user_roles >> method.
+This will check using the currently logged-in user (via C<< $c->user
>>). You pass it the name of a role to check, and it returns true if
the user is a member.
=head3 Using authentication in a testing environment
-Ideally, to write tests for authentication/authorization code one
-would first set up a test database with known data, then use
+Ideally, to write tests for authentication/authorization code one would
+first set up a test database with known data, then use
L<Test::WWW::Mechanize::Catalyst> to simulate a user logging
-in. Unfortunately the former can be rather awkward, which is why it's
-a good thing that the authentication framework is so flexible.
+in. Unfortunately this can be rather awkward, which is why it's a good
+thing that the authentication framework is so flexible.
Instead of using a test database, one can simply change the
authentication store to something a bit easier to deal with in a
modifying one's database, which can be problematic if one forgets to
use the testing instead of production database.
-Alternatively, if you want to authenticate real users, but not have to worry about
-their passwords, you can use L<Catalyst::Authentication::Credential::Testing>
-to force all users to authenticate with a global password.
+Alternatively, if you want to authenticate real users, but not have to
+worry about their passwords, you can use
+L<Catalyst::Authentication::Credential::Testing> to force all users to
+authenticate with a global password.
=head3 More information
=head3 Introduction
Authorization is the step that comes after
-authentication. Authentication establishes that the user agent is
-really representing the user we think it's representing, and then
-authorization determines what this user is allowed to do.
+authentication. Authentication establishes that the user agent is really
+representing the user we think it's representing, and then authorization
+determines what this user is allowed to do.
=head3 Role Based Access Control
Under role based access control each user is allowed to perform any
number of roles. For example, at a zoo no one but specially trained
-personnel can enter the moose cage (Mynd you, møøse bites kan be
+personnel can enter the moose cage (Mynd you, møøse bites kan be
pretty nasti!). For example:
package Zoo::Controller::MooseCage;
the moose, which is a very dangerous thing. We need to restrict this
action, so that only a qualified moose feeder can perform that action.
-The Authorization::Roles plugin let's us perform role based access
+The Authorization::Roles plugin lets us perform role based access
control checks. Let's load it:
use parent qw/Catalyst/;
Checking for roles all the time can be tedious and error prone.
-The Authorization::ACL plugin let's us declare where we'd like checks
+The Authorization::ACL plugin lets us declare where we'd like checks
to be done automatically for us.
For example, we may want to completely block out anyone who isn't a
clean up in your C<end> private action instead.
Also, it's important to note that if you restrict access to "/" then
-C<end>, C<default>, etc will also be restricted.
+C<end>, C<default>, etc. will also be restricted.
MyApp->acl_allow_root_internals;
write a simple component in Catalyst that slurps in an outside Model:
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::DBIC::Schema> is part of your
=head2 Create accessors to preload static data once per server instance
When you have data that you want to load just once from the model at
-server load instead of for each request, use mk_group_accessors to
+startup, instead of for each request, use mk_group_accessors to
create accessors and tie them to resultsets in your package that
-inherits from DBIx::Class::Schema
+inherits from DBIx::Class::Schema:
package My::Schema;
use base qw/DBIx::Class::Schema/;
and now in the controller, you can now access any of these without a
per-request fetch:
- $c->stash->{something} = $c->model('My::Schema')->schema->ACCESSORNAMEn;
+ $c->stash->{something} = $c->model('My::Schema')->schema->ACCESSORNAME;
=head2 XMLRPC
-Unlike SOAP, XMLRPC is a very simple (and imo elegant) web-services
+Unlike SOAP, XMLRPC is a very simple (and elegant) web-services
protocol, exchanging small XML messages like these:
Request:
=head1 Views
Views pertain to the display of your application. As with models,
-catalyst is uncommonly flexible. The recipes below are just a start.
+Catalyst is uncommonly flexible. The recipes below are just a start.
=head2 Catalyst::View::TT
=head3 Type attributes
Each action is a normal method in your controller, except that it has an
-L<attribute|http://search.cpan.org/~nwclark/perl-5.8.7/lib/attributes.pm>
+L<attribute|attributes>
attached. These can be one of several types.
Assume our Controller module starts with the following package declaration: