The CGI::Application documentation proposes a solution that makes sense :
override 'load_tmpl( )' method to behave however you want it to.
FROM THE POD:
-------------
If your application requires more specialized behavior than this, you are
encoraged[sic] to override load_tmpl() by implementing your own load_tmpl()
in your CGI::Application sub-class application module.
-------------
Here at O'Neil, we search through a list of 6-10 dynamic template locations
looking for the file we need, and everywhere we need a file we call
'load_tmpl( 'my_tmpl.html' );' and our 'load_tmpl( )' method finds the
correct template for us.
Also, wouldn't this patch break existing implementations?
Thanks,
Cory Trese
Lead Web Application Developer
O'NEIL & ASSOCIATES, INC.
495 Byers Rd.
Miamisburg, Ohio 45342-3662
Phone: (937) 865-0800 ext. 3038
Fax: (937) 865-5858
E-mail: suppressed
-----Original Message-----
From: Chris Brooks [mailto:suppressed
Sent: Wednesday, April 09, 2003 1:17 PM
To: suppressed
Subject: [cgiapp] Proposed patch to CGI::Application
Hi all,
I would like to propose the following patch for inclusion in
CGI::Application. Essentially, the patch gives you a new interface to
the @extra_params array that is passed to HTML::Template::new_file from
CGI::Application::load_tmpl. It allows you to push a path onto the
end of this array, instead of unshifting it onto the beginning (the
current default behavior).
Here's the scenario that I needed it for:
I have an application (call it MyApp) that subclasses CGI::Application.
The application has 7 templates that are displayed in the various run
modes. I have several clients that use the application, and each client
is allowed to define customized text to appear on each of the 7
templates. The directory structure for the templates is as follows:
/path/to/templates/
|_ default/
|_ tmpl_a.tmpl
|_ ...
|_ tmpl_g.tmpl
|_ client_1/
|_ tmpl_d.tmpl
|_ ...
|_ client_n/
|_ tmpl_a.tmpl
|_ ...
|_ tmpl_g.tmpl
All clients access MyApp through myscript.pl, and myscript.pl figures
out which template directory the client wants, and passes the path to
that directory as a param to new():
my $app = MyApp->new( TMPL_PATH => $path_to_directory );
The trick is that if client_1 does not have custom text for a particular
template, I don't duplicate the template -- I just fall back to the
template with the same name in the default directory. Consider the
scenario where an end user for client_1 requests the template
tmpl_a.tmpl. This patch allows me to define the "fall back" or default
directory in the setup() method with a single additional method call,
like this:
$self->default_tmpl_path( '/path/to/templates/default' );
Now, when load_tmpl() calls HTML::Template::new_file(), it passes two
directories:
/path/to/templates/client_1
/path/to/templates/default
HTML::Template will look for tmpl_a.tmpl in client_1/ and if it isn't
present, it will use the version in default/.
I could have implemented this by passing the default path as part of the
@extra_params array that gets passed to load_tmpl(), but this seems
redundant (and potentially error prone, since you need to manually
maintain the correct order in the arrayref that you pass to load_tmpl()
-- in 7 places, in my case). The patch that follows allows me to define
this directory in one place, and be done with it.
Thoughts?
(I did a context diff to generate the patch, so there's quite a bit of
text. I did a minimal patch to the documentation as well, and there is
a brief test script at the end.)
Thanks,
Chris
*** /usr/lib/perl5/site_perl/5.005/CGI/Application.pm Sat Feb 1
02:46:11 2003
--- CGI/Application.pm Wed Apr 9 09:38:21 2003
***************
*** 325,344 ****
my $self = shift;
my ($tmpl_file, @extra_params) = @_;
! # add tmpl_path to path array of one is set, otherwise add a
path arg
! if (my $tmpl_path = $self->tmpl_path) {
! my $found = 0;
! for( my $x = 0; $x < @extra_params; $x += 2 ) {
! if ($extra_params[$x] eq 'path' and
! ref $extra_params[$x+1] and
! ref $extra_params[$x+1] eq 'ARRAY') {
! unshift @{$extra_params[$x+1]}, $tmpl_path;
! $found = 1;
! last;
! }
! }
! push(@extra_params, path => [ $tmpl_path ]) unless $found;
! }
require HTML::Template;
my $t = HTML::Template->new_file($tmpl_file, @extra_params);
--- 325,331 ----
my $self = shift;
my ($tmpl_file, @extra_params) = @_;
! @extra_params = $self->munge_extra_params( @extra_params );
require HTML::Template;
my $t = HTML::Template->new_file($tmpl_file, @extra_params);
***************
*** 347,352 ****
--- 334,362 ----
}
+ #I have split this out into its own method to simplify testing
+
+ sub munge_extra_params {
+ my $self = shift;
+ my %extra_params = @_;
+ my $default_tmpl = $self->default_tmpl_path();
+
+ # add tmpl_path to path array of one is set, otherwise add a path arg
+ if (my $tmpl_path = $self->tmpl_path) {
+ if ( ref $extra_params{ 'path' } eq 'ARRAY' ) {
+ unshift @{ $extra_params{ 'path' } }, $tmpl_path;
+ push @{ $extra_params{ 'path' } }, $default_tmpl;
+ }
+ else { $extra_params{ 'path' } = [ $tmpl_path, $default_tmpl ] }
+ }
+ else {
+ if ( ref $extra_params{ 'path' } eq 'ARRAY' ) { push @{
$extra_params{ 'path' } }, $default_tmpl }
+ else { $extra_params{ 'path' } = [ $default_tmpl ] }
+ }
+ return %extra_params;
+ }
+
+
sub mode_param {
my $self = shift;
my ($mode_param) = @_;
***************
*** 488,493 ****
--- 498,520 ----
}
+ sub default_tmpl_path {
+ my $self = shift;
+ my ($default_path) = @_;
+
+ # First use? Create new __DEFAULT_TMPL_PATH!
+ $self->{__DEFAULT_TMPL_PATH} = '' unless
(exists($self->{__DEFAULT_TMPL_PATH}));
+
+ # If data is provided, set it!
+ if (defined($default_path)) {
+ $self->{__DEFAULT_TMPL_PATH} = $default_path;
+ }
+
+ # If we've gotten this far, return the value!
+ return $self->{__DEFAULT_TMPL_PATH};
+ }
+
+
sub prerun_mode {
my $self = shift;
my ($prerun_mode) = @_;
***************
*** 899,904 ****
--- 926,932 ----
start_mode() - text scalar containing the default run mode.
run_modes() - hash table containing mode => function mappings.
tmpl_path() - text scalar containing path to template files.
+ default_tmpl_path() - text scalar containing path to default
template files.
Your setup() method may call any of the instance methods of your
application.
This function is a good place to define properties specific to your
application
***************
*** 909,914 ****
--- 937,943 ----
sub setup {
my $self = shift;
$self->tmpl_path('/path/to/my/templates/');
+ $self->default_tmpl_path('/path/to/default/templates/');
$self->start_mode('putform');
$self->run_modes({
'putform' => 'my_putform_func',
***************
*** 1109,1117 ****
is used for create the object. Refer to L<HTML::Template> for specific
usage
of HTML::Template.
! If tmpl_path() has been specified, load_tmpl() will set the
! HTML::Template C<path> option to the path provided. This further
! assists in encapsulating template usage.
The load_tmpl() method will pass any extra paramaters sent to it
directly to
HTML::Template->new_file(). This will allow the HTML::Template object
to be
--- 1138,1149 ----
is used for create the object. Refer to L<HTML::Template> for specific
usage
of HTML::Template.
! If tmpl_path() has been specified, load_tmpl() will unshift this value
onto
! the beginning of the array of paths passed to the HTML::Template
C<path> option.
! If you want to push a path onto the end of the array of paths passed
to the
! HTML::Template C<path> option, call default_tmpl_path() in your setup()
! method and pass it your default path. This further assists in
encapsulating
! template usage.
The load_tmpl() method will pass any extra paramaters sent to it
directly to
HTML::Template->new_file(). This will allow the HTML::Template object
to be
======================================
And here is the test script that I'm running to make sure that
munge_tmpl_path() returns correctly:
#!/usr/bin/perl
use lib qw( . );
use strict;
use Test::More tests => 12;
BEGIN { use_ok( 'CGI::Application' ) }
my $default_path = '/www/perl/templates/';
my $app = CGI::Application->new;
isa_ok( $app, 'CGI::Application' );
is( $app->default_tmpl_path( $default_path ), $default_path, 'Checking
that default_tmpl_path() returns correctly' );
undef $app;
#Test by passing TMPL_PATH to new(), with no conflicts
$app = CGI::Application->new( TMPL_PATH => $default_path );
my %extra_params = $app->munge_extra_params;
is( $extra_params{ path }->[0], $default_path, 'Checking
munge_extra_params()' );
undef $app;
#Test with no params to new(), but calling default_tmpl_path()
$app = CGI::Application->new;
$app->default_tmpl_path( $default_path );
my %extra_params = $app->munge_extra_params;
is( $extra_params{ path }->[0], $default_path, 'Checking
munge_extra_params()' );
undef $app;
#Test with a default path and a path specified through new()
my $new_path = '/www/perl/templates/different';
my $app = CGI::Application->new( TMPL_PATH => $new_path, );
$app->default_tmpl_path( $default_path );
%extra_params = $app->munge_extra_params;
is( $extra_params{ path }->[0], $new_path, 'Checking
munge_extra_params()' );
is( $extra_params{ path }->[1], $default_path, 'Checking
munge_extra_params()' );
undef $app;
#Test by passing a path to load_tmpl as part of @extra_params
my $app = CGI::Application->new;
$app->default_tmpl_path( $default_path );
%extra_params = $app->munge_extra_params( path => [ $new_path ] );
is( $extra_params{ path }->[0], $new_path, 'Checking
munge_extra_params()' );
is( $extra_params{ path }->[1], $default_path, 'Checking
munge_extra_params()' );
undef $app;
#Test by passing a path to load_tmpl as part of @extra_params
my $yadp = '/www/perl/templates/yet_another_different_path/';
my $app = CGI::Application->new( TMPL_PATH => $new_path );
$app->default_tmpl_path( $default_path );
%extra_params = $app->munge_extra_params( path => [ $yadp ] );
is( $extra_params{ path }->[0], $new_path, 'Checking
munge_extra_params()' );
is( $extra_params{ path }->[1], $yadp, 'Checking munge_extra_params()' );
is( $extra_params{ path }->[2], $default_path, 'Checking
munge_extra_params()' );
undef $app;
---------------------------------------------------------------------
Web Archive: http://www.mail-archive.com/suppressed/
To unsubscribe, e-mail: suppressed
For additional commands, e-mail: suppressed
---------------------------------------------------------------------
Web Archive: http://www.mail-archive.com/suppressed/
To unsubscribe, e-mail: suppressed
For additional commands, e-mail: suppressed
Mail converted by mhonarc 2.6.15
This archive provided courtesy of JSW4.NET, Internet Hosting Services for Small Business.