Perl - Catalyst


Important: - done reading - continue reading from "Catalyst has an uncommonly flexible component system."

What is Catalyst?

Catalyst is an MVC framework for web development in Perl. It grew out of Maypole.

What is Maypole?

It is the ancestor of Catalyst. Maypole works well for typical CRUD (Create, Retrieve, Update, Delete) databases on the Web. It includes a variety of useful methods and prewritten templates and template macros that make it very easy to set up a powerful web database. However, it focuses so strongly on CRUD that it is less flexible for other tasks. One of the goals of Catalyst is to provide a framework well suited for any web-related project.

Why should we use Catalyst?

Speed. We planned Catalyst as an enterprise-level framework, able to handle a significant load. It makes heavy use of caching. Catalyst applications register their actions in the dispatcher at compile time, making it possible to process runtime requests quickly, without needing elaborate checks. Regex dispatches are all precompiled. Catalyst builds only the structures it needs, so there are no delays to generate (for example) unused database relations.

Simplicity. Catalyst has many prebuilt components and plugins for common modules and tasks. For example, there are View classes available for Template Toolkit, HTML::Template, Mason, Petal, and PSP. Plugins are available for dozens of applications and functions, including Data::FormValidator, authentication based on LDAP or Class::DBI, several caching modules, HTML::FillInForm, and XML-RPC.

