Begin main content

Using Haml with Catalyst

Thanks to Viacheslav Tykhanovskyi's Text::Haml, we can now enjoy the good clean fun of Haml markup in Perl. Much Perl web templating is done with Template::Toolkit, and using Haml within TT is also now possible thanks to Template::Plugin::Haml by Caleb Cushing. The trouble is, you need to wrap every template in some boilerplate:

[%- USE Haml ; FILTER haml -%]
...
[%- END -%]

So I hacked up a quick solution to using .haml templates directly in Catalyst. First, create a MyApp::View::Haml class:

package Hello::View::Haml;

use strict;
use warnings;

use base 'Catalyst::View::TT';

use Template::Plugin::Haml;

__PACKAGE__->config(
    TEMPLATE_EXTENSION => '.haml',
    render_die => 1,
);

sub render {
    my ($self, $c, $template, $args) = @_;

    $c->log->debug(qq{Rendering Haml/TT template "$template"}) if $c && $c->debug;

    # args may be passed in or be in the stash
    $args = { %{ $c->stash} }
        if ref $args ne 'HASH';

    # let the master haml template know which template to render
    $args->{haml_template} = $template;

    # do the normal TT render
    return $self->SUPER::render($c, 'haml_master.tt', $args);
}

1;

Then you need a haml_master.tt template:

[%- USE Haml ; PROCESS $haml_template | haml -%]

And finally set your config to use the Haml view by default:

default_view => 'Haml'

Et voila - .haml template rendering albeit with only TT style variable interpolation. Getting haml interpolation working might need some change to how the stash is passed to the Text::Haml module.

A controller method might look like this:

sub foo :Global {
    my ($self, $c) = @_;

    $c->stash(foo => 'bar');
    $c->stash(template => 'foo.haml');
}

And foo.haml:

!!! HTML
%body
  %p This is haml inside TT rendering your variables: [% foo %]

Becomes rendered as:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<body>
<p>This is haml inside TT rendering your variables: bar</p>
</body>

06:35 PM, 29 Jul 2010 by Mark Aufflick Permalink | Short Link

Add comment