3 Catalyst::Manual::Cookbook - Cooking with Catalyst
7 Yummy code like your mum used to bake!
11 =head2 Force debug screen
13 You can force Catalyst to display the debug screen at the end of the request by
14 placing a die() call in the _end action.
18 my ( $self, $c ) = @_;
23 If you're tired of removing and adding this all the time, you
24 can easily add a condition. for example:
26 die "Testing" if $c->param->{dump_info};
28 =head2 Disable statistics
30 Just add this line to your application class if you don't want those nifty
31 statistics in your debug messages.
33 sub Catalyst::Log::info { }
37 Scaffolding is very simple with Catalyst.
38 Just use Catalyst::Model::CDBI::CRUD as baseclass.
40 # lib/MyApp/Model/CDBI.pm
41 package MyApp::Model::CDBI;
44 use base 'Catalyst::Model::CDBI::CRUD';
47 dsn => 'dbi:SQLite:/tmp/myapp.db',
56 use Catalyst 'FormValidator';
59 name => 'My Application',
60 root => '/home/joeuser/myapp/root'
65 my ( $self, $c ) = @_;
66 $c->form( optional => [ MyApp::Model::CDBI::Table->columns ] );
67 $c->forward('MyApp::Model::CDBI::Table');
73 Modify the $c->form() parameters to match your needs, and don't forget to copy
76 =head2 Serving static files and CSS as text/css
78 If you want to serve static content (like images, txt or CSS) via Catalyst,
79 then all you need is the plugin Catalyst::Plugin::Static as well as a small
80 regex to set the MIME type for CSS to text/css.
86 use Catalyst qw/-Debug Static/;
91 my ( $self, $c ) = @_;
95 '/^.*\.css$/' => sub {
96 my ( $self, $c ) = @_;
97 $c->serve_static('text/css');
101 =head2 Uploads with Catalyst
103 To implement uploads in Catalyst you need to have a HTML form similiar to
106 <form action="/upload" method="post" enctype="multipart/form-data">
107 <input type="hidden" name="form_submit" value="yes">
108 <input type="file" name="my_file">
109 <input type="submit" value="Send">
112 It's very important not to forget enctype="multipart/form-data" in form,
113 if it's not there, uploads just don't work.
115 Catalyst Controller module 'upload' action:
121 if ($c->req->parameters->{form_submit} eq 'yes') {
122 my $filename = $c->req->parameters->{my_file};
124 my $fh = $c->req->uploads->{$filename}->{fh};
125 open(NEW_FILE, ">/tmp/$filename") or die
126 "Can't open file for writing: $!";
127 while ($fh->read(my $buf, 32768)) {
133 $c->stash->{template} = 'upload_form.tt';
134 $c->forward('MyApp::V::View');
138 If you want to upload bigger files than 1MB, then just add to your Controller
141 $CGI::Simple::POST_MAX = 1048576000;
143 =head2 Authentication with Catalyst::Plugin::Authentication::CDBI
145 There are (at least) two ways to implement authentication with this plugin:
146 1) only checking username and password
147 2) checking username, password and the roles the user has
149 For both variants you'll need the following code in your MyApp package:
151 use Catalyst qw/Session::FastMmap Static Authentication::CDBI/;
153 MyApp->config( authentication => { user_class => 'MyApp::M::MyApp::Users',
154 user_field => 'email',
155 password_field => 'password' });
157 'user_class' is a Class::DBI class for your users table.
158 'user_field' tells which field is used for username lookup (might be
159 email, first name, surname etc).
160 'password_field' is, well, password field in your table and by default
161 password is stored in plain text. Authentication::CDBI looks for 'user'
162 and 'password' fields in table, if they're not defined in the config.
164 In PostgreSQL users table might be something like:
169 surname varchar(100),
170 password varchar(100),
175 We'll discuss the first variant for now:
176 1. user:password login / auth without roles
178 To log in a user you might use a action like this:
182 if ($c->req->params->{username}) {
183 $c->session_login($c->req->params->{username},
184 $c->req->params->{password} );
185 if ($c->req->{user}) {
186 $c->forward('?restricted_area');
191 $c->req->params->{username} and $c->req->params->{password} are html
192 form parameters from a login form. If login succeeds, then $c->req->{user}
193 contains the username of the authenticated user.
195 If you want to remember the users login status inbetween further requests,
196 then just use the $c->session_login method, Catalyst will create a session
197 id, session cookie and automatically append session id to all urls. So
198 all you have to do, is just check $c->req->{user} where needed.
200 To log out user, just call $c->session_logout.
202 Now lets take a look at the second variant:
203 2. user:password login / auth with roles
205 To use roles you need to add to MyApp->config in the 'authentication'
206 section following parameters:
208 role_class => 'MyApp::M::MyApp::Roles',
209 user_role_class => 'MyApp::M::MyApp::UserRoles',
210 user_role_user_field => 'user_id',
211 user_role_role_field => 'role_id',
213 Corresponding tables in PostgreSQL could look like this:
221 CREATE TABLE user_roles (
225 primary key(user_role_id),
226 foreign key(user_id) references users(user_id),
227 foreign key(role_id) references roles(role_id)
230 The 'roles' table is a list of role names and the 'user_role' table is used for
231 the user -> role lookup.
233 Now if a logged in user wants to see a location which is allowed only for
234 people with 'admin' role then in you controller you can check it with:
238 if ($c->roles(qw/admin/)) {
239 $c->req->output("Your account has the role 'admin.'");
241 $c->req->output("You're not allowed to be here");
245 One thing you might need is to forward non-authenticated users to login
246 form, if they try to access restricted areas. If you want to do this
247 controller-wide (if you have one controller for admin section) then it's
248 best to add user check to '!begin' action:
252 unless ($c->req->{user}) {
253 $c->req->action(undef); ## notice this!!
254 $c->forward('?login');
258 Pay attention to $c->req->action(undef). This is needed, because of the
259 way $c->forward works - forward to login gets called, but after that
260 Catalyst executes anyway the action defined in the uri (eg. if you tried to
261 watch /add, then first '!begin' forwards to '?login', but after that
262 anyway '?add' is executed). So $c->req->action(undef) undefines any
263 actions that were to be called and forwards user where we want him/her
266 And this is all you need to do, isn't Catalyst wonderful?
270 Sebastian Riedel, C<sri@oook.de>
271 Danijel Milicevic C<me@danijel.de>
272 Viljo Marrandi C<vilts@yahoo.com>
276 This program is free software, you can redistribute it and/or modify it under
277 the same terms as Perl itself.