1CGI::Ex::App(3)       User Contributed Perl Documentation      CGI::Ex::App(3)
2
3
4

NAME

6       CGI::Ex::App - Anti-framework application framework.
7

SYNOPSIS

9       A basic example:
10
11           -------- File: /cgi-bin/my_cgi --------
12
13           #!/usr/bin/perl -w
14
15           use strict;
16           use base qw(CGI::Ex::App);
17
18           __PACKAGE__->navigate;
19           exit;
20
21           sub main_file_print {
22               return \ "Hello World!";
23           }
24
25       Well, you should put your content in an external file...
26
27           -------- File: /cgi-bin/my_cgi --------
28
29           #!/usr/bin/perl -w
30
31           use strict;
32           use base qw(CGI::Ex::App);
33
34           __PACKAGE__->navigate;
35
36           sub template_path { '/var/www/templates' }
37
38           -------- File: /var/www/templates/my_cgi/main.html --------
39
40           Hello World!
41
42       How about if we want to add substitutions...
43
44           -------- File: /cgi-bin/my_cgi --------
45
46           #!/usr/bin/perl -w
47
48           use strict;
49           use base qw(CGI::Ex::App);
50
51           __PACKAGE__->navigate;
52
53           sub template_path { '/var/www/templates' }
54
55           sub main_hash_swap {
56               my $self = shift;
57               return {
58                   greeting => 'Hello',
59                   date     => sub { scalar localtime },
60               };
61           }
62
63           -------- File: /var/www/templates/my_cgi/main.html --------
64
65           [% greeting %] World! ([% date %])
66
67       How about a form with validation (inluding javascript validation)...
68
69           -------- File: /cgi-bin/my_cgi --------
70
71           #!/usr/bin/perl -w
72
73           use strict;
74           use base qw(CGI::Ex::App);
75
76           __PACKAGE__->navigate;
77
78           sub template_path { '/var/www/templates' }
79
80           sub main_hash_swap { {date => sub { scalar localtime }} }
81
82           sub main_hash_fill {
83               return {
84                   guess => 50,
85               };
86           }
87
88           sub main_hash_validation {
89               return {
90                   guess => {
91                       required => 1,
92                       compare1       => '<= 100',
93                       compare1_error => 'Please enter a value less than 101',
94                       compare2       => '>  0',
95                       compare2_error => 'Please enter a value greater than 0',
96                   },
97               };
98           }
99
100           sub main_finalize {
101               my $self   = shift;
102               my $form   = $self->form;
103
104               $self->add_to_form({was_correct => ($form->{'guess'} == 23)});
105
106               return 0; # indicate to show the page without trying to move along
107           }
108
109           -------- File: /var/www/templates/my_cgi/main.html --------
110
111           <h2>Hello World! ([% date %])</h2>
112
113           [% IF was_correct %]
114              <b>Correct!</b> - The number was [% guess %].<br>
115           [% ELSIF guess %]
116              <b>Incorrect</b> - The number was not [% guess %].<br>
117           [% END %]
118
119           <form name="[% form_name %]" method="post">
120
121           Enter a number between 1 and 100: <input type="text" name="guess"><br>
122           <span id="guess_error" style="color:red">[% guess_error %]</span><br>
123
124           <input type="submit">
125           </form>
126
127           [% js_validation %]
128
129       There are infinite possibilities.  There is a longer "SYNOPSIS" after
130       the process flow discussion and more examples near the end of this doc‐
131       ument.  It is interesting to note that there have been no databases so
132       far.  It is very, very difficult to find a single database abstraction
133       that fits every model.  CGI::Ex::App is Controller/Viewer that is some‐
134       what Model agnostic and doesn't come with any default database abstrac‐
135       tion.
136

DESCRIPTION

138       Fill in the blanks and get a ready made web application.
139
140       This module is somewhat similar in spirit to CGI::Application,
141       CGI::Path, and CGI::Builder and any other "CGI framework."  As with the
142       others, CGI::Ex::App tries to do as much of the mundane things, in a
143       simple manner, without getting in the developer's way.  However, there
144       are various design patterns for CGI applications that CGI::Ex::App han‐
145       dles for you that the other frameworks require you to bring in extra
146       support.  The entire CGI::Ex suite has been taylored to work seamlessly
147       together.  Your mileage in building applications may vary.
148
149       If you build applications that submit user information, validate it,
150       re-display it, fill in forms, or separate logic into separate modules,
151       then this module may be for you.  If all you need is a dispatch engine,
152       then this still may be for you.  If all you want is to look at user
153       passed information, then this may still be for you.  If you like writ‐
154       ing bare metal code, this could still be for you.  If you don't want to
155       write any code, this module will help - but you still need to provide
156       your key actions and html.
157
158       One of the great benefits of CGI::Ex::App vs. Catalyst or Rails style
159       frameworks is that the model of CGI::Ex::App can be much more abstract.
160       And models often are abstract.
161

DEFAULT PROCESS FLOW

163       The following pseudo-code describes the process flow of the
164       CGI::Ex::App framework.  Several portions of the flow are encapsulated
165       in hooks which may be completely overridden to give different flow.
166       All of the default actions are shown.  It may look like a lot to fol‐
167       low, but if the process is broken down into the discrete operations of
168       step iteration, data validation, and template printing the flow feels
169       more natural.
170
171       navigate
172
173       The process starts off by calling ->navigate.
174
175           navigate {
176               eval {
177                   ->pre_navigate
178                   ->nav_loop
179                   ->post_navigate
180               }
181               # dying errors will run the ->handle_error method
182
183               ->destroy
184           }
185
186       nav_loop
187
188       The nav_loop method will run as follows:
189
190           nav_loop {
191               ->path (get the array of path steps)
192                   # ->path_info_map_base (method - map ENV PATH_INFO to form)
193                   # look in ->form for ->step_key
194                   # make sure step is in ->valid_steps (if defined)
195
196               ->pre_loop($path)
197                   # navigation stops if true
198
199               foreach step of path {
200
201                   ->require_auth (hook)
202                       # exits nav_loop if true
203
204                   ->morph
205                       # check ->allow_morph (hook)
206                       # check ->allow_nested_morph
207                       # ->morph_package (hook - get the package to bless into)
208                       # ->fixup_after_morph if morph_package exists
209                       # if no package is found, process continues in current file
210
211                   ->path_info_map (hook - map PATH_INFO to form)
212
213                   ->run_step (hook)
214
215                   ->refine_path (hook)
216                       # only called if run_step returned false (page not printed)
217                       ->next_step (hook) # find next step and add to path
218                       ->set_ready_validate(0) (hook)
219
220                   ->unmorph
221                       # only called if morph worked
222                       # ->fixup_before_unmorph if blessed to current package
223
224                   # exit loop if ->run_step returned true (page printed)
225
226               } end of foreach step
227
228               ->post_loop
229                   # navigation stops if true
230
231               ->default_step
232               ->insert_path (puts the default step into the path)
233               ->nav_loop (called again recursively)
234
235           } end of nav_loop
236
237       run_step (hook)
238
239       For each step of the path the following methods will be run during the
240       run_step hook.
241
242           run_step {
243               ->pre_step (hook)
244                   # skips this step if true and exit nav_loop
245
246               ->skip (hook)
247                   # skips this step if true and stays in nav_loop
248
249               ->prepare (hook - defaults to true)
250
251               ->info_complete (hook - ran if prepare was true)
252                   ->ready_validate (hook)
253                       # returns false from info_complete if ! ready_validate
254                   ->validate (hook - uses CGI::Ex::Validate to validate form info)
255                       ->hash_validation (hook)
256                          ->file_val (hook)
257                              ->vob_path (defaults to template_path)
258                              ->base_dir_rel
259                              ->name_module
260                              ->name_step
261                              ->ext_val
262                   # returns true if validate is true or if nothing to validate
263
264               ->finalize (hook - defaults to true - ran if prepare and info_complete were true)
265
266               if ! ->prepare ⎪⎪ ! ->info_complete ⎪⎪ ! ->finalize {
267                   ->prepared_print
268                       ->hash_base (hook)
269                       ->hash_common (hook)
270                       ->hash_form (hook)
271                       ->hash_fill (hook)
272                       ->hash_swap (hook)
273                       ->hash_errors (hook)
274                       # merge form, base, common, and fill into merged fill
275                       # merge form, base, common, swap, and errors into merged swap
276                       ->print (hook - passed current step, merged swap hash, and merged fill)
277                            ->file_print (hook - uses base_dir_rel, name_module, name_step, ext_print)
278                            ->swap_template (hook - processes the file with CGI::Ex::Template)
279                                 ->template_args (hook - passed to CGI::Ex::Template->new)
280                            ->fill_template (hook - fills the any forms with CGI::Ex::Fill)
281                                 ->fill_args (hook - passed to CGI::Ex::Fill::fill)
282                            ->print_out (hook - print headers and the content to STDOUT)
283
284                   ->post_print (hook - used for anything after the print process)
285
286                   # return true to exit from nav_loop
287               }
288
289               ->post_step (hook)
290                   # exits nav_loop if true
291
292           } end of run_step
293
294       It is important to learn the function and placement of each of the
295       hooks in the process flow in order to make the most of CGI::Ex::App.
296       It is enough to begin by learning a few common hooks - such as
297       hash_validation, hash_swap, and finalize, and then learn about other
298       hooks as needs arise.  Sometimes, it is enough to simply override the
299       run_step hook and take care of processing the entire step yourself.
300
301       Because of the hook based system, and because CGI::Ex::App uses sensi‐
302       ble defaults, it is very easy to override a little or a lot which ends
303       up giving the developer a lot of flexibility.
304
305       Additionally, it should be possible to use CGI::Ex::App with the other
306       frameworks such as CGI::Application or CGI::Prototype.  For these you
307       could simple let each "runmode" call the run_step hook of CGI::Ex::App
308       and you will instantly get all of the common process flow for free.
309

MAPPING URI TO STEP

311       The default out of the box configuration will map URIs to steps as fol‐
312       lows:
313
314           # Assuming /cgi-bin/my_app is the program being run
315
316          URI:  /cgi-bin/my_app
317           STEP: main
318           FORM: {}
319           WHY:  No other information is passed.  The path method is
320                 called which eventually calls ->default_step which
321                 defaults to "main"
322
323          URI:  /cgi-bin/my_app?foo=bar
324           STEP: main
325           FORM: {foo => "bar"}
326           WHY:  Same as previous example except that QUERY_STRING
327                 information was passed and placed in form.
328
329          URI:  /cgi-bin/my_app?step=my_step
330           STEP: my_step
331           FORM: {step => "my_step"}
332           WHY:  The path method is called which looks in $self->form
333                 for the key ->step_key (which defaults to "step").
334
335          URI:  /cgi-bin/my_app?step=my_step&foo=bar
336           STEP: my_step
337           FORM: {foo => "bar", step => "my_step"}
338           WHY:  Same as before but another parameter was passed.
339
340          URI:  /cgi-bin/my_app/my_step
341           STEP: my_step
342           FORM: {step => "my_step"}
343           WHY:  The path method is called which called path_info_map_base
344                 which matched $ENV{'PATH_INFO'} using the default regex
345                 of qr{^/(\w+)$} and place the result in
346                 $self->form->{$self->step_key}.  Path then looks in
347                 $self->form->{$self->step_key} for the initial step. See
348                 the path_info_map_base method for more information.
349
350          URI:  /cgi-bin/my_app/my_step?foo=bar
351           STEP: my_step
352           FORM: {foo => "bar", step => "my_step"}
353           WHY:  Same as before but other parameters were passed.
354
355          URI:  /cgi-bin/my_app/my_step?step=other_step
356           STEP: other_step
357           FORM: {step => "other_step"}
358           WHY:  The same procedure took place, but when the PATH_INFO
359                 string was matched, the form key "step" already existed
360                 and was not replaced by the value from PATH_INFO.
361
362       The remaining examples in this section are based on the assumption that
363       the following method is installed in your script.
364
365           sub my_step_path_info_map {
366               return [
367                   [qr{^/\w+/(\w+)/(\d+)$}, 'foo', 'id'],
368                   [qr{^/\w+/(\w+)$}, 'foo'],
369                   [qr{^/\w+/(.+)$}, 'anything_else'],
370               ];
371           }
372
373          URI:  /cgi-bin/my_app/my_step/bar
374           STEP: my_step
375           FORM: {foo => "bar"}
376           WHY:  The step was matched as in previous examples using
377                 path_info_map_base.  However, the form key "foo"
378                 was set to "bar" because the second regex returned
379                 by the path_info_map hook matched the PATH_INFO string
380                 and the corresponding matched value was placed into
381                 the form using the keys specified following the regex.
382
383          URI:  /cgi-bin/my_app/my_step/bar/1234
384           STEP: my_step
385           FORM: {foo => "bar", id => "1234"}
386           WHY:  Same as the previous example, except that the first
387                 regex matched the string.  The first regex had two
388                 match groups and two form keys specified.  Note that
389                 it is important to order your match regexes in the
390                 order that will match the most data.  The third regex
391                 would also match this PATH_INFO.
392
393          URI:  /cgi-bin/my_app/my_step/some/other/type/of/data
394           STEP: my_step
395           FORM: {anything_else => 'some/other/type/of/data'}
396           WHY:  Same as the previous example, except that the third
397                 regex matched.
398
399          URI:  /cgi-bin/my_app/my_step/bar?bling=blang
400           STEP: my_step
401           FORM: {foo => "bar", bling => "blang"}
402           WHY:  Same as the first sample, but additional QUERY_STRING
403                 information was passed.
404
405          URI:  /cgi-bin/my_app/my_step/one%20two?bar=three%20four
406           STEP: my_step
407           FORM: {anything_else => "one two", bar => "three four"}
408           WHY:  The third path_info_map regex matched.  Note that the
409                 %20 in bar was unescaped by CGI::param, but the %20
410                 in anything_else was unescaped by Apache.  If you are
411                 not using Apache, this behavior may vary.  CGI::Ex::App
412                 doesn't decode parameters mapped from PATH_INFO.
413
414       See the path method for more information about finding the initial step
415       of the path.
416
417       The form method calls CGI::Ex::form which uses CGI::param to retrieve
418       GET and POST parameters.  See the form method for more information on
419       how GET and POST parameters are parsed.
420
421       See the path_info_map_base method, and path_info_map hook for more
422       information on how the path_info maps function.
423
424       Using the following code is very useful for determing what hooks have
425       taken place:
426
427          use CGI::Ex::Dump qw(debug);
428
429          sub post_navigate {
430              my $self = shift;
431              debug $self->dump_history, $self->form;
432          }
433

