package Catalyst::View::TT;
use strict;
-use base qw/Catalyst::Base/;
+use base qw/Catalyst::View/;
use Template;
use Template::Timer;
use NEXT;
-our $VERSION = '0.15';
+our $VERSION = '0.20';
__PACKAGE__->mk_accessors('template');
+__PACKAGE__->mk_accessors('include_path');
=head1 NAME
# configure in lib/MyApp.pm
- our $ROOT = '/home/dent/catalyst/MyApp';
-
MyApp->config({
name => 'MyApp',
- root => $ROOT,
+ root => MyApp->path_to('root');,
'V::TT' => {
# any TT configurations items go here
INCLUDE_PATH => [
- "$ROOT/templates/src",
- "$ROOT/templates/lib"
+ MyApp->path_to( 'root', 'src' ),
+ MyApp->path_to( 'root', 'lib' ),
],
- PRE_PROCESS => 'config/main',
- WRAPPER => 'site/wrapper',
- TEMPLATE_SUFFIX => '.tt',
+ PRE_PROCESS => 'config/main',
+ WRAPPER => 'site/wrapper',
+ TEMPLATE_EXTENSION => '.tt',
# two optional config items
CATALYST_VAR => 'Catalyst',
use strict;
use base 'Catalyst::View::TT';
- our $ROOT = '/home/dent/catalyst/MyApp';
-
MyApp::V::TT->config({
- INCLUDE_PATH => ["$ROOT/templates/src", "$ROOT/templates/lib"],
+ INCLUDE_PATH => [
+ MyApp->path_to( 'root', 'templates', 'lib' ),
+ MyApp->path_to( 'root', 'templates', 'src' ),
+ ],
PRE_PROCESS => 'config/main',
WRAPPER => 'site/wrapper',
});
sub new {
my $self = shift;
$self->config({
- INCLUDE_PATH => ["$ROOT/templates/src", "$ROOT/templates/lib"],
+ INCLUDE_PATH => [
+ MyApp->path_to( 'root', 'templates', 'lib' ),
+ MyApp->path_to( 'root', 'templates', 'src' ),
+ ],
PRE_PROCESS => 'config/main',
WRAPPER => 'site/wrapper',
});
use strict;
use Catalyst;
- our $ROOT = '/home/dent/catalyst/MyApp';
-
MyApp->config({
name => 'MyApp',
- root => $ROOT,
+ root => MyApp->path_to('root'),
'V::TT' => {
- INCLUDE_PATH => ["$ROOT/templates/src", "$ROOT/templates/lib"],
+ INCLUDE_PATH => [
+ MyApp->path_to( 'root', 'templates', 'lib' ),
+ MyApp->path_to( 'root', 'templates', 'src' ),
+ ],
PRE_PROCESS => 'config/main',
WRAPPER => 'site/wrapper',
},
methods will be overwritten by items of the same name provided by the
latter methods.
+=head2 DYNAMIC INCLUDE_PATH
+
+It is sometimes needed to dynamically add additional paths to the
+INCLUDE_PATH variable of the template object. This can be done by setting
+'additional_include_paths' on stash to a referrence to an array with
+additional paths:
+
+ $c->stash->{additional_template_paths} = [$c->config->{root} . '/test_include_path'];
+
=head2 RENDERING VIEWS
The view plugin renders the template specified in the C<template>
=cut
-sub new {
- my ( $class, $c, $arguments ) = @_;
+sub _coerce_paths {
+ my ( $paths, $dlim ) = shift;
+ return () if ( !$paths );
+ return @{$paths} if ( ref $paths eq 'ARRAY' );
- my $root = $c->config->{root};
+ # tweak delim to ignore C:/
+ unless ( defined $dlim ) {
+ $dlim = ( $^O eq 'MSWin32' ) ? ':(?!\\/)' : ':';
+ }
+ return split( /$dlim/, $paths );
+}
+sub new {
+ my ( $class, $c, $arguments ) = @_;
my $config = {
- EVAL_PERL => 0,
+ EVAL_PERL => 0,
TEMPLATE_EXTENSION => '',
- INCLUDE_PATH => [ $root, "$root/base" ],
%{ $class->config },
- %{$arguments}
+ %{$arguments},
};
+ if ( ! (ref $config->{INCLUDE_PATH} eq 'ARRAY') ) {
+ my $delim = $config->{DELIMITER};
+ my @include_path
+ = _coerce_paths( $config->{INCLUDE_PATH}, $delim );
+ if ( !@include_path ) {
+ my $root = $c->config->{root};
+ my $base = Path::Class::dir( $root, 'base' );
+ @include_path = ( "$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
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 CONFIG is already defined'
+ );
}
else {
$config->{CONTEXT} = Template::Timer->new(%$config);
use Data::Dumper;
$c->log->debug( "TT Config: ", Dumper($config) );
}
+ if ( $config->{PROVIDERS} ) {
+ my @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});
+ }
+ }
+ }
+ delete $config->{PROVIDERS};
+ if(@providers) {
+ $config->{LOAD_TEMPLATES} = \@providers;
+ }
+ }
- return $class->NEXT::new(
+ 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);
return undef;
- }
- }
+ },
+ %{$config},
+ },
);
+ $self->include_path($config->{INCLUDE_PATH});
+ $self->config($config);
+
+ return $self;
}
=item process
sub process {
my ( $self, $c ) = @_;
- my $template = $c->stash->{template} || $c->request->match . $self->config->{TEMPLATE_EXTENSION};
+ my $template = $c->stash->{template}
+ || ( $c->request->match || $c->request->action )
+ . $self->config->{TEMPLATE_EXTENSION};
unless ($template) {
$c->log->debug('No template specified for rendering') if $c->debug;
$c->log->debug(qq/Rendering template "$template"/) if $c->debug;
my $output;
- my $cvar = $self->config->{CATALYST_VAR};
- my $vars = {
- defined $cvar
- ? ( $cvar => $c )
- : (
- c => $c,
- base => $c->req->base,
- name => $c->config->{name}
- ),
- %{ $c->stash() }
- };
+ 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"/;
$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 template_vars
+
+Returns a list of keys/values to be used as the variables in the
+template.
+
+=cut
+
+sub template_vars {
+ my ( $self, $c ) = @_;
+
+ my $cvar = $self->config->{CATALYST_VAR};
+
+ defined $cvar
+ ? ( $cvar => $c )
+ : (
+ 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
MyApp->config({
name => 'MyApp',
- root => $ROOT,
+ root => MyApp->path_to('root'),
'V::TT' => {
CATALYST_VAR => 'Catalyst',
},
<!-- TIMER END: process mainmenu/footer.tt (0.003016 seconds) -->
-=item C<TEMPLATE_SUFFIX>
+=item C<TEMPLATE_EXTENSION>
a sufix to add when looking for templates bases on the C<match> method in L<Catalyst::Request>.