CGI-Application-Plugin-TT
view release on metacpan or search on metacpan
lib/CGI/Application/Plugin/TT.pm view on Meta::CPAN
# cgiapp_postrun is only called once after
# the runmode has completed.
#
sub tt_post_process {
my $self = shift;
my $htmlref = shift;
# Do your post-processing here
}
##############################################
###
### tt_process
###
##############################################
#
# Process a Template Toolkit template and return
# the resulting html as a scalar ref
#
sub tt_process {
my $self = shift;
my $file = shift;
my $vars = shift;
my $html = '';
my $can_call_hook = UNIVERSAL::can($self, 'call_hook') ? 1 : 0;
if (! defined($vars) && (Scalar::Util::reftype($file)||'') eq 'HASH') {
$vars = $file;
$file = undef;
}
$file ||= $self->tt_template_name(1);
$vars ||= {};
my $template_name = $file;
# Call the load_tmpl hook that is part of CGI::Application
$self->call_hook(
'load_tmpl',
{}, # template options are ignored
$vars,
$file,
) if $can_call_hook;
# Call tt_pre_process hook
$self->tt_pre_process($file, $vars) if $self->can('tt_pre_process');
$self->call_hook('tt_pre_process', $file, $vars) if $can_call_hook;
# Include any parameters that may have been
# set with tt_params
my %params = ( %{ $self->tt_params() }, %$vars );
# Add c => $self in as a param for convenient access to sessions and such
$params{c} ||= $self;
$self->tt_obj->process($file, \%params, \$html) || croak $self->tt_obj->error();
# Call tt_post_process hook
$self->tt_post_process(\$html) if $self->can('tt_post_process');
$self->call_hook('tt_post_process', \$html) if $can_call_hook;
_tt_add_devpopup_info($self, $template_name, \%params);
return \$html;
}
##############################################
###
### tt_include_path
###
##############################################
#
# Change the include path after the template object
# has already been created
#
sub tt_include_path {
my $self = shift;
return $self->tt_obj->context->load_templates->[0]->include_path unless(@_);
$self->tt_obj->context->load_templates->[0]->include_path(ref($_[0]) ? $_[0] : [@_]);
return;
}
##############################################
###
### tt_template_name
###
##############################################
#
# Auto-generate the filename of a template based on
# the current module, and the name of the
# function that called us.
#
sub tt_template_name {
my $self = shift;
my ($tt, $options, $frompkg) = _get_object_or_options($self);
my $func = $options->{TEMPLATE_NAME_GENERATOR} || \&__tt_template_name;
return $self->$func(@_);
}
##############################################
###
### __tt_template_name
###
##############################################
#
# Generate the filename of a template based on
# the current module, and the name of the
# function that called us.
#
# example:
# module $self is blessed into: My::Module
# function name that called us: my_function
#
# generates: My/Module/my_function.tmpl
#
sub __tt_template_name {
my $self = shift;
my $uplevel = shift || 0;
# the directory is based on the object's package name
my $dir = File::Spec->catdir(split(/::/, ref($self)));
# the filename is the method name of the caller plus
# whatever offset the user asked for
(caller(2+$uplevel))[3] =~ /([^:]+)$/;
my $name = $1;
return File::Spec->catfile($dir, $name.'.tmpl');
}
##
## Private methods
##
sub _set_object {
my $self = shift;
my $tt = shift;
my $class = ref $self ? ref $self : $self;
if (ref $self) {
$self->{__TT_OBJECT} = $tt;
} else {
no strict 'refs';
${$class.'::__TT_OBJECT'} = $tt;
}
}
sub _get_object_or_options {
my $self = shift;
my $class = ref $self ? ref $self : $self;
# Handle the simple case by looking in the object first
if (ref $self) {
return ($self->{__TT_OBJECT}, $self->{__TT_CONFIG}) if $self->{__TT_OBJECT};
return (undef, $self->{__TT_CONFIG}) if $self->{__TT_CONFIG};
}
# See if we can find them in the class hierarchy
# We look at each of the modules in the @ISA tree, and
# their parents as well until we find either a tt
# object or a set of configuration parameters
require Class::ISA;
foreach my $super ($class, Class::ISA::super_path($class)) {
no strict 'refs';
return (${$super.'::__TT_OBJECT'}, ${$super.'::__TT_CONFIG'}, $super) if ${$super.'::__TT_OBJECT'};
return (undef, ${$super.'::__TT_CONFIG'}, $super) if ${$super.'::__TT_CONFIG'};
}
return;
}
##############################################
###
### _tt_add_devpopup_info
###
##############################################
#
# This method will look to see if the devpopup
# plugin is being used, and will display all the
# parameters that were passed to the template.
#
sub _tt_add_devpopup_info {
my $self = shift;
my $name = shift;
my $params = shift;
return unless UNIVERSAL::can($self, 'devpopup');
my %params = %$params;
foreach my $key (keys %params) {
if (my $class = Scalar::Util::blessed($params{$key})) {
$params{$key} = "Object:$class";
}
}
require Data::Dumper;
my $dumper = Data::Dumper->new([\%params]);
$dumper->Varname('Params');
$dumper->Indent(2);
my $dump = $dumper->Dump();
# Entity encode the output since it will be displayed on a webpage and we
# want all HTML content rendered as text (borrowed from HTML::Entities)
$dump =~ s/([^\n\r\t !\#\$%\(-;=?-~])/sprintf "&#x%X;", ord($1)/ge;
$self->devpopup->add_report(
title => "TT params for $name",
summary => "All template parameters passed to template $name",
report => qq{<div style="font-size: 80%"><pre>$dump</pre></div>},
);
return;
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
CGI::Application::Plugin::TT - Plugin that adds Template Toolkit support to CGI::Application
=head1 VERSION
version 1.06
=head1 SYNOPSIS
use base qw(CGI::Application);
use CGI::Application::Plugin::TT;
sub myrunmode {
my $self = shift;
my %params = (
email => 'email@company.com',
menu => [
{ title => 'Home', href => '/home.html' },
{ title => 'Download', href => '/download.html' },
],
session_obj => $self->session,
);
return $self->tt_process('template.tmpl', \%params);
}
=head1 DESCRIPTION
CGI::Application::Plugin::TT adds support for the popular Template Toolkit engine
to your L<CGI::Application> modules by providing several helper methods that
allow you to process template files from within your runmodes.
It compliments the support for L<HTML::Template> that is built into L<CGI::Application>
through the B<load_tmpl> method. It also provides a few extra features than just the ability
to load a template.
=head1 METHODS
=head2 tt_process
This is a simple wrapper around the Template Toolkit process method. It
( run in 1.433 second using v1.01-cache-2.11-cpan-364913b4093 )