ADDING DATA VALIDATION TO A STEP

435       CGI::Ex::App uses CGI::Ex::Validate for its data validation.  See
436       CGI::Ex::Validate for more information about the many ways you can val‐
437       idate your data.
438
439       The default hash_validation hook returns an empty hashref.  This means
440       that passed in data is all valid and the script will automatically call
441       the step's finalize method.
442
443       The following shows how to add some contrived validation to a step
444       called "my_step".
445
446           sub my_step_hash_validation {
447               return {
448                   username => {
449                       required    => 1,
450                       match       => 'm/^(\w+)$/',
451                       match_error => 'The $field field may only contain word characters',
452                       max_len     => 20,
453                   },
454                   password => {
455                       required => 1,
456                       max_len  => 15,
457                   },
458                   password_verify => {
459                       validate_if => 'password',
460                       equals      => 'password',
461                   },
462                   usertype => {
463                       required => 1,
464                       enum     => [qw(animal vegetable mineral)],
465                   },
466               };
467           }
468
469       The step will continue to display the html form until all of the fields
470       pass validation.
471
472       See the hash_validation hook and validate hook for more information
473       about how this takes place.
474

ADDING JAVASCRIPT DATA VALIDATION TO A STEP

476       You must first provide a hash_validation hook as explained in the pre‐
477       vious section.
478
479       Once you have a hash_validation hook, you would place the following
480       tags into your HTML template.
481
482           <form name="[% form_name %]" method="post">
483           ...
484           </form>
485           [% js_validation %]
486
487       The "form_name" swap-in places a name on the form that the javascript
488       returned by the js_validation swap-in will be able to find and check
489       for validity.
490
491       See the hash_validation, js_validation, and form_name hooks for more
492       information.
493
494       Also, CGI::Ex::validate.js allows for inline errors in addition to or
495       in replacement of an alert message.  To use inline errors, you must
496       provide an element in your HTML document where this inline message can
497       be placed.  The common way to do it is as follows:
498
499           <input type="text" name="username"><br>
500           <span class="error" id="username_error">[% username_error %]</span>
501
502       The span around the error allows for the error css class and it pro‐
503       vides a location that the Javascript validation can populate with
504       errors.  The [% username_error %] provides a location for errors gener‐
505       ated on the server side to be swapped in.  If there was no error the [%
506       username_error %] tag would default to "".
507

ADDING ADDITIONAL TEMPLATE VARIABLES

509       All variables returned by the hash_base, hash_common, hash_form,
510       hash_swap, and hash_errors hooks are available for swapping in tem‐
511       plates.
512
513       The following shows how to add variables using the hash_swap hook on
514       the step "main".
515
516           sub main_hash_swap {
517               return {
518                   color   => 'red',
519                   choices => [qw(one two three)],
520                   "warn"  => sub { warn @_ },
521               };
522           }
523
524       You could also return the fields from the hash_common hook and they
525       would be available in both the template swapping as well as form fill‐
526       ing.
527
528       See the hash_base, hash_common, hash_form, hash_swap, hash_errors,
529       swap_template, and template_args hooks for more information.
530
531       The default template engine used is CGI::Ex::Template which is now a
532       subclass of Template::Alloy.  The default interface used is TT which is
533       the Template::Toolkit interface.  Template::Alloy allows for using TT
534       documents, HTML::Template documents, HTML::Template::Expr documents,
535       Text::Tmpl documents, or Velocity (VTL) documents.  See the Tem‐
536       plate::Alloy documentation for more information.
537

ADDING ADDITIONAL FORM FILL VARIABLES

539       All variables returned by the hash_base, hash_common, hash_form, and
540       hash_fill hooks are available for filling html fields in on templates.
541
542       The following shows how to add variables using the hash_fill hook on
543       the step "main".
544
545           sub main_hash_fill {
546               return {
547                   color   => 'red',
548                   choices => [qw(one two three)],
549               };
550           }
551
552       You could also return the fields from the hash_common hook and they
553       would be available in both the form filling as well as in the template
554       swapping.
555
556       See the hash_base, hash_common, hash_form, hash_swap, hash_errors,
557       fill_template, and fill_args hooks for more information.
558
559       The default form filler is CGI::Ex::Fill which is similar to
560       HTML::FillInForm but has several benefits.  See the CGI::Ex::Fill mod‐
561       ule for the available options.
562

FINDING TEMPLATES AND VALIDATION FILES

