File Coverage

blib/lib/CGI/Application/Plugin/Mason.pm
Criterion Covered Total %
statement 22 24 91.6
branch n/a
condition n/a
subroutine 8 8 100.0
pod n/a
total 30 32 93.7


line stmt bran cond sub pod time code
1             package CGI::Application::Plugin::Mason;
2              
3             =pod
4              
5             =head1 NAME
6              
7             CGI::Application::Plugin::Mason - HTML::Mason plugin for CGI::Application
8              
9             =head1 VERSION
10              
11             1.01
12              
13             =head1 SYNOPSIS
14              
15             package YourApp;
16              
17             use strict;
18             use base qw(CGI::Application);
19             use CGI::Application::Plugin::Stash; # require!
20             use CGI::Application::Plugin::Mason;
21              
22             # cgiapp_init
23             sub cgiapp_init {
24             my $self = shift;
25             $self->interp_config( comp_root => "/path/to/root", data_dir => "/tmp/mason" );
26             }
27              
28             # runmode
29             sub start {
30             my $self = shift;
31              
32             # Catalyst like
33             $self->stash->{name} = "kurt";
34             $self->stash->{age} = 27;
35             # template path
36             $self->stash->{template} = "/start.mason";
37             return $self->interp_exec;
38             }
39              
40             # start.mason
41             <%args>
42             $name
43             $age
44            
45            
46            
47             <% # $c is YourApp object %>
48             <% $c->get_current_runmode %>
49            
50              
51            
52             name : <% $name | h %>
53             age : <% $age | h %>
54            
55            
56              
57             =head1 DESCRIPTION
58              
59             CGI::Application::Plugin::Mason is Plug-in that offers HTML::Mason template engine.
60              
61             =cut
62              
63 12     12   595868 use base qw(Exporter);
  12         141  
  12         1221  
64 12     12   67 use strict;
  12         28  
  12         355  
65 12     12   61 use warnings;
  12         30  
  12         323  
66 12     12   63 use Carp;
  12         40  
  12         1070  
67 12     12   72 use Cwd;
  12         38  
  12         1063  
68 12     12   70 use Exporter;
  12         22  
  12         396  
69 12     12   66 use File::Spec;
  12         22  
  12         301  
70 12     12   29765 use HTML::Mason;
  0            
  0            
