NAME
Catalyst::Manual::Tutorial - Getting started with Catalyst
DESCRIPTION
This document aims to get you up and running with Catalyst.
NOTE: THIS DOCUMENT IS STILL VERY MUCH IN AN EARLY DRAFT STATE. SEE THE NOTES AT THE BOTTOM OF THE DOCUMENT.
Installation
The first step is to install Catalyst, and the simplest way to do this is to install the Catalyst bundle from CPAN:
$ perl -MCPAN -e 'install Bundle::Catalyst'
This will retrieve Catalyst and a number of useful extensions and install them for you.
Setting up your application
Catalyst includes a helper script, catalyst.pl
, that will set up a skeleton application for you:
$ catalyst MyApp
created "MyApp"
created "MyApp/script"
created "MyApp/lib"
created "MyApp/root"
created "MyApp/root/static"
created "MyApp/root/static/images"
created "MyApp/t"
created "MyApp/t/Model"
created "MyApp/t/View"
created "MyApp/t/Controller"
created "MyApp/lib/MyApp"
created "MyApp/lib/MyApp/Model"
created "MyApp/lib/MyApp/View"
created "MyApp/lib/MyApp/Controller"
created "MyApp/lib/MyApp.pm"
created "MyApp/Build.PL"
created "MyApp/Makefile.PL"
created "MyApp/README"
created "MyApp/Changes"
created "MyApp/t/01app.t"
created "MyApp/t/02pod.t"
created "MyApp/t/03podcoverage.t"
created "MyApp/root/static/images/catalyst_logo.png"
created "MyApp/root/static/images/btn_120x50_built.png"
created "MyApp/root/static/images/btn_120x50_built_shadow.png"
created "MyApp/root/static/images/btn_120x50_powered.png"
created "MyApp/root/static/images/btn_120x50_powered_shadow.png"
created "MyApp/root/static/images/btn_88x31_built.png"
created "MyApp/root/static/images/btn_88x31_built_shadow.png"
created "MyApp/root/static/images/btn_88x31_powered.png"
created "MyApp/root/static/images/btn_88x31_powered_shadow.png"
created "MyApp/root/favicon.ico"
created "MyApp/script/myapp_cgi.pl"
created "MyApp/script/myapp_fastcgi.pl"
created "MyApp/script/myapp_server.pl"
created "MyApp/script/myapp_test.pl"
created "MyApp/script/myapp_create.pl"
This creates the directory structure shown, populated with skeleton files.
Testing out the sample application
You can test out your new application by running the server script that Catalyst provides:
$ cd MyApp
$ script/myapp_server.pl
[...] [catalyst] [debug] Debug messages enabled
[...] [catalyst] [debug] Loaded plugins:
.------------------------------------------------------------------------------.
| Catalyst::Plugin::Static::Simple |
'------------------------------------------------------------------------------'
[...] [catalyst] [debug] Loaded dispatcher "Catalyst::Dispatcher"
[...] [catalyst] [debug] Loaded engine "Catalyst::Engine::HTTP"
[...] [catalyst] [debug] Found home "/home/users/me/MyApp"
[...] [catalyst] [debug] Loaded Private actions:
.--------------------------------------+---------------------------------------.
| Private | Class |
+--------------------------------------+---------------------------------------+
| /default | MyApp |
'--------------------------------------+---------------------------------------'
[...] [catalyst] [info] MyApp powered by Catalyst 5.5
You can connect to your server at http://localhost:3000
(Note that each line logged by Catalyst begins with a timestamp, which has been replaced here with "...
" so that the text fits onto the lines.)
The server is now waiting for you to make requests of it. Try using telnet to manually make a simple GET request of the server (when telnet responds with "Escape character is '^]'.", type "GET / HTTP/1.0" and hit return twice):
$ telnet localhost 3000
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
GET / HTTP/1.0
HTTP/1.0 200 OK
Date: Mon, 07 Nov 2005 14:57:39 GMT
Content-Length: 5525
Content-Type: text/html; charset=utf-8
Status: 200
X-Catalyst: 5.5
[...]
Connection closed by foreign host.
$
You can see the full welcome message by visting http://localhost:3000/ with your browser.
More trace messages will appear in the original terminal window:
[...] [catalyst] [debug] **********************************
[...] [catalyst] [debug] * Request 1 (0.063/s) [2148]
[...] [catalyst] [debug] **********************************
[...] [catalyst] [debug] Arguments are ""
[...] [catalyst] [debug] "GET" request for "" from localhost
[...] [catalyst] [info] Request took 0.046883s (21.330/s)
.------------------------------------------------------------------+-----------.
| Action | Time |
+------------------------------------------------------------------+-----------+
| /default | 0.000000s |
'------------------------------------------------------------------+-----------'
The server will continue running until you interrupt it.
The application can also be tested from the command line using the generated helper script, script/myapp_test.pl
.
Getting your application invoked
Catalyst applications are usually run from mod_perl, but can also be run as CGI or FastCGI scripts. Running under mod_perl gives better performance, but for development purposes you may want to run your application as a CGI script, especially as changes to your application code take effect under CGI without having to restart the web server.
To run from mod_perl you need to add something like this to your Apache configuration file:
<Location /MyApp>
SetHandler perl-script
PerlHandler MyApp
</Location>
To run as a CGI script you need a wrapper script like:
#!/usr/bin/perl -w
use strict;
use lib '/path/to/MyApp/lib';
use MyApp;
MyApp->run;
Examining the generated code
The generated application code is quite simple and looks something like this (comments removed):
package MyApp;
use strict;
use warnings;
use Catalyst qw/-Debug Static::Simple/;
our $VERSION = '0.01';
__PACKAGE__->config( name => 'MyApp' );
__PACKAGE__->setup;
sub default : Private {
my ( $self, $c ) = @_;
$c->response->body( $c->welcome_message );
}
1;
When the Catalyst
module is imported by the application code, Catalyst performs the first stage of its initialization. This includes loading the appropriate Engine module for the environment in which the application is running, loading any plugins and ensuring that the calling module (the application module) inherits from Catalyst
(which makes the Catalyst methods config
and setup
available to the application module).
The call to config
sets up configuration data for the application. The name
parameter is the only required configuration parameter. You may also specificy a root
parameter, which is the path to the directory where documents, images, and templates can be found.
Catalyst associates actions with URLs and on receiving a request dispatches to the action that matches to request URL. The call to setup
in the code above registers a default action. With just this action registered the application will respond to all requests with the same welcome page.
As you see, the default action is defined as a Private action. Most private actions are not directly available from a web url. This also includes the built-in actions, 'default', 'begin', 'end', and 'auto', although they will be called as part of some chains. The rest can only be reached by using forward
.
The call to the setup
method also triggers the second stage of Catalyst's initialization process. In this phase Catalyst searches for any component modules, locating and registering any actions it finds in those modules.
Component modules have names prefixed with the application module name, followed by Model
, View
or Controller
(or the optional short forms: M
, V
or C
) followed by the component name, for example:
MyApp::Controller::ShoppingCart # long (default) version
MyApp::C::ShoppingCart # short version
MyApp::Model::User # long (default) version
MyApp::M::User # short version
Extending the generated code
You can start extending the application by adding new actions:
sub test1 : Global {
my ( $self, $c ) = @_;
$c->res->body('In a new test action #1');
}
sub default : Private {
my ( $self, $c ) = @_;
$c->res->body('Congratulations, MyApp is on Catalyst!');
}
# called like '/article/2005/06'
sub archive_month : Regex('^article/(\d{4})/(\d{2})$') {
my ( $self, $c ) = @_;
my $datetime = DateTime->new(
year => $c->request->snippets->[0],
month => $c->request->snippets->[1]
);
}
TODO: explain briefly about plugins, actions, and components
If the action is a Regex type, you can use capturing parentheses to extract values within the matching URL (2005, 06 in the above example). Those values are available in the $c->req->snippets anonymous array. See Catalyst::Manual::Intro#Actions for details.
Hooking in to Template Toolkit
One of the first things you will probably want to add to your application is a templating system for generating your output. Catalyst works well with Template Toolkit. If you are unfamiliar with Template Toolkit then I suggest you look at http://tt2.org, install Template
, read the documentation and play around with it, and have a look at the Badger Book (Template Toolkit by Darren Chamberlain, Dave Cross, and Andy Wardley, O'Reilly & Associates, 2004).
You can create a stub Template Toolkit view component by installing Catalyst::View::TT and using the create script that Catalyst set up as part of the skeleton application:
$ script/myapp_create.pl view TT TT
exists "MyApp/lib/MyApp/View"
exists "MyApp/t/View"
created "MyApp/lib/MyApp/View/TT.pm"
created "MyApp/t/View/TT.t"
this generates a view component named MyApp::View::TT
, which you might use by forwarding from your end
action:
# In MyApp or MyApp::Controller::SomeController
sub end : Private {
my($self, $c) = @_;
$c->forward('MyApp::V::TT');
}
The generated TT view component simply subclasses the Catalyst::View::TT
class. It looks like this (with the POD stripped out):
package My::App::V::TT;
use strict;
use base 'Catalyst::View::TT';
1;
Catalyst::View::TT
initializes a Template Toolkit object with an options hash initialized with built-in default settings followed by the contents of the hash <%{__PACKAGE__-
config()}>>. You can configure TT more to your needs by adding a new
method to the generated TT component:
sub new {
my $self = shift;
$self->config->{PRE_PROCESS} = 'config/main';
$self->config->{WRAPPER} = 'site/wrapper';
return $self->SUPER::new(@_);
}
AUTHOR
Andrew Ford, A.Ford@ford-mason.co.uk
Marcus Ramberg, mramberg@cpan.org
As noted above, this document is at an alpha stage. My plan for this document is as follows:
Expand this document fairly rapidly to cover topics relevant to a newcomer to Catalyst, in an order that can be read sequentially
Incorporate feedback
Revise the text
Placeholders are indicated by the words: TODO or CHECK
Please send comments, corrections and suggestions for improvements to A.Ford@ford-mason.co.uk
COPYRIGHT
This program is free software, you can redistribute it and/or modify it under the same terms as Perl itself.