564       CGI::Ex::App tries to help your applications use a good template direc‐
565       tory layout, but allows for you to override everything.
566
567       External template files are used for storing your html templates and
568       for storing your validation files (if you use externally stored valida‐
569       tion files).
570
571       The default file_print hook will look for content on your file system,
572       but it can also be completely overridden to return a reference to a
573       scalar containing the contents of your file (beginning with version
574       2.14 string references can be cached which makes templates passed this
575       way "first class" citizens).  Actually it can return anything that Tem‐
576       plate::Alloy (Template::Toolkit compatible) will treat as input.  This
577       templated html is displayed to the user during any step that enters the
578       "print" phase.
579
580       Similarly the default file_val hook will look for a validation file on
581       the file system, but it too can return a reference to a scalar contain‐
582       ing the contents of a validation file.  It may actually return anything
583       that the CGI::Ex::Validate get_validation method is able to understand.
584       This validation is used by the default "info_complete" method for veri‐
585       fying if the submitted information passes its specific checks.  A more
586       common way of inlining validation is to return a validation hash from a
587       hash_validation hook override.
588
589       If the default file_print and file_val hooks are used, the following
590       methods are employed for finding templates and validation files on your
591       filesystem (they are also documented more in the HOOKS AND METHODS sec‐
592       tion.
593
594       template_path
595           Absolute path or arrayref of paths to the base templates directory.
596           Defaults to base_dir_abs which defaults to ['.'].
597
598       base_dir_rel
599           Relative path inside of the template_path directory where content
600           can be found.  Default "".
601
602       name_module
603           Directory inside of base_dir_rel where files for the current CGI
604           (module) will be stored.  Default value is $ENV{SCRIPT_NAME} with
605           path and extension removed.
606
607       name_step
608           Used with ext_print and ext_val for creating the filename that will
609           be looked for inside of the name_module directory.  Default value
610           is the current step.
611
612       ext_print and ext_val
613           Filename extensions added to name_step to create the filename
614           looked for inside of the name_module directory.  Default is "html"
615           for ext_print and "val" for ext_val.
616
617       It may be easier to understand the usage of each of these methods by
618       showing a contrived example.  The following is a hypothetical layout
619       for your templates:
620
621           /home/user/templates/
622           /home/user/templates/chunks/
623           /home/user/templates/wrappers/
624           /home/user/templates/content/
625           /home/user/templates/content/my_app/
626           /home/user/templates/content/my_app/main.html
627           /home/user/templates/content/my_app/step1.html
628           /home/user/templates/content/my_app/step1.val
629           /home/user/templates/content/another_cgi/main.html
630
631       In this example we would most likely set values as follows:
632
633           template_path /home/user/templates
634           base_dir_rel  content
635           name_module   my_app
636
637       The name_module method defaults to the name of the running program, but
638       with the path and extension removed.  So if we were running
639       /cgi-bin/my_app.pl, /cgi-bin/my_app, or /anypath/my_app, then name_mod‐
640       ule would default to "my_app" and we wouldn't have to hard code the
641       value.  Often it is wise to set the value anyway so that we can change
642       the name of the cgi script without effecting where template content
643       should be stored.
644
645       Continuing with the example and assuming that name of the step that the
646       user has requested is "step1" then the following values would be
647       returned:
648
649           template_path /home/user/templates
650           base_dir_rel  content
651           name_module   my_app
652           name_step     step1
653           ext_print     html
654           ext_val       val
655
656           file_print    content/my_app/step1.html
657           file_val      /home/user/templates/content/my_app/step1.val
658
659       The call to the template engine would look something like the follow‐
660       ing:
661
662           my $t = $self->template_obj({
663               INCLUDE_PATH => $self->template_path, # defaults to base_dir_abs
664           });
665
666           $t->process($self->file_print($step), \%vars);
667
668       The template engine would then look for the relative file inside of the
669       absolute paths (from template_path).
670
671       The call to the validation engine would pass the absolute filename that
672       is returned by file_val.
673
674       The name_module and name_step methods can return filenames with addi‐
675       tional directories included.  The previous example could also have been
676       setup using the following values:
677
678           template_path /home/user/templates
679           base_dir_rel
680           name_module   content/my_app
681
682       In this case the same values would be returned for the file_print and
683       file_val hooks as were returned in the previous setup.
684

SYNOPSIS (A LONG "SYNOPSIS")

686       This example script would most likely be in the form of a cgi, accessi‐
687       ble via the path http://yourhost.com/cgi-bin/my_app (or however you do
688       CGIs on your system.  About the best way to get started is to paste the
689       following code into a cgi script (such as cgi-bin/my_app) and try it
690       out.  A detailed walk-through follows in the next section.  There is
691       also a longer recipe database example at the end of this document that
692       covers other topics including making your module a mod_perl handler.
693
694           ### File: /var/www/cgi-bin/my_app (depending upon Apache configuration)
695           ### --------------------------------------------
696           #!/usr/bin/perl -w
697
698           use strict;
699           use base qw(CGI::Ex::App);
700           use CGI::Ex::Dump qw(debug);
701
702           __PACKAGE__->navigate;
703           # OR
704           # my $obj = __PACKAGE__->new;
705           # $obj->navigate;
706
707           exit;
708
709           ###------------------------------------------###
710
711           sub post_navigate {
712               # show what happened
713               debug shift->dump_history;
714           }
715
716           sub main_hash_validation {
717               return {
718                   'general no_alert'   => 1,
719                   'general no_confirm' => 1,
720                   'group order' => [qw(username password password2)],
721                   username => {
722                       required => 1,
723                       min_len  =>  3,
724                       max_len  => 30,
725                       match    => 'm/^\w+$/',
726                       match_error => 'You may only use letters and numbers.',
727                   },
728                   password => {
729                       required => 1,
730                       min_len  => 6,
731                   },
732                   password2 => {
733                       equals => 'password',
734                   },
735               };
736           }
737
738           sub main_file_print {
739               # reference to string means ref to content
740               # non-reference means filename
741               return \ "<h1>Main Step</h1>
742                 <form method=post name=[% form_name %]>
743                 <input type=hidden name=step>
744                 <table>
745                 <tr>
746                   <td><b>Username:</b></td>
747                   <td><input type=text name=username><span style='color:red' id=username_error>[% username_error %]</span></td>
748                 </tr><tr>
749                   <td><b>Password:</b></td>
750                   <td><input type=text name=password><span style='color:red' id=password_error>[% password_error %]</span></td>
751                 </tr><tr>
752                   <td><b>Verify Password:</b></td>
753                   <td><input type=text name=password2><span style='color:red' id=password2_error>[% password2_error %]</span></td>
754                 </tr>
755                 <tr><td colspan=2 align=right><input type=submit></td></tr>
756                 </table>
757                 </form>
758                 [% js_validation %]
759               ";
760           }
761
762           sub main_finalize {
763               my $self = shift;
764
765               if ($self->form->{'username'} eq 'bar') {
766                   $self->add_errors(username => 'A trivial check to say the username cannot be "bar"');
767                   return 0;
768               }
769
770               debug $self->form, "Do something useful with form here in the finalize hook.";
771
772               ### add success step
773               $self->add_to_swap({success_msg => "We did something"});
774               $self->append_path('success');
775               $self->set_ready_validate(0);
776               return 1;
777           }
778
779           sub success_file_print {
780               \ "<div style=background:lightblue>
781                  <h1>Success Step - [% success_msg %]</h1>
782                  Username: <b>[% username %]</b><br>
783                  Password: <b>[% password %]</b><br>
784                  </div>
785                 ";
786           }
787
788           __END__
789
790       Note: This example would be considerably shorter if the html file
791       (file_print) and the validation file (file_val) had been placed in sep‐
792       arate files.  Though CGI::Ex::App will work "out of the box" as shown
793       it is more probable that any platform using it will customize the vari‐
794       ous hooks to their own tastes (for example, switching print to use a
795       templating system other than Template::Alloy).
796

SYNOPSIS STEP BY STEP

798       This section goes step by step over the previous example.
799
800       Well - we start out with the customary CGI introduction.
801
802           #!/usr/bin/perl -w
803
804           use strict;
805           use base qw(CGI::Ex::App);
806           use CGI::Ex::Dump qw(debug);
807
808       Note:  the "use base" is not normally used in the "main" portion of a
809       script.  It does allow us to just do __PACKAGE__->navigate.
810
811       Now we need to invoke the process:
812
813           __PACKAGE__->navigate;
814           # OR
815           # my $obj = __PACKAGE__->new;
816           # $obj->navigate;
817           exit;
818
819       Note: the "exit" isn't necessary - but it is kind of nice to infer that
820       process flow doesn't go beyond the ->navigate call.
821
822       The navigate routine is now going to try and "run" through a series of
823       steps.  Navigate will call the ->path method which should return an
824       arrayref containing the valid steps.  By default, if path method has
825       not been overridden, the path method will default first to the step
826       found in form key named ->step_name, then it will fall to the contents
827       of $ENV{'PATH_INFO'}.  If navigation runs out of steps to run it will
828       run the step found in ->default_step which defaults to 'main'.  So the
829       URI '/cgi-bin/my_app' would run the step 'main' first by default.  The
830       URI '/cgi-bin/my_app?step=foo' would run the step 'foo' first.  The URI
831       '/cgi-bin/my_app/bar' would run the step 'bar' first.
832
833       CGI::Ex::App allows for running steps in a preset path or each step may
834       choose the next step that should follow.  The navigate method will go
835       through one step of the path at a time and see if it is completed (var‐
836       ious methods determine the definition of "completed").  This preset
837       type of path can also be automated using the CGI::Path module.  Rather
838       than using a preset path, CGI::Ex::App also has methods that allow for
839       dynamic changing of the path, so that each step can determine which
840       step to do next (see the jump, append_path, insert_path, and
841       replace_path methods).
842
843       During development it would be nice to see what happened during the
844       course of our navigation.  This is stored in the arrayref contained in
845       ->history.  There is a method that is called after all of the naviga‐
846       tion has taken place called "post_navigate".  This chunk will display
847       history after we have printed the content.
848
849           sub post_navigate {
850               debug shift->dump_history;
851           } # show what happened
852
853       Ok.  Finally we are looking at the methods used by each step of the
854       path.  The hook mechanism of CGI::Ex::App will look first for a method
855       ${step}_${hook_name} called before falling back to the method named
856       $hook_name.  Internally in the code there is a call that looks like
857       $self->run_hook('hash_validation', $step).  In this case the step is
858       main.  The dispatch mechanism finds our method at the following chunk
859       of code.
860
861           sub main_hash_validation { ... }
862
863       The process flow will see if the data is ready to validate.  Once it is
864       ready (usually when the user presses the submit button) the data will
865       be validated.  The hash_validation hook is intended to describe the
866       data and will be tested using CGI::Ex::Validate.  See the CGI::Ex::Val‐
867       idate perldoc for more information about the many types of validation
868       available.
869
870           sub main_file_print { ... }
871
872       The navigation process will see if user submitted information (the
873       form) is ready for validation.  If not, or if validation fails, the
874       step needs to be printed.  Eventually the file_print hook is called.
875       This hook should return either the filename of the template to be
876       printed, or a reference to the actual template content.  In this exam‐
877       ple we return a reference to the content to be printed (this is useful
878       for prototyping applications and is also fine in real world use - but
879       generally production applications use external html templates).
880
881       A few things to note about the template:
882
883       First, we add a hidden form field called step.  This will be filled in
884       automatically at a later point with the current step we are on.
885
886       We provide locations to swap in inline errors.
887
888           <span style="color:red" id="username_error">[% username_error %]</span>
889
890       As part of the error html we name each span with the name of the error.
891       This will allow for us to have Javascript update the error spots when
892       the javascript finds an error.
893
894       At the very end we add the TT variable [% js_validation %].  This swap
895       in is provided by the default hash_base hook and will provide for form
896       data to be validated using javascript.
897
898       Once the process flow has deemed that the data is validated, it then
899       calls the finalize hook.  Finalize is where the bulk of operations
900       should go.  We'll look at it more in depth.
901
902           sub main_finalize {
903               my $self = shift;
904               my $form = $self->form;
905
906       At this point, all of the validated data is in the $form hashref.
907
908               if ($form->{'username'} eq 'bar') {
909                   $self->add_errors(username => 'A trivial check to say the username cannot be "bar"');
910                   return 0;
911               }
912
913       It is most likely that though the data is of the correct type and for‐
914       matting, it still isn't completely correct.  This previous section
915       shows a hard coded test to see if the username was 'bar'.  If it was
916       then an appropriate error will be set, the routine returns 0 and the
917       run_step process knows that it needs to redisplay the form page for
918       this step.  The username_error will be shown inline.  The program could
919       do more complex things such as checking to see if the username was
920       already taken in a database.
921
922               debug $form, "Do something useful with form here in the finalize hook.";
923
924       This debug $form piece is simply a place holder.  It is here that the
925       program would do something useful such as add the information to a
926       database.
927
928               ### add success step
929               $self->add_to_swap({success_msg => "We did something"});
930
931       Now that we have finished finalize, we add a message that will be
932       passed to the template engine.
933
934               $self->append_path('success');
935               $self->set_ready_validate(0);
936
937       The program now needs to move on to the next step.  In this case we
938       want to follow with a page that informs us we succeeded.  So, we append
939       a step named "success".  We also call set_ready_validate(0) to inform
940       the navigation control that the form is no longer ready to validate -
941       which will cause the success page to print without trying to validate
942       the data.  It is normally a good idea to set this as leaving the engine
943       in a "ready to validate" state can result in an recursive loop (that
944       will be caught).
945
946               return 1;
947           }
948
949       We then return 1 which tells the engine that we completed this step
950       successfully and it needs to move on to the next step.
951
952       Finally we run the "success" step because we told it to.  That step
953       isn't ready to validate so it prints out the template page.
954
955       For more of a real world example, it would be good to read the sample
956       recipe db application included at the end of this document.
957

AVAILABLE METHODS / HOOKS

959       CGI::Ex::App's dispatch system works on the principles of hooks (which
960       are essentially glorified method lookups).  When the run_hook method is
961       called, CGI::Ex::App will look for a corresponding method call for that
962       hook for the current step name.  It is perhaps easier to show than to
963       explain.
964
965       If we are calling the "print" hook for the step "edit" we would call
966       run_hook like this:
967
968           $self->run_hook('print', 'edit', $template, \%swap, \%fill);
969
970       This would first look for a method named "edit_print".  If it is unable
971       to find a method by that name, it will look for a method named "print".
972       If it is unable to find this method - it will die.
973
974       If allow_morph is set to true, the same methods are searched for but it
975       becomes possible to move some of those methods into an external pack‐
976       age.
977
978       See the discussions under the methods named "find_hook" and "run_hook"
979       for more details.
980
981       The following is the alphabetical list of methods and hooks.
982
983       allow_morph (hook)
984           Should return true if this step is allowed to "morph" the current
985           App object into another package.  Default is false.  It is passed a
986           single argument of the current step.  For more granularity, if true
987           value is a hash, the step being morphed to must be in the hash.
988
989           To enable morphing for all steps, add the following:
990
991               sub allow_morph { 1 }
992
993           To enable morph on specific steps, do either of the following:
994
995               sub allow_morph {
996                   return {
997                       edit => 1,
998                       delete => 1,
999                   };
1000               }
1001
1002               # OR
1003
1004               sub allow_morph {
1005                   my ($self, $step) = @_;
1006                   return $step =~ /^(edit⎪delete)$/;
1007               }
1008
1009           See the morph "hook" for more information.
1010
1011       allow_nested_morph (method)
1012           Similar to the allow_morph hook, but allows for one more level of
1013           morphing.  This is useful in cases where the base class was morphed
1014           early on, or if a step needs to call a sub-step but morph first.
1015
1016           See the allow_morph and the morph method for more information.
1017
1018           Should return a boolean value or hash of allowed steps - just as
1019           the allow_morph method does.
1020
1021       append_path (method)
1022           Arguments are the steps to append.  Can be called any time.  Adds
1023           more steps to the end of the current path.
1024
1025       auth_args (method)
1026           Should return a hashref that will be passed to the auth_obj method
1027           which should return a CGI::Ex::Auth compatible object.  It is aug‐
1028           mented with arguments that integrate it into CGI::Ex::App.
1029
1030           See the get_valid_auth method and the CGI::Ex::Auth documentation.
1031
1032               sub auth_args {
1033                   return {
1034                       login_header => '<h1>My login header</h1>',
1035                       login_footer => '[% TRY %][% INCLUDE login/login_footer.htm %][% CATCH %]<!-- [% error %] -->[% END %]',
1036                       secure_hash_keys => [qw(aaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbb ccccccccccccccccccccccc 2222222222222)],
1037                       # use_blowfish => 'my_blowfish_key',
1038                   };
1039               }
1040
1041       auth_data (method)
1042           Contains authentication data stored during the get_valid_auth
1043           method.  The data is normally blessed into the CGI::Ex::Auth::Data
1044           package which evaluates to false if there was an error and true if
1045           the authentication was successful - so this data can be defined but
1046           false.
1047
1048           See the get_valid_auth method.
1049
1050       auth_obj (method)
1051           Passed auth_args.  Should return a CGI::Ex::Auth compatible object.
1052           Default is to call CGI::Ex::Auth->new with the passed args.
1053
1054       base_dir_abs (method)
1055           Used as the absolute base directory to find template, validation
1056           and conf files.  It may return a single value or an arrayref of
1057           values, or a coderef that returns an arrayref or coderef of values.
1058           You may pass base_dir_abs as a parameter in the arguments passed to
1059           the "new" method.
1060
1061           Default value is ['.'].
1062
1063           For example, to pass multiple paths, you would use something simi‐
1064           lar to the following:
1065
1066               sub base_dir_abs {
1067                   return ['/my/path/one', '/some/other/path'];
1068               }
1069
1070           The base_dir_abs value is used by template_path along with the
1071           base_dir_rel, name_module, name_step, ext_print and ext_values for
1072           determining the values returned by the default file_print and
1073           file_val hooks.  See those methods for further discussion.
1074
1075           See the section on FINDING TEMPLATES for further discussion.
1076
1077           The base_dir_abs method is also used as the default value for
1078           conf_path and vob_path.
1079
1080       base_dir_rel (method)
1081           Added as a relative base directory to content under the
1082           base_dir_abs directory.
1083
1084           Default value is "".
1085
1086           The template_path method is used as top level where template
1087           includes may pull from, while the base_dir_rel is directory rela‐
1088           tive to the template_path where the content files will be stored.
1089
1090           A value for base_dir_rel may passed as a parameter in the arguments
1091           passed to the new method.
1092
1093           See the template_path and base_dir_abs methods for more discussion.
1094
1095           See the section on FINDING TEMPLATES for further discussion.
1096
1097       cleanup_user (method)
1098           Used as a hook during get_valid_auth.  Allows for cleaning up the
1099           username.  See the get_valid_auth method.
1100
1101               sub cleanup_user {
1102                   my ($self, $user) = @_;
1103                   return lc $user;
1104               }
1105
1106       clear_app (method)
1107           If the same CGI::Ex::App based object is used to run multiple navi‐
1108           gate sessions, the clear_app method should be called which will
1109           attempt to clear as much session information as it can.  The fol‐
1110           lowing items will be cleared:
1111
1112               cgix
1113               vob
1114               form
1115               cookies
1116               stash
1117               path
1118               path_i
1119               history
1120               _morph_lineage_start_index
1121               _morph_lineage
1122               hash_errors
1123               hash_fill
1124               hash_swap
1125               hash_common
1126
1127       conf (method)
1128           Used by default in init_from_conf if load_conf returns true.  Will
1129           try to read the file returned by the conf_file method using the
1130           object returned by conf_obj using that object's read method.  If
1131           conf_validation returns a non-empty hashref, the conf hash will be
1132           validated using $self->vob->validate (see the validate method).
1133
1134           This method may be used for other purposes as well (including when
1135           load_conf is false)..
1136
1137           Caches results in $self->{'conf'}.
1138
1139           If the conf_file can't be found, the method will die unless
1140           conf_die_on_fail returns 0 (defaults to true).
1141
1142       conf_args
1143           Used by conf_obj.
1144
1145           Defaults to $self->{'conf_args'} which defaults to {}.  Will have
1146           paths => $self->conf_path added before passing to
1147           CGI::Ex::Conf->new.
1148
1149       conf_file (method)
1150           Used by conf for finding the configuration file to load.  Defaults
1151           to $self->{'conf_file'} which defaults $self->name_module with the
1152           extention returned by $self->ext_conf added on.  For example, if
1153           name_module returns "my_app" and ext_conf returns "ini" the value
1154           returned will be "my_app.ini".
1155
1156           The value returned can absolute.  If the value will be searched for
1157           in the paths passed to conf_obj.
1158
1159           The ext_conf may be any of those extentions understood by
1160           CGI::Ex::Conf.
1161
1162       conf_obj
1163           Used by the conf method to load the file returned by conf_file.
1164           Defaults to conf_obj which defaults to loading args from conf_args,
1165           adding in paths returned by conf_path, and calling
1166           CGI::Ex::Conf->new.
1167
1168           Any object that provides a read method that returns a hashref can
1169           be used.
1170
1171       conf_path
1172           Defaults to $self->{'conf_path'} which defaults to base_dir_abs.
1173           Should be a path or an arrayref of paths to look the configuration
1174           file returned by conf_file when that file is not absolute.
1175
1176       conf_validation
1177           Used by default conf method.  Defaults to an empty hashref.  If
1178           non-empty hashref is passed, the hashref returned by conf_obj->read
1179           will be validated using the hashref returned by conf_validation.
1180
1181       current_step (method)
1182           Returns the current step that the nav_loop is functioning on.
1183
1184       default_step (method)
1185           Step to show if the path runs out of steps.  Default value is the
1186           'default_step' property which defaults to 'main'.
1187
1188           If nav_loop runs of the end of the path (runs out of steps), this
1189           method is called, the step is added to the path, and nav_loop calls
1190           itself recursively.
1191
1192       destroy (method)
1193           Called at the end of navigate after all other actions have run.
1194           Can be used for undoing things done in the ->init method called
1195           during the ->new method.
1196
1197       dump_history (method)
1198           Show simplified trace information of which steps were called, the
1199           order they were called in, the time they took to run, and a brief
1200           list of the output (to see the full response returned by each hook,
1201           pass a true value as the only argument to dump_history -
1202           $self->dump_history(1)).  Indentation is also applied to show which
1203           hooks called other hooks.
1204
1205           The first line shows the amount of time elapsed for the entire nav‐
1206           igate execution.  Subsequent lines contain:
1207
1208               Step   - the name of the current step.
1209               Hook   - the name of the hook being called.
1210               Found  - the name of the method that was found.
1211               Time   - the total elapsed seconds that method took to run.
1212               Output - the response of the hook - shown in shortened form.
1213
1214           Note - to get full output responses - pass a true value to
1215           dump_history - or just call ->history.  Times displayed are to 5
1216           decimal places - this accuracy can only be provided if the
1217           Time::HiRes module is installed on your system (it will only be
1218           used if installed).
1219
1220           It is usually best to print this history during the post_navigate
1221           method as in the following:
1222
1223               use CGI::Ex::Dump qw(debug);
1224               sub post_navigate { debug shift->dump_history }
1225
1226           The following is a sample output of dump_history called from the
1227           sample recipe application at the end of this document.  The step
1228           called is "view".
1229
1230               debug: admin/Recipe.pm line 14
1231               shift->dump_history = [
1232                       "Elapsed: 0.00562",
1233                       "view - require_auth - require_auth - 0.00001 - 0",
1234                       "view - run_step - run_step - 0.00488 - 1",
1235                       "    view - pre_step - pre_step - 0.00003 - 0",
1236                       "    view - skip - view_skip - 0.00004 - 0",
1237                       "    view - prepare - prepare - 0.00003 - 1",
1238                       "    view - info_complete - info_complete - 0.00010 - 0",
1239                       "        view - ready_validate - ready_validate - 0.00004 - 0",
1240                       "    view - prepared_print - prepared_print - 0.00441 - 1",
1241                       "        view - hash_base - hash_base - 0.00009 - HASH(0x84ea6ac)",
1242                       "        view - hash_common - view_hash_common - 0.00148 - HASH(0x8310a20)",
1243                       "        view - hash_form - hash_form - 0.00004 - HASH(0x84eaa78)",
1244                       "        view - hash_fill - hash_fill - 0.00003 - {}",
1245                       "        view - hash_swap - hash_swap - 0.00003 - {}",
1246                       "        view - hash_errors - hash_errors - 0.00003 - {}",
1247                       "        view - print - print - 0.00236 - 1",
1248                       "            view - file_print - file_print - 0.00024 - recipe/view.html",
1249                       "                view - name_module - name_module - 0.00007 - recipe",
1250                       "                view - name_step - name_step - 0.00004 - view",
1251                       "            view - swap_template - swap_template - 0.00161 - <html> ...",
1252                       "                view - template_args - template_args - 0.00008 - HASH(0x865abf8)",
1253                       "            view - fill_template - fill_template - 0.00018 - 1",
1254                       "                view - fill_args - fill_args - 0.00003 - {}",
1255                       "            view - print_out - print_out - 0.00015 - 1",
1256                       "    view - post_print - post_print - 0.00003 - 0"
1257               ];
1258
1259       error_step (method)
1260           Defaults to "__error".  The name of a step to run should a dying
1261           error be caught by the default handle_error method.  See the han‐
1262           dle_error method.
1263
1264       exit_nav_loop (method)
1265           This method should not normally used but there is no problem with
1266           using it on a regular basis.  Essentially it is a "goto" that
1267           allows for a long jump to the end of all nav_loops (even if they
1268           are recursively nested).  This effectively short circuits all
1269           remaining hooks for the current and remaining steps.  It is used to
1270           allow the ->jump functionality.  If the application has morphed, it
1271           will be unmorphed before returning.  Also - the post_navigate
1272           method will still be called.
1273
1274       ext_conf
1275           Used by the default conf_file method.  Defaults to
1276           $self->{'ext_conf'} which defaults to 'pl' meaning that the read
1277           configuration file should return a valid perl hashref.
1278
1279       ext_print (method)
1280           Added as suffix to "name_step" during the default file_print hook.
1281
1282           Default value is 'html'.
1283
1284           For example, if name_step returns "foo" and ext_print returns
1285           "html" then the file "foo.html" will be searched for.
1286
1287           See the section on FINDING TEMPLATES for further discussion.
1288
1289       ext_val (method)
1290           Added as suffix to "name_step" during the default file_val hook.
1291
1292           Default value is 'val'.
1293
1294           For example, if name_step returns "foo" and ext_val returns "val"
1295           then the file "foo.val" will be searched for.
1296
1297           See the section on FINDING TEMPLATES for further discussion.
1298
1299       fill_args (hook)
1300           Returns a hashref of args that will be passed to the
1301           CGI::Ex::Fill::fill.  It is augmented with the template to swap and
1302           the fill hash.  This could be useful if you needed to only swap a
1303           particular form on the template page.  Arguments are passed
1304           directly to the fill function.
1305
1306              sub fill_args { {target => 'my_form'} }
1307
1308       fill_template (hook)
1309           Arguments are a template and a hashref.  Takes the template that
1310           was prepared using swap_template, and swaps html form fields using
1311           the passed hashref.  Overriding this method can control the fill
1312           behavior.
1313
1314           Calls the fill_args hook prior to calling CGI::Ex::Fill::fill
1315
1316       file_print (hook)
1317           Returns a filename of the content to be used in the default print
1318           hook.  Adds method base_dir_rel to hook name_module, and name_step
1319           and adds on the default file extension found in $self->ext_print
1320           which defaults to the property $self->{ext_print} which will
1321           default to ".html".  Should return a filename relative to tem‐
1322           plate_path that can be swapped using Template::Alloy, or should be
1323           a scalar reference to the template content that can be swapped.
1324           This will be used by the hook print.
1325
1326               sub template_path { '/var/www/templates' }
1327               sub base_dir_rel  { 'content' }
1328               sub name_module   { 'recipe' }
1329               sub ext_print     { 'html' } # default
1330
1331               # ->file_print('this_step')
1332               # would return 'content/recipe/this_step.html'
1333               # the template engine would look in '/var/www/templates'
1334               # for a file by that name
1335
1336           It may also return a reference to a string containing the html tem‐
1337           plate.  This is useful for prototyping applications and/or keeping
1338           all of the data for the application in a single location.
1339
1340       file_val (hook)
1341           Returns a filename containing the validation.  Performs the same as
1342           file_print, but uses ext_val to get the extension, and it adds
1343           vob_path (which defaults to template_path which defaults to
1344           base_dir_abs) onto the returned value (file_print is relative to
1345           template_path, while file_val is fully qualified with vob_path).
1346           If vob_path returns an arrayref of paths, then each path is checked
1347           for the existence of the file.
1348
1349           The file should be readable by CGI::Ex::Validate::get_validation.
1350
1351           This hook is only necessary if the hash_validation hook has not
1352           been overridden.  5B This method an also return a hashref contain‐
1353           ing the validation - but then you may have wanted to override the
1354           hash_validation hook.
1355
1356       finalize (hook)
1357           Defaults to true. Used to do whatever needs to be done with the
1358           data once prepare has returned true and info_complete has returned
1359           true.  On failure the print operations are ran.  On success naviga‐
1360           tion moves on to the next step.
1361
1362           This is normally were there core logic of a script will occur (such
1363           as adding to a database, or updating a record).  At this point, the
1364           data should be validated.  It is possible to do additional valida‐
1365           tion and return errors using code such as the following.
1366
1367               if (! $user_is_unique) {
1368                   $self->add_errors(username => 'The username was already used');
1369                   return 0;
1370               }
1371
1372       find_hook (method)
1373           Called by run_hook.  Arguments are a hook name, a step name.  It
1374           should return an arrayref containing the code_ref to run, and the
1375           name of the method looked for.  It uses ->can to find the appropri‐
1376           ate hook.
1377
1378               my $code = $self->hook('finalize', 'main');
1379               ### will look first for $self->main_finalize;
1380               ### will then look  for $self->finalize;
1381
1382           This system is used to allow for multiple steps to be in the same
1383           file and still allow for moving some steps out to external sub
1384           classed packages (if desired).
1385
1386           If the application has successfully morphed via the morph method
1387           and allow_morph then it is not necessary to add the step name to
1388           the beginning of the method name as the morphed packages method
1389           will override the base package (it is still OK to use the full
1390           method name "${step}_hookname").
1391
1392           See the run_hook method and the morph method for more details.
1393
1394       first_step (method)
1395           Returns the first step of the path.  Note that first_step may not
1396           be the same thing as default_step if the path was overridden.
1397
1398       forbidden_step (method)
1399           Defaults to "__forbidden".  The name of a step to run should the
1400           current step name be invalid, or if a step found by the default
1401           path method is invalid.  See the path method.
1402
1403       form (method)
1404           Returns a hashref of the items passed to the CGI.  Returns
1405           $self->{form} which defaults to CGI::Ex::get_form.
1406
1407       form_name (hook)
1408           Return the name of the form to attach the js validation to.  Used
1409           by js_validation.
1410
1411       get_pass_by_user (method)
1412           This method is passed a username and the authentication object.  It
1413           should return the password for the given user.  See the
1414           get_pass_by_user method of CGI::Ex::Auth for more information.
1415           Installed as a hook to the authentication object during the
1416           get_valid_auth method.
1417
1418       get_valid_auth (method)
1419           If require_auth hook returns true on any given step then
1420           get_valid_auth will be called.
1421
1422           It will call auth_args to get some default args to pass to
1423           CGI::Ex::Auth->new.  It augments the args with sensible defaults
1424           that App already provides (such as form, cookies, and template
1425           facilities).  It also installs hooks for the get_pass_by_user,
1426           cleanup_user, and verify_user hooks of CGI::Ex::Auth.
1427
1428           It stores the $auth->last_auth_data in $self->auth_data for later
1429           use.  For example, to get the authenticated user:
1430
1431               sub require_auth { 1 }
1432
1433               sub cleanup_user {
1434                   my ($self, $user) = @_;
1435                   return lc $user;
1436               }
1437
1438               sub get_pass_by_user {
1439                   my ($self, $user) = @_;
1440                   my $pass = $self->some_method_to_get_the_pass($user);
1441                   return $pass;
1442               }
1443
1444               sub auth_args {
1445                   return {
1446                       login_header => '<h1>My login header</h1>',
1447                       login_footer => '[% TRY %][% INCLUDE login/login_footer.htm %][% CATCH %]<!-- [% error %] -->[% END %]',
1448                   };
1449               }
1450
1451               sub main_hash_swap {
1452                   my $self = shift;
1453                   my $user = $self->auth_data->{'user'};
1454                   return {user => $user};
1455               }
1456
1457           Successful authentication is cached for the duration of the
1458           nav_loop so multiple steps will run the full authentication routine
1459           only once.
1460
1461           Full customization of the login process and the login template can
1462           be done via the auth_args hash.  See the auth_args method and
1463           CGI::Ex::Auth perldoc for more information.
1464
1465       handle_error (method)
1466           If anything dies during execution, handle_error will be called with
1467           the error that had happened.  Default action is to try running the
1468           step returned by the error_step method.
1469
1470       hash_base (hook)
1471           A hash of base items to be merged with hash_form - such as pulldown
1472           menus, javascript validation, etc.  It will now also be merged with
1473           hash_fill, so it can contain default fillins as well.  It can be
1474           populated by passing a hash to ->add_to_base.  By default a sub
1475           similar to the following is what is used for hash_common.  Note the
1476           use of values that are code refs - so that the js_validation and
1477           form_name hooks are only called if requested:
1478
1479               sub hash_base {
1480                   my ($self, $step) = @_;
1481                   return $self->{hash_base} ⎪⎪= {
1482                       script_name   => $ENV{SCRIPT_NAME},
1483                       js_validation => sub { $self->run_hook('js_validation', $step) },
1484                       form_name     => sub { $self->run_hook('form_name', $step) },
1485                   };
1486               }
1487
1488       hash_common (hook)
1489           Almost identical in function and purpose to hash_base.  It is
1490           intended that hash_base be used for common items used in various
1491           scripts inheriting from a common CGI::Ex::App type parent.
1492           Hash_common is more intended for step level populating of both swap
1493           and fill.
1494
1495       hash_errors (hook)
1496           Called in preparation for print after failed prepare, info_com‐
1497           plete, or finalize.  Should contain a hash of any errors that
1498           occurred.  Will be merged into hash_form before the pass to print.
1499           Each error that occurred will be passed to method format_error
1500           before being added to the hash.  If an error has occurred, the
1501           default validate will automatically add {has_errors =>1}.  To the
1502           error hash at the time of validation.  has_errors will also be
1503           added during the merge in case the default validate was not used.
1504           Can be populated by passing a hash to ->add_to_errors or
1505           ->add_errors.
1506
1507       hash_fill (hook)
1508           Called in preparation for print after failed prepare, info_com‐
1509           plete, or finalize.  Should contain a hash of any items needed to
1510           be filled into the html form during print.  Items from hash_form,
1511           hash_base, and hash_common will be layered together.  Can be popu‐
1512           lated by passing a hash to ->add_to_fill.
1513
1514           By default - forms are sticky and data from previous requests will
1515           try and populate the form.  You can use the fill_template hook to
1516           disable templating on a single page or on all pages.
1517
1518           This method can be used to pre-populate the form as well (such as
1519           on an edit step).  If a form fails validation, hash_fill will also
1520           be called and will only want the submitted form fields to be
1521           sticky.  You can use the ready_validate hook to prevent pre-popula‐
1522           tion in these cases as follows:
1523
1524               sub edit_hash_fill {
1525                   my $self = shift;
1526                   my $step = shift;
1527                   return {} if $self->run_hook('ready_validate', $step);
1528
1529                   my %hash;
1530
1531                   ### get previous values from the database
1532
1533                   return \%hash;
1534               }
1535
1536       hash_form (hook)
1537           Called in preparation for print after failed prepare, info_com‐
1538           plete, or finalize.  Defaults to ->form.  Can be populated by pass‐
1539           ing a hash to ->add_to_form.
1540
1541       hash_swap (hook)
1542           Called in preparation for print after failed prepare, info_com‐
1543           plete, or finalize.  Should contain a hash of any items needed to
1544           be swapped into the html during print.  Will be merged with
1545           hash_base, hash_common, hash_form, and hash_errors.  Can be popu‐
1546           lated by passing a hash to ->add_to_swap.
1547
1548           The hash will be passed as the second argument to swap_template.
1549
1550       hash_validation (hook)
1551           Returns a hash of the validation information to check form against.
1552           By default, will look for a filename using the hook file_val and
1553           will pass it to CGI::Ex::Validate::get_validation.  If no file_val
1554           is returned or if the get_validation fails, an empty hash will be
1555           returned.  Validation is implemented by ->vob which loads a
1556           CGI::Ex::Validate object.
1557
1558       history (method)
1559           Returns an arrayref which contains trace history of which hooks of
1560           which steps were ran.  Useful for seeing what happened.  In general
1561           - each line of the history will show the current step, the hook
1562           requested, and which hook was actually called.
1563
1564           The dump_history method shows a short condensed version of this
1565           history which makes it easier to see what path was followed.
1566
1567           In general, the arrayref is free for anything to push onto which
1568           will help in tracking other occurrences in the program as well.
1569
1570       info_complete (hook)
1571           Calls the ready_validate hook to see if data is ready to validate.
1572           If so it calls the validate hook to validate the data.  Should make
1573           sure the data is ready and valid.  Will not be run unless prepare
1574           returns true (default).
1575
1576       init (method)
1577           Called by the default new method.  Allows for any object initiliza‐
1578           tions that may need to take place.  Default action does nothing.
1579
1580       init_from_conf (method)
1581           Called by the default new method.  If load_conf is true, then the
1582           conf method will be called and the keys returned will be added to
1583           the $self object.
1584
1585           This method is called after the init method.  If you need to fur‐
1586           ther fix up values added during init_from_conf, you can use the
1587           pre_navigate method.
1588
1589       insert_path (method)
1590           Arguments are the steps to insert.  Can be called any time.
1591           Inserts the new steps at the current path location.
1592
1593       is_authed (method)
1594           Returns true if the object has successful authentication data.  It
1595           returns false if the object has not been authenticated.
1596
1597       js_uri_path (method)
1598           Return the URI path where the CGI/Ex/yaml_load.js and CGI/Ex/vali‐
1599           date.js files can be found.  This will default to
1600           "$ENV{SCRIPT_NAME}/js" if the path method has not been overridden,
1601           otherwise it will default to "$ENV{SCRIPT_NAME}?step=js&js=" (the
1602           latter is more friendly with overridden paths).  A default handler
1603           for the "js" step has been provided in "js_run_step" (this handler
1604           will nicely print out the javascript found in the js files which
1605           are included with this distribution.  js_run_step will work prop‐
1606           erly with the default "path" handler.
1607
1608       js_validation (hook)
1609           Requires JSON or YAML.  Will return Javascript that is capable of
1610           validating the form.  This is done using the capabilities of
1611           CGI::Ex::Validate.  This will call the hook hash_validation which
1612           will then be encoded either json or into yaml and placed in a
1613           javascript string.  It will also call the hook form_name to deter‐
1614           mine which html form to attach the validation to.  The method
1615           js_uri_path is called to determine the path to the appropriate val‐
1616           idate.js files.  If the method ext_val is htm, then js_validation
1617           will return an empty string as it assumes the htm file will take
1618           care of the validation itself.  In order to make use of js_valida‐
1619           tion, it must be added to the variables returned by either the
1620           hash_base, hash_common, hash_swap or hash_form hook (see examples
1621           of hash_base used in this doc).
1622
1623           By default it will try and use JSON first and then fail to YAML and
1624           then will fail to returning an html comment that does nothing.
1625
1626       jump (method)
1627           This method should not normally be used but is fine to use it on a
1628           regular basis.  It provides for moving to the next step at any
1629           point during the nav_loop.  It effectively short circuits the
1630           remaining hooks for the current step.  It does increment the recur‐
1631           sion counter (which has a limit of ->recurse_limit - default 15).
1632           It is normally better to allow the other hooks in the loop to carry
1633           on their normal functions and avoid jumping.  (Essentially, this
1634           hook behaves like a goto method to bypass everything else and con‐
1635           tinue at a different location in the path - there are times when it
1636           is necessary or useful to do this).
1637
1638           Jump takes a single argument which is the location in the path to
1639           jump to.  This argument may be either a step name, the special
1640           strings "FIRST, LAST, CURRENT, PREVIOUS, OR NEXT" or the number of
1641           steps to jump forward (or backward) in the path.  The default
1642           value, 1, indicates that CGI::Ex::App should jump to the next step
1643           (the default action for jump).  A value of 0 would repeat the cur‐
1644           rent step (watch out for recursion).  A value of -1 would jump to
1645           the previous step.  The special value of "LAST" will jump to the
1646           last step.  The special value of "FIRST" will jump back to the
1647           first step.  In each of these cases, the path array returned by
1648           ->path is modified to allow for the jumping (the path is modified
1649           so that the path history is not destroyed - if we were on step 3
1650           and jumped to one, that path would contain 1, 2, 3, *1, 2, 3, 4,
1651           etc and we would be at the *).
1652
1653               ### goto previous step
1654               $self->jump($self->previous_step);
1655               $self->jump('PREVIOUS');
1656               $self->jump(-1);
1657
1658               ### goto next step
1659               $self->jump($self->next_step);
1660               $self->jump('NEXT');
1661               $self->jump(1);
1662               $self->jump;
1663
1664               ### goto current step (repeat)
1665               $self->jump($self->current_step);
1666               $self->jump('CURRENT');
1667               $self->jump(0);
1668
1669               ### goto last step
1670               $self->jump($self->last_step);
1671               $self->jump('LAST');
1672
1673               ### goto first step
1674               $self->jump($self->first_step);
1675               $self->jump('FIRST');
1676
1677       last_step (method)
1678           Returns the last step of the path.  Can be used to jump to the last
1679           step.
1680
1681       load_conf (method)
1682           Defaults to ->{load_conf} which defaults to false.  If true, will
1683           allow keys returned by the conf method to be added to $self during
1684           the init_from_conf method.
1685
1686           Enabling this method allows for out-of-the-box file based configu‐
1687           ration.
1688
1689       morph (method)
1690           Allows for temporarily "becoming" another object type for the exe‐
1691           cution of the current step.  This allows for separating some steps
1692           out into their own packages.
1693
1694           Morph will only run if the method allow_morph returns true.  Addi‐
1695           tionally if the allow_morph returns a hash ref, morph will only run
1696           if the step being morphed to is in the hash.  Morph also passes the
1697           step name to allow_morph.
1698
1699           The morph call occurs at the beginning of the step loop.  A corre‐
1700           sponding unmorph call occurs before the loop is exited.  An object
1701           can morph several levels deep if allow_nested_morph returns true.
1702           For example, an object running as Foo::Bar that is looping on the
1703           step "my_step" that has allow_morph = 1, will do the following:
1704
1705               Call the morph_package hook (which would default to returning
1706               Foo::Bar::MyStep in this case)
1707
1708               Translate this to a package filename (Foo/Bar/MyStep.pm) and try
1709               and require it, if the file can be required, the object is blessed
1710               into that package.
1711
1712               Call the fixup_after_morph method.
1713
1714               Continue on with the run_step for the current step.
1715
1716           At any exit point of the loop, the unmorph call is made which re-
1717           blesses the object into the original package.
1718
1719           Samples of allowing morph:
1720
1721               sub allow_morph { 1 }
1722
1723               sub allow_morph { {edit => 1} }
1724
1725               sub allow_morph { my ($self, $step) = @_; return $step eq 'edit' }
1726
1727           It is possible to call morph earlier on in the program.  An example
1728           of a useful early use of morph would be as in the following code:
1729
1730               sub allow_morph { 1 }
1731
1732               sub pre_navigate {
1733                   my $self = shift;
1734                   if ($ENV{'PATH_INFO'} && $ENV{'PATH_INFO'} =~ s⎪^/(\w+)⎪⎪) {
1735                       my $step = $1;
1736                       $self->morph($step);
1737                       $ENV{'PATH_INFO'} = "/$step";
1738                       $self->stash->{'base_morphed'} = 1;
1739                   }
1740                   return 0;
1741               }
1742
1743               sub post_navigate {
1744                   my $self = shift;
1745                   $self->unmorph if $self->stash->{'base_morphed'};
1746               }
1747
1748           If this code was in a module Base.pm and the cgi running was
1749           cgi/base and called:
1750
1751               Base->navigate;
1752
1753           and you created a sub module that inherited Base.pm called
1754           Base/Ball.pm -- you could then access it using cgi/base/ball.  You
1755           would be able to pass it steps using either cgi/base/ball/step_name
1756           or cgi/base/ball?step=step_name - Or Base/Ball.pm could implement
1757           its own path.  It should be noted that if you do an early morph, it
1758           is suggested to provide a call to unmorph. And if you want to let
1759           your early morphed object morph again - you will need to provide
1760
1761               sub allow_nested_morph { 1 }
1762
1763           With allow_nested_morph enabled you could create the file
1764           Base/Ball/StepName.pm which inherits Base/Ball.pm.  The Base.pm,
1765           with the custom init and default path method, would automatically
1766           morph us first into a Base::Ball object (during init) and then into
1767           a Base::Ball::StepName object (during the navigation loop).
1768
1769           Since it is complicated to explain - it may be a bit complicated to
1770           those who will try to follow your code later.  CGI::Ex::App pro‐
1771           vides many ways to do things, but use the best one for your situa‐
1772           tion.
1773
1774       morph_package (hook)
1775           Used by morph.  Return the package name to morph into during a
1776           morph call.  Defaults to using the current object type as a base.
1777           For example, if the current object running is a Foo::Bar object and
1778           the step running is my_step, then morph_package will return
1779           Foo::Bar::MyStep.
1780
1781           Because of the way that run_hook works, it is possible that several
1782           steps could be located in the same external file and overriding
1783           morph_package could allow for this to happen.
1784
1785           See the morph method.
1786
1787       name_module (hook)
1788           Return the name (relative path) that should be pre-pended to
1789           name_step during the default file_print and file_val lookups.
1790           Defaults to the value in $self->{name_module} which in turn
1791           defaults to the name of the current script.
1792
1793               cgi-bin/my_app.pl  =>  my_app
1794               cgi/my_app         =>  my_app
1795
1796           This method is provided so that each cgi or mod_perl application
1797           can have its own directory for storing html for its steps.
1798
1799           See the file_print method for more information.
1800
1801           See the section on FINDING TEMPLATES for further discussion.
1802
1803       name_step (hook)
1804           Return the step (appended to name_module) that should used when
1805           looking up the file in file_print and file_val lookups.  Defaults
1806           to the current step.
1807
1808           See the section on FINDING TEMPLATES for further discussion.
1809
1810       nav_loop (method)
1811           This is the main loop runner.  It figures out the current path and
1812           runs all of the appropriate hooks for each step of the path.  If
1813           nav_loop runs out of steps to run (which happens if no path is set,
1814           or if all other steps run successfully), it will insert the
1815           ->default_step into the path and run nav_loop again (recursively).
1816           This way a step is always assured to run.  There is a method
1817           ->recurse_limit (default 15) that will catch logic errors (such as
1818           inadvertently running the same step over and over and over because
1819           there is either no hash_validation, or the data is valid but the
1820           set_ready_validate(0) method was not called).
1821
1822       navigate (method)
1823           Takes a class name or a CGI::Ex::App object as arguments.  If a
1824           class name is given it will call the "new" method to instantiate an
1825           object by that class (passing any extra arguments to the new
1826           method).  All returns from navigate will return the object.
1827
1828           The method navigate is essentially a safe wrapper around the
1829           ->nav_loop method.  It will catch any dies and pass them to ->han‐
1830           dle_error.
1831
1832           This starts the process flow for the path and its steps.
1833
1834       navigate_authenticated (method)
1835           Same as the method navigate but calls ->require_auth(1) before run‐
1836           ning.  It will only work if the navigate_authenticated method has
1837           not been overwritten. See the require_auth method.
1838
1839       new (class method)
1840           Object creator.  Takes a hashref of arguments that will become the
1841           initial properties of the object.  Calls the init method once the
1842           object has been blessed to allow for any other initilizations.
1843
1844               my $app = MyApp->new({name_module => 'my_app'});
1845
1846       next_step (hook and method)
1847           Returns the next step in the path.  If there is no next step, it
1848           returns the default_step.
1849
1850           It can be used as a method to return the next step in the path to
1851           pass to a method such as ->jump.
1852
1853           It is also used as a hook by the refine_path hook.  If there is no
1854           more steps, it will call the next_step hook to try and find a step
1855           to append to the path.
1856
1857       path (method)
1858           Return an arrayref (modifiable) of the steps in the path.  For each
1859           step the run_step hook and all of its remaining hooks will be run.
1860
1861           Hook methods are looked up and ran using the method "run_hook"
1862           which uses the method "find_hook" to lookup the hook.  A history of
1863           ran hooks is stored in the array ref returned by $self->history.
1864
1865           If path has not been defined, the method will look first in the
1866           form for a key by the name found in ->step_key.  It will then look
1867           in $ENV{'PATH_INFO'}.  It will use this step to create a path with
1868           that one step as its contents.  If a step is passed in via either
1869           of these ways, the method will call valid_steps to make sure that
1870           the step is valid (by default valid_steps returns undef - which
1871           means that any step is valid).  Any step beginning with _ can not
1872           be passed in and are intended for use on private paths.  If a non-
1873           valid step is found, then path will be set to contain a single step
1874           of ->forbidden_step.
1875
1876           For the best functionality, the arrayref returned should be the
1877           same reference returned for every call to path - this ensures that
1878           other methods can add to the path (and will most likely break if
1879           the arrayref is not the same).
1880
1881           If navigation runs out of steps to run, the default step found in
1882           default_step will be run.  This is what allows for us to default to
1883           the "main" step for many applications.
1884
1885       path_info_map (hook)
1886           Used to map path_info parts to form variables.  Similar to the
1887           path_info_map_base method.  See the path_info_map_base method for a
1888           discussion of how to use this hook.
1889
1890       path_info_map_base (method)
1891           Called during the default path method.  It is used to custom map
1892           portions of $ENV{'PATH_INFO'} to form values.  If should return an
1893           arrayref of arrayrefs where each child arrayref contains a regex qr
1894           with match parens as the first element of the array.  Subsequent
1895           elements of the array are the key names to store the corresponding
1896           matched value from the regex under.  The outer arrayref is iterated
1897           until it one of child arrayrefs matches against $ENV{'PATH_INFO'}.
1898           The matched values are only added to the form if there is not
1899           already a defined value for that key in the form.
1900
1901           The default value returned by this method looks something like the
1902           following:
1903
1904              sub path_info_map_base {
1905                  return [[qr{^/(\w+)}, $self->step_key]];
1906              }
1907
1908           This example would map the following PATH_INFO string as follows:
1909
1910              /my_step
1911
1912              # $self->form->{'step'} now equals "my_step"
1913
1914           The following is another example:
1915
1916              sub path_info_map_base {
1917                  return [
1918                      [qr{^/([^/]+)/(\w+)}, 'username', $self->step_key],
1919                      [qr{^/(\w+)}, $self->step_key],
1920                  ];
1921              }
1922
1923              # the PATH_INFO /my_step
1924              # still results in
1925              # $self->form->{'step'} now equals "my_step"
1926
1927              # but with the PATH_INFO /my_user/my_step
1928              # $self->form->{'step'} now equals "my_step"
1929              # and $self->form->{'username'} equals "my_user"
1930
1931           In most cases there is not a need to override the
1932           path_info_map_base method, but rather override the path_info_map
1933           hook for a particular step.  When the step is being run, just
1934           before the run_step hook is called, the path_info_map hook is
1935           called.  The path_info_map hook is similar to the
1936           path_info_map_base method, but is used to allow step level manipu‐
1937           lation of form based on elements in the $ENV{'PATH_INFO'}.
1938
1939              sub my_step_path_info_map {
1940                  return [[qr{^/my_step/(\w+)$}, 'username']];
1941              }
1942
1943              # the PATH_INFO /my_step/my_user
1944              # results in
1945              # $self->form->{'step'} equal to "my_step" because of default path_info_map_base
1946              # and $self->form->{'username'} equals "my_user" because of my_step_path_info_map
1947
1948           The section on mapping URIs to steps has additional examples.
1949
1950       post_loop (method)
1951           Ran after all of the steps in the loop have been processed (if pre‐
1952           pare, info_complete, and finalize were true for each of the steps).
1953           If it returns a true value the navigation loop will be aborted.  If
1954           it does not return true, navigation continues by then inserting the
1955           step $self->default_step and running $self->nav_loop again
1956           (recurses) to fall back to the default step.
1957
1958       post_navigate (method)
1959           Called from within navigate.  Called after the nav_loop has fin‐
1960           ished running but within the eval block to catch errors.  Will only
1961           run if there were no errors which died during the nav_loop process.
1962
1963           It can be disabled from running by setting the _no_post_navigate
1964           property.
1965
1966           If per-step authentication is enabled and authentication fails, the
1967           post_navigate method will still be called (the post_navigate method
1968           can check the ->is_authed method to change behavior).  If applica‐
1969           tion level authentication is enabled and authentication fails, none
1970           of the pre_navigate, nav_loop, or post_navigate methods will be
1971           called.
1972
1973       post_print (hook)
1974           A hook which occurs after the printing has taken place.  Is only
1975           run if the information was not complete.  Useful for cases such as
1976           printing rows of a database query after displaying a query form.
1977
1978       post_step (hook)
1979           Ran at the end of the step's loop if prepare, info_complete, and
1980           finalize all returned true.  Allows for cleanup.  If a true value
1981           is returned, execution of navigate is returned and no more steps
1982           are processed.
1983
1984       pre_loop (method)
1985           Called right before the navigation loop is started (at the begin‐
1986           ning of nav_loop).  At this point the path is set (but could be
1987           modified).  The only argument is a reference to the path array.  If
1988           it returns a true value - the navigation routine is aborted.
1989
1990       pre_navigate (method)
1991           Called at the very beginning of the navigate method, but within the
1992           eval block to catch errors.  Called before the nav_loop method is
1993           started.  If a true value is returned then navigation is skipped
1994           (the nav_loop is never started).
1995
1996       pre_step (hook)
1997           Ran at the beginning of the loop before prepare, info_compelete,
1998           and finalize are called.  If it returns true, execution of nav_loop
1999           is returned and no more steps are processed..
2000
2001       prepare (hook)
2002           Defaults to true.  A hook before checking if the info_complete is
2003           true.  Intended to be used to cleanup the form data.
2004
2005       prepared_print (hook)
2006           Called when any of prepare, info_complete, or finalize fail.  Pre‐
2007           pares a form hash and a fill hash to pass to print.  The form hash
2008           is primarily intended for use by the templating system.  The fill
2009           hash is intended to be used to fill in any html forms.
2010
2011       previous_step (method)
2012           List the step previous to this one.  Will return '' if there is no
2013           previous step.
2014
2015       print (hook)
2016           Take the information generated by prepared_print, format it using
2017           swap_template, fill it using fill_template and print it out using
2018           print_out.  Default incarnation uses CGI::Ex::Template (a subclass
2019           of Template::Alloy) which is compatible with Template::Toolkit to
2020           do the swapping.  Arguments are: step name (used to call the
2021           file_print hook), swap hashref (passed to call swap_template), and
2022           fill hashref (passed to fill_template).
2023
2024           During the print call, the file_print hook is called which should
2025           return a filename or a scalar reference to the template content is
2026
2027       print_out (hook)
2028           Called with the finished document.  Should print out the appropri‐
2029           ate headers.  The default method calls $self->cgix->print_con‐
2030           tent_type and then prints the content.
2031
2032           The print_content_type is passed $self->mimetype (which defaults to
2033           $self->{'mimetype'} which defaults to 'text/html') and
2034           $self->charset (which defaults to $self->{'charset'} which defaults
2035           to '').
2036
2037       ready_validate (hook)
2038           Should return true if enough information is present to run vali‐
2039           date.  Default is to look if $ENV{'REQUEST_METHOD'} is 'POST'.  A
2040           common usage is to pass a common flag in the form such as 'process‐
2041           ing' => 1 and check for its presence - such as the following:
2042
2043               sub ready_validate { shift->form->{'processing'} }
2044
2045           Changing the behavior of ready_validate can help in making wizard
2046           type applications.
2047
2048       refine_path (hook)
2049           Called at the end of nav_loop.  Passed a single value indicating if
2050           there are currently more steps in the path.
2051
2052           The default implementation returns if there are still more steps in
2053           the path.  Otherwise, it calls the next_step hook and appends it to
2054           the path with the append_path method, and then calls the
2055           set_ready_validate hook and passes it 0.
2056
2057           This allows you to simply put
2058
2059               sub edit_next_step { '_edit_success' }
2060
2061           In your code and it will automatically do the right thing and go to
2062           the _edit_success step.
2063
2064       recurse_limit (method)
2065           Default 15.  Maximum number of times to allow nav_loop to call
2066           itself.  The recurse level will increase every time that ->jump is
2067           called, or if the end of the nav_loop is reached and the process
2068           tries to add the default_step and run it again.
2069
2070           If ->jump is used often - the recurse_limit will be reached more
2071           quickly.  It is safe to raise this as high as is necessary - so
2072           long as it is intentional.
2073
2074           Often the limit is reached if a step did not have a validation
2075           hash, or if the set_ready_validate(0) method was not called once
2076           the data had been successfully validated and acted upon.
2077
2078       replace_path (method)
2079           Arguments are the steps used to replace.  Can be called any time.
2080           Replaces the remaining steps (if any) of the current path.
2081
2082       require_auth (hook)
2083           Defaults to self->{require_auth} which defaults to undef.  If
2084           called as a method and passed a single value of 1, 0, or undef it
2085           will set the value of $self->{require_auth} to that value.  If set
2086           to a true value then any subsequent step will require authentica‐
2087           tion (unless its hook has been overwritten).
2088
2089           Any of the following ways can be used to require authentication on
2090           every step.
2091
2092           *
2093                   sub require_auth { 1 }
2094
2095           *
2096                   __PACKAGE__->navigate_authenticated; # instead of __PACKAGE__->navigate;
2097
2098           *
2099                   __PACKAGE__->new({require_auth => 1}->navigate;
2100
2101           *
2102                   sub init { shift->require_auth(1) }
2103
2104           Because it is called as a hook, the current step is passed as the
2105           first argument.  If the hook returns false, no authentication will
2106           be required on this step.  If the hook returns a true, non-hashref
2107           value, authentication will be required via the get_valid_auth
2108           method.  If the method returns a hashref of stepnames to require
2109           authentication on, the step will require authentication via the
2110           get_valid_auth method if the current step is in the hashref.  If
2111           authentication is required and succeeds, the step will proceed.  If
2112           authentication is required and fails at the step level the current
2113           step will be aborted, authentication will be asked for (the
2114           post_navigate method will still be called).
2115
2116           For example you could add authentication to the add, edit, and
2117           delete steps in any of the following ways:
2118
2119           *
2120                   sub require_auth { {add => 1, edit => 1, delete => 1} }
2121
2122           *
2123                   sub add_require_auth    { 1 }
2124                   sub edit_require_auth   { 1 }
2125                   sub delete_require_auth { 1 }
2126
2127           *
2128                   sub require_auth {
2129                       my ($self, $step) = @_;
2130                       return 1 if $step && $step =~ /^(add⎪edit⎪delete)$/;
2131                       return 0;
2132                   }
2133
2134           If however you wanted to require authentication on all but one or
2135           two methods (such as requiring authentication on all but a for‐
2136           got_password step) you could do either of the following:
2137
2138           *
2139                   sub require_auth {
2140                       my ($self, $step) = @_;
2141                       return 0 if $step && $step eq 'forgot_password';
2142                       return 1; # require auth on all other steps
2143                   }
2144
2145           *
2146                   sub require_auth { 1 } # turn it on for all steps
2147
2148                   sub forgot_password_require_auth { 0 } # turn it off
2149
2150           See the get_valid_auth method for what occurs should authentication
2151           be required.
2152
2153           There is one key difference from the 2.14 version of App.  In 2.14
2154           and previous versions, the pre_navigate and post_navigate methods
2155           would not be called if require_auth returned a true non-hashref
2156           value.  In version 2.15 and later, the 2.15 pre_navigate and
2157           post_navigate methods are always called - even if authentication
2158           fails.  Also in 2.15 and later, the method is called as a hook
2159           meaning the step is passed in.
2160
2161       run_hook (method)
2162           Arguments are a hook name and the step to find the hook for.  Calls
2163           the find_hook method to get a code ref which it then calls and
2164           returns the result passing any extra arguments to run_hook as argu‐
2165           ments to the code ref.
2166
2167           Each call to run_hook is logged in the arrayref returned by the
2168           history method.  This information is summarized in the dump_history
2169           method and is useful for tracing the flow of the program.
2170
2171           The run_hook method is part of the core of CGI::Ex::App.  It allows
2172           for an intermediate layer in normal method calls.  Because of
2173           run_hook, it is possible to logically override methods on a step by
2174           step basis, or override a method for all of the steps, or even to
2175           break code out into separate modules.
2176
2177       run_step (hook)
2178           Runs all of the hooks specific to each step, beginning with
2179           pre_step and ending with post_step (for a full listing of steps,
2180           see the section on process flow).  Called after ->morph($step) has
2181           been run.  If this hook returns true, the nav_loop is exited (mean‐
2182           ing the run_step hook displayed a printed page).  If it returns
2183           false, the nav_loop continues on to run the next step.
2184
2185           This hook performs the same base functionality as a method defined
2186           in CGI::Applications ->run_modes.  The default run_step method pro‐
2187           vides much more granular control over the flow of the CGI.
2188
2189       set_path (method)
2190           Arguments are the steps to set.  Should be called before navigation
2191           begins.  This will set the path arrayref to the passed steps.
2192
2193           This method is not normally used.
2194
2195       set_ready_validate (hook and method)
2196           Sets that the validation is ready (or not) to validate.  Should set
2197           the value checked by the hook ready_validate.  The following would
2198           complement the processing flag above:
2199
2200               sub set_ready_validate {
2201                   my $self = shift;
2202                   my ($step, $is_ready) = (@_ == 2) ? @_ : (undef, shift);
2203                   if ($is_ready) {
2204                       $self->form->{'processing'} = 1;
2205                   } else {
2206                       delete $self->form->{'processing'};
2207                   }
2208                   return $is_ready;
2209               }
2210
2211           Note that for this example the form key "processing" was deleted.
2212           This is so that the call to fill in any html forms won't swap in a
2213           value of zero for form elements named "processing."
2214
2215           Also note that this method may be called as a hook as in
2216
2217               $self->run_hook('set_ready_validate', $step, 0)
2218               # OR
2219               $self->set_ready_validate($step, 0);
2220
2221           Or it can take a single argument and should set the ready status
2222           regardless of the step as in:
2223
2224               $self->set_ready_validate(0);
2225
2226       skip (hook)
2227           Ran at the beginning of the loop before prepare, info_complete, and
2228           finalize are called.  If it returns true, nav_loop moves on to the
2229           next step (the current step is skipped).
2230
2231       stash (method)
2232           Returns a hashref that can store arbitrary user space data without
2233           worrying about overwriting the internals of the application.
2234
2235       step_key (method)
2236           Should return the keyname that will be used by the default "path"
2237           method to look for in the form.  Default value is 'step'.
2238
2239       swap_template (hook)
2240           Takes the template and hash of variables prepared in print, and
2241           processes them through the current template engine (default engine
2242           is CGI::Ex::Template a subclass of Template::Alloy).
2243
2244           Arguments are the template and the swap hashref.  The template can
2245           be either a scalar reference to the actual content, or the filename
2246           of the content.  If the filename is specified - it should be rela‐
2247           tive to template_path (which will be used to initialize
2248           INCLUDE_PATH by default).
2249
2250           The default method will create a template object by calling the
2251           template_args hook and passing the returned hashref to the tem‐
2252           plate_obj method.  The default template_obj method returns a
2253           CGI::Ex::Template object, but could easily be swapped to use a Tem‐
2254           plate::Toolkit based object.  If a non-Template::Toolkit compatible
2255           object is to be used, then the swap_template hook can be overridden
2256           to use another templating engine.
2257
2258           For example to use the HTML::Template engine you could override the
2259           swap_template method as follows:
2260
2261               use HTML::Template;
2262
2263               sub swap_template {
2264                   my ($self, $step, $file, $swap) = @_;
2265
2266                   my $type = UNIVERSAL::isa($file, 'SCALAR') ? 'scalarref'
2267                            : UNIVERSAL::isa($file, 'ARRAY')  ? 'arrayref'
2268                            : ref($file)                      ? 'filehandle'
2269                            :                                   'filename';
2270
2271                   my $t = HTML::Template->new(source => $file,
2272                                               type   => $type,
2273                                               path   => $self->template_path,
2274                                               die_on_bad_params => 0,
2275                                               );
2276
2277                   $t->param($swap);
2278
2279                   return $t->output;
2280               }
2281
2282           As of version 2.13 of CGI::Ex::Template you could also simply do
2283           the following to parse the templates using HTML::Template::Expr
2284           syntax.
2285
2286               sub template_args {
2287                   return {SYNTAX => 'hte'};
2288               }
2289
2290           For a listing of the available syntaxes, see the current Tem‐
2291           plate::Alloy documentation.
2292
2293       template_args (hook)
2294           Returns a hashref of args that will be passed to the "new" method
2295           of CGI::Ex::Template.  The method is normally called from the
2296           swap_template hook.  The swap_template hook will add a value for
2297           INCLUDE_PATH which is set equal to template_path, if the
2298           INCLUDE_PATH value is not already set.
2299
2300           The returned hashref can contain any arguments that CGI::Ex::Tem‐
2301           plate (a subclass of Template::Alloy) would understand.
2302
2303               sub template_args {
2304                   return {
2305                       PRE_CHOMP => 1,
2306                       WRAPPER   => 'wrappers/main_wrapper.html',
2307                   };
2308               }
2309
2310           See the Template::Alloy documentation for a listing of all possible
2311           configuration arguments.
2312
2313       template_obj (method)
2314           Called from swap_template.  It is passed the result of tem‐
2315           plate_args that have had a default INCLUDE_PATH added via tem‐
2316           plate_path.  The default implementation uses CGI::Ex::Template (a
2317           subclass of Template::Alloy) but can easily be changed to use Tem‐
2318           plate::Toolkit by using code similar to the following:
2319
2320               use Template;
2321
2322               sub template_obj {
2323                   my ($self, $args) = @_;
2324                   return Template->new($args);
2325               }
2326
2327       template_path (method)
2328           Defaults to $self->{'template_path'} which defaults to
2329           base_dir_abs.  Used by the template_obj method.
2330
2331       unmorph (method)
2332           Allows for returning an object back to its previous blessed state
2333           if the "morph" method was successful in morphing the App object.
2334           This only happens if the object was previously morphed into another
2335           object type.  Before the object is re-blessed the method
2336           fixup_before_unmorph is called.
2337
2338           See allow_morph and morph.
2339
2340       valid_steps (method)
2341           Called by the default path method.  Should return a hashref of path
2342           steps that are allowed.  If the current step is not found in the
2343           hash (or is not the default_step or js_step) the path method will
2344           return a single step of ->forbidden_step and run its hooks.  If no
2345           hash or undef is returned, all paths are allowed (default).  A key
2346           "forbidden_step" containing the step that was not valid will be
2347           placed in the stash.  Often the valid_steps method does not need to
2348           be defined as arbitrary method calls are not possible with
2349           CGI::Ex::App.
2350
2351           Any steps that begin with _ are also "not" valid for passing in via
2352           the form or path info.  See the path method.
2353
2354           Also, the pre_step, skip, prepare, and info_complete hooks allow
2355           for validating the data before running finalize.
2356
2357       validate (hook)
2358           Passed the form from $self->form.  Runs validation on the informa‐
2359           tion contained in the passed form.  Uses CGI::Ex::Validate for the
2360           default validation.  Calls the hook hash_validation to load valida‐
2361           tion hashref (an empty hash means to pass validation).  Should
2362           return true if the form passed validation and false otherwise.
2363           Errors are stored as a hash in $self->{hash_errors} via method
2364           add_errors and can be checked for at a later time with method
2365           has_errors (if the default validate was used).
2366
2367           There are many ways and types to validate the data.  Please see the
2368           CGI::Ex::Validate module.
2369
2370           Upon success, it will look through all of the items which were val‐
2371           idated, if any of them contain the keys append_path, insert_path,
2372           or replace_path, that method will be called with the value as argu‐
2373           ments.  This allows for the validation to apply redirection to the
2374           path.  A validation item of:
2375
2376               {field => 'foo', required => 1, append_path => ['bar', 'baz']}
2377
2378           would append 'bar' and 'baz' to the path should all validation suc‐
2379           ceed.
2380
2381       verify_user (method)
2382           Installed as a hook to CGI::Ex::App during get_valid_auth.  Should
2383           return true if the user is ok.  Default is to always return true.
2384           This can be used to abort early before the get_pass_by_user hook is
2385           called.
2386
2387                sub verify_user {
2388                    my ($self, $user) = @_;
2389                    return 0 if $user eq 'paul'; # don't let paul in
2390                    return 1;                    # let anybody else in
2391                }
2392

HOW DO I SET COOKIES, REDIRECT, ETC

2394       Often in your program you will want to set cookies or bounce to a dif‐
2395       fernt URL.  This can be done using either the builtin CGI::Ex object or
2396       the built in CGI object.  It is suggested that you only use the CGI::Ex
2397       methods as it will automatically send headers and method calls under
2398       cgi, mod_perl1, or mod_perl2.  The following shows how to do basic
2399       items using the CGI::Ex object returned by the ->cgix method.
2400
2401       printing content-type headers
2402               ### CGI::Ex::App prints headers for you,
2403               ### but if you are printing custom types, you can send your own
2404               $self->cgix->print_content_type;
2405               # SAME AS
2406               # $self->cgix->print_content_type('text/html');
2407
2408       setting a cookie
2409               $self->cgix->set_cookie({
2410                   -name    => "my_key",
2411                   -value   => 'Some Value',
2412                   -expires => '1y',
2413                   -path    => '/',
2414               });
2415
2416       redirecting to another URL
2417               $self->cgix->location_bounce("http://somewhereelse.com");
2418               $self->exit_nav_loop; # normally should do this to long jump out of navigation
2419
2420       making a QUERY_STRING
2421               my $data  = {foo => "bar", one => "two or three"};
2422               my $query = $self->cgix->make_form($data);
2423               # $query now equals "foo=bar&one=two%20or%20three"
2424
2425       getting form parameters
2426               my $form = $self->form;
2427
2428           In this example $form would now contain a hashref of all POST and
2429           GET parameters passed to the server.  The form method calls
2430           $self->cgix->get_form which in turn uses CGI->param to parse val‐
2431           ues.  Fields with multiple passed values will be in the form of an
2432           arrayref.
2433
2434       getting cookies
2435               my $cookies = $self->cookies;
2436
2437           In this example $cookies would be a hashref of all passed in cook‐
2438           ies.  The cookies method calls $self->cgix->get_cookies which in
2439           turn uses CGI->cookie to parse values.
2440
2441       See the CGI::Ex and CGI documentation for more information.
2442

COMPARISON TO OTHER APPLICATION MODULES

2444       The concepts used in CGI::Ex::App are not novel or unique.  However,
2445       they are all commonly used and very useful.  All application builders
2446       were built because somebody observed that there are common design pat‐
2447       terns in CGI building.  CGI::Ex::App differs in that it has found more
2448       common design patterns of CGI's than other application builders and
2449       tries to get in the way less than others.
2450
2451       CGI::Ex::App is intended to be sub classed, and sub sub classed, and
2452       each step can choose to be sub classed or not.  CGI::Ex::App tries to
2453       remain simple while still providing "more than one way to do it."  It
2454       also tries to avoid making any sub classes have to call ->SUPER::
2455       (although that is fine too).
2456
2457       And if what you are doing on a particular is far too complicated or
2458       custom for what CGI::Ex::App provides, CGI::Ex::App makes it trivial to
2459       override all behavior.
2460
2461       There are certainly other modules for building CGI applications.  The
2462       following is a short list of other modules and how CGI::Ex::App is dif‐
2463       ferent.
2464
2465       "CGI::Application"
2466           Seemingly the most well know of application builders.  CGI::Ex::App
2467           is different in that it:
2468
2469             * Uses Template::Toolkit compatible CGI::Ex::Template (a
2470                 subclass of Template::Alloy) by default.
2471                 CGI::Ex::App can easily use another toolkit by simply
2472                 overriding the ->swap_template method.
2473                 CGI::Application uses HTML::Template.
2474             * Offers integrated data validation.
2475                 CGI::Application has had custom plugins created that
2476                 add some of this functionality.  CGI::Ex::App has the benefit
2477                 that validation is automatically available in javascript as well.
2478             * Allows the user to print at any time (so long as proper headers
2479                 are sent.  CGI::Application requires data to be pipelined.
2480             * Offers hooks into the various phases of each step ("mode" in
2481                 CGI::Application lingo).  CGI::Application provides only ->runmode
2482                 which is only a dispatch.
2483             * Support for easily jumping around in navigation steps.
2484             * Support for storing some steps in another package.
2485             * Integrated authentication
2486             * Integrated form filling
2487             * Integrated PATH_INFO mapping
2488
2489           CGI::Ex::App and CGI::Application are similar in that they take
2490           care of handling headers and they allow for calling other "run‐
2491           modes" from within any given runmode.  CGI::Ex::App's ->run_step is
2492           essentially equivalent to a method call defined in CGI::Applica‐
2493           tion's ->run_modes.  The ->run method of CGI::Application starts
2494           the application in the same manner as CGI::Ex::App's ->navigate
2495           call.  Many of the hooks around CGI::Ex::App's ->run_step call are
2496           similar in nature to those provided by CGI::Application.
2497
2498       "CGI::Prototype"
2499           There are actually many similarities.  One of the nicest things
2500           about CGI::Prototype is that it is extremely short (very very
2501           short).  The ->activate starts the application in the same manner
2502           as CGI::Ex::App's ->navigate call.  Both use Template::Toolkit as
2503           the default template system (CGI::Ex::App uses CGI::Ex::Template
2504           which is TT compatible).  CGI::Ex::App is differrent in that it:
2505
2506             * Offers more hooks into the various phases of each step.
2507             * Support for easily jumping around in navigation steps.
2508             * Support for storing only some steps in another package.
2509             * Integrated data validation
2510             * Integrated authentication
2511             * Integrated form filling
2512             * Integrated PATH_INFO mapping
2513

SIMPLE EXTENDED EXAMPLE

2515       The following example shows the creation of a basic recipe database.
2516       It requires the use of DBD::SQLite, but that is all.  Once you have
2517       configured the db_file and template_path methods of the "recipe" file,
2518       you will have a working script that does CRUD for the recipe table.
2519       The observant reader may ask - why not use Catalyst or Ruby on Rails?
2520       The observant programmer will reply that making a framework do some‐
2521       thing simple is easy, but making it do something complex is complex and
2522       any framework that tries to do the those complex things for you is too
2523       complex.  CGI::Ex::App lets you write the complex logic but gives you
2524       the ability to not worry about the boring details such as template
2525       engines, or sticky forms, or cgi parameters, or data validation.  Once
2526       you are setup and are running, you are only left with providing the
2527       core logic of the application.
2528
2529           ### File: /var/www/cgi-bin/recipe (depending upon Apache configuration)
2530           ### --------------------------------------------
2531           #!/usr/bin/perl -w
2532
2533           use lib qw(/var/www/lib);
2534           use Recipe;
2535           Recipe->navigate;
2536
2537           ### File: /var/www/lib/Recipe.pm
2538           ### --------------------------------------------
2539           package Recipe;
2540
2541           use strict;
2542           use base qw(CGI::Ex::App);
2543           use CGI::Ex::Dump qw(debug);
2544
2545           use DBI;
2546           use DBD::SQLite;
2547
2548           ###------------------------------------------###
2549
2550           sub post_navigate {
2551               # show what happened
2552               debug shift->dump_history;
2553           }
2554
2555           sub template_path { '/var/www/templates' }
2556
2557           sub base_dir_rel { 'content' }
2558
2559           sub db_file { '/var/www/recipe.sqlite' }
2560
2561           sub dbh {
2562               my $self = shift;
2563               if (! $self->{'dbh'}) {
2564                   my $file   = $self->db_file;
2565                   my $exists = -e $file;
2566                   $self->{'dbh'} = DBI->connect("dbi:SQLite:dbname=$file", '', '',
2567                                                 {RaiseError => 1});
2568                   $self->create_tables if ! $exists;
2569               }
2570               return $self->{'dbh'};
2571           }
2572
2573           sub create_tables {
2574               my $self = shift;
2575
2576               $self->dbh->do("CREATE TABLE recipe (
2577                   id INTEGER PRIMARY KEY AUTOINCREMENT,
2578                   title VARCHAR(50) NOT NULL,
2579                   ingredients VARCHAR(255) NOT NULL,
2580                   directions VARCHAR(255) NOT NULL,
2581                   date_added VARCHAR(20) NOT NULL
2582               )");
2583           }
2584
2585           ###----------------------------------------------------------------###
2586
2587           sub main_info_complete { 0 }
2588
2589           sub main_hash_swap {
2590               my $self = shift;
2591
2592               my $s = "SELECT id, title, date_added
2593                          FROM recipe
2594                         ORDER BY date_added";
2595               my $data = $self->dbh->selectall_arrayref($s);
2596               my @data = map {my %h; @h{qw(id title date_added)} = @$_; \%h} @$data;
2597
2598               return {
2599                   recipies => \@data,
2600               };
2601           }
2602
2603           ###----------------------------------------------------------------###
2604
2605           sub add_name_step { 'edit' }
2606
2607           sub add_hash_validation {
2608               return {
2609                   'group order' => [qw(title ingredients directions)],
2610                   title => {
2611                       required => 1,
2612                       max_len  => 30,
2613                   },
2614                   ingredients => {
2615                       required => 1,
2616                       max_len  => 255,
2617                   },
2618                   directions => {
2619                       required => 1,
2620                       max_len  => 255,
2621                   },
2622               };
2623           }
2624
2625           sub add_finalize {
2626               my $self = shift;
2627               my $form = $self->form;
2628
2629               my $s = "SELECT COUNT(*) FROM recipe WHERE title = ?";
2630               my ($count) = $self->dbh->selectrow_array($s, {}, $form->{'title'});
2631               if ($count) {
2632                   $self->add_errors(title => 'A recipe by this title already exists');
2633                   return 0;
2634               }
2635
2636               $s = "INSERT INTO recipe (title, ingredients, directions, date_added)
2637                     VALUES (?, ?, ?, ?)";
2638               $self->dbh->do($s, {}, $form->{'title'},
2639                                      $form->{'ingredients'},
2640                                      $form->{'directions'},
2641                                      scalar(localtime));
2642
2643               $self->add_to_form(success => "Recipe added to the database");
2644
2645               return 1;
2646           }
2647
2648           ###----------------------------------------------------------------###
2649
2650           sub edit_skip { shift->form->{'id'} ? 0 : 1 }
2651
2652           sub edit_hash_common {
2653               my $self = shift;
2654               return {} if $self->ready_validate;
2655
2656               my $sth  = $self->dbh->prepare("SELECT * FROM recipe WHERE id = ?");
2657               $sth->execute($self->form->{'id'});
2658               my $hash = $sth->fetchrow_hashref;
2659
2660               return $hash;
2661           }
2662
2663           sub edit_hash_validation { shift->add_hash_validation(@_) }
2664
2665           sub edit_finalize {
2666               my $self = shift;
2667               my $form = $self->form;
2668
2669               my $s = "SELECT COUNT(*) FROM recipe WHERE title = ? AND id != ?";
2670               my ($count) = $self->dbh->selectrow_array($s, {}, $form->{'title'}, $form->{'id'});
2671               if ($count) {
2672                   $self->add_errors(title => 'A recipe by this title already exists');
2673                   return 0;
2674               }
2675
2676               $s = "UPDATE recipe SET title = ?, ingredients = ?, directions = ? WHERE id = ?";
2677               $self->dbh->do($s, {}, $form->{'title'},
2678                                      $form->{'ingredients'},
2679                                      $form->{'directions'},
2680                                      $form->{'id'});
2681
2682               $self->add_to_form(success => "Recipe updated in the database");
2683
2684               return 1;
2685           }
2686
2687           ###----------------------------------------------------------------###
2688
2689           sub view_skip { shift->edit_skip(@_) }
2690
2691           sub view_hash_common { shift->edit_hash_common(@_) }
2692
2693           ###----------------------------------------------------------------###
2694
2695           sub delete_skip { shift->edit_skip(@_) }
2696
2697           sub delete_info_complete { 1 }
2698
2699           sub delete_finalize {
2700               my $self = shift;
2701               $self->dbh->do("DELETE FROM recipe WHERE id = ?", {}, $self->form->{'id'});
2702
2703               $self->add_to_form(success => "Recipe deleted from the database");
2704               return 1;
2705           }
2706
2707           1;
2708
2709           __END__
2710
2711           File: /var/www/templates/content/recipe/main.html
2712           ### --------------------------------------------
2713           <html>
2714           <head>
2715           <title>Recipe DB</title>
2716           </head>
2717           <h1>Recipe DB</h1>
2718
2719           [% IF success %]<span style="color:darkgreen"><h2>[% success %]</h2></span>[% END %]
2720
2721           <table style="border:1px solid blue">
2722           <tr><th>#</th><th>Title</th><th>Date Added</th></tr>
2723
2724           [% FOR row IN recipies %]
2725           <tr>
2726             <td>[% loop.count %].</td>
2727             <td><a href="[% script_name %]/view?id=[% row.id %]">[% row.title %]</a>
2728               (<a href="[% script_name %]/edit?id=[% row.id %]">Edit</a>)
2729             </td>
2730             <td>[% row.date_added %]</td>
2731           </tr>
2732           [% END %]
2733
2734           <tr><td colspan=2 align=right><a href="[% script_name %]/add">Add new recipe</a></td></tr>
2735           </table>
2736
2737           </html>
2738
2739           File: /var/www/templates/content/recipe/edit.html
2740           ### --------------------------------------------
2741           <html>
2742           <head>
2743           <title>[% step == 'add' ? "Add" : "Edit" %] Recipe</title>
2744           </head>
2745           <h1>[% step == 'add' ? "Add" : "Edit" %] Recipe</h1>
2746
2747           <form method=post name=[% form_name %]>
2748           <input type=hidden name=step>
2749
2750           <table>
2751
2752           [% IF step != 'add' ~%]
2753           <tr>
2754             <td><b>Id:</b></td><td>[% id %]</td></tr>
2755             <input type=hidden name=id>
2756           </tr>
2757           <tr>
2758             <td><b>Date Added:</b></td><td>[% date_added %]</td></tr>
2759           </tr>
2760           [% END ~%]
2761
2762           <tr>
2763             <td valign=top><b>Title:</b></td>
2764             <td><input type=text name=title>
2765                 <span style='color:red' id=title_error>[% title_error %]</span></td>
2766           </tr>
2767           <tr>
2768             <td valign=top><b>Ingredients:</b></td>
2769             <td><textarea name=ingredients rows=10 cols=40 wrap=physical></textarea>
2770                 <span style='color:red' id=ingredients_error>[% ingredients_error %]</span></td>
2771           </tr>
2772           <tr>
2773             <td valign=top><b>Directions:</b></td>
2774             <td><textarea name=directions rows=10 cols=40 wrap=virtual></textarea>
2775                 <span style='color:red' id=directions_error>[% directions_error %]</span></td>
2776           </tr>
2777           <tr>
2778             <td colspan=2 align=right>
2779                 <input type=submit value="[% step == 'add' ? 'Add' : 'Update' %]"></td>
2780           </tr>
2781           </table>
2782           </form>
2783
2784           (<a href="[% script_name %]">Main Menu</a>)
2785           [% IF step != 'add' ~%]
2786             (<a href="[% script_name %]/delete?id=[% id %]">Delete this recipe</a>)
2787           [%~ END %]
2788
2789           [% js_validation %]
2790
2791           </html>
2792
2793           File: /var/www/templates/content/recipe/view.html
2794           ### --------------------------------------------
2795           <html>
2796           <head>
2797           <title>[% title %] - Recipe DB</title>
2798           </head>
2799           <h1>[% title %]</h1>
2800           <h3>Date Added: [% date_added %]</h3>
2801
2802           <h2>Ingredients</h2>
2803           [% ingredients %]
2804
2805           <h2>Directions</h2>
2806           [% directions %]
2807
2808           <hr>
2809           (<a href="[% script_name %]">Main Menu</a>)
2810           (<a href="[% script_name %]/edit?id=[% id %]">Edit this recipe</a>)
2811
2812           </html>
2813
2814           ### --------------------------------------------
2815
2816       Notes:
2817
2818       The dbh method returns an SQLite dbh handle and auto creates the
2819       schema.  You will normally want to use MySQL or Oracle, or Postgres and
2820       you will want your schema to NOT be auto-created.
2821
2822       This sample uses hand rolled SQL.  Class::DBI or a similar module might
2823       make this example shorter.  However, more complex cases that need to
2824       involve two or three or four tables would probably be better off using
2825       the hand crafted SQL.
2826
2827       This sample uses SQL.  You could write the application to use whatever
2828       storage you want - or even to do nothing with the submitted data.
2829
2830       We had to write our own HTML (Catalyst and Ruby on Rails do this for
2831       you).  For most development work - the HTML should be in a static loca‐
2832       tion so that it can be worked on by designers.  It is nice that the
2833       other frameworks give you stub html - but that is all it is.  It is
2834       worth about as much as copying and pasting the above examples.  All
2835       worthwhile HTML will go through a non-automated design/finalization
2836       process.
2837
2838       The add step used the same template as the edit step.  We did this
2839       using the add_name_step hook which returned "edit".  The template con‐
2840       tains IF conditions to show different information if we were in add
2841       mode or edit mode.
2842
2843       We reused code, validation, and templates.  Code and data reuse is a
2844       good thing.
2845
2846       The edit_hash_common returns an empty hashref if the form was ready to
2847       validate.  When hash_common is called and the form is ready to vali‐
2848       date, that means the form failed validation and is now printing out the
2849       page.  To let us fall back and use the "sticky" form fields that were
2850       just submitted, we need to not provide values in the hash_common
2851       method.
2852
2853       We use hash_common.  Values from hash_common are used for both template
2854       swapping and filling.  We could have used hash_swap and hash_fill inde‐
2855       pendently.
2856
2857       The hook main_info_complete is hard coded to 0.  This basically says
2858       that we will never try and validate or finalize the main step - which
2859       is most often the case.
2860

SEPARATING STEPS INTO SEPARATE FILES

2862       It may be useful sometimes to separate some or all of the steps of an
2863       application into separate files.  This is the way that CGI::Prototype
2864       works.  This is useful in cases were some steps and their hooks are
2865       overly large - or are seldom used.
2866
2867       The following modifications can be made to the previous "recipe db"
2868       example that would move the "delete" step into its own file.  Similar
2869       actions can be taken to break other steps into their own file as well.
2870
2871           ### File: /var/www/lib/Recipe.pm
2872           ### Same as before but add the following line:
2873           ### --------------------------------------------
2874
2875           sub allow_morph { 1 }
2876
2877           ### File: /var/www/lib/Recipe/Delete.pm
2878           ### Remove the delete_* subs from lib/Recipe.pm
2879           ### --------------------------------------------
2880           package Recipe::Delete;
2881
2882           use strict;
2883           use base qw(Recipe);
2884
2885           sub skip { shift->edit_skip(@_) }
2886
2887           sub info_complete { 1 }
2888
2889           sub finalize {
2890               my $self = shift;
2891               $self->dbh->do("DELETE FROM recipe WHERE id = ?", {}, $self->form->{'id'});
2892
2893               $self->add_to_form(success => "Recipe deleted from the database");
2894               return 1;
2895           }
2896
2897       Notes:
2898
2899       The hooks that are called (skip, info_complete, and finalize) do not
2900       have to be prefixed with the step name because they are now in their
2901       own individual package space.  However, they could still be named
2902       delete_skip, delete_info_complete, and delete_finalize and the run_hook
2903       method will find them (this would allow several steps with the same
2904       "morph_package" to still be stored in the same external module).
2905
2906       The method allow_morph is passed the step that we are attempting to
2907       morph to.  If allow_morph returns true every time, then it will try and
2908       require the extra packages every time that step is ran.  You could
2909       limit the morphing process to run only on certain steps by using code
2910       similar to the following:
2911
2912           sub allow_morph { return {delete => 1} }
2913
2914           # OR
2915
2916           sub allow_morph {
2917               my ($self, $step) = @_;
2918               return ($step eq 'delete') ? 1 : 0;
2919           }
2920
2921       The CGI::Ex::App temporarily blesses the object into the "morph_pack‐
2922       age" for the duration of the step and re-blesses it into the original
2923       package upon exit.  See the morph method and allow_morph for more
2924       information.
2925

RUNNING UNDER MOD_PERL

2927       The previous samples are essentially suitable for running under flat
2928       CGI, Fast CGI, or mod_perl Registry or mod_perl PerlRun type environ‐
2929       ments.  It is very easy to move the previous example to be a true
2930       mod_perl handler.
2931
2932       To convert the previous recipe example, simply add the following:
2933
2934           ### File: /var/www/lib/Recipe.pm
2935           ### Same as before but add the following lines:
2936           ### --------------------------------------------
2937
2938           sub handler {
2939               Recipe->navigate;
2940               return;
2941           }
2942
2943           ### File: apache2.conf - or whatever your apache conf file is.
2944           ### --------------------------------------------
2945           <Location /recipe>
2946               SetHandler perl-script
2947               PerlHandler Recipe
2948           </Location>
2949
2950       Notes:
2951
2952       Both the /cgi-bin/recipe version and the /recipe version can co-exist.
2953       One of them will be a normal cgi and the other will correctly use
2954       mod_perl hooks for headers.
2955
2956       Setting the location to /recipe means that the $ENV{SCRIPT_NAME} will
2957       also be set to /recipe.  This means that name_module method will
2958       resolve to "recipe".  If a different URI location is desired such as
2959       "/my_cool_recipe" but the program is to use the same template content
2960       (in the /var/www/templates/content/recipe directory), then we would
2961       need to explicitly set the "name_module" parameter.  It could be done
2962       in either of the following ways:
2963
2964           ### File: /var/www/lib/Recipe.pm
2965           ### Same as before but add the following line:
2966           ### --------------------------------------------
2967
2968           sub name_module { 'recipe' }
2969
2970           # OR
2971
2972           sub init {
2973               my $self = shift;
2974               $self->{'name_module'} = 'recipe';
2975           }
2976
2977       In most use cases it isn't necessary to set name_module, but it also
2978       doesn't hurt and in all cases it is more descriptive to anybody who is
2979       going to maintain the code later.
2980

ADDING AUTHENTICATION TO THE ENTIRE APPLICATION

2982       Having authentication is sometimes a good thing.  To force the entire
2983       application to be authenticated (require a valid username and password
2984       before doing anything) you could do the following.
2985
2986           ### File: /var/www/lib/Recipe.pm
2987           ### Same as before but add
2988           ### --------------------------------------------
2989
2990           sub get_pass_by_user {
2991               my $self = shift;
2992               my $user = shift;
2993               my $pass = $self->lookup_and_cache_the_pass($user);
2994               return $pass;
2995           }
2996
2997           ### File: /var/www/cgi-bin/recipe (depending upon Apache configuration)
2998           ### Change the line with ->navigate; to
2999           ### --------------------------------------------
3000
3001           Recipe->navigate_authenticated;
3002
3003           # OR
3004
3005           ### File: /var/www/lib/Recipe.pm
3006           ### Same as before but add
3007           ### --------------------------------------------
3008
3009           sub require_auth { 1 }
3010
3011           # OR
3012
3013           ### File: /var/www/lib/Recipe.pm
3014           ### Same as before but add
3015           ### --------------------------------------------
3016
3017           sub init { shift->require_auth(1) }
3018
3019       See the require_auth, get_valid_auth, and auth_args methods for more
3020       information.  Also see the CGI::Ex::Auth perldoc.
3021

ADDING AUTHENTICATION TO INDIVIDUAL STEPS

3023       Sometimes you may only want to have certain steps require authentica‐
3024       tion.  For example, in the previous recipe example we might want to let
3025       the main and view steps be accessible to anybody, but require authenti‐
3026       cation for the add, edit, and delete steps.
3027
3028       To do this, we would do the following to the original example (the nav‐
3029       igation must start with ->navigate.  Starting with ->navigate_authenti‐
3030       cated will cause all steps to require validation):
3031
3032           ### File: /var/www/lib/Recipe.pm
3033           ### Same as before but add
3034           ### --------------------------------------------
3035
3036           sub get_pass_by_user {
3037               my $self = shift;
3038               my $user = shift;
3039               my $pass = $self->lookup_and_cache_the_pass($user);
3040               return $pass;
3041           }
3042
3043           sub require_auth { {add => 1, edit => 1, delete => 1} }
3044
3045       We could also enable authentication by using individual hooks as in:
3046
3047           sub add_require_auth    { 1 }
3048           sub edit_require_auth   { 1 }
3049           sub delete_require_auth { 1 }
3050
3051       Or we could require authentication on everything - but let a few steps
3052       in:
3053
3054           sub require_auth { 1 }      # turn authentication on for all
3055           sub main_require_auth { 0 } # turn it off for main and view
3056           sub view_require_auth { 0 }
3057
3058       That's it.  The add, edit, and delete steps will now require authenti‐
3059       cation.  See the require_auth, get_valid_auth, and auth_args methods
3060       for more information.  Also see the CGI::Ex::Auth perldoc.
3061

THANKS

3063       The following corporation and individuals contributed in some part to
3064       the original versions.
3065
3066           Bizhosting.com  - giving a problem that fit basic design patterns.
3067
3068           Earl Cahill     - pushing the idea of more generic frameworks.
3069
3070           Adam Erickson   - design feedback, bugfixing, feature suggestions.
3071
3072           James Lance     - design feedback, bugfixing, feature suggestions.
3073
3074           Krassimir Berov - feedback and some warnings issues with POD examples.
3075

LICENSE

3077       This module may be distributed under the same terms as Perl itself.
3078

AUTHOR

3080       Paul Seamons <perl at seamons dot com>
3081
3082
3083
3084perl v5.8.8                       2007-10-18                   CGI::Ex::App(3)
Impressum