71              
72             our(@EXPORT, $VERSION);
73              
74             @EXPORT = qw(interp interp_config interp_exec);
75             $VERSION = 1.00;
76              
77             sub import {
78              
79             my $pkg = caller;
80             # register new hook
81             $pkg->new_hook("interp_pre_exec");
82             $pkg->new_hook("interp_post_exec");
83             # register hook
84             $pkg->add_callback("interp_pre_exec", \&interp_pre_exec);
85             $pkg->add_callback("interp_post_exec", \&interp_post_exec);
86             goto &Exporter::import;
87             }
88              
89             =pod
90              
91             =head1 METHOD
92              
93             =head2 interp_config
94              
95             Initialize HTML::Mason::Interp method.
96              
97             Option:
98              
99             comp_root : HTML::Mason root dir(default: Cwd::getcwd value)
100             data_dir : HTML::Mason cache and object file directory(default: /tmp/mason)
101             template_extension : template extension(default: .mason)
102              
103             Example:
104              
105             sub cgiapp_init {
106             my $self = shift;
107             $self->interp_config( comp_root => "/path/to/comp_root", data_dir => "/tmp/mason" );
108              
109             # When pass other HTML::Mason option
110             $self->interp_config(
111             comp_root => "/path/to/comp_root",
112             default_escape_flags => [ "h" ],
113             autohandler_name => "autohandler",
114             );
115             }
116              
117             =cut
118              
119             sub interp_config {
120              
121             my($self, %args) = @_;
122              
123             # C::A::P::Stash check
124             if(!$self->can("stash")){
125             croak("C::A::P::Stash module is not load to your app");
126             }
127              
128             # config option
129             $self->{__CAP_INTERP_CONFIG} = {};
130             # output buffer
131             $self->{__CAP_INTERP_OUTPUT} = "";
132             # HTML::Mason::Interp object
133             $self->{__CAP_INTERP_OBJECT} = "";
134            
135             my %config = %args;
136             # comp_root
137             $config{comp_root} ||= getcwd;
138             # data_dir
139             $config{data_dir} ||= File::Spec->catfile(File::Spec->tmpdir, "mason");
140             # allow_globals
141             $config{allow_globals} = [ '$c' ];
142             # template_extension
143             $config{template_extension} ||= ".mason";
144              
145             $self->{__CAP_INTERP_CONFIG} = { %config };
146            
147             delete $config{template_extension};
148             my $interp = HTML::Mason::Interp->new(
149             %config,
150             out_method => \$self->{__CAP_INTERP_OUTPUT}
151             );
152             $interp->set_global( '$c' => $self );
153             # VERSION 1.01 add h
154             $interp->set_escape( h => \&h );
155              
156             $self->{__CAP_INTERP_OBJECT} = $interp;
157             }
158              
159             =pod
160              
161             =head2 interp
162              
163             HTML::Mason::Interp object wrapper
164              
165             Example:
166              
167             # HTML::Mason::Interp#set_escape
168             $self->interp->set_escape( uc => sub { ${$_[0]} =~ tr/a-z/A-Z/ } );
169             # HTML::Mason::Interp#comp_root
170             my $comp_root = $self->interp->comp_root;
171              
172             =cut
173              
174             sub interp {
175            
176             my $self = shift;
177             if(ref($self->{__CAP_INTERP_OBJECT}) ne "HTML::Mason::Interp"){
178             croak("HTML::Mason::Interp has not been loaded. Execute unpalatable \$self->interp_config.");
179             }
180             return $self->{__CAP_INTERP_OBJECT};
181             }
182              
183             =pod
184              
185             =head2 interp_exec
186              
187             Return HTML::Mason::Interp#exec result.
188              
189             The specification of the template file
190              
191             Example:
192              
193             # file name
194             $self->stash->{template} = "/template.mason"
195             # file handle
196             open my $fh, "/path/to/template.mason" or croak("can not open file");
197             $self->stash->{template} = $fh;
198             # scalarref
199             $self->stash->{template} = \q{<%args>$name my name is <% $name %>};
200              
201             default template name is /package_name/runmode_method_name . ${template_extension}
202              
203             Example:
204              
205             # ex1
206             package MyApp;
207             sub start {
208             my $self = shift;
209             do something...
210            
211             # The file passing used at this time is /MyApp/start.mason
212             return $self->interp_exec;
213             }
214              
215             # ex2
216             package My::App;
217             sub start {
218             my $self = shift;
219             do something...
220            
221             # The file passing used at this time is /My/App/start.mason
222             return $self->interp_exec;
223             }
224              
225             Specification of variable allocated in template
226              
227             Example:
228              
229             # ex1
230             sub start {
231             my $self = shift;
232             # stash method setting
233             $self->stash->{name} = "kurt";
234             $self->stash->{age} = 27;
235             return $self->interp_exec;
236             }
237              
238             # ex2
239             sub start {
240             my $self = shift;
241             # interp_exec param setting
242             return $self->interp_exec( name => "kurt", age => 27 );
243             }
244              
245             =cut
246              
247             sub interp_exec {
248              
249             my($self, %args) = @_;
250              
251             %args = %{$self->stash} if !keys %args;
252              
253             my $template = $self->stash->{template};
254              
255             $template = _get_interp_template_path($self) if !defined $template;
256              
257             # interp_pre_exec
258             $self->call_hook("interp_pre_exec", $template, \%args);
259              
260             # component
261             my $comp = undef;
262             if(ref($template) eq "SCALAR"){
263             $comp = $self->interp->make_component( comp_source => ${$template} );
264             }elsif(ref($template) eq "GLOB"){
265             $comp = $self->interp->make_component( comp_source => do { local $/ = undef; <$template> } );
266             close $template;
267             }else{
268              
269             $comp = $template;
270             if($comp !~ m#^/#){
271             $comp = File::Spec->catfile("/", $comp);
272             }
273             }
274              
275             # interp->exec
276             $self->interp->exec( $comp, %args );
277              
278             # interp_post_exec
279             $self->call_hook("interp_post_exec", \$self->{__CAP_INTERP_OUTPUT});
280              
281             return $self->{__CAP_INTERP_OUTPUT};
282             }
283              
284              
285             =pod
286              
287             =head2 interp_pre_exec
288              
289             Trigger method before interp_exec. the argument is $temlate, and $arg.
290              
291             $template : $self->{template} value
292             $args : $self->{stash} or $self->interp_exec args hashref
293              
294             Example:
295              
296             sub interp_pre_exec {
297             my($self, $template, $args) = @_;
298             $args->{newval} = "interp_pre_exec setting value!";
299             }
300              
301             # or
302              
303             $self->add_callback("interp_pre_exec", sub {
304             my($self, $template, $args) = @_;
305             $args->{newval} = "interp_pre_exec setting value!";
306             });
307              
308             =cut
309              
310             sub interp_pre_exec {
311              
312             my($self, $template, $args) = @_;
313             # do something...
314             }
315              
316             =pod
317              
318             =head2 interp_post_exec
319              
320             Trigger method after interp_exec. the argument is $bodyref.
321              
322             $bodyref : content value scalarref
323              
324             Example:
325              
326             sub interp_post_exec {
327             my($self, $bodyref) = @_;
328             ${$bodyref} = encode("shiftjis", decode("utf8", ${$bodyref}));
329             }
330              
331             # or
332              
333             $self->add_callback("interp_post_exec", sub {
334             my($self, $bodyref) = @_;
335             ${$bodyref} = encode("shiftjis", decode("utf8", ${$bodyref}));
336             });
337              
338             =cut
339              
340             sub interp_post_exec {
341              
342             my($self, $bodyref) = @_;
343             # do something...
344             }
345              
346             =pod
347              
348             =head1 ESCAPE METHOD
349              
350             =head2 h
351              
352             html escape
353              
354             =cut
355              
356             sub h {
357              
358             &HTML::Mason::Escapes::basic_html_escape($_[0]);
359             ${$_[0]} =~ s/'/'/g;
360             }
361              
362              
363             =pod
364              
365             =head1 PRIVATE METHOD
366              
367             =head2 _get_interp_template_path
368              
369             Get default template path.
370              
371             =cut
372              
373             sub _get_interp_template_path {
374              
375             my $self = shift;
376             my $path = File::Spec->catfile(split(/::/, ref($self)), $self->get_current_runmode);
377             $path .= $self->{__CAP_INTERP_CONFIG}->{template_extension};
378             return File::Spec->catfile("/", $path);
379             }
380              
381             1;
382              
383             __END__