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 )