Catalyst supports component auto-discovery; if you put a component in the correct place, Catalyst will find and load it automagically. Just place a Catalog controller in /AppName/Controller/ (or, in practice, in the shortened /AppName/C/; there's no need to use each item. You can also declare plugins in the application class with short names, so that:

use Catalyst qw/Email Prototype Textile/;

will load Catalyst::Plugin::Email, Catalyst::Plugin::Prototype, and Catalyst::Plugin::Textile in one shot.

Ease of development. Catalyst comes with a built-in lightweight HTTP server for development purposes. This runs on any platform; you can quickly restart it to reload any changes. This server functions similarly to production-level servers, so you can use it throughout the testing process—or longer; it's a great choice if you want to deliver a self-contained desktop application. Scalability is simple, though: when you want to move on, it is trivial to switch the engine to use plain CGI, mod_perl1, mod_perl2, FastCGI, or even the Zeus web server.

Debugging and logging support is also built-in. With debugging enabled, Catalyst sends very detailed reports to the error log, including summaries of the loaded components, fine-grained timing of each action and request, argument listings for requests, and more. Logging works by using the the Catalyst::Log class; you can log any action for debugging or information purposes by adding lines like:

$c->log->info("We made it past the for loop");
$c->log->debug( $sql_query );

Helper scripts, generated with Template Toolkit, are available for the main application and most components. These allow you to quickly generate starter code (including basic unit tests) for the application framework. With a single line, you can create a Model class based on Class::DBI that pulls in the appropriate Catalyst base model class, sets up the pattern for the CDBI configuration hash, and generates a perldoc skeleton.

Flexibility. Catalyst allows you to use multiple models, views, and controllers—not just as an option when setting up an application, but as a totally flexible part of an application's flow. You can mix and match different elements within the same application or even within the same method. Want to use Class::DBI for your database storage and LDAP for authentication? You can have two models. Want to use Template Toolkit for web display and PDF::Template for print output? No problem. Catalyst uses a simple building-block approach to its add-ins: if you want to use a component, you say so, and if you don't say so, Catalyst won't use it. With so many components and plugins available, based on CPAN modules, it's easy to use what you want, but you don't have to use something you don't need. Catalyst features advanced URL-to-action dispatching. There are multiple ways to map a URL to an action (that is, a Catalyst method), depending on your requirements. First, there is literal dispatching, which will match a specific path:

How can we install Catalyst?

Catalyst has a relatively large number of requirements; most, however, are easy to install, along with their dependencies, from CPAN. The following list should take care of everything you need for this project:

  • Catalyst
  • Catalyst::Model::CDBI
  • Class::DBI::SQLite
  • Catalyst::View::TT
  • Catalyst::Plugin::Textile
  • Catalyst::Plugin::Prototype
  • SQLite (the binary, not the Perl module)
# perl -MCPAN -e 'install Catalyst::Runtime'
# perl -MCPAN -e 'install Catalyst::Devel'
# perl -MCPAN -e 'install Catalyst::View::TT'

How can we generate the skeleton for our application?

$ MiniMojo
$ cd MiniMojo MyApp
cd MyApp
script/ controller Library::Login

You've just created the skeleton for your entire application, complete with a helper script keyed to MiniMojo to generate individual classes, basic test scripts, and more.

How can we run the built-in server?


MiniMojo is already running, though it isn't doing much just yet. (You should have received a web page consisting solely of the text "Congratulations, MiniMojo is on Catalyst!") Press Ctrl-C to stop the server.

How can we add methods to our application class?

Add a private end action to your application class, lib/, by editing the new file:

sub end : Private {
    my ( $self, $c ) = @_;
    $c->forward('MiniMojo::V::TT') unless $c->res->output;

What is the purpose of 'end' action?

Catalyst automatically calls the end action at the end of a request cycle. It's one of four built-in Private actions. It's a typical pattern in Catalyst to use end to forward the application to the View component for rendering, though if necessary you could do it yourself (for example, if you want to use different Views in the same application—perhaps one to generate web pages with Template Toolkit and another to generate PDFs with PDF::Template).

What is the purpose of the 'default' action?

Replace the existing, helper-generated default action in the same class with:

sub default : Private {
    my ( $self, $c ) = @_;

In case the client has specified no other appropriate action, this will forward on to the page controller's show method. As Private actions, nothing can call these from outside the application. Any method from within the application can call them. The default action is another built-in Private action, along with begin, auto, and end. Again, Catalyst calls them automatically at relevant points in the request cycle.

How can we setup a model and model class?

Next, create a file, minimojo.sql, that contains the SQL for setting up your page table in SQLite.

-- minimojo.sql
    title TEXT,
    body TEXT

Create a database from it, using the sqlite command-line program:

sqlite minimojo.db < minimojo.sql

Depending on your setup, it might be necessary to call this as sqlite3.

Use the helper to create model classes and basic unit tests:

script/ model CDBI CDBI dbi:SQLite:/path/to/minimojo.db

The script is a helper that uses Template Toolkit to automate the creation of particular modules. The previous command creates a model (in contrast to a controller or a view) called, using the CDBI helper, setting the connection string to dbi:SQLite:/path/to/minimojo.db, the database you just created. (Use the appropriate path for your system.) The helper will write the models into lib/MiniMojo/M/. There are various options for the helper scripts; the only requirement is the type and the name. (You can create your own modules from scratch, without using the helper.)

How can we set up the view and view class?

Use the helper to create a view class:

script/ view TT TT

View classes go into lib/MiniMojo/V/

How can we setup a controller class?

Create a controller class called Page with the helper:

script/ controller Page

Controller classes live in lib/MiniMojo/C/.

How can we add a method to our controller?

Add a show action to lib/MiniMojo/C/

sub show : Regex('^(\w+)\.html$') {
    my ( $self, $c ) = @_;
    $c->stash->{template} = '';
    # $c->forward('page');

The Regex dispatch matches a page in foo.html, where foo is any sequence of word characters. This sequence is available in the $context->request->snippets array, where the page action uses it to display an existing page or to create a new one. The rest of this action sets the appropriate template and sends the application to the page action. (Leave the forward command commented out until you have written the page action.)

Restart the server with $ script/ and point a web browser to http://localhost:3000/show/ to see the debug screen (you don't yet have the template that show is trying to send people to).

Create root/

        <h1>MiniMojo is set up!</h1>

Test again by killing the server with Ctrl-C and restarting it, and go to http://localhost:3000/show/. You should see the page you just defined.

How can we do more advanced stuff?

Re-read the article ( ) and actually try it out.

Can we have multiple models, views, controllers?

Yes. To build a Catalyst application, you handle each type of concern inside special modules called "Components". Often this code will be very simple, just calling out to Perl modules like those listed above under "MVC". Catalyst handles these components in a very flexible way. Use as many Models, Views, and Controllers as you like, using as many different Perl modules as you like, all in the same application. Want to manipulate multiple databases, and retrieve some data via LDAP? No problem. Want to present data from the same Model using Template Toolkit and PDF::Template? Easy.

Can we have unrestrainted URL-to-action mapping?

Yes. Catalyst allows you to dispatch any URLs to any application "Actions", even through regular expressions! Unlike most other frameworks, it doesn't require mod_rewrite or class and method names in URLs. With Catalyst you register your actions and address them directly. For example:

sub hello : Local {
    my ( $self, $context ) = @_;
    $context->response->body('Hello World!');
Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License