An Introduction to Application Development with Catalyst and Perl

Template::Toolkit Views

One of the most common needs of a Web application is a templating system for rendering content. Templates probably are the best all-around approach to rendering text-based content, especially for markup like HTML.

Catalyst can use multiple Perl template systems, but the most popular is Template::Toolkit—a powerful, general-purpose template-processing system that is fast and feature-rich. It has a versatile and robust syntax that is simple and easy to use, but it also supports advanced capabilities, such as control structures, stream processing and extendability. Template::Toolkit is a whole programming language in its own right.

Catalyst provides a drop-in interface to Template::Toolkit via the view/component class Catalyst::View::TT. You can create a view within your application that extends this class using the helper script. Run this to create a new view named "HTML":

script/ view HTML TT

The new view is fully functional out of the box. As a general-purpose wrapper around Template::Toolkit, it provides a simple API to select templates and supply input data. The rest of the view-specific code goes in the templates themselves, which are stored within "root" in your application directory.

Here is an example of a simple Template::Toolkit template to render an HTML page:

<h3>[% title %]</h3>
<h1>Message: [% message %]</h1>

The character sequences within [% %] are "directives"—snippets of code that get replaced when the template is processed. The directives above are simple variable substitutions, which are the most basic kind. In this case, the values supplied for title and message will be inserted when the template is rendered.

If you saved the above template in a file named within root/templates, for example, you could use it with an action like this:

sub myaction :Path('/some/place') :Args(0) {
        my ( $self, $c ) = @_;
        $c->stash->{template} = 'templates/';
        $c->stash->{data}->{title} = 'TT rendered page';
        $c->stash->{data}->{message} = 'A cool message!';
        $c->forward( $c->view('HTML') );

The stash object above is another built-in feature of Catalyst that I haven't covered so far. It isn't very complicated; it's simply a hashref within the context object. It provides a standard per-request place to share data across components, similar to request and response, but for general use.

Catalyst::View::TT-based views use the content of the stash to determine operation. The value of template identifies the template to call, and the stash as a whole is used as the input data—each key in the stash becomes a variable in the template. The content generated from processing the template is used to set the body of the response.

The data in a real application probably will be more complex than the simple key/values in the previous example. One of Template::Toolkit's great features is its ability to handle Perl data structures directly. Consider the following action:

sub myaction :Path('/some/place') :Args(0) {
        my ( $self, $c ) = @_;
        $c->stash->{template} = 'templates/';
        $c->stash->{data} = {
                title	=> 'TT rendered page',
                subhash => {
                        alpha => 'foo',
                        bravo => 'abdc',
                        charlie => 'xyz'
                thinglist => [
                        'Thing 1',
                        'Thing 2',
                        'Big thing',
                        'Small thing'
        $c->forward( $c->view('HTML') );

This would work with a template like this:

<h3>[% data.title %]</h3>
<b>Alpha:</b> [% data.subhash.alpha %]<br>
<b>Bravo:</b> [% data.subhash.bravo %]<br>
<b>Charlie:</b> [% data.subhash.charlie %]<br>
<b>List of Things:</b><br>
[% FOREACH item IN data.thinglist %]
        [% item %]<br>
[% END %]

Objects also can be supplied and accessed in the same manner as hashes. In fact, the context object is supplied automatically in "c". For example, if you want to display the client's IP address, instead of separately putting $c->request->address in the stash, you can just access it directly within the template like this:

[% c.request.address %]

Template::Toolkit has many more features and abilities, including wrappers, conditional statements, filters, function calls and so on. Catalyst::View::TT also has additional defaults and configuration options that I didn't cover here (see the documentation for more details).

It is totally up to you how to balance logic between the templates and the rest of your application. Depending on what you are trying to achieve, your application easily could be written more in Template::Toolkit than in Perl!

DBIx::Class Models

One of the other most common needs of an application is a database. DBIx::Class (often shortened to DBIC) has emerged as the most popular ORM (Object Relational Mapper) library available for Perl. It is an exceptionally powerful, robust, object-oriented interface to many relational database servers (including MySQL, PostgreSQL, Oracle, MSSQL and many others).

Like Template::Toolkit, but to an even greater degree, Catalyst provides refined, drop-in component wrappers to interface with DBIx::Class (Catalyst::Model::DBIC::Schema).

Using DBIx::Class is a whole topic in and of itself that I don't have space to cover here, but it is a must-have if you plan to integrate your application with a database. See Resources for information on where to go to start learning about this wonderful library.



Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

Error in template?

j0e's picture

In page 3 of this article:

$c->stash->{data}->{title} = 'TT rendered page';

Shouldn't the template have this:

[% data.title %]

Instead of what is in the article:

[% title %]

This was an effective review for me, thank you!

[% data.message %] too

j0e's picture

I should have also mentioned that given:

$c->stash->{data}->{message} = 'A cool message!';

The following in the template:

[% message %]

needs to be:

[% data.message %]

Good work

Mas BlackBerry's picture

I like post a complete catalyst tutorial, i want to know if reference for it article, tks

Really nice article! Catalyst

Anonymous's picture

Really nice article! Catalyst is great framework with great community behind it


Jon Bjornstad's picture

In this text:

The alias for /static/ above tells Apache to serve the files directly in this directory (images, CSS, JavaScript files and so on). This is more efficient than serving these files through the application, which isn't necessary.

The <code> and </code> HTML tags surrounding /static/ somehow got through.

Good Job!

daniel.cristian's picture

Nice work! I hope you'll continue with another MVC framework from Perl, a more lighter one, Perl Dancer.



Dominic's picture

With so many people still thinking of perl as "that legacy language that you run from the cgi-bin directory", it's good to see the modern stuff get some coverage. Nice one!

Good work, looking for more!

Chankey Pathak's picture

Only LinuxJournal could have come up with such article. Good work!

Try to post a complete catalyst tutorial, there's only one single tutorial available (CPAN's tutorial for catalyst, the best one).