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       Properly put 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
39           -------- File: /var/www/templates/my_cgi/main.html --------
40
41           Hello World!
42
43       Adding substitutions...
44
45           -------- File: /cgi-bin/my_cgi --------
46
47           #!/usr/bin/perl -w
48
49           use strict;
50           use base qw(CGI::Ex::App);
51
52           __PACKAGE__->navigate;
53
54           sub template_path { '/var/www/templates' }
55
56           sub main_hash_swap {
57               my $self = shift;
58               return {
59                   greeting => 'Hello',
60                   date     => sub { scalar localtime },
61               };
62           }
63
64
65           -------- File: /var/www/templates/my_cgi/main.html --------
66
67           [% greeting %] World! ([% date %])
68
69       Add forms and  validation (inluding javascript validation)...
70
71           -------- File: /cgi-bin/my_cgi --------
72
73           #!/usr/bin/perl -w
74
75           use strict;
76           use base qw(CGI::Ex::App);
77
78           __PACKAGE__->navigate;
79
80           sub template_path { '/var/www/templates' }
81
82           sub main_hash_swap { {date => sub { scalar localtime }} }
83
84           sub main_hash_fill {
85               return {
86                   guess => 50,
87               };
88           }
89
90           sub main_hash_validation {
91               return {
92                   guess => {
93                       required => 1,
94                       compare1       => '<= 100',
95                       compare1_error => 'Please enter a value less than 101',
96                       compare2       => '>  0',
97                       compare2_error => 'Please enter a value greater than 0',
98                   },
99               };
100           }
101
102           sub main_finalize {
103               my $self   = shift;
104               my $form   = $self->form;
105
106               $self->add_to_form({was_correct => ($form->{'guess'} == 23)});
107
108               return 0; # indicate to show the page without trying to move along
109           }
110
111
112           -------- File: /var/www/templates/my_cgi/main.html --------
113
114           <h2>Hello World! ([% date %])</h2>
115
116           [% IF was_correct %]
117              <b>Correct!</b> - The number was [% guess %].<br>
118           [% ELSIF guess %]
119              <b>Incorrect</b> - The number was not [% guess %].<br>
120           [% END %]
121
122           <form name="[% form_name %]" method="post">
123
124           Enter a number between 1 and 100: <input type="text" name="guess"><br>
125           <span id="guess_error" style="color:red">[% guess_error %]</span><br>
126
127           <input type="submit">
128           </form>
129
130           [% js_validation %]
131
132       There are infinite possibilities.  There is a longer "SYNOPSIS" after
133       the process flow discussion and more examples near the end of this
134       document.  It is interesting to note that there have been no databases
135       so far.  It is very, very difficult to find a single database
136       abstraction that fits every model.  CGI::Ex::App is Controller/Viewer
137       that is somewhat Model agnostic and doesn't come with any default
138       database abstraction.
139

DESCRIPTION

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

DEFAULT PROCESS FLOW

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

MAPPING URI TO STEP

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

ADDING DATA VALIDATION TO A STEP

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

ADDING JAVASCRIPT DATA VALIDATION TO A STEP

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

ADDING ADDITIONAL TEMPLATE VARIABLES

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

ADDING ADDITIONAL FORM FILL VARIABLES

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

FINDING TEMPLATES AND VALIDATION FILES

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

SYNOPSIS (A LONG "SYNOPSIS")

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

HOW DO I SET COOKIES, REDIRECT, ETC

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

COMPARISON TO OTHER APPLICATION MODULES

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

SIMPLE EXTENDED EXAMPLE

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

SEPARATING STEPS INTO SEPARATE FILES

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

RUNNING UNDER MOD_PERL

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

ADDING AUTHENTICATION TO THE ENTIRE APPLICATION

2996       Having authentication is sometimes a good thing.  To force the entire
2997       application to be authenticated (require a valid username and password
2998       before doing anything) you could do the following.
2999
3000           ### File: /var/www/lib/Recipe.pm
3001           ### Same as before but add
3002           ### --------------------------------------------
3003
3004           sub get_pass_by_user {
3005               my $self = shift;
3006               my $user = shift;
3007               my $pass = $self->lookup_and_cache_the_pass($user);
3008               return $pass;
3009           }
3010
3011
3012           ### File: /var/www/cgi-bin/recipe (depending upon Apache configuration)
3013           ### Change the line with ->navigate; to
3014           ### --------------------------------------------
3015
3016           Recipe->navigate_authenticated;
3017
3018           # OR
3019
3020           ### File: /var/www/lib/Recipe.pm
3021           ### Same as before but add
3022           ### --------------------------------------------
3023
3024           sub require_auth { 1 }
3025
3026           # OR
3027
3028           ### File: /var/www/lib/Recipe.pm
3029           ### Same as before but add
3030           ### --------------------------------------------
3031
3032           sub init { shift->require_auth(1) }
3033
3034       See the require_auth, get_valid_auth, and auth_args methods for more
3035       information.  Also see the CGI::Ex::Auth perldoc.
3036

ADDING AUTHENTICATION TO INDIVIDUAL STEPS

3038       Sometimes you may only want to have certain steps require
3039       authentication.  For example, in the previous recipe example we might
3040       want to let the main and view steps be accessible to anybody, but
3041       require authentication for the add, edit, and delete steps.
3042
3043       To do this, we would do the following to the original example (the
3044       navigation must start with ->navigate.  Starting with
3045       ->navigate_authenticated will cause all steps to require validation):
3046
3047           ### File: /var/www/lib/Recipe.pm
3048           ### Same as before but add
3049           ### --------------------------------------------
3050
3051           sub get_pass_by_user {
3052               my $self = shift;
3053               my $user = shift;
3054               my $pass = $self->lookup_and_cache_the_pass($user);
3055               return $pass;
3056           }
3057
3058           sub require_auth { {add => 1, edit => 1, delete => 1} }
3059
3060       We could also enable authentication by using individual hooks as in:
3061
3062           sub add_require_auth    { 1 }
3063           sub edit_require_auth   { 1 }
3064           sub delete_require_auth { 1 }
3065
3066       Or we could require authentication on everything - but let a few steps
3067       in:
3068
3069           sub require_auth { 1 }      # turn authentication on for all
3070           sub main_require_auth { 0 } # turn it off for main and view
3071           sub view_require_auth { 0 }
3072
3073       That's it.  The add, edit, and delete steps will now require
3074       authentication.  See the require_auth, get_valid_auth, and auth_args
3075       methods for more information.  Also see the CGI::Ex::Auth perldoc.
3076

THANKS

3078       The following corporation and individuals contributed in some part to
3079       the original versions.
3080
3081           Bizhosting.com  - giving a problem that fit basic design patterns.
3082
3083           Earl Cahill     - pushing the idea of more generic frameworks.
3084
3085           Adam Erickson   - design feedback, bugfixing, feature suggestions.
3086
3087           James Lance     - design feedback, bugfixing, feature suggestions.
3088
3089           Krassimir Berov - feedback and some warnings issues with POD examples.
3090

LICENSE

3092       This module may be distributed under the same terms as Perl itself.
3093

AUTHOR

3095       Paul Seamons <perl at seamons dot com>
3096
3097
3098
3099perl v5.30.1                      2020-01-29                   CGI::Ex::App(3)
Impressum