CGI-Application-Plugin-TT-1.05000755001750001750 011402112046 15073 5ustar00ceescees000000000000MANIFEST000444001750001750 126611402112046 16307 0ustar00ceescees000000000000CGI-Application-Plugin-TT-1.05Build.PL Changes lib/CGI/Application/Plugin/TT.pm Makefile.PL MANIFEST META.yml README t/01_basic.t t/02_error.t t/03_tname.t t/04_singleton.t t/05_include_path.t t/06_callback.t t/07_devpopup.t t/08_load_tmpl.t t/09_precompile_dir.t t/98_pod.t t/99_pod_coverage.t t/include1/TestAppIncludePath/test_mode.tmpl t/include2/TestAppIncludePath/test_mode.tmpl t/TestAppBase.pm t/TestAppBasic.pm t/TestAppCallback.pm t/TestAppDevPopup.pm t/TestAppError.pm t/TestAppIncludePath.pm t/TestAppLoadtmpl.pm t/TestAppPrecompile.pm t/TestAppSingleton.pm t/TestAppTName.pm t/TestAppTName/test.tmpl t/TestAppTName/test_mode.tmpl t/TestAppTName/NoNameNoVars/test_mode.tmpl t/TestAppTName/UpLevel/test_mode.tmpl Build.PL000444001750001750 107511402112046 16450 0ustar00ceescees000000000000CGI-Application-Plugin-TT-1.05use Module::Build; Module::Build->new( module_name => 'CGI::Application::Plugin::TT', license => 'perl', requires => { 'CGI::Application' => '4.0', 'Template' => '2.0', 'Scalar::Util' => 0, 'File::Spec' => 0, 'Class::ISA' => 0, }, recommends => { 'CGI::Application::Plugin::DevPopup' => 0, }, create_makefile_pl => 'traditional', dist_author => 'Cees Hek ', dist_abstract => 'Plugin that adds Template Toolkit support to CGI::Application', )->create_build_script; Makefile.PL000444001750001750 117511402112046 17127 0ustar00ceescees000000000000CGI-Application-Plugin-TT-1.05# Note: this file was auto-generated by Module::Build::Compat version 0.340201 use ExtUtils::MakeMaker; WriteMakefile ( 'NAME' => 'CGI::Application::Plugin::TT', 'VERSION_FROM' => 'lib/CGI/Application/Plugin/TT.pm', 'PREREQ_PM' => { 'CGI::Application' => '4.0', 'Class::ISA' => 0, 'File::Spec' => 0, 'Scalar::Util' => 0, 'Template' => '2.0' }, 'INSTALLDIRS' => 'site', 'EXE_FILES' => [], 'PL_FILES' => {} ) ; README000444001750001750 126211402112046 16032 0ustar00ceescees000000000000CGI-Application-Plugin-TT-1.05CGI::Application::Plugin::TT Add Template Toolkit support to CGI::Application INSTALLATION To install this module, run the following commands: perl Build.PL ./Build ./Build test ./Build install Alternatively, if you do not have Module::Build but you do have 'make', you can used the included Makefile.PL and run the following commands: perl Makefile.PL make make test make install DEPENDENCIES CGI::Application v4.0 Template Scalar::Util File::Spec Class::ISA COPYRIGHT AND LICENCE Copyright (C) 2005 Cees Hek, All Rights Reserved. This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. Changes000444001750001750 667011402112046 16455 0ustar00ceescees000000000000CGI-Application-Plugin-TT-1.05Revision history for Perl extension CGI::Application::Plugin::TT. 1.05 Fri Jun 4 14:25:49 EST 2010 - fix dev popup support by html encoding the data sent to the popup window (patch by Clayton L. Scott) - fix test failure on windows (patch by Alexandr Ciornii) 1.04 Wed Nov 1 07:08:50 EST 2006 - add TEMPLATE_PRECOMPILE_DIR option which can automatically compile all your templates on startup (patch by Michael Peters) - slightly refactored the default tt_template_name code - doc fix (Trammell Hudson/Robert Sedlacek) 1.03 Thu May 18 12:27:26 EDT 2006 - the default tt_template_name method now accepts a parameter that specifies how many caller levels we walk up (from the calling method) to find the method name to use as a base for the template name (defaults to 0) - a side effect of this change is that you can now pass any parameters you like to your custom TEMPLATE_NAME_GENERATOR method, when calling $self->tt_template_name(...). 1.02 Sun Feb 5 20:11:23 EST 2006 - Allow call to tt_process with no parameters (brad -at- footle.org) 1.01 Wed Jan 25 16:00:38 EST 2006 - Fix doc error in synopsis (Jonathan Anderson) - Before calling 'call_hook' make sure it exists - Update pod coverage tests 1.00 Wed Oct 19 14:11:22 EDT 2005 - added support for tt_include_path to return the current value of INCLUDE_PATH 0.10 Fri Sep 23 08:58:34 EDT 2005 - fix tests for DevPopup so it doesn't fail if it is not installed (Thanks to Jason Purdy and Rhesa Rozendaal) 0.09 Wed Sep 21 15:59:03 EDT 2005 - added support for the load_tmpl hook in CGI::App - added support for the DevPopup plugin - added pod coverage tests 0.08 Sun Jul 31 17:38:16 EDT 2005 - Made some small doc changes that I meant to put in the last release. 0.07 Sat Jul 30 9:18:46 EDT 2005 - fixed Windows path bug in test suite (Emanuele Zeppieri) - Simplify the pod tests according to Test::Pod docs - Support the new callback hooks in CGI::Application 4.0 - Automatically add { c => $self } to template params (see docs under DEFAULT PARAMETERS) - minor doc cleanups 0.06 Thu Feb 3 15:38:39 EST 2005 - Document use of tt_config as a class method for singleton support - Some other small documentation cleanups 0.05 Mon Jan 24 11:47:06 EST 2005 - add tt_template_name which autogenerates template filenames - tt_process will call tt_template_name if the template name is not provided as an arguement - add Singleton support for TT object 0.04 Fri Dec 3 12:02:56 EST 2004 - die if there is an error processing a template in tt_process 0.03 Sun Sep 19 18:13:03 EST 2004 - scrap CGI::Application::Plugin support for simple Exporter system. - Moved module to the CGI::Application::Plugin namespace. - module no longer depends on inheritance, so just use'ing the module will suffice to import the required methods into the current class. 0.02 Mon Jul 26 23:44:39 EST 2004 - add support for the new CGI::Application::Plugin base class. This means the usage has changed. Altering the inheritance tree is no longer necesary, as you only need to use the module and it will import the plugin methods into the callers namespace automatically. See the docs for more details... 0.01 Sun Feb 15 16:10:39 EST 2004 - original version META.yml000444001750001750 123611402112046 16424 0ustar00ceescees000000000000CGI-Application-Plugin-TT-1.05--- name: CGI-Application-Plugin-TT version: 1.05 author: - 'Cees Hek ' abstract: Plugin that adds Template Toolkit support to CGI::Application license: perl resources: license: http://dev.perl.org/licenses/ requires: CGI::Application: 4.0 Class::ISA: 0 File::Spec: 0 Scalar::Util: 0 Template: 2.0 recommends: CGI::Application::Plugin::DevPopup: 0 configure_requires: Module::Build: 0.340201 provides: CGI::Application::Plugin::TT: file: lib/CGI/Application/Plugin/TT.pm version: 1.05 generated_by: Module::Build version 0.340201 meta-spec: url: http://module-build.sourceforge.net/META-spec-v1.4.html version: 1.4 t000755001750001750 011402112046 15257 5ustar00ceescees000000000000CGI-Application-Plugin-TT-1.05TestAppIncludePath.pm000444001750001750 104111402112046 21447 0ustar00ceescees000000000000CGI-Application-Plugin-TT-1.05/tpackage TestAppIncludePath; use strict; use base qw(CGI::Application); use CGI::Application::Plugin::TT ( TEMPLATE_OPTIONS => { POST_CHOMP => 1, DEBUG => 1, }, ); sub setup { my $self = shift; $self->start_mode('test_mode'); $self->run_modes(test_mode => 'test_mode' ); } sub test_mode { my $self = shift; my $path = $ENV{TT_INCLUDE_PATH}; $self->tt_include_path([$path]); return $self->tt_process({ include_path => $path }); } 1; 99_pod_coverage.t000444001750001750 24111402112046 20534 0ustar00ceescees000000000000CGI-Application-Plugin-TT-1.05/tuse Test::More; eval "use Test::Pod::Coverage 1.00"; plan skip_all => "Test::Pod::Coverage 1.00 required for testing POD coverage" if $@; all_pod_coverage_ok(); TestAppTName.pm000444001750001750 470211402112046 20262 0ustar00ceescees000000000000CGI-Application-Plugin-TT-1.05/tpackage TestAppTName; use strict; use base qw(TestAppBase); sub test_mode { my $self = shift; $self->tt_params(template_param_hash => 'template param hash'); $self->tt_params({template_param_hashref => 'template param hashref'}); my $tt_vars = { template_var => 'template param', template_name => $self->tt_template_name, }; return $self->tt_process($tt_vars); } sub tt_pre_process { my $self = shift; my $file = shift; my $vars = shift; $vars->{pre_process_var} = 'pre_process param'; } sub tt_post_process { my $self = shift; my $htmlref = shift; $$htmlref =~ s/post_process_var/post_process param/; } package TestAppTName::CustName; use strict; use TestAppTName; @TestAppTName::CustName::ISA = qw(TestAppTName); sub cgiapp_init { my $self = shift; $self->tt_config( TEMPLATE_OPTIONS => { INCLUDE_PATH => 't', POST_CHOMP => 1, DEBUG => 1, }, TEMPLATE_NAME_GENERATOR => sub { return 'TestAppTName/test.tmpl' }, ); } package TestAppTName::NoVars; use strict; @TestAppTName::NoVars::ISA = qw(TestAppTName); sub test_mode { my $self = shift; $self->tt_params(template_param_hash => 'template param hash'); $self->tt_params({template_param_hashref => 'template param hashref'}); return $self->tt_process('TestAppTName/test_mode.tmpl'); } package TestAppTName::NoNameNoVars; use strict; @TestAppTName::NoNameNoVars::ISA = qw(TestAppTName); sub test_mode { my $self = shift; $self->tt_params(template_param_hash => 'template param hash'); $self->tt_params({template_param_hashref => 'template param hashref'}); return $self->tt_process; } package TestAppTName::UpLevel; use strict; @TestAppTName::UpLevel::ISA = qw(TestAppTName); sub test_mode { my $self = shift; $self->tt_params(template_param_hash => 'template param hash'); $self->tt_params({template_param_hashref => 'template param hashref'}); my $tt_vars = { template_var => 'template param', template_name => $self->call_tt_template_name, }; return $self->call_tt_process($tt_vars); } sub call_tt_process { my $self = shift; return $self->tt_process($self->tt_template_name(1), @_); } sub call_tt_template_name { my $self = shift; return $self->tt_template_name(1); } 1; TestAppBasic.pm000444001750001750 151611402112046 20277 0ustar00ceescees000000000000CGI-Application-Plugin-TT-1.05/tpackage TestAppBasic; use strict; use base qw(TestAppBase); sub test_mode { my $self = shift; $self->tt_params(template_param_hash => 'template param hash.'); $self->tt_params({template_param_hashref => 'template param hashref.'}); my $tt_vars = { template_var => 'template param.' }; return $self->tt_process(\*DATA, $tt_vars); } sub tt_pre_process { my $self = shift; my $file = shift; my $vars = shift; $vars->{pre_process_var} = 'pre_process param.'; } sub tt_post_process { my $self = shift; my $htmlref = shift; $$htmlref =~ s/post_process_var/post_process param./; } 1; # The test template file is below in the DATA segment __DATA__ [% template_var %] [% template_param_hash %] [% template_param_hashref %] [% pre_process_var %] post_process_var 06_callback.t000444001750001750 103311402112046 17637 0ustar00ceescees000000000000CGI-Application-Plugin-TT-1.05/tuse Test::More tests => 5; use lib './t'; use strict; $ENV{CGI_APP_RETURN_ONLY} = 1; use CGI; use TestAppCallback; my $t1_obj = TestAppCallback->new(); my $t1_output = $t1_obj->run(); like($t1_output, qr/template param\./, 'template parameter'); like($t1_output, qr/template param hash\./, 'template parameter hash'); like($t1_output, qr/template param hashref\./, 'template parameter hashref'); like($t1_output, qr/pre_process param\./, 'pre process parameter'); like($t1_output, qr/post_process param\./, 'post process parameter'); 03_tname.t000444001750001750 455011402112046 17213 0ustar00ceescees000000000000CGI-Application-Plugin-TT-1.05/tuse Test::More tests => 27; use lib './t'; use strict; $ENV{CGI_APP_RETURN_ONLY} = 1; use TestAppTName; my $t1_obj = TestAppTName->new(); my $t1_output = $t1_obj->run(); like($t1_output, qr/file: test_mode\.tmpl/, 'correct template file'); like($t1_output, qr/:template param:/, 'template parameter'); like($t1_output, qr/:template param hash:/, 'template parameter hash'); like($t1_output, qr/:template param hashref:/, 'template parameter hashref'); like($t1_output, qr/:pre_process param:/, 'pre process parameter'); like($t1_output, qr/:post_process param:/, 'post process parameter'); like($t1_output, qr/:TestAppTName[\/\\]test_mode\.tmpl:/, 'template name ok'); my $t2_obj = TestAppTName::CustName->new(); my $t2_output = $t2_obj->run(); like($t2_output, qr/file: test\.tmpl/, 'correct template file'); like($t2_output, qr/:template param:/, 'template parameter'); like($t2_output, qr/:template param hash:/, 'template parameter hash'); like($t2_output, qr/:template param hashref:/, 'template parameter hashref'); like($t2_output, qr/:pre_process param:/, 'pre process parameter'); like($t2_output, qr/:post_process param:/, 'post process parameter'); like($t2_output, qr/:TestAppTName[\/\\]test\.tmpl:/, 'template name ok'); my $t3_obj = TestAppTName::NoVars->new(); my $t3_output = $t3_obj->run(); like($t3_output, qr/file: test_mode\.tmpl/, 'correct template file'); like($t3_output, qr/:pre_process param:/, 'pre process parameter'); like($t3_output, qr/:post_process param:/, 'post process parameter'); my $t4_obj = TestAppTName::NoNameNoVars->new(); my $t4_output = $t4_obj->run(); like($t4_output, qr/file: test_mode\.tmpl/, 'correct template file'); like($t4_output, qr/:pre_process param:/, 'pre process parameter'); like($t4_output, qr/:post_process param:/, 'post process parameter'); my $t5_obj = TestAppTName::UpLevel->new(); my $t5_output = $t5_obj->run(); like($t5_output, qr/file: test_mode\.tmpl/, 'correct template file'); like($t5_output, qr/:template param:/, 'template parameter'); like($t5_output, qr/:template param hash:/, 'template parameter hash'); like($t5_output, qr/:template param hashref:/, 'template parameter hashref'); like($t5_output, qr/:pre_process param:/, 'pre process parameter'); like($t5_output, qr/:post_process param:/, 'post process parameter'); like($t5_output, qr/:TestAppTName[\/\\]UpLevel[\/\\]test_mode\.tmpl:/, 'template name ok'); 05_include_path.t000444001750001750 151211402112046 20543 0ustar00ceescees000000000000CGI-Application-Plugin-TT-1.05/tuse Test::More; use lib './t'; use strict; eval { require Class::ISA; Class::ISA->import; }; if ($@) { plan skip_all => "Class::ISA required for Singleton support"; exit; } plan tests => 5; $ENV{CGI_APP_RETURN_ONLY} = 1; use TestAppIncludePath; $ENV{TT_INCLUDE_PATH} = 't/include1'; my $t1_obj = TestAppIncludePath->new(); my $t1_output = $t1_obj->run(); like($t1_output, qr/include path: t\/include1/, 'include path'); like($t1_output, qr/template dir: include1/, 'template dir'); $ENV{TT_INCLUDE_PATH} = 't/include2'; my $t2_obj = TestAppIncludePath->new(); my $t2_output = $t2_obj->run(); like($t2_output, qr/include path: t\/include2/, 'include path second time'); like($t2_output, qr/template dir: include2/, 'template dir second time'); is_deeply($t1_obj->tt_include_path, [qw[t/include2]],'returns current paths'); TestAppPrecompile.pm000444001750001750 71611402112046 21336 0ustar00ceescees000000000000CGI-Application-Plugin-TT-1.05/tpackage TestAppPrecompile; use strict; use base qw(TestAppBase); sub cgiapp_init { my $self = shift; $self->tt_config( TEMPLATE_OPTIONS => { INCLUDE_PATH => $self->param('TT_DIR'), ABSOLUTE => 1, }, TEMPLATE_PRECOMPILE_DIR => $self->param('TT_DIR'), TEMPLATE_PRECOMPILE_FILETEST => $self->param('TEMPLATE_PRECOMPILE_FILETEST'), ); } 1; TestAppDevPopup.pm000444001750001750 65211402112046 21000 0ustar00ceescees000000000000CGI-Application-Plugin-TT-1.05/tpackage TestAppDevPopup; use strict; use base qw(TestAppBase); use CGI::Application::Plugin::DevPopup; sub test_mode { my $self = shift; my $tt_vars = { template_var => 'template param.', html_var => '
' }; return $self->tt_process(\*DATA, $tt_vars); } 1; # The test template file is below in the DATA segment __DATA__ [% template_var %] TestAppLoadtmpl.pm000444001750001750 110211402112046 21021 0ustar00ceescees000000000000CGI-Application-Plugin-TT-1.05/tpackage TestAppLoadtmpl; use strict; use base qw(TestAppBase); __PACKAGE__->add_callback('load_tmpl', sub { my $self = shift; my $options = shift; my $vars = shift; my $file = shift; $vars->{load_tmpl_var} = 'load_tmpl param.'; } ); sub test_mode { my $self = shift; my $tt_vars = { template_var => 'template param.' }; return $self->tt_process(\*DATA, $tt_vars); } 1; # The test template file is below in the DATA segment __DATA__ [% template_var %] [% load_tmpl_var %] TestAppBase.pm000444001750001750 73411402112046 20111 0ustar00ceescees000000000000CGI-Application-Plugin-TT-1.05/tpackage TestAppBase; use strict; use base qw(CGI::Application); use CGI::Application::Plugin::TT; sub cgiapp_init { my $self = shift; $self->tt_config( TEMPLATE_OPTIONS => { INCLUDE_PATH => 't', POST_CHOMP => 1, DEBUG => 1, }, ); } sub setup { my $self = shift; $self->start_mode('test_mode'); $self->run_modes(test_mode => 'test_mode' ); } 1; 07_devpopup.t000444001750001750 123611402112046 17753 0ustar00ceescees000000000000CGI-Application-Plugin-TT-1.05/tuse Test::More; use lib './t'; use strict; BEGIN { $ENV{CAP_DEVPOPUP_EXEC} = 1; eval { require CGI::Application::Plugin::DevPopup; }; if ($@) { plan skip_all => "CGI::Application::Plugin::DevPopup required for these tests"; exit; } } plan tests => 3; $ENV{CGI_APP_RETURN_ONLY} = 1; use CGI; use TestAppDevPopup; my $t1_obj = TestAppDevPopup->new(); my $t1_output = $t1_obj->run(); like($t1_output, qr/template param\./, 'template parameter'); like($t1_output, qr/<div class="test"><\/div>/, 'HTML tags were encoded as entities'); like($t1_output, qr/TT params for/, 'popup title found'); 04_singleton.t000444001750001750 152011402112046 20104 0ustar00ceescees000000000000CGI-Application-Plugin-TT-1.05/tuse Test::More; use lib './t'; use strict; eval { require Class::ISA; Class::ISA->import; }; if ($@) { plan skip_all => "Class::ISA required for Singleton support"; exit; } plan tests => 6; $ENV{CGI_APP_RETURN_ONLY} = 1; use TestAppSingleton; my $t1_obj = TestAppSingleton->new(); my $t1_output = $t1_obj->run(); like($t1_output, qr/template param\./, 'template parameter'); like($t1_output, qr/template param hash\./, 'template parameter hash'); like($t1_output, qr/template param hashref\./, 'template parameter hashref'); like($t1_output, qr/pre_process param\./, 'pre process parameter'); like($t1_output, qr/post_process param\./, 'post process parameter'); # make sure the CGI::Application instance is destroyed, and then check for TT object undef $t1_obj; ok(ref($TestAppSingleton::__TT_OBJECT), 'singleton still exists'); 09_precompile_dir.t000444001750001750 307511402112046 21113 0ustar00ceescees000000000000CGI-Application-Plugin-TT-1.05/tuse strict; use lib './t'; use Test::More tests => 6; use TestAppPrecompile; use File::Spec::Functions qw(catdir catfile rel2abs); # get a temp directory that we can later look into # to find the pre-compiled templates my $tt_dir = catdir('t', 'include1', 'TestAppIncludePath'); my $file = rel2abs(catfile($tt_dir, 'test_mode.tmpl')); test_success('tmpl'); test_success(qr/\.(tt|tmpl|html)$/); test_success(sub { rel2abs($_[0]) eq $file }); test_failure('nottmpl'); test_failure(qr/\.(nottmpl)$/); test_failure(sub { rel2abs($_[0]) eq 'blahblah' }); sub test_success { my $cgiapp = TestAppPrecompile->new(PARAMS => { TEMPLATE_PRECOMPILE_FILETEST => shift, TT_DIR => $tt_dir, }); my $tt = $cgiapp->tt_obj; # make sure we have this internally cached in our TT obj # This is kinda dirty since we are peeking pretty far into TT's internals # but it doesn't expose this stuff externally is( rel2abs($tt->{SERVICE}->{CONTEXT}->{LOAD_TEMPLATES}->[0]->{HEAD}->[1]), $file, 'file is cached' ); } sub test_failure { my $cgiapp = TestAppPrecompile->new(PARAMS => { TEMPLATE_PRECOMPILE_FILETEST => shift, TT_DIR => $tt_dir, }); my $tt = $cgiapp->tt_obj; # make sure we have this internally cached in our TT obj # This is kinda dirty since we are peeking pretty far into TT's internals # but it doesn't expose this stuff externally is( $tt->{SERVICE}->{CONTEXT}->{LOAD_TEMPLATES}->[0]->{HEAD}->[1], undef, 'file is not cached' ); } TestAppSingleton.pm000444001750001750 230511402112046 21215 0ustar00ceescees000000000000CGI-Application-Plugin-TT-1.05/tpackage TestAppSingleton; use strict; use base qw(CGI::Application); use CGI::Application::Plugin::TT; TestAppSingleton->tt_config( TEMPLATE_OPTIONS => { INCLUDE_PATH => 't', POST_CHOMP => 1, DEBUG => 1, }, ); sub setup { my $self = shift; $self->start_mode('test_mode'); $self->run_modes(test_mode => 'test_mode' ); } sub test_mode { my $self = shift; $self->tt_params(template_param_hash => 'template param hash.'); $self->tt_params({template_param_hashref => 'template param hashref.'}); my $tt_vars = { template_var => 'template param.' }; return $self->tt_process(\*DATA, $tt_vars); } sub tt_pre_process { my $self = shift; my $file = shift; my $vars = shift; $vars->{pre_process_var} = 'pre_process param.'; } sub tt_post_process { my $self = shift; my $htmlref = shift; $$htmlref =~ s/post_process_var/post_process param./; } 1; # The test template file is below in the DATA segment __DATA__ [% template_var %] [% template_param_hash %] [% template_param_hashref %] [% pre_process_var %] post_process_var 01_basic.t000444001750001750 111311402112046 17156 0ustar00ceescees000000000000CGI-Application-Plugin-TT-1.05/tuse Test::More tests => 6; BEGIN { require_ok('CGI::Application::Plugin::TT') }; use lib './t'; use strict; $ENV{CGI_APP_RETURN_ONLY} = 1; use CGI; use TestAppBasic; my $t1_obj = TestAppBasic->new(); my $t1_output = $t1_obj->run(); like($t1_output, qr/template param\./, 'template parameter'); like($t1_output, qr/template param hash\./, 'template parameter hash'); like($t1_output, qr/template param hashref\./, 'template parameter hashref'); like($t1_output, qr/pre_process param\./, 'pre process parameter'); like($t1_output, qr/post_process param\./, 'post process parameter'); TestAppError.pm000444001750001750 55711402112046 20333 0ustar00ceescees000000000000CGI-Application-Plugin-TT-1.05/tpackage TestAppError; use strict; use base qw(TestAppBase); sub test_mode { my $self = shift; my $tt_vars = { unclosed_if => 'unclosed if' }; return $self->tt_process(\*DATA, $tt_vars); } 1; # The test template file is below in the DATA segment __DATA__ [% IF unclosed_if %] [% unclosed_if %] testing invalid template 08_load_tmpl.t000444001750001750 47311402112046 20047 0ustar00ceescees000000000000CGI-Application-Plugin-TT-1.05/tuse Test::More tests => 2; use lib './t'; use strict; $ENV{CGI_APP_RETURN_ONLY} = 1; use CGI; use TestAppLoadtmpl; my $t1_obj = TestAppLoadtmpl->new(); my $t1_output = $t1_obj->run(); like($t1_output, qr/template param\./, 'template parameter'); like($t1_output, qr/load_tmpl param\./, 'load_tmpl parameter'); 98_pod.t000444001750001750 20111402112046 16654 0ustar00ceescees000000000000CGI-Application-Plugin-TT-1.05/tuse Test::More; eval "use Test::Pod 1.00"; plan skip_all => "Test::Pod 1.00 required for testing POD" if $@; all_pod_files_ok(); TestAppCallback.pm000444001750001750 167711402112046 20762 0ustar00ceescees000000000000CGI-Application-Plugin-TT-1.05/tpackage TestAppCallback; use strict; use base qw(TestAppBase); __PACKAGE__->add_callback('tt_pre_process', sub { my $self = shift; my $file = shift; my $vars = shift; $vars->{pre_process_var} = 'pre_process param.'; } ); __PACKAGE__->add_callback('tt_post_process', sub { my $self = shift; my $htmlref = shift; $$htmlref =~ s/post_process_var/post_process param./; } ); sub test_mode { my $self = shift; $self->tt_params(template_param_hash => 'template param hash.'); $self->tt_params({template_param_hashref => 'template param hashref.'}); my $tt_vars = { template_var => 'template param.' }; return $self->tt_process(\*DATA, $tt_vars); } 1; # The test template file is below in the DATA segment __DATA__ [% template_var %] [% template_param_hash %] [% template_param_hashref %] [% pre_process_var %] post_process_var 02_error.t000444001750001750 36411402112046 17216 0ustar00ceescees000000000000CGI-Application-Plugin-TT-1.05/tuse Test::More tests => 1; use lib './t'; use strict; $ENV{CGI_APP_RETURN_ONLY} = 1; use CGI; use TestAppError; my $t1_obj = TestAppError->new(); my $t1_output = eval { $t1_obj->run() }; like($@, qr/parse error/, 'template parse error'); include2000755001750001750 011402112046 16764 5ustar00ceescees000000000000CGI-Application-Plugin-TT-1.05/tTestAppIncludePath000755001750001750 011402112046 22465 5ustar00ceescees000000000000CGI-Application-Plugin-TT-1.05/t/include2test_mode.tmpl000444001750001750 7011402112046 25440 0ustar00ceescees000000000000CGI-Application-Plugin-TT-1.05/t/include2/TestAppIncludePathinclude path: [% include_path %] template dir: include2 TestAppTName000755001750001750 011402112046 17564 5ustar00ceescees000000000000CGI-Application-Plugin-TT-1.05/ttest_mode.tmpl000444001750001750 24611402112046 22564 0ustar00ceescees000000000000CGI-Application-Plugin-TT-1.05/t/TestAppTNamefile: test_mode.tmpl :[% template_var %]: :[% template_param_hash %]: :[% template_param_hashref %]: :[% pre_process_var %]: :post_process_var: :[% template_name %]: test.tmpl000444001750001750 24111402112046 21553 0ustar00ceescees000000000000CGI-Application-Plugin-TT-1.05/t/TestAppTNamefile: test.tmpl :[% template_var %]: :[% template_param_hash %]: :[% template_param_hashref %]: :[% pre_process_var %]: :post_process_var: :[% template_name %]: NoNameNoVars000755001750001750 011402112046 22072 5ustar00ceescees000000000000CGI-Application-Plugin-TT-1.05/t/TestAppTNametest_mode.tmpl000444001750001750 24611402112046 25072 0ustar00ceescees000000000000CGI-Application-Plugin-TT-1.05/t/TestAppTName/NoNameNoVarsfile: test_mode.tmpl :[% template_var %]: :[% template_param_hash %]: :[% template_param_hashref %]: :[% pre_process_var %]: :post_process_var: :[% template_name %]: UpLevel000755001750001750 011402112046 21140 5ustar00ceescees000000000000CGI-Application-Plugin-TT-1.05/t/TestAppTNametest_mode.tmpl000444001750001750 24611402112046 24140 0ustar00ceescees000000000000CGI-Application-Plugin-TT-1.05/t/TestAppTName/UpLevelfile: test_mode.tmpl :[% template_var %]: :[% template_param_hash %]: :[% template_param_hashref %]: :[% pre_process_var %]: :post_process_var: :[% template_name %]: include1000755001750001750 011402112046 16763 5ustar00ceescees000000000000CGI-Application-Plugin-TT-1.05/tTestAppIncludePath000755001750001750 011402112046 22464 5ustar00ceescees000000000000CGI-Application-Plugin-TT-1.05/t/include1test_mode.tmpl000444001750001750 7011402112046 25437 0ustar00ceescees000000000000CGI-Application-Plugin-TT-1.05/t/include1/TestAppIncludePathinclude path: [% include_path %] template dir: include1 lib000755001750001750 011402112046 15562 5ustar00ceescees000000000000CGI-Application-Plugin-TT-1.05CGI000755001750001750 011402112046 16164 5ustar00ceescees000000000000CGI-Application-Plugin-TT-1.05/libApplication000755001750001750 011402112046 20427 5ustar00ceescees000000000000CGI-Application-Plugin-TT-1.05/lib/CGIPlugin000755001750001750 011402112046 21665 5ustar00ceescees000000000000CGI-Application-Plugin-TT-1.05/lib/CGI/ApplicationTT.pm000444001750001750 7440211402112046 22736 0ustar00ceescees000000000000CGI-Application-Plugin-TT-1.05/lib/CGI/Application/Pluginpackage CGI::Application::Plugin::TT; use Template 2.0; use CGI::Application 4.0; use Carp; use File::Spec (); use Scalar::Util (); use strict; use vars qw($VERSION @EXPORT); $VERSION = '1.05'; require Exporter; @EXPORT = qw( tt_obj tt_config tt_params tt_clear_params tt_process tt_include_path tt_template_name ); sub import { my $pkg = shift; my $callpkg = caller; no strict 'refs'; foreach my $sym (@EXPORT) { *{"${callpkg}::$sym"} = \&{$sym}; } $callpkg->tt_config(@_) if @_; if ($callpkg->isa('CGI::Application')) { $callpkg->new_hook('tt_pre_process'); $callpkg->new_hook('tt_post_process'); } else { warn "Calling package is not a CGI::Application module so not installing tt_pre_process and tt_post_process hooks. If you are using \@ISA instead of 'use base', make sure it is in a BEGIN { } block, and make sure these statements appear before the plugin is loaded"; } } ############################################## ### ### tt_obj ### ############################################## # # Get a Template Toolkit object. The same object # will be returned everytime this method is called # during a request cycle. # sub tt_obj { my $self = shift; my ($tt, $options, $frompkg) = _get_object_or_options($self); if (!$tt) { my $tt_options = $options->{TEMPLATE_OPTIONS}; if (keys %{$options->{TEMPLATE_OPTIONS}}) { $tt = Template->new( $options->{TEMPLATE_OPTIONS} ) || carp "Can't load Template"; } else { $tt = Template->new || carp "Can't load Template"; } _set_object($frompkg||$self, $tt); } return $tt; } ############################################## ### ### tt_config ### ############################################## # # Configure the Template Toolkit object # sub tt_config { my $self = shift; my $class = ref $self ? ref $self : $self; my $tt_config; if (ref $self) { die "Calling tt_config after the tt object has already been created" if @_ && defined $self->{__TT}; $tt_config = $self->{__TT_CONFIG} ||= {}; } else { no strict 'refs'; ${$class.'::__TT_CONFIG'} ||= {}; $tt_config = ${$class.'::__TT_CONFIG'}; } if (@_) { my $props; if (ref($_[0]) eq 'HASH') { my $rthash = %{$_[0]}; $props = CGI::Application->_cap_hash($_[0]); } else { $props = CGI::Application->_cap_hash({ @_ }); } my %options; # Check for TEMPLATE_OPTIONS if ($props->{TEMPLATE_OPTIONS}) { carp "tt_config error: parameter TEMPLATE_OPTIONS is not a hash reference" if Scalar::Util::reftype($props->{TEMPLATE_OPTIONS}) ne 'HASH'; $tt_config->{TEMPLATE_OPTIONS} = delete $props->{TEMPLATE_OPTIONS}; } # Check for TEMPLATE_NAME_GENERATOR if ($props->{TEMPLATE_NAME_GENERATOR}) { carp "tt_config error: parameter TEMPLATE_NAME_GENERATOR is not a subroutine reference" if Scalar::Util::reftype($props->{TEMPLATE_NAME_GENERATOR}) ne 'CODE'; $tt_config->{TEMPLATE_NAME_GENERATOR} = delete $props->{TEMPLATE_NAME_GENERATOR}; } # Check for TEMPLATE_PRECOMPILE_FILETEST if ($props->{TEMPLATE_PRECOMPILE_FILETEST}) { carp "tt_config error: parameter TEMPLATE_PRECOMPILE_FILETEST is not a subroutine reference or regexp or string" if defined Scalar::Util::reftype($props->{TEMPLATE_PRECOMPILE_FILETEST}) && Scalar::Util::reftype($props->{TEMPLATE_PRECOMPILE_FILETEST}) ne 'CODE' && overload::StrVal($props->{TEMPLATE_PRECOMPILE_FILETEST}) !~ /^Regexp=/; $tt_config->{TEMPLATE_PRECOMPILE_FILETEST} = delete $props->{TEMPLATE_PRECOMPILE_FILETEST}; } # This property must be tested last, since it creates the TT object in order to # preload all the templates. # # Check for TEMPLATE_PRECOMPILE_DIR if( $props->{TEMPLATE_PRECOMPILE_DIR} ) { my $type = Scalar::Util::reftype($props->{TEMPLATE_PRECOMPILE_DIR}); carp "tt_config error: parameter TEMPLATE_PRECOMPILE_DIR must be a SCALAR or an ARRAY ref" unless( !defined($type) or $type eq 'ARRAY' ); # now look at each file and my @dirs = ($type && $type eq 'ARRAY') ? @{$props->{TEMPLATE_PRECOMPILE_DIR}} : ($props->{TEMPLATE_PRECOMPILE_DIR}); delete $props->{TEMPLATE_PRECOMPILE_DIR}; my $tt = $self->tt_obj; my $junk = ''; my $filetester = sub { 1 }; if ($tt_config->{TEMPLATE_PRECOMPILE_FILETEST}) { if (! defined Scalar::Util::reftype($tt_config->{TEMPLATE_PRECOMPILE_FILETEST})) { $filetester = sub { $_[0] =~ /\.$tt_config->{TEMPLATE_PRECOMPILE_FILETEST}$/ }; } elsif (Scalar::Util::reftype($tt_config->{TEMPLATE_PRECOMPILE_FILETEST}) eq 'CODE') { $filetester = $tt_config->{TEMPLATE_PRECOMPILE_FILETEST}; } elsif (overload::StrVal($tt_config->{TEMPLATE_PRECOMPILE_FILETEST}) =~ /^Regexp=/) { $filetester = sub { $_[0] =~ $tt_config->{TEMPLATE_PRECOMPILE_FILETEST} }; } } require File::Find; File::Find::find( sub { my $file = $File::Find::name; return unless $filetester->($file); if( !-d $file ) { $tt->process( $file, {}, \$junk ); } }, map { File::Spec->rel2abs($_) } @dirs, ); } # If there are still entries left in $props then they are invalid carp "Invalid option(s) (".join(', ', keys %$props).") passed to tt_config" if %$props; } $tt_config; } ############################################## ### ### tt_params ### ############################################## # # Set some parameters that will be added to # any template object we process in this # request cycle. # sub tt_params { my $self = shift; my @data = @_; # Define the params stash if it doesn't exist $self->{__TT_PARAMS} ||= {}; if (@data) { my $params = $self->{__TT_PARAMS}; my $newparams = {}; if (ref $data[0] eq 'HASH') { # hashref %$newparams = %{ $data[0] }; } elsif ( (@data % 2) == 0 ) { %$newparams = @data; } else { carp "tt_params requires a hash or hashref!"; } # merge the new values into our stash of parameters @$params{keys %$newparams} = values %$newparams; } return $self->{__TT_PARAMS}; } ############################################## ### ### tt_clear_params ### ############################################## # # Clear any template parameters that may have # been set during this request cycle. # sub tt_clear_params { my $self = shift; my $params = $self->{__TT_PARAMS}; $self->{__TT_PARAMS} = {}; return $params; } ############################################## ### ### tt_pre_process ### ############################################## # # Sample method that is called just before # a Template is processed. # Useful for setting global template params. # It is passed the template filename and the hashref # of template data # sub tt_pre_process { my $self = shift; my $file = shift; my $vars = shift; # Do your pre-processing here } ############################################## ### ### tt_post_process ### ############################################## # # Sample method that is called just after # a Template is processed. # Useful for post processing the HTML. # It is passed a scalar reference to the HTML code. # # Note: This could also be accomplished using the # cgiapp_postrun method, except that this # method is called after every template is # processed (you could process multiple # templates in one request), whereas # 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{
$dump
}, ); return; } 1; __END__ =head1 NAME CGI::Application::Plugin::TT - Add Template Toolkit support to CGI::Application =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 modules by providing several helper methods that allow you to process template files from within your runmodes. It compliments the support for L that is built into L through the B 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 accepts zero, one or two parameters; an optional template filename, and an optional hashref of template parameters (the template filename is optional, and will be autogenerated by a call to $self->tt_template_name if not provided). The return value will be a scalar reference to the output of the template. package My::App::Browser sub myrunmode { my $self = shift; return $self->tt_process( 'Browser/myrunmode.tmpl', { foo => 'bar' } ); } sub myrunmode2 { my $self = shift; return $self->tt_process( { foo => 'bar' } ); # will process template 'My/App/Browser/myrunmode2.tmpl' } =head2 tt_config This method can be used to customize the functionality of the CGI::Application::Plugin::TT module, and the Template Toolkit module that it wraps. The recommended place to call C is as a class method in the global scope of your module (See SINGLETON SUPPORT for an explanation of why this is a good idea). If this method is called after a call to tt_process or tt_obj, then it will die with an error message. It is not a requirement to call this method, as the module will work without any configuration. However, most will find it useful to set at least a path to the location of the template files ( or you can set the path later using the tt_include_path method). our $TEMPLATE_OPTIONS = { COMPILE_DIR => '/tmp/tt_cache', DEFAULT => 'notfound.tmpl', PRE_PROCESS => 'defaults.tmpl', }; __PACKAGE__->tt_config( TEMPLATE_OPTIONS => $TEMPLATE_OPTIONS ); The following parameters are accepted: =over 4 =item TEMPLATE_OPTIONS This allows you to customize how the L