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.13';
+our $VERSION = '0.15';
__PACKAGE__->mk_accessors('template');
# configure in lib/MyApp.pm
- our $ROOT = '/home/dent/catalyst/MyApp';
-
MyApp->config({
name => 'MyApp',
- root => $ROOT,
- 'MyApp::V::TT' => {
+ 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',
# two optional config items
CATALYST_VAR => 'Catalyst',
# render view from lib/MyApp.pm or lib/MyApp::C::SomeController.pm
sub message : Global {
- my ($self, $c) = @_;
- $c->stash->{ template } = 'message.tt2';
- $c->stash->{ message } = 'Hello World!';
+ my ( $self, $c ) = @_;
+ $c->stash->{template} = 'message.tt2';
+ $c->stash->{message} = 'Hello World!';
$c->forward('MyApp::V::TT');
}
# In MyApp or MyApp::Controller::SomeController
sub end : Private {
- my($self, $c) = @_;
+ my( $self, $c ) = @_;
$c->forward('MyApp::V::TT');
}
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',
});
return $self->NEXT::new(@_);
}
-The final, and perhaps most direct way, is to define a C<template>
+The final, and perhaps most direct way, is to define a class
item in your main application configuration, again by calling the
-uniquitous C<config()> method. The items in the C<template> hash are
+uniquitous C<config()> method. The items in the class hash are
added to those already defined by the above two methods. This happens
in the base class new() method (which is one reason why you must
remember to call it via C<NEXT> if you redefine the C<new()> method in a
use strict;
use Catalyst;
- our $ROOT = '/home/dent/catalyst/MyApp';
-
MyApp->config({
name => 'MyApp',
- root => $ROOT,
- 'MyApp::V::TT' => {
- INCLUDE_PATH => ["$ROOT/templates/src", "$ROOT/templates/lib"],
+ root => MyApp->path_to('root'),
+ 'V::TT' => {
+ INCLUDE_PATH => [
+ MyApp->path_to( 'root', 'templates', 'lib' ),
+ MyApp->path_to( 'root', 'templates', 'src' ),
+ ],
PRE_PROCESS => 'config/main',
WRAPPER => 'site/wrapper',
},
item in the stash.
sub message : Global {
- my ($self, $c) = @_;
- $c->stash->{ template } = 'message.tt2';
+ my ( $self, $c ) = @_;
+ $c->stash->{template} = 'message.tt2';
$c->forward('MyApp::V::TT');
}
-If a C<template> item isn't defined, then it instead uses the
+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
example, this would be C<message>.
sub message : Global {
sub default : Private {
- my ($self, $c) = @_;
- $c->stash->{ template } = 'message.tt2';
- $c->stash->{ message } = 'Hello World!';
+ my ( $self, $c ) = @_;
+ $c->stash->{template} = 'message.tt2';
+ $c->stash->{message} = 'Hello World!';
$c->forward('MyApp::V::TT');
}
The base is [% base %]
The name is [% name %]
-If you prefer, you can set the C<CATALYST_VAR> configuration item to
-define the name of a template variable through which the context can
-be referenced.
-
- MyApp->config({
- name => 'MyApp',
- root => $ROOT,
- 'MyApp::V::TT' => {
- CATALYST_VAR => 'Catalyst',
- },
- });
-
-F<message.tt2>:
-
- The base is [% Catalyst.req.base %]
- The name is [% Catalyst.config.name %]
The output generated by the template is stored in
C<$c-E<gt>response-E<gt>output>.
=head2 TEMPLATE PROFILING
-If you have configured Catalyst for debug output,
-C<Catalyst::View::TT> will enable profiling of template processing
-(using L<Template::Timer>). This will embed HTML comments in the
-output from your templates, such as:
-
- <!-- TIMER START: process mainmenu/mainmenu.ttml -->
- <!-- TIMER START: include mainmenu/cssindex.tt -->
- <!-- TIMER START: process mainmenu/cssindex.tt -->
- <!-- TIMER END: process mainmenu/cssindex.tt (0.017279 seconds) -->
- <!-- TIMER END: include mainmenu/cssindex.tt (0.017401 seconds) -->
-
- ....
-
- <!-- TIMER END: process mainmenu/footer.tt (0.003016 seconds) -->
-
-You can suppress template profiling by setting the C<TIMER> configuration
-item to a false value.
-
- MyApp->config({
- 'MyApp::V::TT' => {
- TIMER => 0,
- },
- });
-
=head2 METHODS
=over 4
my $root = $c->config->{root};
- my %config = (
- EVAL_PERL => 0,
- INCLUDE_PATH => [ $root, "$root/base" ],
+ my $config = {
+ EVAL_PERL => 0,
+ TEMPLATE_EXTENSION => '',
+ INCLUDE_PATH => [ $root, "$root/base" ],
%{ $class->config },
%{$arguments}
- );
+ };
# 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} || ( $c->debug() && !exists $config{TIMER} ) ) {
- if ( $config{CONTEXT} ) {
+ if ( $config->{TIMER} ) {
+ if ( $config->{CONTEXT} ) {
$c->log->error(
'Cannot use Template::Timer - a TT CONFIG is already defined');
}
else {
- $config{CONTEXT} = Template::Timer->new( \%config );
+ $config->{CONTEXT} = Template::Timer->new(%$config);
}
}
- if ( $c->debug && $config{DUMP_CONFIG} ) {
+ if ( $c->debug && $config->{DUMP_CONFIG} ) {
use Data::Dumper;
- $c->log->debug( "TT Config: ", Dumper( \%config ) );
+ $c->log->debug( "TT Config: ", Dumper($config) );
}
return $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);
sub process {
my ( $self, $c ) = @_;
- my $template = $c->stash->{template} || $c->request->match;
+ my $template = $c->stash->{template}
+ || $c->request->match . $self->config->{TEMPLATE_EXTENSION};
unless ($template) {
$c->log->debug('No template specified for rendering') if $c->debug;
=item config
This method allows your view subclass to pass additional settings to
-the TT configuration hash, or to set the C<CATALYST_VAR> and C<TIMER>
-options.
+the TT configuration hash, or to set the options as below:
+
+=over 2
+
+=item C<CATALYST_VAR>
+
+Allows you to change the name of the Catalyst context object. If set, it will also
+remove the base and name aliases, so you will have access them through <context>.
+
+For example:
+
+ MyApp->config({
+ name => 'MyApp',
+ root => MyApp->path_to('root'),
+ 'V::TT' => {
+ CATALYST_VAR => 'Catalyst',
+ },
+ });
+
+F<message.tt2>:
+
+ The base is [% Catalyst.req.base %]
+ The name is [% Catalyst.config.name %]
+
+=item C<TIMER>
+
+If you have configured Catalyst for debug output, and turned on the TIMER setting,
+C<Catalyst::View::TT> will enable profiling of template processing
+(using L<Template::Timer>). This will embed HTML comments in the
+output from your templates, such as:
+
+ <!-- TIMER START: process mainmenu/mainmenu.ttml -->
+ <!-- TIMER START: include mainmenu/cssindex.tt -->
+ <!-- TIMER START: process mainmenu/cssindex.tt -->
+ <!-- TIMER END: process mainmenu/cssindex.tt (0.017279 seconds) -->
+ <!-- TIMER END: include mainmenu/cssindex.tt (0.017401 seconds) -->
+
+ ....
+
+ <!-- TIMER END: process mainmenu/footer.tt (0.003016 seconds) -->
+
+
+=item C<TEMPLATE_SUFFIX>
+
+a sufix to add when looking for templates bases on the C<match> method in L<Catalyst::Request>.
+
+For example:
+
+ package MyApp::C::Test;
+ sub test : Local { .. }
+
+Would by default look for a template in <root>/test/test. If you set TEMPLATE_EXTENSION to '.tt', it will look for
+<root>/test/test.tt.
+
+=back
=back
L<Catalyst>, L<Catalyst::Helper::View::TT>,
L<Catalyst::Helper::View::TTSite>, L<Template::Manual>
-=head1 AUTHOR
+=head1 AUTHORS
Sebastian Riedel, C<sri@cpan.org>
+
Marcus Ramberg, C<mramberg@cpan.org>
+
Jesse Sheidlower, C<jester@panix.com>
+
Andy Wardley, C<abw@cpan.org>
=head1 COPYRIGHT