File Coverage

blib/lib/CGI/Application/Plugin/HTDot.pm
Criterion Covered Total %
statement 31 39 79.4
branch 12 22 54.5
condition 1 3 33.3
subroutine 4 4 100.0
pod 1 1 100.0
total 49 69 71.0


line stmt bran cond sub pod time code
1             package CGI::Application::Plugin::HTDot;
2              
3 4     4   112612 use strict;
  4         9  
  4         1044  
4              
5             =head1 NAME
6              
7             CGI::Application::Plugin::HTDot - Enable "magic dot" notation in
8             L-derived applications that use L for their
9             templating mechanism.
10              
11             =head1 VERSION
12              
13             Version 0.07
14              
15             =cut
16              
17             $CGI::Application::Plugin::HTDot::VERSION = '0.07';
18              
19             =head1 SYNOPSIS
20              
21             # In your CGI::Application-derived base class. . .
22             use base ("CGI::Application::Plugin::HTDot", "CGI::Application");
23              
24             # Later, in a run mode far, far away. . .
25             sub view {
26             my $self = shift;
27             my $username = $self->query->param( 'user' );
28             my $user = My::Users->retrieve( $username );
29              
30             my $tmpl_view = $self->load_tmpl( 'view_user.tmpl' );
31              
32             # The magic happens here! Pass our Class::DBI object
33             # to the template and display it
34             $tmpl_view->param( user => $user );
35              
36             return $tmpl_view->output;
37             }
38              
39             =head1 DESCRIPTION
40              
41             Imagine this: you've written a lot of code based upon L, and
42             also with L because the two have always had such a high level
43             of integration. You reach a situation (many times, perhaps) where you could
44             really use the power and convenience of being able to pass objects to your
45             templates and call methods of those objects from within your template (ala
46             Template Toolkit), but your development schedule doesn't give you the time
47             to learn (much less migrate to!) Template Toolkit or AnyTemplate. Well, you
48             need fret no more! C helps you bring the
49             power of the magic dot to your L-based templates from within
50             your L-derived webapps.
51              
52             L provides the glue between
53             L, L and
54             L. It overrides the C method
55             provided with L and replaces it with one that turns on the
56             magic dot in L. The C method provided here is
57             100% compatible with the one found in a stock L app, so
58             using this plugin does not require refactoring of any code. You can use the
59             magic dot in your application and templates going forward, and refactor older
60             code to use it as your schedule permits.
61              
62             When you have lots of apps and lots of templates, and no means to switch to
63             Template Toolkit, this will make your life infinitely easier.
64              
65             For more information about the magic dot, see L.
66              
67             As of version 4.31 of L< CGI::Application >, you can use the
68             C< html_tmpl_class() > method as an alternative to this plugin. TIMTOWTDI.
69              
70             =head1 METHODS
71              
72             =head2 load_tmpl()
73              
74             For the most part, this is the exact C method from
75             L, except it uses L and
76             L instead of L.
77              
78             See the L reference for more detailed information
79             on what parameters can be passed to C.
80              
81             =cut
82              
83             sub load_tmpl {
84 5     5 1 2640 my $self = shift;
85 5         14 my ( $tmpl_file, @extra_params ) = @_;
86              
87             # Add tmpl_path to path array if one is set, otherwise add a path arg
88 5 50       21 if (my $tmpl_path = $self->tmpl_path) {
89 5 50       72 my @tmpl_paths = (ref $tmpl_path eq 'ARRAY') ? @$tmpl_path : $tmpl_path;
90 5         11 my $found = 0;
91 5         21 for( my $x = 0; $x < @extra_params; $x += 2 ) {
92 1 50 33     8 if ($extra_params[$x] eq 'path' and
93             ref $extra_params[$x+1] eq 'ARRAY') {
94 0         0 unshift @{$extra_params[$x+1]}, @tmpl_paths;
  0         0  
95 0         0 $found = 1;
96 0         0 last;
97             }
98             }
99 5 50       34 push( @extra_params, path => [ @tmpl_paths ] ) unless $found;
100             }
101              
102 5         14 my %tmpl_params = ();
103 5         15 my %ht_params = @extra_params;
104 5 50       18 %ht_params = () unless keys %ht_params;
105              
106             # Define our extension if one doesn't already exist
107 5 50       26 $self->{__CURRENT_TMPL_EXTENSION} = '.html' unless defined $self->{__CURRENT_TMPL_EXTENSION};
108              
109             # Define a default template name based on the current run mode
110 5 50       17 unless (defined $tmpl_file) {
111 0         0 $tmpl_file = $self->get_current_runmode . $self->{__CURRENT_TMPL_EXTENSION};
112             }
113              
114 5         23 $self->call_hook('load_tmpl', \%ht_params, \%tmpl_params, $tmpl_file);
115              
116             # This is really where the magic occurs. We replace HTML::Template with
117             # the magic-dot enabled version, and the rest really works itself out.
118 4     4   3654 use HTML::Template::Pluggable;
  4         99355  
  4         137  
119 4     4   4282 use HTML::Template::Plugin::Dot;
  4         106473  
  4         28  
120              
121             # Check $tmpl_file and see what kind of parameter it is:
122             # - scalar (filename)
123             # - ref to scalar (the actual html/template content)
124             # - reference to filehandle
125 5         133 my $t = undef;
126 5 50       30 if ( ref $tmpl_file eq 'SCALAR' ) {
    50          
127 0         0 $t = HTML::Template::Pluggable->new_scalar_ref( $tmpl_file, %ht_params );
128             }
129             elsif ( ref $tmpl_file eq 'GLOB' ) {
130 0         0 $t = HTML::Template::Pluggable->new_filehandle( $tmpl_file, %ht_params );
131             }
132             else {
133 5         67 $t = HTML::Template::Pluggable->new_file( $tmpl_file, %ht_params );
134             }
135              
136 5 50       3109 if ( keys %tmpl_params ) {
137 0         0 $t->param( %tmpl_params );
138             }
139              
140             # Pass the CGI::Application object to the template (if it's being referenced
141             # somewhere in the template...)
142 5         36 my @vars = $t->query;
143 5         95 foreach my $var ( @vars ) {
144 6 100       2260 $t->param( c => $self ) if $var =~ /^c\./;
145             }
146              
147             # Give the user back their template
148 5         1484 return $t;
149             }
150              
151             =head2 Extending load_tmpl()
152              
153             There are times when the basic C functionality just isn't
154             enough. Many L developers set C to C<0>
155             on all of their templates. The easiest way to do this is by replacing or
156             extending the functionality of L's C method.
157             This is still possible using the plugin.
158              
159             The following code snippet illustrates one possible way of achieving this:
160              
161             sub load_tmpl {
162             my ($self, $tmpl_file, @extra_params) = @_;
163              
164             push @extra_params, "die_on_bad_params", "0";
165             push @extra_params, "cache", "1";
166              
167             return $self->SUPER::load_tmpl($tmpl_file, @extra_params);
168             }
169              
170             This plugin honors the C callback. Any C-based
171             callbacks you have created will be executed as intended:
172              
173             =head1 DEFAULT PARAMETERS
174              
175             By default, this plugin will automatically add a parameter 'c' to your
176             template that will return your L object. This will allow
177             you to access any methods in your application from within your template.
178             This allows for some powerful actions in your templates. For example, your
179             templates can access query parameters, or if you use the excellent
180             L module, you can access session parameters:
181              
182             Hello !
183              
184             Reload this page
185              
186             Another useful plugin that can use this feature is the
187             L plugin, which gives easy access to
188             the F JavaScript library:
189              
190            
191             Extra Info
192            
193              
194             With this extra flexibility comes some responsibilty as well. It could lead
195             down a dangerous path if you start making alterations to your object from
196             within the template. For example you could call c.header_add to add new
197             outgoing headers, but that is something that should be left in your code,
198             not in your template. Try to limit yourself to pulling in information into
199             your templates (like the session example above does).
200              
201             This plugin will respect your current C setting. If
202             C is set to C<1> and your template does not use 'c', the
203             plugin will not attempt to pass the L object to your
204             template. In other words, it does not force your application to set
205             C to C<0> to accomplish this action.
206              
207             =head1 AUTHOR
208              
209             Jason A. Crome, C<< >>
210              
211             =head1 BUGS
212              
213             Please report any bugs or feature requests to
214             C, or through the web interface at
215             L.
216             I will be notified, and then you'll automatically be notified of progress on
217             your bug as I make changes.
218              
219             =head1 ACKNOWLEDGMENTS
220              
221             Thanks and credit needs to be given to Jesse Erlbaum and Mark Stosberg for the
222             original C method that this is based on, to Rhesa Rozendaal and
223             Mark Stosberg for their work on enabling the magic dot in L,
224             Cees Hek for his idea (and tutorial on how) to use multiple inheritance to
225             make this plugin work, and to the usual crowd in #cgiapp on irc.perl.org for
226             making this all worthwhile for me :)
227              
228             An extra special thanks to Cees Hek for the inspiration, code, and examples to
229             implement the 'c' parameter in templates.
230              
231             =head1 SEE ALSO
232              
233             L, L, L,
234             L, L.
235              
236             =head1 COPYRIGHT & LICENSE
237              
238             Copyright (C) 2005-2007, Jason A. Crome. All rights reserved.
239              
240             This program is free software; you can redistribute it and/or modify it
241             under the same terms as Perl itself.
242              
243             =cut
244              
245             1; # End of CGI::Application::Plugin::HTDot