package Catalyst::View::Mason; use strict; use base qw/Catalyst::Base/; use HTML::Mason; use NEXT; our $VERSION = '0.08'; __PACKAGE__->mk_accessors('template'); =head1 NAME Catalyst::View::Mason - Mason View Class =head1 SYNOPSIS # use the helper script/create.pl view Mason Mason # lib/MyApp/View/Mason.pm package MyApp::View::Mason; use base 'Catalyst::View::Mason'; __PACKAGE__->config->{DEBUG} = 'all'; __PACKAGE__->config->{comp_root} = '/path/to/comp_root'; __PACKAGE__->config->{data_dir} = '/path/to/data_dir'; 1; $c->forward('MyApp::View::Mason'); =head1 DESCRIPTION Want to use a Mason component in your views? No problem! Catalyst::View::Mason comes to the rescue. =head1 EXAMPLE From the Catalyst controller: $c->stash->{name} = 'Homer'; # Pass a scalar $c->stash->{extra_info} = { last_name => 'Simpson', children => [qw(Bart Lisa Maggie)] }; # A ref works too From the Mason template: <%args> $name $extra_info

Your name is <% $name %> <% $extra_info->{last_name} %>

Your children are:

=head1 CAVEATS You have to define C and C. If C is not directly defined within C, the value comes from C<$c-Econfig-E{root}>. If you don't define it at all, Mason is going to complain :) The default C is C. =head1 METHODS =cut sub new { my $self = shift; my $c = shift; $self = $self->NEXT::new(@_); $self->{output} = ''; my %config = ( comp_root => ( $c->config->{root} . '' ), data_dir => '/tmp', %{ $self->config() }, out_method => \$self->{output}, ); $self->template( HTML::Mason::Interp->new( %config, allow_globals => [qw($c $base $name)], ) ); return $self; } =head3 process Renders the component specified in $c->stash->{template} or $c->request->match to $c->response->body. Note that the component name must be absolute, or is converted to absolute (i.e., a / is added to the beginning if it doesn't start with one). Mason global variables C<$base>, C<$c>, and c<$name> are automatically set to the base, context, and name of the app, respectively. =cut sub process { my ( $self, $c ) = @_; my $component_path = $c->stash->{template} || $c->req->match; unless ($component_path) { $c->log->debug('No Mason component specified for rendering') if $c->debug; return 0; } unless ( $component_path =~ m[^/]o ) { $component_path = '/' . $component_path; } $c->log->debug(qq/Rendering component "$component_path"/) if $c->debug; # Set the URL base, context and name of the app as global Mason vars # $base, $c and $name $self->template->set_global(@$_) foreach ( [ '$base' => $c->req->base ], [ '$c' => $c ], [ '$name' => $c->config->{name} ] ); $self->{output} = ''; eval { $self->template->exec( $component_path, %{ $c->stash }, # pass the stash ); }; if ( my $error = $@ ) { chomp $error; $error = qq/Couldn't render component "$component_path" - error was "$error"/; $c->log->error($error); $c->error($error); return 0; } unless ( $c->response->content_type ) { $c->response->content_type('text/html;charset=utf8'); } $c->response->body( $self->{output} ); return 1; } =head3 config This allows your view subclass to pass additional settings to the Mason HTML::Mason::Interp->new constructor. =cut =head1 SEE ALSO L, L, "Using Mason from a Standalone Script" in L =head1 AUTHOR Andres Kievsky C Sebastian Riedel C Marcus Ramberg =head1 COPYRIGHT This program is free software, you can redistribute it and/or modify it under the same terms as Perl itself. =cut 1;