File Coverage

blib/lib/CGI/Application.pm
Criterion Covered Total %
statement 356 380 93.6
branch 158 186 84.9
condition 17 27 62.9
subroutine 41 44 93.1
pod 29 31 93.5
total 601 668 89.9


line stmt bran cond sub pod time code
1             package CGI::Application;
2 17     17   281041 use Carp;
  17         33  
  17         1326  
3 17     17   109 use strict;
  17         25  
  17         475  
4 17     17   7979 use Class::ISA;
  17         27319  
  17         454  
5 17     17   98 use Scalar::Util;
  17         27  
  17         65463  
6              
7             $CGI::Application::VERSION = '4.50_50';
8              
9             my %INSTALLED_CALLBACKS = (
10             # hook name package sub
11             init => { 'CGI::Application' => [ 'cgiapp_init' ] },
12             prerun => { 'CGI::Application' => [ 'cgiapp_prerun' ] },
13             postrun => { 'CGI::Application' => [ 'cgiapp_postrun' ] },
14             teardown => { 'CGI::Application' => [ 'teardown' ] },
15             load_tmpl => { },
16             error => { },
17             );
18              
19             ###################################
20             #### INSTANCE SCRIPT METHODS ####
21             ###################################
22              
23             sub new {
24 69     69 1 83825 my $class = shift;
25              
26 69         134 my @args = @_;
27              
28 69 50       189 if (ref($class)) {
29             # No copy constructor yet!
30 0         0 $class = ref($class);
31             }
32              
33             # Create our object!
34 69         104 my $self = {};
35 69         140 bless($self, $class);
36              
37             ### SET UP DEFAULT VALUES ###
38             #
39             # We set them up here and not in the setup() because a subclass
40             # which implements setup() still needs default values!
41              
42 69         280 $self->header_type('header');
43 69         213 $self->mode_param('rm');
44 69         203 $self->start_mode('start');
45              
46             # Process optional new() parameters
47 69         56 my $rprops;
48 69 100       162 if (ref($args[0]) eq 'HASH') {
49 1         4 $rprops = $self->_cap_hash($args[0]);
50             } else {
51 68         258 $rprops = $self->_cap_hash({ @args });
52             }
53              
54             # Set tmpl_path()
55 69 100       192 if (exists($rprops->{TMPL_PATH})) {
56 4         25 $self->tmpl_path($rprops->{TMPL_PATH});
57             }
58              
59             # Set CGI query object
60 69 100       148 if (exists($rprops->{QUERY})) {
61 20         72 $self->query($rprops->{QUERY});
62             }
63              
64             # Set up init param() values
65 69 100       275 if (exists($rprops->{PARAMS})) {
66 2 100       202 croak("PARAMS is not a hash ref") unless (ref($rprops->{PARAMS}) eq 'HASH');
67 1         2 my $rparams = $rprops->{PARAMS};
68 1         4 while (my ($k, $v) = each(%$rparams)) {
69 2         8 $self->param($k, $v);
70             }
71             }
72              
73             # Lock prerun_mode from being changed until cgiapp_prerun()
74 68         117 $self->{__PRERUN_MODE_LOCKED} = 1;
75              
76             # Call cgiapp_init() method, which may be implemented in the sub-class.
77             # Pass all constructor args forward. This will allow flexible usage
78             # down the line.
79 68         199 $self->call_hook('init', @args);
80              
81             # Call setup() method, which should be implemented in the sub-class!
82 68         195 $self->setup();
83              
84 67         349 return $self;
85             }
86              
87             sub __get_runmode {
88 61     61   64 my $self = shift;
89 61         66 my $rm_param = shift;
90              
91 61         65 my $rm;
92             # Support call-back instead of CGI mode param
93 61 100       217 if (ref($rm_param) eq 'CODE') {
    100          
94             # Get run mode from subref
95 4         7 $rm = $rm_param->($self);
96             }
97             # support setting run mode from PATH_INFO
98             elsif (ref($rm_param) eq 'HASH') {
99 4         4 $rm = $rm_param->{run_mode};
100             }
101             # Get run mode from CGI param
102             else {
103 53         113 $rm = $self->query->param($rm_param);
104             }
105              
106             # If $rm undefined, use default (start) mode
107 61 100 100     1052 $rm = $self->start_mode unless defined($rm) && length($rm);
108              
109 61         96 return $rm;
110             }
111              
112             sub __get_runmeth {
113 61     61   76 my $self = shift;
114 61         65 my $rm = shift;
115              
116 61         55 my $rmeth;
117              
118 61         71 my $is_autoload = 0;
119              
120 61         116 my %rmodes = ($self->run_modes());
121 61 100       160 if (exists($rmodes{$rm})) {
122 58         92 $rmeth = $rmodes{$rm};
123             }
124             else {
125             # Look for run mode "AUTOLOAD" before dieing
126 3 100       9 unless (exists($rmodes{'AUTOLOAD'})) {
127 1         155 croak("No such run mode '$rm'");
128             }
129 2         3 $rmeth = $rmodes{'AUTOLOAD'};
130 2         4 $is_autoload = 1;
131             }
132              
133 60         146 return ($rmeth, $is_autoload);
134             }
135              
136             sub __get_body {
137 61     61   68 my $self = shift;
138 61         66 my $rm = shift;
139              
140 61         165 my ($rmeth, $is_autoload) = $self->__get_runmeth($rm);
141              
142 60         62 my $body;
143 60         65 eval {
144 60 100       247 $body = $is_autoload ? $self->$rmeth($rm) : $self->$rmeth();
145             };
146 60 100       877 if ($@) {
147 3         5 my $error = $@;
148 3         9 $self->call_hook('error', $error);
149 3 100       14 if (my $em = $self->error_mode) {
150 2         14 $body = $self->$em( $error );
151             } else {
152 1         70 croak("Error executing run mode '$rm': $error");
153             }
154             }
155              
156             # Make sure that $body is not undefined (suppress 'uninitialized value'
157             # warnings)
158 58 100       172 return defined $body ? $body : '';
159             }
160              
161              
162             sub run {
163 61     61 1 800 my $self = shift;
164 61         149 my $q = $self->query();
165              
166 61         138 my $rm_param = $self->mode_param();
167              
168 61         226 my $rm = $self->__get_runmode($rm_param);
169              
170             # Set get_current_runmode() for access by user later
171 61         99 $self->{__CURRENT_RUNMODE} = $rm;
172              
173             # Allow prerun_mode to be changed
174 61         108 delete($self->{__PRERUN_MODE_LOCKED});
175              
176             # Call PRE-RUN hook, now that we know the run mode
177             # This hook can be used to provide run mode specific behaviors
178             # before the run mode actually runs.
179 61         139 $self->call_hook('prerun', $rm);
180              
181             # Lock prerun_mode from being changed after cgiapp_prerun()
182 61         108 $self->{__PRERUN_MODE_LOCKED} = 1;
183              
184             # If prerun_mode has been set, use it!
185 61         200 my $prerun_mode = $self->prerun_mode();
186 61 100       137 if (length($prerun_mode)) {
187 1         2 $rm = $prerun_mode;
188 1         1 $self->{__CURRENT_RUNMODE} = $rm;
189             }
190              
191             # Process run mode!
192 61         180 my $body = $self->__get_body($rm);
193              
194             # Support scalar-ref for body return
195 58 100       138 $body = $$body if ref $body eq 'SCALAR';
196              
197             # Call cgiapp_postrun() hook
198 58         145 $self->call_hook('postrun', \$body);
199              
200 58         111 my $return_value;
201 58 100       138 if ($self->{__IS_PSGI}) {
202 1         5 my ($status, $headers) = $self->_send_psgi_headers();
203              
204 1 50 33     249 if (ref($body) eq 'GLOB' || (Scalar::Util::blessed($body) && $body->can('getline'))) {
    50 33        
205             # body a file handle - return it
206 0         0 $return_value = [ $status, $headers, $body];
207             }
208             elsif (ref($body) eq 'CODE') {
209              
210             # body is a subref, or an explicit callback method is set
211             $return_value = sub {
212 0     0   0 my $respond = shift;
213              
214 0         0 my $writer = $respond->([ $status, $headers ]);
215              
216 0         0 &$body($writer);
217 0         0 };
218             }
219             else {
220              
221 1         3 $return_value = [ $status, $headers, [ $body ]];
222             }
223             }
224             else {
225             # Set up HTTP headers non-PSGI responses
226 57         167 my $headers = $self->_send_headers();
227              
228             # Build up total output
229 57         23330 $return_value = $headers.$body;
230 57 100       197 print $return_value unless $ENV{CGI_APP_RETURN_ONLY};
231             }
232              
233             # clean up operations
234 58         123 $self->call_hook('teardown');
235              
236 58         182 return $return_value;
237             }
238              
239              
240             sub psgi_app {
241 0     0 1 0 my $class = shift;
242 0         0 my $args_to_new = shift;
243              
244             return sub {
245 0     0   0 my $env = shift;
246              
247 0 0       0 if (not defined $args_to_new->{QUERY}) {
248 0         0 require CGI::PSGI;
249 0         0 $args_to_new->{QUERY} = CGI::PSGI->new($env);
250             }
251              
252 0         0 my $webapp = $class->new($args_to_new);
253 0         0 return $webapp->run_as_psgi;
254             }
255 0         0 }
256              
257             sub run_as_psgi {
258 1     1 1 6 my $self = shift;
259 1         2 $self->{__IS_PSGI} = 1;
260              
261             # Run doesn't officially support any args, but pass them through in case some sub-class uses them.
262 1         5 return $self->run(@_);
263             }
264              
265              
266             ############################
267             #### OVERRIDE METHODS ####
268             ############################
269              
270             sub cgiapp_get_query {
271 14     14 1 22 my $self = shift;
272              
273             # Include CGI.pm and related modules
274 14         8528 require CGI;
275              
276             # Get the query object
277 14         62802 my $q = CGI->new();
278              
279 14         33158 return $q;
280             }
281              
282              
283             sub cgiapp_init {
284 45     45 1 51 my $self = shift;
285 45         101 my @args = (@_);
286              
287             # Nothing to init, yet!
288             }
289              
290              
291             sub cgiapp_prerun {
292 53     53 1 63 my $self = shift;
293 53         92 my $rm = shift;
294              
295             # Nothing to prerun, yet!
296             }
297              
298              
299             sub cgiapp_postrun {
300 51     51 1 63 my $self = shift;
301 51         98 my $bodyref = shift;
302              
303             # Nothing to postrun, yet!
304             }
305              
306              
307             sub setup {
308 11     11 1 16 my $self = shift;
309             }
310              
311              
312             sub teardown {
313 39     39 1 68 my $self = shift;
314              
315             # Nothing to shut down, yet!
316             }
317              
318              
319              
320              
321             ######################################
322             #### APPLICATION MODULE METHODS ####
323             ######################################
324              
325             sub dump {
326 2     2 1 3 my $self = shift;
327 2         4 my $output = '';
328              
329             # Dump run mode
330 2         6 my $current_runmode = $self->get_current_runmode();
331 2 100       7 $current_runmode = "" unless (defined($current_runmode));
332 2         6 $output .= "Current Run mode: '$current_runmode'\n";
333              
334             # Dump Params
335 2         4 $output .= "\nQuery Parameters:\n";
336 2         5 my @params = $self->query->param();
337 2         30 foreach my $p (sort(@params)) {
338 1         2 my @data = $self->query->param($p);
339 1         15 my $data_str = "'".join("', '", @data)."'";
340 1         5 $output .= "\t$p => $data_str\n";
341             }
342              
343             # Dump ENV
344 2         5 $output .= "\nQuery Environment:\n";
345 2         28 foreach my $ek (sort(keys(%ENV))) {
346 34         62 $output .= "\t$ek => '".$ENV{$ek}."'\n";
347             }
348              
349 2         8 return $output;
350             }
351              
352              
353             sub dump_html {
354 1     1 1 1 my $self = shift;
355 1         3 my $query = $self->query();
356 1         2 my $output = '';
357              
358             # Dump run-mode
359 1         4 my $current_runmode = $self->get_current_runmode();
360 1         3 $output .= "

Current Run-mode:

361             '$current_runmode'

\n";
362              
363             # Dump Params
364 1         2 $output .= "

Query Parameters:

\n";
365 1         47 $output .= $query->Dump;
366              
367             # Dump ENV
368 1         266 $output .= "

Query Environment:

\n
    \n";
369 1         12 foreach my $ek ( sort( keys( %ENV ) ) ) {
370 17         1149 $output .= sprintf(
371             "
  • %s => '%s'
  • \n",
    372             $query->escapeHTML( $ek ),
    373             $query->escapeHTML( $ENV{$ek} )
    374             );
    375             }
    376 1         51 $output .= "\n";
    377              
    378 1         3 return $output;
    379             }
    380              
    381              
    382             sub no_runmodes {
    383              
    384 9     9 0 13 my $self = shift;
    385 9         18 my $query = $self->query();
    386 9         186 my $output = $query->start_html;
    387            
    388             # If no runmodes specified by app return error message
    389 9         7387 my $current_runmode = $self->get_current_runmode();
    390 9         160 my $query_params = $query->Dump;
    391            
    392 9         1708 $output .= qq{
    393            

    Error - No runmodes specified.

    394            

    Runmode called: $current_runmode"

    395            

    Query paramaters:

    $query_params
    396            

    Your application has not specified any runmodes.

    397            

    Please read the

    398             CGI::Application documentation.

    399             };
    400            
    401 9         124 $output .= $query->end_html();
    402 9         318 return $output;
    403             }
    404              
    405              
    406             sub header_add {
    407 5     5 1 610 my $self = shift;
    408 5         14 return $self->_header_props_update(\@_,add=>1);
    409             }
    410              
    411             sub header_props {
    412 67     67 1 3114 my $self = shift;
    413 67         196 return $self->_header_props_update(\@_,add=>0);
    414             }
    415              
    416             # used by header_props and header_add to update the headers
    417             sub _header_props_update {
    418 72     72   67 my $self = shift;
    419 72         70 my $data_ref = shift;
    420 72         129 my %in = @_;
    421              
    422 72         100 my @data = @$data_ref;
    423              
    424             # First use? Create new __HEADER_PROPS!
    425 72 100       209 $self->{__HEADER_PROPS} = {} unless (exists($self->{__HEADER_PROPS}));
    426              
    427 72         63 my $props;
    428              
    429             # If data is provided, set it!
    430 72 100       134 if (scalar(@data)) {
    431 19 100       33 if ($self->header_type eq 'none') {
    432 1         12 warn "header_props called while header_type set to 'none', headers will NOT be sent!"
    433             }
    434             # Is it a hash, or hash-ref?
    435 19 100       69 if (ref($data[0]) eq 'HASH') {
        100          
    436             # Make a copy
    437 4         4 %$props = %{$data[0]};
      4         12  
    438             } elsif ((scalar(@data) % 2) == 0) {
    439             # It appears to be a possible hash (even # of elements)
    440 13         33 %$props = @data;
    441             } else {
    442 2 100       7 my $meth = $in{add} ? 'add' : 'props';
    443 2         301 croak("Odd number of elements passed to header_$meth(). Not a valid hash")
    444             }
    445              
    446             # merge in new headers, appending new values passed as array refs
    447 17 100       38 if ($in{add}) {
    448 4         10 for my $key_set_to_aref (grep { ref $props->{$_} eq 'ARRAY'} keys %$props) {
      4         15  
    449 2         4 my $existing_val = $self->{__HEADER_PROPS}->{$key_set_to_aref};
    450 2 100       5 next unless defined $existing_val;
    451 1 50       4 my @existing_val_array = (ref $existing_val eq 'ARRAY') ? @$existing_val : ($existing_val);
    452 1         1 $props->{$key_set_to_aref} = [ @existing_val_array, @{ $props->{$key_set_to_aref} } ];
      1         4  
    453             }
    454 4         9 $self->{__HEADER_PROPS} = { %{ $self->{__HEADER_PROPS} }, %$props };
      4         12  
    455             }
    456             # Set new headers, clobbering existing values
    457             else {
    458 13         23 $self->{__HEADER_PROPS} = $props;
    459             }
    460              
    461             }
    462              
    463             # If we've gotten this far, return the value!
    464 70         75 return (%{ $self->{__HEADER_PROPS}});
      70         1070  
    465             }
    466              
    467              
    468             sub header_type {
    469 157     157 1 196 my $self = shift;
    470 157         184 my ($header_type) = @_;
    471              
    472 157         291 my @allowed_header_types = qw(header redirect none);
    473              
    474             # First use? Create new __HEADER_TYPE!
    475 157 100       508 $self->{__HEADER_TYPE} = 'header' unless (exists($self->{__HEADER_TYPE}));
    476              
    477             # If data is provided, set it!
    478 157 100       320 if (defined($header_type)) {
    479 80         137 $header_type = lc($header_type);
    480 240         448 croak("Invalid header_type '$header_type'")
    481 80 50       136 unless(grep { $_ eq $header_type } @allowed_header_types);
    482 80         134 $self->{__HEADER_TYPE} = $header_type;
    483             }
    484              
    485             # If we've gotten this far, return the value!
    486 157         297 return $self->{__HEADER_TYPE};
    487             }
    488              
    489              
    490             sub param {
    491 106     106 1 15426 my $self = shift;
    492 106         183 my (@data) = (@_);
    493              
    494             # First use? Create new __PARAMS!
    495 106 100       242 $self->{__PARAMS} = {} unless (exists($self->{__PARAMS}));
    496              
    497 106         110 my $rp = $self->{__PARAMS};
    498              
    499             # If data is provided, set it!
    500 106 100       159 if (scalar(@data)) {
    501             # Is it a hash, or hash-ref?
    502 98 100       307 if (ref($data[0]) eq 'HASH') {
        100          
        50          
    503             # Make a copy, which augments the existing contents (if any)
    504 1         3 %$rp = (%$rp, %{$data[0]});
      1         7  
    505             } elsif ((scalar(@data) % 2) == 0) {
    506             # It appears to be a possible hash (even # of elements)
    507 62         246 %$rp = (%$rp, @data);
    508             } elsif (scalar(@data) > 1) {
    509 0         0 croak("Odd number of elements passed to param(). Not a valid hash");
    510             }
    511             } else {
    512             # Return the list of param keys if no param is specified.
    513 8         50 return (keys(%$rp));
    514             }
    515              
    516             # If exactly one parameter was sent to param(), return the value
    517 98 100       222 if (scalar(@data) <= 2) {
    518 96         92 my $param = $data[0];
    519 96         276 return $rp->{$param};
    520             }
    521 2         4 return; # Otherwise, return undef
    522             }
    523              
    524              
    525             sub delete {
    526 3     3 1 12 my $self = shift;
    527 3         4 my ($param) = @_;
    528              
    529             # return undef it the param name isn't given
    530 3 100       13 return undef unless defined $param;
    531              
    532             #simply delete this param from $self->{__PARAMS}
    533 2         7 delete $self->{__PARAMS}->{$param};
    534             }
    535              
    536              
    537             sub query {
    538 247     247 1 13074 my $self = shift;
    539 247         245 my ($query) = @_;
    540              
    541             # If data is provided, set it! Otherwise, create a new one.
    542 247 100       363 if (defined($query)) {
    543 44         80 $self->{__QUERY_OBJ} = $query;
    544             } else {
    545             # We're only allowed to create a new query object if one does not yet exist!
    546 203 100       440 unless (exists($self->{__QUERY_OBJ})) {
    547 15         70 $self->{__QUERY_OBJ} = $self->cgiapp_get_query();
    548             }
    549             }
    550              
    551 247         15891 return $self->{__QUERY_OBJ};
    552             }
    553              
    554              
    555             sub run_modes {
    556 131     131 1 400 my $self = shift;
    557 131         200 my (@data) = (@_);
    558              
    559             # First use? Create new __RUN_MODES!
    560 131 100       469 $self->{__RUN_MODES} = { 'start' => 'no_runmodes' } unless (exists($self->{__RUN_MODES}));
    561              
    562 131         158 my $rr_m = $self->{__RUN_MODES};
    563              
    564             # If data is provided, set it!
    565 131 100       235 if (scalar(@data)) {
    566             # Is it a hash, hash-ref, or array-ref?
    567 70 100       252 if (ref($data[0]) eq 'HASH') {
        100          
        100          
    568             # Make a copy, which augments the existing contents (if any)
    569 1         2 %$rr_m = (%$rr_m, %{$data[0]});
      1         4  
    570             } elsif (ref($data[0]) eq 'ARRAY') {
    571             # Convert array-ref into hash table
    572 12         16 foreach my $rm (@{$data[0]}) {
      12         24  
    573 26         44 $rr_m->{$rm} = $rm;
    574             }
    575             } elsif ((scalar(@data) % 2) == 0) {
    576             # It appears to be a possible hash (even # of elements)
    577 56         363 %$rr_m = (%$rr_m, @data);
    578             } else {
    579 1         179 croak("Odd number of elements passed to run_modes(). Not a valid hash");
    580             }
    581             }
    582              
    583             # If we've gotten this far, return the value!
    584 130         466 return (%$rr_m);
    585             }
    586              
    587              
    588             sub start_mode {
    589 145     145 1 257 my $self = shift;
    590 145         155 my ($start_mode) = @_;
    591              
    592             # First use? Create new __START_MODE
    593 145 100       380 $self->{__START_MODE} = 'start' unless (exists($self->{__START_MODE}));
    594              
    595             # If data is provided, set it
    596 145 100       264 if (defined($start_mode)) {
    597 119         144 $self->{__START_MODE} = $start_mode;
    598             }
    599              
    600 145         218 return $self->{__START_MODE};
    601             }
    602              
    603              
    604             sub error_mode {
    605 5     5 1 17 my $self = shift;
    606 5         6 my ($error_mode) = @_;
    607              
    608             # First use? Create new __ERROR_MODE
    609 5 100       21 $self->{__ERROR_MODE} = undef unless (exists($self->{__ERROR_MODE}));
    610              
    611             # If data is provided, set it.
    612 5 100       12 if (defined($error_mode)) {
    613 2         7 $self->{__ERROR_MODE} = $error_mode;
    614             }
    615              
    616 5         14 return $self->{__ERROR_MODE};
    617             }
    618              
    619              
    620             sub tmpl_path {
    621 13     13 1 30 my $self = shift;
    622 13         16 my ($tmpl_path) = @_;
    623              
    624             # First use? Create new __TMPL_PATH!
    625 13 100       45 $self->{__TMPL_PATH} = '' unless (exists($self->{__TMPL_PATH}));
    626              
    627             # If data is provided, set it!
    628 13 100       33 if (defined($tmpl_path)) {
    629 5         10 $self->{__TMPL_PATH} = $tmpl_path;
    630             }
    631              
    632             # If we've gotten this far, return the value!
    633 13         33 return $self->{__TMPL_PATH};
    634             }
    635              
    636              
    637             sub prerun_mode {
    638 64     64 1 77 my $self = shift;
    639 64         71 my ($prerun_mode) = @_;
    640              
    641             # First use? Create new __PRERUN_MODE
    642 64 100       195 $self->{__PRERUN_MODE} = '' unless (exists($self->{__PRERUN_MODE}));
    643              
    644             # Was data provided?
    645 64 100       130 if (defined($prerun_mode)) {
    646             # Are we allowed to set prerun_mode?
    647 3 100       24 if (exists($self->{__PRERUN_MODE_LOCKED})) {
    648             # Not allowed! Throw an exception.
    649 2         311 croak("prerun_mode() can only be called within cgiapp_prerun()! Error");
    650             } else {
    651             # If data is provided, set it!
    652 1         2 $self->{__PRERUN_MODE} = $prerun_mode;
    653             }
    654             }
    655              
    656             # If we've gotten this far, return the value!
    657 62         106 return $self->{__PRERUN_MODE};
    658             }
    659              
    660              
    661             sub get_current_runmode {
    662 22     22 1 923 my $self = shift;
    663              
    664             # It's OK if we return undef if this method is called too early
    665 22         55 return $self->{__CURRENT_RUNMODE};
    666             }
    667              
    668              
    669              
    670              
    671              
    672             ###########################
    673             #### PRIVATE METHODS ####
    674             ###########################
    675              
    676              
    677             # return headers as a string
    678             sub _send_headers {
    679 57     57   74 my $self = shift;
    680 57         101 my $q = $self->query;
    681 57         118 my $type = $self->header_type;
    682              
    683             return
    684 57 50       273 $type eq 'redirect' ? $q->redirect( $self->header_props )
        100          
        100          
    685             : $type eq 'header' ? $q->header ( $self->header_props )
    686             : $type eq 'none' ? ''
    687             : croak "Invalid header_type '$type'"
    688             }
    689              
    690             # return a 2 element array modeling the first PSGI redirect values: status code and arrayref of header pairs
    691             sub _send_psgi_headers {
    692 1     1   2 my $self = shift;
    693 1         2 my $q = $self->query;
    694 1         3 my $type = $self->header_type;
    695              
    696             return
    697 1 0       7 $type eq 'redirect' ? $q->psgi_redirect( $self->header_props )
        50          
        50          
    698             : $type eq 'header' ? $q->psgi_header ( $self->header_props )
    699             : $type eq 'none' ? ''
    700             : croak "Invalid header_type '$type'"
    701              
    702             }
    703              
    704              
    705             # Make all hash keys CAPITAL
    706             # although this method is internal, some other extensions
    707             # have come to rely on it, so any changes here should be
    708             # made with great care or avoided.
    709             sub _cap_hash {
    710 69     69   85 my $self = shift;
    711 69         67 my $rhash = shift;
    712 26         37 my %hash = map {
    713 69         187 my $k = $_;
    714 26         35 my $v = $rhash->{$k};
    715 26         53 $k =~ tr/a-z/A-Z/;
    716 26         164 $k => $v;
    717 69         108 } keys(%{$rhash});
    718 69         166 return \%hash;
    719             }
    720              
    721              
    722              
    723             1;
    724              
    725              
    726              
    727              
    728             =pod
    729              
    730             =head1 NAME
    731              
    732             CGI::Application - Framework for building reusable web-applications
    733              
    734             =head1 SYNOPSIS
    735              
    736             # In "WebApp.pm"...
    737             package WebApp;
    738             use base 'CGI::Application';
    739              
    740             # ( setup() can even be skipped for common cases. See docs below. )
    741             sub setup {
    742             my $self = shift;
    743             $self->start_mode('mode1');
    744             $self->mode_param('rm');
    745             $self->run_modes(
    746             'mode1' => 'do_stuff',
    747             'mode2' => 'do_more_stuff',
    748             'mode3' => 'do_something_else'
    749             );
    750             }
    751             sub do_stuff { ... }
    752             sub do_more_stuff { ... }
    753             sub do_something_else { ... }
    754             1;
    755              
    756              
    757             ### In "webapp.cgi"...
    758             use WebApp;
    759             my $webapp = WebApp->new();
    760             $webapp->run();
    761              
    762             ### Or, in a PSGI file, webapp.psgi
    763             use WebApp;
    764             WebApp->psgi_app();
    765              
    766             =head1 INTRODUCTION
    767              
    768             CGI::Application makes it easier to create sophisticated, high-performance,
    769             reusable web-based applications. CGI::Application helps makes your web
    770             applications easier to design, write, and evolve.
    771              
    772             CGI::Application judiciously avoids employing technologies and techniques which
    773             would bind a developer to any one set of tools, operating system or web server.
    774              
    775             It is lightweight in terms of memory usage, making it suitable for common CGI
    776             environments, and a high performance choice in persistent environments like
    777             FastCGI or mod_perl.
    778              
    779             By adding L as your needs grow, you can add advanced and complex
    780             features when you need them.
    781              
    782             First released in 2000 and used and expanded by a number of professional
    783             website developers, CGI::Application is a stable, reliable choice.
    784              
    785             =head1 USAGE EXAMPLE
    786              
    787             Imagine you have to write an application to search through a database
    788             of widgets. Your application has three screens:
    789              
    790             1. Search form
    791             2. List of results
    792             3. Detail of a single record
    793              
    794             To write this application using CGI::Application you will create two files:
    795              
    796             1. WidgetView.pm -- Your "Application Module"
    797             2. widgetview.cgi -- Your "Instance Script"
    798              
    799             The Application Module contains all the code specific to your
    800             application functionality, and it exists outside of your web server's
    801             document root, somewhere in the Perl library search path.
    802              
    803             The Instance Script is what is actually called by your web server. It is
    804             a very small, simple file which simply creates an instance of your
    805             application and calls an inherited method, run(). Following is the
    806             entirety of "widgetview.cgi":
    807              
    808             #!/usr/bin/perl -w
    809             use WidgetView;
    810             my $webapp = WidgetView->new();
    811             $webapp->run();
    812              
    813             As you can see, widgetview.cgi simply "uses" your Application module
    814             (which implements a Perl package called "WidgetView"). Your Application Module,
    815             "WidgetView.pm", is somewhat more lengthy:
    816              
    817             package WidgetView;
    818             use base 'CGI::Application';
    819             use strict;
    820              
    821             # Needed for our database connection
    822             use CGI::Application::Plugin::DBH;
    823              
    824             sub setup {
    825             my $self = shift;
    826             $self->start_mode('mode1');
    827             $self->run_modes(
    828             'mode1' => 'showform',
    829             'mode2' => 'showlist',
    830             'mode3' => 'showdetail'
    831             );
    832              
    833             # Connect to DBI database, with the same args as DBI->connect();
    834             $self->dbh_config();
    835             }
    836              
    837             sub teardown {
    838             my $self = shift;
    839              
    840             # Disconnect when we're done, (Although DBI usually does this automatically)
    841             $self->dbh->disconnect();
    842             }
    843              
    844             sub showform {
    845             my $self = shift;
    846              
    847             # Get CGI query object
    848             my $q = $self->query();
    849              
    850             my $output = '';
    851             $output .= $q->start_html(-title => 'Widget Search Form');
    852             $output .= $q->start_form();
    853             $output .= $q->textfield(-name => 'widgetcode');
    854             $output .= $q->hidden(-name => 'rm', -value => 'mode2');
    855             $output .= $q->submit();
    856             $output .= $q->end_form();
    857             $output .= $q->end_html();
    858              
    859             return $output;
    860             }
    861              
    862             sub showlist {
    863             my $self = shift;
    864              
    865             # Get our database connection
    866             my $dbh = $self->dbh();
    867              
    868             # Get CGI query object
    869             my $q = $self->query();
    870             my $widgetcode = $q->param("widgetcode");
    871              
    872             my $output = '';
    873             $output .= $q->start_html(-title => 'List of Matching Widgets');
    874              
    875             ## Do a bunch of stuff to select "widgets" from a DBI-connected
    876             ## database which match the user-supplied value of "widgetcode"
    877             ## which has been supplied from the previous HTML form via a
    878             ## CGI.pm query object.
    879             ##
    880             ## Each row will contain a link to a "Widget Detail" which
    881             ## provides an anchor tag, as follows:
    882             ##
    883             ## "widgetview.cgi?rm=mode3&widgetid=XXX"
    884             ##
    885             ## ...Where "XXX" is a unique value referencing the ID of
    886             ## the particular "widget" upon which the user has clicked.
    887              
    888             $output .= $q->end_html();
    889              
    890             return $output;
    891             }
    892              
    893             sub showdetail {
    894             my $self = shift;
    895              
    896             # Get our database connection
    897             my $dbh = $self->dbh();
    898              
    899             # Get CGI query object
    900             my $q = $self->query();
    901             my $widgetid = $q->param("widgetid");
    902              
    903             my $output = '';
    904             $output .= $q->start_html(-title => 'Widget Detail');
    905              
    906             ## Do a bunch of things to select all the properties of
    907             ## the particular "widget" upon which the user has
    908             ## clicked. The key id value of this widget is provided
    909             ## via the "widgetid" property, accessed via the CGI.pm
    910             ## query object.
    911              
    912             $output .= $q->end_html();
    913              
    914             return $output;
    915             }
    916              
    917             1; # Perl requires this at the end of all modules
    918              
    919              
    920             CGI::Application takes care of implementing the new() and the run()
    921             methods. Notice that at no point do you call print() to send any
    922             output to STDOUT. Instead, all output is returned as a scalar.
    923              
    924             CGI::Application's most significant contribution is in managing
    925             the application state. Notice that all which is needed to push
    926             the application forward is to set the value of a HTML form
    927             parameter 'rm' to the value of the "run mode" you wish to handle
    928             the form submission. This is the key to CGI::Application.
    929              
    930              
    931             =head1 ABSTRACT
    932              
    933             The guiding philosophy behind CGI::Application is that a web-based
    934             application can be organized into a specific set of "Run Modes."
    935             Each Run Mode is roughly analogous to a single screen (a form, some
    936             output, etc.). All the Run Modes are managed by a single "Application
    937             Module" which is a Perl module. In your web server's document space
    938             there is an "Instance Script" which is called by the web server as a
    939             CGI (or an Apache::Registry script if you're using Apache + mod_perl).
    940              
    941             This methodology is an inversion of the "Embedded" philosophy (ASP, JSP,
    942             EmbPerl, Mason, etc.) in which there are "pages" for each state of the
    943             application, and the page drives functionality. In CGI::Application,
    944             form follows function -- the Application Module drives pages, and the
    945             code for a single application is in one place; not spread out over
    946             multiple "pages". If you feel that Embedded architectures are
    947             confusing, unorganized, difficult to design and difficult to manage,
    948             CGI::Application is the methodology for you!
    949              
    950             Apache is NOT a requirement for CGI::Application. Web applications based on
    951             CGI::Application will run equally well on NT/IIS or any other
    952             CGI-compatible environment. CGI::Application-based projects
    953             are, however, ripe for use on Apache/mod_perl servers, as they
    954             naturally encourage Good Programming Practices and will often work
    955             in persistent environments without modification.
    956              
    957             For more information on using CGI::Application with mod_perl, please see our
    958             website at http://www.cgi-app.org/, as well as
    959             L, which integrates with L.
    960              
    961             =head1 DESCRIPTION
    962              
    963             It is intended that your Application Module will be implemented as a sub-class
    964             of CGI::Application. This is done simply as follows:
    965              
    966             package My::App;
    967             use base 'CGI::Application';
    968              
    969             B
    970              
    971             For the purpose of this document, we will refer to the
    972             following conventions:
    973              
    974             WebApp.pm The Perl module which implements your Application Module class.
    975             WebApp Your Application Module class; a sub-class of CGI::Application.
    976             webapp.cgi The Instance Script which implements your Application Module.
    977             $webapp An instance (object) of your Application Module class.
    978             $c Same as $webapp, used in instance methods to pass around the
    979             current object. (Sometimes referred as "$self" in other code)
    980              
    981              
    982              
    983              
    984             =head2 Instance Script Methods
    985              
    986             By inheriting from CGI::Application you have access to a
    987             number of built-in methods. The following are those which
    988             are expected to be called from your Instance Script.
    989              
    990             =head3 new()
    991              
    992             The new() method is the constructor for a CGI::Application. It returns
    993             a blessed reference to your Application Module package (class). Optionally,
    994             new() may take a set of parameters as key => value pairs:
    995              
    996             my $webapp = WebApp->new(
    997             TMPL_PATH => 'App/',
    998             PARAMS => {
    999             'custom_thing_1' => 'some val',
    1000             'another_custom_thing' => [qw/123 456/]
    1001             }
    1002             );
    1003              
    1004             This method may take some specific parameters:
    1005              
    1006             B - This optional parameter defines a path to a directory of templates.
    1007             This is used by the load_tmpl() method (specified below), and may also be used
    1008             for the same purpose by other template plugins. This run-time parameter allows
    1009             you to further encapsulate instantiating templates, providing potential for
    1010             more re-usability. It can be either a scalar or an array reference of multiple
    1011             paths.
    1012              
    1013             B - This optional parameter allows you to specify an
    1014             already-created CGI.pm query object. Under normal use,
    1015             CGI::Application will instantiate its own CGI.pm query object.
    1016             Under certain conditions, it might be useful to be able to use
    1017             one which has already been created.
    1018              
    1019             B - This parameter, if used, allows you to set a number
    1020             of custom parameters at run-time. By passing in different
    1021             values in different instance scripts which use the same application
    1022             module you can achieve a higher level of re-usability. For instance,
    1023             imagine an application module, "Mailform.pm". The application takes
    1024             the contents of a HTML form and emails it to a specified recipient.
    1025             You could have multiple instance scripts throughout your site which
    1026             all use this "Mailform.pm" module, but which set different recipients
    1027             or different forms.
    1028              
    1029             One common use of instance scripts is to provide a path to a config file. This
    1030             design allows you to define project wide configuration objects used by many
    1031             several instance scripts. There are several plugins which simplify the syntax
    1032             for this and provide lazy loading. Here's an example using
    1033             L, which uses L to support
    1034             many configuration file formats.
    1035              
    1036             my $app = WebApp->new(PARAMS => { cfg_file => 'config.pl' });
    1037              
    1038             # Later in your app:
    1039             my %cfg = $self->cfg()
    1040             # or ... $self->cfg('HTML_ROOT_DIR');
    1041              
    1042             See the list of plugins below for more config file integration solutions.
    1043              
    1044             =head3 run()
    1045              
    1046             The run() method is called upon your Application Module object, from
    1047             your Instance Script. When called, it executes the functionality
    1048             in your Application Module.
    1049              
    1050             my $webapp = WebApp->new();
    1051             $webapp->run();
    1052              
    1053             This method first determines the application state by looking at the
    1054             value of the CGI parameter specified by mode_param() (defaults to
    1055             'rm' for "Run Mode"), which is expected to contain the name of the mode of
    1056             operation. If not specified, the state defaults to the value
    1057             of start_mode().
    1058              
    1059             Once the mode has been determined, run() looks at the dispatch
    1060             table stored in run_modes() and finds the function pointer which
    1061             is keyed from the mode name. If found, the function is called and the
    1062             data returned is print()'ed to STDOUT and to the browser. If
    1063             the specified mode is not found in the run_modes() table, run() will
    1064             croak().
    1065              
    1066             =head2 PSGI support
    1067              
    1068             CGI::Application offers native L support. The default query object
    1069             for this is L, which simply wrappers CGI.pm to provide PSGI
    1070             support to it.
    1071              
    1072             =head3 psgi_app()
    1073              
    1074             $psgi_coderef = WebApp->psgi_app({ ... args to new() ... });
    1075              
    1076             The simplest way to create and return a PSGI-compatible coderef. Pass in
    1077             arguments to a hashref just as would to new. This returns a PSGI-compatible
    1078             coderef, using L as the query object. To use a different query
    1079             object, construct your own object using C<< run_as_psgi() >>, as shown below.
    1080              
    1081             It's possible that we'll change from CGI::PSGI to a different-but-compatible
    1082             query object for PSGI support in the future, perhaps if CGI.pm adds native
    1083             PSGI support.
    1084              
    1085             =head3 run_as_psgi()
    1086              
    1087             my $psgi_aref = $webapp->run_as_psgi;
    1088              
    1089             Just like C<< run >>, but prints no output and returns the data structure
    1090             required by the L specification. Use this if you want to run the
    1091             application on top of a PSGI-compatible handler, such as L provides.
    1092              
    1093             If you are just getting started, just use C<< run() >>. It's easy to switch to using
    1094             C<< run_as_psgi >> later.
    1095              
    1096             Why use C<< run_as_psgi() >>? There are already solutions to run
    1097             CGI::Application-based projects on several web servers with dozens of plugins.
    1098             Running as a PSGI-compatible application provides the ability to run on
    1099             additional PSGI-compatible servers, as well as providing access to all of the
    1100             "Middleware" solutions available through the L project.
    1101              
    1102             The structure returned is an arrayref, containing the status code, an arrayref
    1103             of header key/values and an arrayref containing the body.
    1104              
    1105             [ 200, [ 'Content-Type' => 'text/html' ], [ $body ] ]
    1106              
    1107             By default the body is a single scalar, but plugins may modify this to return
    1108             other value PSGI values. See L for details about the
    1109             response format.
    1110              
    1111             Note that calling C<< run_as_psgi >> only handles the I portion of the
    1112             PSGI spec. to handle the input, you need to use a CGI.pm-like query object that
    1113             is PSGI-compliant, such as L. This query object must provide L
    1114             and L methods.
    1115              
    1116             The final result might look like this:
    1117              
    1118             use WebApp;
    1119             use CGI::PSGI;
    1120              
    1121             my $handler = sub {
    1122             my $env = shift;
    1123             my $webapp = WebApp->new({ QUERY => CGI::PSGI->new($env) });
    1124             $webapp->run_as_psgi;
    1125             };
    1126              
    1127             =head2 Additional PSGI Return Values
    1128              
    1129             The PSGI Specification allows for returning a file handle or a subroutine reference instead of byte strings. In PSGI mode this is supported directly by CGI::Application. Have your run mode return a file handle or compatible subref as follows:
    1130              
    1131             sub returning_a_file_handle {
    1132             my $self = shift;
    1133              
    1134             $self->header_props(-type => 'text/plain');
    1135              
    1136             open my $fh, "<", 'test_file.txt' or die "OOPS! $!";
    1137              
    1138             return $fh;
    1139             }
    1140              
    1141             sub returning_a_subref {
    1142             my $self = shift;
    1143              
    1144             $self->header_props(-type => 'text/plain');
    1145             return sub {
    1146             my $writer = shift;
    1147             foreach my $i (1..10) {
    1148             #sleep 1;
    1149             $writer->write("check $i: " . time . "\n");
    1150             }
    1151             };
    1152             }
    1153              
    1154             =head2 Methods to possibly override
    1155              
    1156             CGI::Application implements some methods which are expected to be overridden
    1157             by implementing them in your sub-class module. These methods are as follows:
    1158              
    1159             =head3 setup()
    1160              
    1161             This method is called by the inherited new() constructor method. The
    1162             setup() method should be used to define the following property/methods:
    1163              
    1164             mode_param() - set the name of the run mode CGI param.
    1165             start_mode() - text scalar containing the default run mode.
    1166             error_mode() - text scalar containing the error mode.
    1167             run_modes() - hash table containing mode => function mappings.
    1168             tmpl_path() - text scalar or array reference containing path(s) to template files.
    1169              
    1170             Your setup() method may call any of the instance methods of your application.
    1171             This function is a good place to define properties specific to your application
    1172             via the $webapp->param() method.
    1173              
    1174             Your setup() method might be implemented something like this:
    1175              
    1176             sub setup {
    1177             my $self = shift;
    1178             $self->tmpl_path('/path/to/my/templates/');
    1179             $self->start_mode('putform');
    1180             $self->error_mode('my_error_rm');
    1181             $self->run_modes({
    1182             'putform' => 'my_putform_func',
    1183             'postdata' => 'my_data_func'
    1184             });
    1185             $self->param('myprop1');
    1186             $self->param('myprop2', 'prop2value');
    1187             $self->param('myprop3', ['p3v1', 'p3v2', 'p3v3']);
    1188             }
    1189              
    1190             However, often times all that needs to be in setup() is defining your run modes
    1191             and your start mode. L allows you to do
    1192             this with a simple syntax, using run mode attributes:
    1193              
    1194             use CGI::Application::Plugin::AutoRunmode;
    1195              
    1196             sub show_first : StartRunmode { ... };
    1197             sub do_next : Runmode { ... }
    1198              
    1199             =head3 teardown()
    1200              
    1201             If implemented, this method is called automatically after your application runs. It
    1202             can be used to clean up after your operations. A typical use of the
    1203             teardown() function is to disconnect a database connection which was
    1204             established in the setup() function. You could also use the teardown()
    1205             method to store state information about the application to the server.
    1206              
    1207              
    1208             =head3 cgiapp_init()
    1209              
    1210             If implemented, this method is called automatically right before the
    1211             setup() method is called. This method provides an optional initialization
    1212             hook, which improves the object-oriented characteristics of
    1213             CGI::Application. The cgiapp_init() method receives, as its parameters,
    1214             all the arguments which were sent to the new() method.
    1215              
    1216             An example of the benefits provided by utilizing this hook is
    1217             creating a custom "application super-class" from which all
    1218             your web applications would inherit, instead of CGI::Application.
    1219              
    1220             Consider the following:
    1221              
    1222             # In MySuperclass.pm:
    1223             package MySuperclass;
    1224             use base 'CGI::Application';
    1225             sub cgiapp_init {
    1226             my $self = shift;
    1227             # Perform some project-specific init behavior
    1228             # such as to load settings from a database or file.
    1229             }
    1230              
    1231              
    1232             # In MyApplication.pm:
    1233             package MyApplication;
    1234             use base 'MySuperclass';
    1235             sub setup { ... }
    1236             sub teardown { ... }
    1237             # The rest of your CGI::Application-based follows...
    1238              
    1239              
    1240             By using CGI::Application and the cgiapp_init() method as illustrated,
    1241             a suite of applications could be designed to share certain
    1242             characteristics. This has the potential for much cleaner code
    1243             built on object-oriented inheritance.
    1244              
    1245              
    1246             =head3 cgiapp_prerun()
    1247              
    1248             If implemented, this method is called automatically right before the
    1249             selected run mode method is called. This method provides an optional
    1250             pre-runmode hook, which permits functionality to be added at the point
    1251             right before the run mode method is called. To further leverage this
    1252             hook, the value of the run mode is passed into cgiapp_prerun().
    1253              
    1254             Another benefit provided by utilizing this hook is
    1255             creating a custom "application super-class" from which all
    1256             your web applications would inherit, instead of CGI::Application.
    1257              
    1258             Consider the following:
    1259              
    1260             # In MySuperclass.pm:
    1261             package MySuperclass;
    1262             use base 'CGI::Application';
    1263             sub cgiapp_prerun {
    1264             my $self = shift;
    1265             # Perform some project-specific init behavior
    1266             # such as to implement run mode specific
    1267             # authorization functions.
    1268             }
    1269              
    1270              
    1271             # In MyApplication.pm:
    1272             package MyApplication;
    1273             use base 'MySuperclass';
    1274             sub setup { ... }
    1275             sub teardown { ... }
    1276             # The rest of your CGI::Application-based follows...
    1277              
    1278              
    1279             By using CGI::Application and the cgiapp_prerun() method as illustrated,
    1280             a suite of applications could be designed to share certain
    1281             characteristics. This has the potential for much cleaner code
    1282             built on object-oriented inheritance.
    1283              
    1284             It is also possible, within your cgiapp_prerun() method, to change the
    1285             run mode of your application. This can be done via the prerun_mode()
    1286             method, which is discussed elsewhere in this POD.
    1287              
    1288             =head3 cgiapp_postrun()
    1289              
    1290             If implemented, this hook will be called after the run mode method
    1291             has returned its output, but before HTTP headers are generated. This
    1292             will give you an opportunity to modify the body and headers before they
    1293             are returned to the web browser.
    1294              
    1295             A typical use for this hook is pipelining the output of a CGI-Application
    1296             through a series of "filter" processors. For example:
    1297              
    1298             * You want to enclose the output of all your CGI-Applications in
    1299             an HTML table in a larger page.
    1300              
    1301             * Your run modes return structured data (such as XML), which you
    1302             want to transform using a standard mechanism (such as XSLT).
    1303              
    1304             * You want to post-process CGI-App output through another system,
    1305             such as HTML::Mason.
    1306              
    1307             * You want to modify HTTP headers in a particular way across all
    1308             run modes, based on particular criteria.
    1309              
    1310             The cgiapp_postrun() hook receives a reference to the output from
    1311             your run mode method, in addition to the CGI-App object. A typical
    1312             cgiapp_postrun() method might be implemented as follows:
    1313              
    1314             sub cgiapp_postrun {
    1315             my $self = shift;
    1316             my $output_ref = shift;
    1317              
    1318             # Enclose output HTML table
    1319             my $new_output = ""; "; ";
    1320             $new_output .= "
    Hello, World!
    1321             $new_output .= "
    ". $$output_ref ."
    1322             $new_output .= "
    ";
    1323              
    1324             # Replace old output with new output
    1325             $$output_ref = $new_output;
    1326             }
    1327              
    1328              
    1329             Obviously, with access to the CGI-App object you have full access to use all
    1330             the methods normally available in a run mode. You could, for example, use
    1331             C to replace the static HTML in this example with HTML::Template.
    1332             You could change the HTTP headers (via C and C
    1333             methods) to set up a redirect. You could also use the objects properties
    1334             to apply changes only under certain circumstance, such as a in only certain run
    1335             modes, and when a C is a particular value.
    1336              
    1337              
    1338             =head3 cgiapp_get_query()
    1339              
    1340             my $q = $webapp->cgiapp_get_query;
    1341              
    1342             Override this method to retrieve the query object if you wish to use a
    1343             different query interface instead of CGI.pm.
    1344              
    1345             CGI.pm is only loaded if it is used on a given request.
    1346              
    1347             If you can use an alternative to CGI.pm, it needs to have some compatibility
    1348             with the CGI.pm API. For normal use, just having a compatible C method
    1349             should be sufficient.
    1350              
    1351             If you use the C option to the mode_param() method, then we will call
    1352             the C method on the query object.
    1353              
    1354             If you use the C method in CGI::Application, we will call the C and
    1355             C methods on the query object.
    1356              
    1357             =head2 Essential Application Methods
    1358              
    1359             The following methods are inherited from CGI::Application, and are
    1360             available to be called by your application within your Application
    1361             Module. They are called essential because you will use all are most
    1362             of them to get any application up and running. These functions are listed in alphabetical order.
    1363              
    1364             =head3 load_tmpl()
    1365              
    1366             my $tmpl_obj = $webapp->load_tmpl;
    1367             my $tmpl_obj = $webapp->load_tmpl('some.html');
    1368             my $tmpl_obj = $webapp->load_tmpl( \$template_content );
    1369             my $tmpl_obj = $webapp->load_tmpl( FILEHANDLE );
    1370              
    1371             This method takes the name of a template file, a reference to template data
    1372             or a FILEHANDLE and returns an HTML::Template object. If the filename is undefined or missing, CGI::Application will default to trying to use the current run mode name, plus the extension ".html".
    1373              
    1374             If you use the default template naming system, you should also use
    1375             L, which simply helps to keep the current
    1376             name accurate when you pass control from one run mode to another.
    1377              
    1378             ( For integration with other template systems
    1379             and automated template names, see "Alternatives to load_tmpl() below. )
    1380              
    1381             When you pass in a filename, the HTML::Template->new_file() constructor
    1382             is used for create the object. When you pass in a reference to the template
    1383             content, the HTML::Template->new_scalar_ref() constructor is used and
    1384             when you pass in a filehandle, the HTML::Template->new_filehandle()
    1385             constructor is used.
    1386              
    1387             Refer to L for specific usage of HTML::Template.
    1388              
    1389             If tmpl_path() has been specified, load_tmpl() will set the
    1390             HTML::Template C option to the path(s) provided. This further
    1391             assists in encapsulating template usage.
    1392              
    1393             The load_tmpl() method will pass any extra parameters sent to it directly to
    1394             HTML::Template->new_file() (or new_scalar_ref() or new_filehandle()).
    1395             This will allow the HTML::Template object to be further customized:
    1396              
    1397             my $tmpl_obj = $webapp->load_tmpl('some_other.html',
    1398             die_on_bad_params => 0,
    1399             cache => 1
    1400             );
    1401              
    1402             Note that if you want to pass extra arguments but use the default template
    1403             name, you still need to provide a name of C:
    1404              
    1405             my $tmpl_obj = $webapp->load_tmpl(undef,
    1406             die_on_bad_params => 0,
    1407             cache => 1
    1408             );
    1409              
    1410             B
    1411              
    1412             If your application requires more specialized behavior than this, you can
    1413             always replace it by overriding load_tmpl() by implementing your own
    1414             load_tmpl() in your CGI::Application sub-class application module.
    1415              
    1416             First, you may want to check out the template related plugins.
    1417              
    1418             L focuses just on Template Toolkit integration,
    1419             and features pre-and-post features, singleton support and more.
    1420              
    1421             L can help if you want to return a stream and
    1422             not a file. It features a simple syntax and MIME-type detection.
    1423              
    1424             B
    1425              
    1426             You may specify an API-compatible alternative to L by setting
    1427             a new C:
    1428              
    1429             $self->html_tmpl_class('HTML::Template::Dumper');
    1430              
    1431             The default is "HTML::Template". The alternate class should
    1432             provide at least the following parts of the HTML::Template API:
    1433              
    1434             $t = $class->new( scalarref => ... ); # If you use scalarref templates
    1435             $t = $class->new( filehandle => ... ); # If you use filehandle templates
    1436             $t = $class->new( filename => ... );
    1437             $t->param(...);
    1438              
    1439             Here's an example case allowing you to precisely test what's sent to your
    1440             templates:
    1441              
    1442             $ENV{CGI_APP_RETURN_ONLY} = 1;
    1443             my $webapp = WebApp->new;
    1444             $webapp->html_tmpl_class('HTML::Template::Dumper');
    1445             my $out_str = $webapp->run;
    1446             my $tmpl_href = eval "$out_str";
    1447              
    1448             # Now Precisely test what would be set to the template
    1449             is ($tmpl_href->{pet_name}, 'Daisy', "Daisy is sent template");
    1450              
    1451             This is a powerful technique because HTML::Template::Dumper loads and considers
    1452             the template file that would actually be used. If the 'pet_name' token was missing
    1453             in the template, the above test would fail. So, you are testing both your code
    1454             and your templates in a much more precise way than using simple regular
    1455             expressions to see if the string "Daisy" appeared somewhere on the page.
    1456              
    1457             B
    1458              
    1459             Plugin authors will be interested to know that you can register a callback that
    1460             will be executed just before load_tmpl() returns:
    1461              
    1462             $self->add_callback('load_tmpl',\&your_method);
    1463              
    1464             When C is executed, it will be passed three arguments:
    1465              
    1466             1. A hash reference of the extra params passed into C
    1467             2. Followed by a hash reference to template parameters.
    1468             With both of these, you can modify them by reference to affect
    1469             values that are actually passed to the new() and param() methods of the
    1470             template object.
    1471             3. The name of the template file.
    1472              
    1473             Here's an example stub for a load_tmpl() callback:
    1474              
    1475             sub my_load_tmpl_callback {
    1476             my ($c, $ht_params, $tmpl_params, $tmpl_file) = @_
    1477             # modify $ht_params or $tmpl_params by reference...
    1478             }
    1479              
    1480             =head3 param()
    1481              
    1482             $webapp->param('pname', $somevalue);
    1483              
    1484             The param() method provides a facility through which you may set
    1485             application instance properties which are accessible throughout
    1486             your application.
    1487              
    1488             The param() method may be used in two basic ways. First, you may use it
    1489             to get or set the value of a parameter:
    1490              
    1491             $webapp->param('scalar_param', '123');
    1492             my $scalar_param_values = $webapp->param('some_param');
    1493              
    1494             Second, when called in the context of an array, with no parameter name
    1495             specified, param() returns an array containing all the parameters which
    1496             currently exist:
    1497              
    1498             my @all_params = $webapp->param();
    1499              
    1500             The param() method also allows you to set a bunch of parameters at once
    1501             by passing in a hash (or hashref):
    1502              
    1503             $webapp->param(
    1504             'key1' => 'val1',
    1505             'key2' => 'val2',
    1506             'key3' => 'val3',
    1507             );
    1508              
    1509             The param() method enables a very valuable system for
    1510             customizing your applications on a per-instance basis.
    1511             One Application Module might be instantiated by different
    1512             Instance Scripts. Each Instance Script might set different values for a
    1513             set of parameters. This allows similar applications to share a common
    1514             code-base, but behave differently. For example, imagine a mail form
    1515             application with a single Application Module, but multiple Instance
    1516             Scripts. Each Instance Script might specify a different recipient.
    1517             Another example would be a web bulletin boards system. There could be
    1518             multiple boards, each with a different topic and set of administrators.
    1519              
    1520             The new() method provides a shortcut for specifying a number of run-time
    1521             parameters at once. Internally, CGI::Application calls the param()
    1522             method to set these properties. The param() method is a powerful tool for
    1523             greatly increasing your application's re-usability.
    1524              
    1525             =head3 query()
    1526              
    1527             my $q = $webapp->query();
    1528             my $remote_user = $q->remote_user();
    1529              
    1530             This method retrieves the CGI.pm query object which has been created
    1531             by instantiating your Application Module. For details on usage of this
    1532             query object, refer to L. CGI::Application is built on the CGI
    1533             module. Generally speaking, you will want to become very familiar
    1534             with CGI.pm, as you will use the query object whenever you want to
    1535             interact with form data.
    1536              
    1537             When the new() method is called, a CGI query object is automatically created.
    1538             If, for some reason, you want to use your own CGI query object, the new()
    1539             method supports passing in your existing query object on construction using
    1540             the QUERY attribute.
    1541              
    1542             There are a few rare situations where you want your own query object to be
    1543             used after your Application Module has already been constructed. In that case
    1544             you can pass it to c like this:
    1545              
    1546             $webapp->query($new_query_object);
    1547             my $q = $webapp->query(); # now uses $new_query_object
    1548              
    1549             =head3 run_modes()
    1550              
    1551             # The common usage: an arrayref of run mode names that exactly match subroutine names
    1552             $webapp->run_modes([qw/
    1553             form_display
    1554             form_process
    1555             /]);
    1556              
    1557             # With a hashref, use a different name or a code ref
    1558             $webapp->run_modes(
    1559             'mode1' => 'some_sub_by_name',
    1560             'mode2' => \&some_other_sub_by_ref
    1561             );
    1562              
    1563             This accessor/mutator specifies the dispatch table for the
    1564             application states, using the syntax examples above. It returns
    1565             the dispatch table as a hash.
    1566              
    1567             The run_modes() method may be called more than once. Additional values passed
    1568             into run_modes() will be added to the run modes table. In the case that an
    1569             existing run mode is re-defined, the new value will override the existing value.
    1570             This behavior might be useful for applications which are created via inheritance
    1571             from another application, or some advanced application which modifies its
    1572             own capabilities based on user input.
    1573              
    1574             The run() method uses the data in this table to send the application to the
    1575             correct function as determined by reading the CGI parameter specified by
    1576             mode_param() (defaults to 'rm' for "Run Mode"). These functions are referred
    1577             to as "run mode methods".
    1578              
    1579             The hash table set by this method is expected to contain the mode
    1580             name as a key. The value should be either a hard reference (a subref)
    1581             to the run mode method which you want to be called when the application enters
    1582             the specified run mode, or the name of the run mode method to be called:
    1583              
    1584             'mode_name_by_ref' => \&mode_function
    1585             'mode_name_by_name' => 'mode_function'
    1586              
    1587             The run mode method specified is expected to return a block of text (e.g.:
    1588             HTML) which will eventually be sent back to the web browser. The run mode
    1589             method may return its block of text as a scalar or a scalar-ref.
    1590              
    1591             An advantage of specifying your run mode methods by name instead of
    1592             by reference is that you can more easily create derivative applications
    1593             using inheritance. For instance, if you have a new application which is
    1594             exactly the same as an existing application with the exception of one
    1595             run mode, you could simply inherit from that other application and override
    1596             the run mode method which is different. If you specified your run mode
    1597             method by reference, your child class would still use the function
    1598             from the parent class.
    1599              
    1600             An advantage of specifying your run mode methods by reference instead of by name
    1601             is performance. Dereferencing a subref is faster than eval()-ing
    1602             a code block. If run-time performance is a critical issue, specify
    1603             your run mode methods by reference and not by name. The speed differences
    1604             are generally small, however, so specifying by name is preferred.
    1605              
    1606             Specifying the run modes by array reference:
    1607              
    1608             $webapp->run_modes([ 'mode1', 'mode2', 'mode3' ]);
    1609              
    1610             This is the same as using a hash, with keys equal to values
    1611              
    1612             $webapp->run_modes(
    1613             'mode1' => 'mode1',
    1614             'mode2' => 'mode2',
    1615             'mode3' => 'mode3'
    1616             );
    1617              
    1618             Often, it makes good organizational sense to have your run modes map to
    1619             methods of the same name. The array-ref interface provides a shortcut
    1620             to that behavior while reducing verbosity of your code.
    1621              
    1622             Note that another importance of specifying your run modes in either a
    1623             hash or array-ref is to assure that only those Perl methods which are
    1624             specifically designated may be called via your application. Application
    1625             environments which don't specify allowed methods and disallow all others
    1626             are insecure, potentially opening the door to allowing execution of
    1627             arbitrary code. CGI::Application maintains a strict "default-deny" stance
    1628             on all method invocation, thereby allowing secure applications
    1629             to be built upon it.
    1630              
    1631             B
    1632              
    1633             Your application should *NEVER* print() to STDOUT.
    1634             Using print() to send output to STDOUT (including HTTP headers) is
    1635             exclusively the domain of the inherited run() method. Breaking this
    1636             rule is a common source of errors. If your program is erroneously
    1637             sending content before your HTTP header, you are probably breaking this rule.
    1638              
    1639              
    1640             B
    1641              
    1642             If CGI::Application is asked to go to a run mode which doesn't exist
    1643             it will usually croak() with errors. If this is not your desired
    1644             behavior, it is possible to catch this exception by implementing
    1645             a run mode with the reserved name "AUTOLOAD":
    1646              
    1647             $self->run_modes(
    1648             "AUTOLOAD" => \&catch_my_exception
    1649             );
    1650              
    1651             Before CGI::Application calls croak() it will check for the existence
    1652             of a run mode called "AUTOLOAD". If specified, this run mode will in
    1653             invoked just like a regular run mode, with one exception: It will
    1654             receive, as an argument, the name of the run mode which invoked it:
    1655              
    1656             sub catch_my_exception {
    1657             my $self = shift;
    1658             my $intended_runmode = shift;
    1659              
    1660             my $output = "Looking for '$intended_runmode', but found 'AUTOLOAD' instead";
    1661             return $output;
    1662             }
    1663              
    1664             This functionality could be used for a simple human-readable error
    1665             screen, or for more sophisticated application behaviors.
    1666              
    1667              
    1668             =head3 start_mode()
    1669              
    1670             $webapp->start_mode('mode1');
    1671              
    1672             The start_mode contains the name of the mode as specified in the run_modes()
    1673             table. Default mode is "start". The mode key specified here will be used
    1674             whenever the value of the CGI form parameter specified by mode_param() is
    1675             not defined. Generally, this is the first time your application is executed.
    1676              
    1677             =head3 tmpl_path()
    1678              
    1679             $webapp->tmpl_path('/path/to/some/templates/');
    1680              
    1681             This access/mutator method sets the file path to the directory (or directories)
    1682             where the templates are stored. It is used by load_tmpl() to find the template
    1683             files, using HTML::Template's C option. To set the path you can either
    1684             pass in a text scalar or an array reference of multiple paths.
    1685              
    1686              
    1687              
    1688             =head2 More Application Methods
    1689              
    1690             You can skip this section if you are just getting started.
    1691              
    1692             The following additional methods are inherited from CGI::Application, and are
    1693             available to be called by your application within your Application Module.
    1694             These functions are listed in alphabetical order.
    1695              
    1696             =head3 delete()
    1697              
    1698             $webapp->delete('my_param');
    1699              
    1700             The delete() method is used to delete a parameter that was previously
    1701             stored inside of your application either by using the PARAMS hash that
    1702             was passed in your call to new() or by a call to the param() method.
    1703             This is similar to the delete() method of CGI.pm. It is useful if your
    1704             application makes decisions based on the existence of certain params that
    1705             may have been removed in previous sections of your app or simply to
    1706             clean-up your param()s.
    1707              
    1708              
    1709             =head3 dump()
    1710              
    1711             print STDERR $webapp->dump();
    1712              
    1713             The dump() method is a debugging function which will return a
    1714             chunk of text which contains all the environment and web form
    1715             data of the request, formatted nicely for human readability.
    1716             Useful for outputting to STDERR.
    1717              
    1718              
    1719             =head3 dump_html()
    1720              
    1721             my $output = $webapp->dump_html();
    1722              
    1723             The dump_html() method is a debugging function which will return
    1724             a chunk of text which contains all the environment and web form
    1725             data of the request, formatted nicely for human readability via
    1726             a web browser. Useful for outputting to a browser. Please consider
    1727             the security implications of using this in production code.
    1728              
    1729             =head3 error_mode()
    1730              
    1731             $webapp->error_mode('my_error_rm');
    1732              
    1733             If the runmode dies for whatever reason, C see if you have set a
    1734             value for C. If you have, C will call that method
    1735             as a run mode, passing $@ as the only parameter.
    1736              
    1737             Plugins authors will be interested to know that just before C is
    1738             called, the C hook will be executed, with the error message passed in as
    1739             the only parameter.
    1740              
    1741             No C is defined by default. The death of your C run
    1742             mode is not trapped, so you can also use it to die in your own special way.
    1743              
    1744             For a complete integrated logging solution, check out L.
    1745              
    1746             =head3 get_current_runmode()
    1747              
    1748             $webapp->get_current_runmode();
    1749              
    1750             The C method will return a text scalar containing
    1751             the name of the run mode which is currently being executed. If the
    1752             run mode has not yet been determined, such as during setup(), this method
    1753             will return undef.
    1754              
    1755             =head3 header_add()
    1756              
    1757             # add or replace the 'type' header
    1758             $webapp->header_add( -type => 'image/png' );
    1759              
    1760             - or -
    1761              
    1762             # add an additional cookie
    1763             $webapp->header_add(-cookie=>[$extra_cookie]);
    1764              
    1765             The C method is used to add one or more headers to the outgoing
    1766             response headers. The parameters will eventually be passed on to the CGI.pm
    1767             header() method, so refer to the L docs for exact usage details.
    1768              
    1769             Unlike calling C, C will preserve any existing
    1770             headers. If a scalar value is passed to C it will replace
    1771             the existing value for that key.
    1772              
    1773             If an array reference is passed as a value to C, values in
    1774             that array ref will be appended to any existing values for that key.
    1775             This is primarily useful for setting an additional cookie after one has already
    1776             been set.
    1777              
    1778             =head3 header_props()
    1779              
    1780             # Set a complete set of headers
    1781             %set_headers = $webapp->header_props(-type=>'image/gif',-expires=>'+3d');
    1782              
    1783             # clobber / reset all headers
    1784             %set_headers = $webapp->header_props({});
    1785              
    1786             # Just retrieve the headers
    1787             %set_headers = $webapp->header_props();
    1788              
    1789             The C method expects a hash of CGI.pm-compatible
    1790             HTTP header properties. These properties will be passed directly
    1791             to the C or C methods of the query() object. Refer
    1792             to the docs of your query object for details. (Be default, it's L.pm).
    1793              
    1794             Calling header_props with an empty hashref clobber any existing headers that have
    1795             previously set.
    1796              
    1797             C returns a hash of all the headers that have currently been
    1798             set. It can be called with no arguments just to get the hash current headers
    1799             back.
    1800              
    1801             To add additional headers later without clobbering the old ones,
    1802             see C.
    1803              
    1804             B
    1805              
    1806             It is through the C and C method that you may modify the outgoing
    1807             HTTP headers. This is necessary when you want to set a cookie, set the mime
    1808             type to something other than "text/html", or perform a redirect. The
    1809             header_props() method works in conjunction with the header_type() method.
    1810             The value contained in header_type() determines if we use CGI::header() or
    1811             CGI::redirect(). The content of header_props() is passed as an argument to
    1812             whichever CGI.pm function is called.
    1813              
    1814             Understanding this relationship is important if you wish to manipulate
    1815             the HTTP header properly.
    1816              
    1817             =head3 header_type()
    1818              
    1819             $webapp->header_type('redirect');
    1820             $webapp->header_type('none');
    1821              
    1822             This method used to declare that you are setting a redirection header,
    1823             or that you want no header to be returned by the framework.
    1824              
    1825             The value of 'header' is almost never used, as it is the default.
    1826              
    1827             B:
    1828              
    1829             sub some_redirect_mode {
    1830             my $self = shift;
    1831             # do stuff here....
    1832             $self->header_type('redirect');
    1833             $self->header_props(-url=> "http://site/path/doc.html" );
    1834             }
    1835              
    1836             To simplify that further, use L:
    1837              
    1838             return $self->redirect('http://www.example.com/');
    1839              
    1840             Setting the header to 'none' may be useful if you are streaming content.
    1841             In other contexts, it may be more useful to set C<$ENV{CGI_APP_RETURN_ONLY} = 1;>,
    1842             which suppresses all printing, including headers, and returns the output instead.
    1843              
    1844             That's commonly used for testing, or when using L as a controller
    1845             for a cron script!
    1846              
    1847             =cut
    1848              
    1849             sub html_tmpl_class {
    1850 7     7 0 12 my $self = shift;
    1851 7         9 my $tmpl_class = shift;
    1852              
    1853             # First use? Create new __ERROR_MODE
    1854 7 100       59 $self->{__HTML_TMPL_CLASS} = 'HTML::Template' unless (exists($self->{__HTML_TMPL_CLASS}));
    1855              
    1856 7 50       18 if (defined $tmpl_class) {
    1857 0         0 $self->{__HTML_TMPL_CLASS} = $tmpl_class;
    1858             }
    1859              
    1860 7         16 return $self->{__HTML_TMPL_CLASS};
    1861             }
    1862              
    1863             sub load_tmpl {
    1864 7     7 1 1190 my $self = shift;
    1865 7         16 my ($tmpl_file, @extra_params) = @_;
    1866              
    1867             # add tmpl_path to path array if one is set, otherwise add a path arg
    1868 7 100       19 if (my $tmpl_path = $self->tmpl_path) {
    1869 6 100       26 my @tmpl_paths = (ref $tmpl_path eq 'ARRAY') ? @$tmpl_path : $tmpl_path;
    1870 6         10 my $found = 0;
    1871 6         26 for( my $x = 0; $x < @extra_params; $x += 2 ) {
    1872 2 50 33     10 if ($extra_params[$x] eq 'path' and
    1873             ref $extra_params[$x+1] eq 'ARRAY') {
    1874 0         0 unshift @{$extra_params[$x+1]}, @tmpl_paths;
      0         0  
    1875 0         0 $found = 1;
    1876 0         0 last;
    1877             }
    1878             }
    1879 6 50       24 push(@extra_params, path => [ @tmpl_paths ]) unless $found;
    1880             }
    1881              
    1882 7         14 my %tmpl_params = ();
    1883 7         20 my %ht_params = @extra_params;
    1884 7 100       21 %ht_params = () unless keys %ht_params;
    1885              
    1886             # Define our extension if doesn't already exist;
    1887 7 100       28 $self->{__CURRENT_TMPL_EXTENSION} = '.html' unless defined $self->{__CURRENT_TMPL_EXTENSION};
    1888              
    1889             # Define a default template name based on the current run mode
    1890 7 50       20 unless (defined $tmpl_file) {
    1891 0         0 $tmpl_file = $self->get_current_runmode . $self->{__CURRENT_TMPL_EXTENSION};
    1892             }
    1893              
    1894 7         24 $self->call_hook('load_tmpl', \%ht_params, \%tmpl_params, $tmpl_file);
    1895              
    1896 7         32 my $ht_class = $self->html_tmpl_class;
    1897 7 50       485 eval "require $ht_class;" || die "require $ht_class failed: $@";
    1898              
    1899             # let's check $tmpl_file and see what kind of parameter it is - we
    1900             # now support 3 options: scalar (filename), ref to scalar (the
    1901             # actual html/template content) and reference to FILEHANDLE
    1902 7         48684 my $t = undef;
    1903 7 50       45 if ( ref $tmpl_file eq 'SCALAR' ) {
        50          
    1904 0         0 $t = $ht_class->new( scalarref => $tmpl_file, %ht_params );
    1905             } elsif ( ref $tmpl_file eq 'GLOB' ) {
    1906 0         0 $t = $ht_class->new( filehandle => $tmpl_file, %ht_params );
    1907             } else {
    1908 7         53 $t = $ht_class->new( filename => $tmpl_file, %ht_params);
    1909             }
    1910              
    1911 7 100       3828 if (keys %tmpl_params) {
    1912 1         7 $t->param(%tmpl_params);
    1913             }
    1914              
    1915 7         95 return $t;
    1916             }
    1917              
    1918             =pod
    1919              
    1920             =head3 mode_param()
    1921              
    1922             # Name the CGI form parameter that contains the run mode name.
    1923             # This is the default behavior, and is often sufficient.
    1924             $webapp->mode_param('rm');
    1925              
    1926             # Set the run mode name directly from a code ref
    1927             $webapp->mode_param(\&some_method);
    1928              
    1929             # Alternate interface, which allows you to set the run
    1930             # mode name directly from $ENV{PATH_INFO}.
    1931             $webapp->mode_param(
    1932             path_info=> 1,
    1933             param =>'rm'
    1934             );
    1935              
    1936             This accessor/mutator method is generally called in the setup() method.
    1937             It is used to help determine the run mode to call. There are three options for calling it.
    1938              
    1939             $webapp->mode_param('rm');
    1940              
    1941             Here, a CGI form parameter is named that will contain the name of the run mode
    1942             to use. This is the default behavior, with 'rm' being the parameter named used.
    1943              
    1944             $webapp->mode_param(\&some_method);
    1945              
    1946             Here a code reference is provided. It will return the name of the run mode
    1947             to use directly. Example:
    1948              
    1949             sub some_method {
    1950             my $self = shift;
    1951             return 'run_mode_x';
    1952             }
    1953              
    1954             This would allow you to programmatically set the run mode based on arbitrary logic.
    1955              
    1956             $webapp->mode_param(
    1957             path_info=> 1,
    1958             param =>'rm'
    1959             );
    1960              
    1961             This syntax allows you to easily set the run mode from $ENV{PATH_INFO}. It
    1962             will try to set the run mode from the first part of $ENV{PATH_INFO} (before the
    1963             first "/"). To specify that you would rather get the run mode name from the 2nd
    1964             part of $ENV{PATH_INFO}:
    1965              
    1966             $webapp->mode_param( path_info=> 2 );
    1967              
    1968             This also demonstrates that you don't need to pass in the C hash key. It will
    1969             still default to C.
    1970              
    1971             You can also set C to a negative value. This works just like a negative
    1972             list index: if it is -1 the run mode name will be taken from the last part of
    1973             $ENV{PATH_INFO}, if it is -2, the one before that, and so on.
    1974              
    1975              
    1976             If no run mode is found in $ENV{PATH_INFO}, it will fall back to looking in the
    1977             value of a the CGI form field defined with 'param', as described above. This
    1978             allows you to use the convenient $ENV{PATH_INFO} trick most of the time, but
    1979             also supports the edge cases, such as when you don't know what the run mode
    1980             will be ahead of time and want to define it with JavaScript.
    1981              
    1982             B.
    1983              
    1984             Using $ENV{PATH_INFO} to name your run mode creates a clean separation between
    1985             the form variables you submit and how you determine the processing run mode. It
    1986             also creates URLs that are more search engine friendly. Let's look at an
    1987             example form submission using this syntax:
    1988              
    1989            
    1990            
    1991              
    1992             Here the run mode would be set to "edit_form". Here's another example with a
    1993             query string:
    1994              
    1995             /cgi-bin/instance.cgi/edit_form?breed_id=2
    1996              
    1997             This demonstrates that you can use $ENV{PATH_INFO} and a query string together
    1998             without problems. $ENV{PATH_INFO} is defined as part of the CGI specification
    1999             should be supported by any web server that supports CGI scripts.
    2000              
    2001             =cut
    2002              
    2003             sub mode_param {
    2004 172     172 1 299 my $self = shift;
    2005 172         167 my $mode_param;
    2006              
    2007             # First use? Create new __MODE_PARAM
    2008 172 100       416 $self->{__MODE_PARAM} = 'rm' unless (exists($self->{__MODE_PARAM}));
    2009              
    2010 172         177 my %p;
    2011             # expecting a scalar or code ref
    2012 172 100       323 if ((scalar @_) == 1) {
    2013 104         134 $mode_param = $_[0];
    2014             }
    2015             # expecting hash style params
    2016             else {
    2017 68 50       169 croak("CGI::Application->mode_param() : You gave me an odd number of parameters to mode_param()!")
    2018             unless ((@_ % 2) == 0);
    2019 68         106 %p = @_;
    2020 68         86 $mode_param = $p{param};
    2021              
    2022 68 100 100     184 if ( $p{path_info} && $self->query->path_info() ) {
    2023 4         718 my $pi = $self->query->path_info();
    2024              
    2025 4         95 my $idx = $p{path_info};
    2026             # two cases: negative or positive index
    2027             # negative index counts from the end of path_info
    2028             # positive index needs to be fixed because
    2029             # computer scientists like to start counting from zero.
    2030 4 100       13 $idx -= 1 if ($idx > 0) ;
    2031              
    2032             # remove the leading slash
    2033 4         21 $pi =~ s!^/!!;
    2034              
    2035             # grab the requested field location
    2036 4   50     17 $pi = (split q'/', $pi)[$idx] || '';
    2037              
    2038 4 50       15 $mode_param = (length $pi) ? { run_mode => $pi } : $mode_param;
    2039             }
    2040              
    2041             }
    2042              
    2043             # If data is provided, set it
    2044 172 100 66     731 if (defined $mode_param and length $mode_param) {
    2045 109         158 $self->{__MODE_PARAM} = $mode_param;
    2046             }
    2047              
    2048 172         299 return $self->{__MODE_PARAM};
    2049             }
    2050              
    2051              
    2052             =head3 prerun_mode()
    2053              
    2054             $webapp->prerun_mode('new_run_mode');
    2055              
    2056             The prerun_mode() method is an accessor/mutator which can be used within
    2057             your cgiapp_prerun() method to change the run mode which is about to be executed.
    2058             For example, consider:
    2059              
    2060             # In WebApp.pm:
    2061             package WebApp;
    2062             use base 'CGI::Application';
    2063             sub cgiapp_prerun {
    2064             my $self = shift;
    2065              
    2066             # Get the web user name, if any
    2067             my $q = $self->query();
    2068             my $user = $q->remote_user();
    2069              
    2070             # Redirect to login, if necessary
    2071             unless ($user) {
    2072             $self->prerun_mode('login');
    2073             }
    2074             }
    2075              
    2076              
    2077             In this example, the web user will be forced into the "login" run mode
    2078             unless they have already logged in. The prerun_mode() method permits
    2079             a scalar text string to be set which overrides whatever the run mode
    2080             would otherwise be.
    2081              
    2082             The use of prerun_mode() within cgiapp_prerun() differs from setting
    2083             mode_param() to use a call-back via subroutine reference. It differs
    2084             because cgiapp_prerun() allows you to selectively set the run mode based
    2085             on some logic in your cgiapp_prerun() method. The call-back facility of
    2086             mode_param() forces you to entirely replace CGI::Application's mechanism
    2087             for determining the run mode with your own method. The prerun_mode()
    2088             method should be used in cases where you want to use CGI::Application's
    2089             normal run mode switching facility, but you want to make selective
    2090             changes to the mode under specific conditions.
    2091              
    2092             B The prerun_mode() method may ONLY be called in the context of
    2093             a cgiapp_prerun() method. Your application will die() if you call
    2094             prerun_mode() elsewhere, such as in setup() or a run mode method.
    2095              
    2096             =head2 Dispatching Clean URIs to run modes
    2097              
    2098             Modern web frameworks dispense with cruft in URIs, providing in clean
    2099             URIs instead. Instead of:
    2100              
    2101             /cgi-bin/item.cgi?rm=view&id=15
    2102              
    2103             A clean URI to describe the same resource might be:
    2104              
    2105             /item/15/view
    2106              
    2107             The process of mapping these URIs to run modes is called dispatching and is
    2108             handled by L. Dispatching is not required and is a
    2109             layer you can fairly easily add to an application later.
    2110              
    2111             =head2 Offline website development
    2112              
    2113             You can work on your CGI::Application project on your desktop or laptop without
    2114             installing a full-featured web-server like Apache. Instead, install
    2115             L from CPAN. After a few minutes of setup, you'll
    2116             have your own private application server up and running.
    2117              
    2118             =head2 Automated Testing
    2119              
    2120             L allows functional testing of a CGI::App-based project
    2121             without starting a web server. L could be used to test the app
    2122             through a real web server.
    2123              
    2124             Direct testing is also easy. CGI::Application will normally print the output of it's
    2125             run modes directly to STDOUT. This can be suppressed with an environment variable,
    2126             CGI_APP_RETURN_ONLY. For example:
    2127              
    2128             $ENV{CGI_APP_RETURN_ONLY} = 1;
    2129             $output = $webapp->run();
    2130             like($output, qr/good/, "output is good");
    2131              
    2132             Examples of this style can be seen in our own test suite.
    2133              
    2134             =head1 PLUG-INS
    2135              
    2136             CGI::Application has a plug-in architecture that is easy to use and easy
    2137             to develop new plug-ins for.
    2138              
    2139             =head2 Recommended Plug-ins
    2140              
    2141             The following plugins are recommended for general purpose web/db development:
    2142              
    2143             =over 4
    2144              
    2145             =item *
    2146              
    2147             L - is a simple plugin to provide a shorter syntax for executing a redirect.
    2148              
    2149             =item *
    2150              
    2151             L - Keeping your config details in a separate file is recommended for every project. This one integrates with L. Several more config plugin options are listed below.
    2152              
    2153             =item *
    2154              
    2155             L - Provides easy management of one or more database handles and can delay making the database connection until the moment it is actually used.
    2156              
    2157             =item *
    2158              
    2159             L - makes it a breeze to fill in an HTML form from data originating from a CGI query or a database record.
    2160              
    2161             =item *
    2162              
    2163             L - For a project that requires session
    2164             management, this plugin provides a useful wrapper around L
    2165              
    2166             =item *
    2167              
    2168             L - Integration with Data::FormValidator and HTML::FillInForm
    2169              
    2170             =back
    2171              
    2172             =head2 More plug-ins
    2173              
    2174             Many more plugins are available as alternatives and for specific uses. For a
    2175             current complete list, please consult CPAN:
    2176              
    2177             http://search.cpan.org/search?m=dist&q=CGI%2DApplication%2DPlugin
    2178              
    2179             =over 4
    2180              
    2181             =item *
    2182              
    2183             L - Use any templating system from within CGI::Application using a unified interface
    2184              
    2185             =item *
    2186              
    2187             L - Use Apache::* modules without interference
    2188              
    2189             =item *
    2190              
    2191             L - Automatically register runmodes
    2192              
    2193              
    2194             =item *
    2195              
    2196             L - Integration with L.
    2197              
    2198             =item *
    2199              
    2200             L - Integration with L.
    2201              
    2202             =item *
    2203              
    2204             L - Integration with L.
    2205              
    2206             =item *
    2207              
    2208             L - Add Gzip compression
    2209              
    2210              
    2211             =item *
    2212              
    2213             L - Integration with L
    2214              
    2215             =item *
    2216              
    2217             L - Help stream files to the browser
    2218              
    2219             =item *
    2220              
    2221             L - Allows for more of an ASP-style
    2222             code structure, with the difference that code and HTML for each screen are in
    2223             separate files.
    2224              
    2225             =item *
    2226              
    2227             L - Use L as an alternative to HTML::Template.
    2228              
    2229              
    2230             =back
    2231              
    2232              
    2233              
    2234             Consult each plug-in for the exact usage syntax.
    2235              
    2236             =head2 Writing Plug-ins
    2237              
    2238             Writing plug-ins is simple. Simply create a new package, and export the
    2239             methods that you want to become part of a CGI::Application project. See
    2240             L for an example.
    2241              
    2242             In order to avoid namespace conflicts within a CGI::Application object,
    2243             plugin developers are recommended to use a unique prefix, such as the
    2244             name of plugin package, when storing information. For instance:
    2245              
    2246             $app->{__PARAM} = 'foo'; # BAD! Could conflict.
    2247             $app->{'MyPlugin::Module::__PARAM'} = 'foo'; # Good.
    2248             $app->{'MyPlugin::Module'}{__PARAM} = 'foo'; # Good.
    2249              
    2250             =head2 Writing Advanced Plug-ins - Using callbacks
    2251              
    2252             When writing a plug-in, you may want some action to happen automatically at a
    2253             particular stage, such as setting up a database connection or initializing a
    2254             session. By using these 'callback' methods, you can register a subroutine
    2255             to run at a particular phase, accomplishing this goal.
    2256              
    2257             B
    2258              
    2259             # register a callback to the standard CGI::Application hooks
    2260             # one of 'init', 'prerun', 'postrun', 'teardown' or 'load_tmpl'
    2261             # As a plug-in author, this is probably the only method you need.
    2262              
    2263             # Class-based: callback will persist for all runs of the application
    2264             $class->add_callback('init', \&some_other_method);
    2265              
    2266             # Object-based: callback will only last for lifetime of this object
    2267             $self->add_callback('prerun', \&some_method);
    2268              
    2269             # If you want to create a new hook location in your application,
    2270             # You'll need to know about the following two methods to create
    2271             # the hook and call it.
    2272              
    2273             # Create a new hook
    2274             $self->new_hook('pretemplate');
    2275              
    2276             # Then later execute all the callbacks registered at this hook
    2277             $self->call_hook('pretemplate');
    2278              
    2279             B
    2280              
    2281             =head3 add_callback()
    2282              
    2283             $self->add_callback ('teardown', \&callback);
    2284             $class->add_callback('teardown', 'method');
    2285              
    2286             The add_callback method allows you to register a callback
    2287             function that is to be called at the given stage of execution.
    2288             Valid hooks include 'init', 'prerun', 'postrun' and 'teardown',
    2289             'load_tmpl', and any other hooks defined using the C
    2290             method.
    2291              
    2292             The callback should be a reference to a subroutine or the name of a
    2293             method.
    2294              
    2295             If multiple callbacks are added to the same hook, they will all be
    2296             executed one after the other. The exact order depends on which class
    2297             installed each callback, as described below under B.
    2298              
    2299             Callbacks can either be I or I, depending
    2300             upon whether you call C as an object method or a class
    2301             method:
    2302              
    2303             # add object-based callback
    2304             $self->add_callback('teardown', \&callback);
    2305              
    2306             # add class-based callbacks
    2307             $class->add_callback('teardown', \&callback);
    2308             My::Project->add_callback('teardown', \&callback);
    2309              
    2310             Object-based callbacks are stored in your web application's C<$c>
    2311             object; at the end of the request when the C<$c> object goes out of
    2312             scope, the callbacks are gone too.
    2313              
    2314             Object-based callbacks are useful for one-time tasks that apply only to
    2315             the current running application. For instance you could install a
    2316             C callback to trigger a long-running process to execute at the
    2317             end of the current request, after all the HTML has been sent to the
    2318             browser.
    2319              
    2320             Class-based callbacks survive for the duration of the running Perl
    2321             process. (In a persistent environment such as C or
    2322             C, a single Perl process can serve many web requests.)
    2323              
    2324             Class-based callbacks are useful for plugins to add features to all web
    2325             applications.
    2326              
    2327             Another feature of class-based callbacks is that your plugin can create
    2328             hooks and add callbacks at any time - even before the web application's
    2329             C<$c> object has been initialized. A good place to do this is in
    2330             your plugin's C subroutine:
    2331              
    2332             package CGI::Application::Plugin::MyPlugin;
    2333             use base 'Exporter';
    2334             sub import {
    2335             my $caller = scalar(caller);
    2336             $caller->add_callback('init', 'my_setup');
    2337             goto &Exporter::import;
    2338             }
    2339              
    2340             Notice that C<< $caller->add_callback >> installs the callback
    2341             on behalf of the module that contained the line:
    2342              
    2343             use CGI::Application::Plugin::MyPlugin;
    2344              
    2345             =cut
    2346              
    2347             sub add_callback {
    2348 44     44 1 1908 my ($c_or_class, $hook, $callback) = @_;
    2349              
    2350 44         51 $hook = lc $hook;
    2351              
    2352 44 50       90 die "no callback provided when calling add_callback" unless $callback;
    2353 44 50       125 die "Unknown hook ($hook)" unless exists $INSTALLED_CALLBACKS{$hook};
    2354              
    2355 44 100       57 if (ref $c_or_class) {
    2356             # Install in object
    2357 5         6 my $self = $c_or_class;
    2358 5         6 push @{ $self->{__INSTALLED_CALLBACKS}{$hook} }, $callback;
      5         18  
    2359             }
    2360             else {
    2361             # Install in class
    2362 39         36 my $class = $c_or_class;
    2363 39         29 push @{ $INSTALLED_CALLBACKS{$hook}{$class} }, $callback;
      39         99  
    2364             }
    2365              
    2366             }
    2367              
    2368             =head3 new_hook(HOOK)
    2369              
    2370             $self->new_hook('pretemplate');
    2371              
    2372             The C method can be used to create a new location for developers to
    2373             register callbacks. It takes one argument, a hook name. The hook location is
    2374             created if it does not already exist. A true value is always returned.
    2375              
    2376             For an example, L adds hooks before and after every
    2377             template is processed.
    2378              
    2379             See C for more details about how hooks are called.
    2380              
    2381             =cut
    2382              
    2383             sub new_hook {
    2384 5     5 1 311 my ($class, $hook) = @_;
    2385 5   100     25 $INSTALLED_CALLBACKS{$hook} ||= {};
    2386 5         11 return 1;
    2387             }
    2388              
    2389             =head3 call_hook(HOOK)
    2390              
    2391             $self->call_hook('pretemplate', @args);
    2392              
    2393             The C method is used to executed the callbacks that have been registered
    2394             at the given hook. It is used in conjunction with the C method which
    2395             allows you to create a new hook location.
    2396              
    2397             The first argument to C is the hook name. Any remaining arguments
    2398             are passed to every callback executed at the hook location. So, a stub for a
    2399             callback at the 'pretemplate' hook would look like this:
    2400              
    2401             sub my_hook {
    2402             my ($c,@args) = @_;
    2403             # ....
    2404             }
    2405              
    2406             Note that hooks are semi-public locations. Calling a hook means executing
    2407             callbacks that were registered to that hook by the current object and also
    2408             those registered by any of the current object's parent classes. See below for
    2409             the exact ordering.
    2410              
    2411             =cut
    2412              
    2413             sub call_hook {
    2414 261     261 1 326 my $self = shift;
    2415 261   33     546 my $app_class = ref $self || $self;
    2416 261         345 my $hook = lc shift;
    2417 261         329 my @args = @_;
    2418              
    2419 261 50       543 die "Unknown hook ($hook)" unless exists $INSTALLED_CALLBACKS{$hook};
    2420              
    2421 261         203 my %executed_callback;
    2422              
    2423             # First, run callbacks installed in the object
    2424 261         223 foreach my $callback (@{ $self->{__INSTALLED_CALLBACKS}{$hook} }) {
      261         774  
    2425 5 50       13 next if $executed_callback{$callback};
    2426 5         5 eval { $self->$callback(@args); };
      5         20  
    2427 5         38 $executed_callback{$callback} = 1;
    2428 5 50       14 die "Error executing object callback in $hook stage: $@" if $@;
    2429             }
    2430              
    2431             # Next, run callbacks installed in class hierarchy
    2432              
    2433             # Cache this value as a performance boost
    2434 261   100     776 $self->{__CALLBACK_CLASSES} ||= [ Class::ISA::self_and_super_path($app_class) ];
    2435              
    2436             # Get list of classes that the current app inherits from
    2437 261         2389 foreach my $class (@{ $self->{__CALLBACK_CLASSES} }) {
      261         439  
    2438              
    2439             # skip those classes that contain no callbacks
    2440 521 100       1099 next unless exists $INSTALLED_CALLBACKS{$hook}{$class};
    2441              
    2442             # call all of the callbacks in the class
    2443 277         305 foreach my $callback (@{ $INSTALLED_CALLBACKS{$hook}{$class} }) {
      277         463  
    2444 305 100       703 next if $executed_callback{$callback};
    2445 295         312 eval { $self->$callback(@args); };
      295         958  
    2446 295         764 $executed_callback{$callback} = 1;
    2447 295 50       1023 die "Error executing class callback in $hook stage: $@" if $@;
    2448             }
    2449             }
    2450              
    2451             }
    2452              
    2453             =pod
    2454              
    2455             B
    2456              
    2457             Object-based callbacks are run before class-based callbacks.
    2458              
    2459             The order of class-based callbacks is determined by the inheritance tree of the
    2460             running application. The built-in methods of C, C,
    2461             C, and C are also executed this way, according to the
    2462             ordering below.
    2463              
    2464             In a persistent environment, there might be a lot of applications
    2465             in memory at the same time. For instance:
    2466              
    2467             CGI::Application
    2468             Other::Project # uses CGI::Application::Plugin::Baz
    2469             Other::App # uses CGI::Application::Plugin::Bam
    2470              
    2471             My::Project # uses CGI::Application::Plugin::Foo
    2472             My::App # uses CGI::Application::Plugin::Bar
    2473              
    2474             Suppose that each of the above plugins each added a callback to be run
    2475             at the 'init' stage:
    2476              
    2477             Plugin init callback
    2478             ------ -------------
    2479             CGI::Application::Plugin::Baz baz_startup
    2480             CGI::Application::Plugin::Bam bam_startup
    2481              
    2482             CGI::Application::Plugin::Foo foo_startup
    2483             CGI::Application::Plugin::Bar bar_startup
    2484              
    2485             When C runs, only C and C will
    2486             run. The other callbacks are skipped.
    2487              
    2488             The C<@ISA> list of C is:
    2489              
    2490             My::App
    2491             My::Project
    2492             CGI::Application
    2493              
    2494             This order determines the order of callbacks run.
    2495              
    2496             When C is run on a C application, callbacks
    2497             installed by these modules are run in order, resulting in:
    2498             C, C, and then finally C.
    2499              
    2500             If a single class installs more than one callback at the same hook, then
    2501             these callbacks are run in the order they were registered (FIFO).
    2502              
    2503              
    2504              
    2505             =cut
    2506              
    2507              
    2508             =head1 COMMUNITY
    2509              
    2510             Therese are primary resources available for those who wish to learn more
    2511             about CGI::Application and discuss it with others.
    2512              
    2513             B
    2514              
    2515             This is a community built and maintained resource that anyone is welcome to
    2516             contribute to. It contains a number of articles of its own and links
    2517             to many other CGI::Application related pages:
    2518              
    2519             L
    2520              
    2521             B
    2522              
    2523             If you have any questions, comments, bug reports or feature suggestions,
    2524             post them to the support mailing list! To join the mailing list, simply
    2525             send a blank message to "cgiapp-subscribe@lists.erlbaum.net".
    2526              
    2527             B
    2528              
    2529             You can also drop by C<#cgiapp> on C with a good chance of finding
    2530             some people involved with the project there.
    2531              
    2532             B
    2533              
    2534             This project is managed using git and is available on Github:
    2535              
    2536             L
    2537              
    2538             =head1 SEE ALSO
    2539              
    2540             =over 4
    2541              
    2542             =item o
    2543              
    2544             L
    2545              
    2546             =item o
    2547              
    2548             L
    2549              
    2550             =item o
    2551              
    2552             B - A full-featured web application based on
    2553             CGI::Application. http://www.cafweb.org/
    2554              
    2555             =back
    2556              
    2557             =head1 MORE READING
    2558              
    2559             If you're interested in finding out more about CGI::Application, the
    2560             following articles are available on Perl.com:
    2561              
    2562             Using CGI::Application
    2563             http://www.perl.com/pub/a/2001/06/05/cgi.html
    2564              
    2565             Rapid Website Development with CGI::Application
    2566             http://www.perl.com/pub/a/2006/10/19/cgi_application.html
    2567              
    2568             Thanks to O'Reilly for publishing these articles, and for the incredible value
    2569             they provide to the Perl community!
    2570              
    2571             =head1 AUTHOR
    2572              
    2573             Jesse Erlbaum
    2574              
    2575             Mark Stosberg has served as a co-maintainer since version 3.2, Martin McGrath
    2576             became a co-maintainer as of version 4.51, with the help of the numerous
    2577             contributors documented in the Changes file.
    2578              
    2579             =head1 CREDITS
    2580              
    2581             CGI::Application was originally developed by The Erlbaum Group, a software
    2582             engineering and consulting firm in New York City.
    2583              
    2584             Thanks to Vanguard Media (http://www.vm.com) for funding the initial
    2585             development of this library and for encouraging Jesse Erlbaum to release it to
    2586             the world.
    2587              
    2588             Many thanks to Sam Tregar (author of the most excellent
    2589             HTML::Template module!) for his innumerable contributions
    2590             to this module over the years, and most of all for getting
    2591             me off my ass to finally get this thing up on CPAN!
    2592              
    2593             Many other people have contributed specific suggestions or patches,
    2594             which are documented in the C file.
    2595              
    2596             Thanks also to all the members of the CGI-App mailing list!
    2597             Your ideas, suggestions, insights (and criticism!) have helped
    2598             shape this module immeasurably. (To join the mailing list, simply
    2599             send a blank message to "cgiapp-subscribe@lists.erlbaum.net".)
    2600              
    2601             =head1 LICENSE
    2602              
    2603             CGI::Application : Framework for building reusable web-applications
    2604             Copyright (C) 2000-2003 Jesse Erlbaum
    2605              
    2606             This module is free software; you can redistribute it and/or modify it
    2607             under the terms of either:
    2608              
    2609             a) the GNU General Public License as published by the Free Software
    2610             Foundation; either version 1, or (at your option) any later version,
    2611              
    2612             or
    2613              
    2614             b) the "Artistic License" which comes with this module.
    2615              
    2616             This program is distributed in the hope that it will be useful,
    2617             but WITHOUT ANY WARRANTY; without even the implied warranty of
    2618             MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See either
    2619             the GNU General Public License or the Artistic License for more details.
    2620              
    2621             You should have received a copy of the Artistic License with this
    2622             module, in the file ARTISTIC. If not, I'll be glad to provide one.
    2623              
    2624             You should have received a copy of the GNU General Public License
    2625             along with this program; if not, write to the Free Software
    2626             Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
    2627             USA
    2628              
    2629              
    2630             =cut
    2631