@{ $c->view('TT')->include_path } = qw/path another_path/;
+If you are calling C<render> directly then you can specify dynamic paths by
+having a C<additional_include_paths> key with a value of additonal directories
+to search. See L<CAPTURING TEMPLATE OUTPUT> for an example showing this.
+
=head2 RENDERING VIEWS
The view plugin renders the template specified in the C<template>
}
If a class item isn't defined, then it instead uses the
-current match, as returned by C<$c-E<gt>match>. In the above
+current match, as returned by C<< $c->match >>. In the above
example, this would be C<message>.
The items defined in the stash are passed to the Template Toolkit for
use as template variables.
-sub message : Global {
sub default : Private {
my ( $self, $c ) = @_;
$c->stash->{template} = 'message.tt2';
The name is [% name %]
-The output generated by the template is stored in
-C<$c-E<gt>response-E<gt>output>.
+The output generated by the template is stored in C<< $c->response->body >>.
+
+=head2 CAPTURING TEMPLATE OUTPUT
+
+If you wish to use the output of a template for some other purpose than
+displaying in the response, e.g. for sending an email, this is possible using
+L<Catalyst::Plugin::Email> and the L<render> method:
+
+ sub send_email : Local {
+ my ($self, $c) = @_;
+
+ $c->email(
+ header => [
+ To => 'me@localhost',
+ Subject => 'A TT Email',
+ ],
+ body => $c->view('TT')->render($c, 'email.tt', {
+ additional_include_paths => [ $c->config->{root} . '/email_templates'],
+ email_tmpl_param1 => 'foo'
+ }
+ ),
+ );
+ # Redirect or display a message
+ }
=head2 TEMPLATE PROFILING
+See L<C<TIMER>> property of the L<config> method.
+
=head2 METHODS
=over 4
%{ $class->config },
%{$arguments},
};
- if ( ! (ref $config->{INCLUDE_PATH} eq 'ARRAY') ) {
+ if ( !( ref $config->{INCLUDE_PATH} eq 'ARRAY' ) ) {
my $delim = $config->{DELIMITER};
- my @include_path
- = _coerce_paths( $config->{INCLUDE_PATH}, $delim );
+ my @include_path = _coerce_paths( $config->{INCLUDE_PATH}, $delim );
if ( !@include_path ) {
my $root = $c->config->{root};
my $base = Path::Class::dir( $root, 'base' );
$config->{INCLUDE_PATH} = \@include_path;
}
-
-
# if we're debugging and/or the TIMER option is set, then we install
# Template::Timer as a custom CONTEXT object, but only if we haven't
# already got a custom CONTEXT defined
if ( $config->{TIMER} ) {
if ( $config->{CONTEXT} ) {
$c->log->error(
- 'Cannot use Template::Timer - a TT CONFIG is already defined'
+ 'Cannot use Template::Timer - a TT CONTEXT is already defined'
);
}
else {
}
if ( $config->{PROVIDERS} ) {
my @providers = ();
- if ( ref($config->{PROVIDERS}) eq 'ARRAY') {
- foreach my $p (@{$config->{PROVIDERS}}) {
+ if ( ref( $config->{PROVIDERS} ) eq 'ARRAY' ) {
+ foreach my $p ( @{ $config->{PROVIDERS} } ) {
my $pname = $p->{name};
eval "require Template::Provider::$pname";
- if(!$@) {
- push @providers, "Template::Provider::${pname}"->new($p->{args});
+ if ( !$@ ) {
+ push @providers,
+ "Template::Provider::${pname}"->new( $p->{args} );
}
}
}
delete $config->{PROVIDERS};
- if(@providers) {
+ if (@providers) {
$config->{LOAD_TEMPLATES} = \@providers;
}
}
my $self = $class->NEXT::new(
$c,
- { template => Template->new($config) || do {
+ {
+ template => Template->new($config) || do {
my $error = Template->error();
$c->log->error($error);
$c->error($error);
%{$config},
},
);
- $self->include_path($config->{INCLUDE_PATH});
+ $self->include_path( $config->{INCLUDE_PATH} );
$self->config($config);
return $self;
=item process
-Renders the template specified in C<$c-E<gt>stash-E<gt>{template}> or
-C<$c-E<gt>action> (the private name of the matched action.
-Template variables are set up from the contents of C<$c-E<gt>stash>,
-augmented with C<base> set to C<$c-E<gt>req-E<gt>base>, C<c> to C<$c> and
-C<name> to C<$c-E<gt>config-E<gt>{name}>. Alternately, the C<CATALYST_VAR>
-configuration item can be defined to specify the name of a template
-variable through which the context reference (C<$c>) can be accessed.
-In this case, the C<c>, C<base> and C<name> variables are omitted.
-Output is stored in C<$c-E<gt>response-E<gt>output>.
+Renders the template specified in C<< $c->stash->{template} >> or
+C<< $c->action >> (the private name of the matched action. Calls L<render> to
+perform actual rendering. Output is stored in C<< $c->response->body >>.
=cut
my ( $self, $c ) = @_;
my $template = $c->stash->{template}
- || $c->action . $self->config->{TEMPLATE_EXTENSION};
+ || $c->action . $self->config->{TEMPLATE_EXTENSION};
unless ($template) {
$c->log->debug('No template specified for rendering') if $c->debug;
return 0;
}
- $c->log->debug(qq/Rendering template "$template"/) if $c->debug;
+ my $output = $self->render( $c, $template );
- my $output;
- my $vars = { $self->template_vars($c) };
-
- unshift @{ $self->include_path },
- @{ $c->stash->{additional_template_paths} }
- if ref $c->stash->{additional_template_paths};
- unless ( $self->template->process( $template, $vars, \$output ) ) {
- my $error = $self->template->error;
- $error = qq/Couldn't render template "$error"/;
+ if ( (Scalar::Util::blessed($output)||'') eq 'Template::Exception' ) {
+ my $error = qq/Coldn't render template "$output"/;
$c->log->error($error);
$c->error($error);
return 0;
}
- splice @{ $self->include_path }, 0,
- scalar @{ $c->stash->{additional_template_paths} }
- if ref $c->stash->{additional_template_paths};
unless ( $c->response->content_type ) {
$c->response->content_type('text/html; charset=utf-8');
return 1;
}
+=item render($c, $template, \%args)
+
+Renders the given template and returns output, or a L<Template::Exception>
+object upon error.
+
+The template variables are set to C<%$args> if $args is a hashref, or
+$C<< $c->stash >> otherwise. In either case the variables are augmented with
+C<base> set to C< << $c->req->base >>, C<c> to C<$c> and C<name> to
+C<< $c->config->{name} >>. Alternately, the C<CATALYST_VAR> configuration item
+can be defined to specify the name of a template variable through which the
+context reference (C<$c>) can be accessed. In this case, the C<c>, C<base> and
+C<name> variables are omitted.
+
+C<$template> can be anything that Template::process understands how to
+process, including the name of a template file or a reference to a test string.
+See L<Template::process|Template/process> for a full list of supported formats.
+
+=cut
+
+sub render {
+ my ( $self, $c, $template, $args ) = @_;
+
+ $c->log->debug(qq/Rendering template "$template"/) if $c->debug;
+
+ my $output;
+ my $vars = {
+ ( ref $args eq 'HASH' ? %$args : %{ $c->stash() } ),
+ $self->template_vars($c)
+ };
+
+ local $self->{include_path} = $self->include_path;
+ unshift @{ $self->{include_path} }, @{ $vars->{additional_template_paths} }
+ if ref $c->stash->{additional_template_paths};
+
+ unless ( $self->template->process( $template, $vars, \$output ) ) {
+ return $self->template->error;
+ }
+ else {
+ return $output;
+ }
+}
+
=item template_vars
-Returns a list of keys/values to be used as the variables in the
+Returns a list of keys/values to be used as the catalyst variables in the
template.
=cut
c => $c,
base => $c->req->base,
name => $c->config->{name}
- ),
- %{ $c->stash() }
-
+ );
}
+
=item config
This method allows your view subclass to pass additional settings to