3 CGI::Ex::App - Anti-framework application framework.
9 -------- File: /cgi-bin/my_cgi --------
14 use base qw(CGI::Ex::App);
16 __PACKAGE__->navigate;
20 return \ "Hello World!";
23 Well, you should put your content in an external file...
25 -------- File: /cgi-bin/my_cgi --------
30 use base qw(CGI::Ex::App);
32 __PACKAGE__->navigate;
34 sub template_path { '/var/www/templates' }
37 -------- File: /var/www/templates/my_cgi/main.html --------
41 How about if we want to add substitutions...
43 -------- File: /cgi-bin/my_cgi --------
48 use base qw(CGI::Ex::App);
50 __PACKAGE__->navigate;
52 sub template_path { '/var/www/templates' }
58 date => sub { scalar localtime },
63 -------- File: /var/www/templates/my_cgi/main.html --------
65 [% greeting %] World! ([% date %])
68 How about a form with validation (inluding javascript validation)...
70 -------- File: /cgi-bin/my_cgi --------
75 use base qw(CGI::Ex::App);
77 __PACKAGE__->navigate;
79 sub template_path { '/var/www/templates' }
81 sub main_hash_swap { {date => sub { scalar localtime }} }
89 sub main_hash_validation {
94 compare1_error => 'Please enter a value less than 101',
96 compare2_error => 'Please enter a value greater than 0',
103 my $form = $self->form;
105 $self->add_to_form({was_correct => ($form->{'guess'} == 23)});
107 return 0; # indicate to show the page without trying to move along
111 -------- File: /var/www/templates/my_cgi/main.html --------
113 <h2>Hello World! ([% date %])</h2>
116 <b>Correct!</b> - The number was [% guess %].<br>
118 <b>Incorrect</b> - The number was not [% guess %].<br>
121 <form name="[% form_name %]" method="post">
123 Enter a number between 1 and 100: <input type="text" name="guess"><br>
124 <span id="guess_error" style="color:red">[% guess_error %]</span><br>
126 <input type="submit">
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.
142 Fill in the blanks and get a ready made web application.
144 This module is somewhat similar in spirit to CGI::Application,
145 CGI::Path, and CGI::Builder and any other "CGI framework." As with
146 the others, CGI::Ex::App tries to do as much of the mundane things, in
147 a simple manner, without getting in the developer's way. However,
148 there are various design patterns for CGI applications that
149 CGI::Ex::App handles for you that the other frameworks require you to
150 bring in extra support. The entire CGI::Ex suite has been taylored to
151 work seamlessly together. Your mileage in building applications may
154 If you build applications that submit user information, validate it,
155 re-display it, fill in forms, or separate logic into separate modules,
156 then this module may be for you. If all you need is a dispatch
157 engine, then this still may be for you. If all you want is to look at
158 user passed information, then this may still be for you. If you like
159 writing bare metal code, this could still be for you. If you don't want
160 to write any code, this module will help - but you still need to
161 provide your key actions and html.
163 One of the great benefits of CGI::Ex::App vs. Catalyst or Rails style
164 frameworks is that the model of CGI::Ex::App can be much more abstract.
165 And models often are abstract.
167 =head1 DEFAULT PROCESS FLOW
169 The following pseudo-code describes the process flow
170 of the CGI::Ex::App framework. Several portions of the flow
171 are encapsulated in hooks which may be completely overridden to give
172 different flow. All of the default actions are shown. It may look
173 like a lot to follow, but if the process is broken down into the
174 discrete operations of step iteration, data validation, and template
175 printing the flow feels more natural.
179 The process starts off by calling ->navigate.
187 # dying errors will run the ->handle_error method
194 The nav_loop method will run as follows:
197 ->path (get the array of path steps)
198 # ->path_info_map_base (method - map ENV PATH_INFO to form)
199 # look in ->form for ->step_key
200 # make sure step is in ->valid_steps (if defined)
203 # navigation stops if true
205 foreach step of path {
207 ->require_auth (hook)
208 # exits nav_loop if true
211 # check ->allow_morph (hook)
212 # ->morph_package (hook - get the package to bless into)
213 # ->fixup_after_morph if morph_package exists
214 # if no package is found, process continues in current file
216 ->path_info_map (hook - map PATH_INFO to form)
221 # only called if run_step returned false (page not printed)
222 ->next_step (hook) # find next step and add to path
223 ->set_ready_validate(0) (hook)
226 # ->fixup_before_unmorph if blessed to current package
228 # exit loop if ->run_step returned true (page printed)
230 } end of foreach step
233 # navigation stops if true
236 ->insert_path (puts the default step into the path)
237 ->nav_loop (called again recursively)
241 =head2 run_step (hook)
243 For each step of the path the following methods will be run
244 during the run_step hook.
248 # skips this step if true and exit nav_loop
251 # skips this step if true and stays in nav_loop
253 ->prepare (hook - defaults to true)
255 ->info_complete (hook - ran if prepare was true)
256 ->ready_validate (hook)
257 ->validate_when_data (hook)
258 # returns false from info_complete if ! ready_validate
259 ->validate (hook - uses CGI::Ex::Validate to validate form info)
260 ->hash_validation (hook)
262 ->vob_path (defaults to template_path)
267 # returns true if validate is true or if nothing to validate
269 ->finalize (hook - defaults to true - ran if prepare and info_complete were true)
271 if ! ->prepare || ! ->info_complete || ! ->finalize {
279 # merge form, base, common, and fill into merged fill
280 # merge form, base, common, swap, and errors into merged swap
281 ->print (hook - passed current step, merged swap hash, and merged fill)
282 ->file_print (hook - uses base_dir_rel, name_module, name_step, ext_print)
283 ->swap_template (hook - processes the file with Template::Alloy)
284 ->template_args (hook - passed to Template::Alloy->new)
285 ->fill_template (hook - fills the any forms with CGI::Ex::Fill)
286 ->fill_args (hook - passed to CGI::Ex::Fill::fill)
287 ->print_out (hook - print headers and the content to STDOUT)
289 ->post_print (hook - used for anything after the print process)
291 # return true to exit from nav_loop
295 # exits nav_loop if true
299 It is important to learn the function and placement of each of the
300 hooks in the process flow in order to make the most of CGI::Ex::App.
301 It is enough to begin by learning a few common hooks - such as
302 hash_validation, hash_swap, and finalize, and then learn about other
303 hooks as needs arise. Sometimes, it is enough to simply override the
304 run_step hook and take care of processing the entire step yourself.
306 Because of the hook based system, and because CGI::Ex::App uses
307 sensible defaults, it is very easy to override a little or a lot which
308 ends up giving the developer a lot of flexibility.
310 Additionally, it should be possible to use CGI::Ex::App with the other
311 frameworks such as CGI::Application or CGI::Prototype. For these you
312 could simple let each "runmode" call the run_step hook of CGI::Ex::App
313 and you will instantly get all of the common process flow for free.
315 =head1 MAPPING URI TO STEP
317 The default out of the box configuration will map URIs to steps as follows:
319 # Assuming /cgi-bin/my_app is the program being run
324 WHY: No other information is passed. The path method is
325 called which eventually calls ->default_step which
328 URI: /cgi-bin/my_app?foo=bar
331 WHY: Same as previous example except that QUERY_STRING
332 information was passed and placed in form.
334 URI: /cgi-bin/my_app?step=my_step
336 FORM: {step => "my_step"}
337 WHY: The path method is called which looks in $self->form
338 for the key ->step_key (which defaults to "step").
340 URI: /cgi-bin/my_app?step=my_step&foo=bar
342 FORM: {foo => "bar", step => "my_step"}
343 WHY: Same as before but another parameter was passed.
345 URI: /cgi-bin/my_app/my_step
347 FORM: {step => "my_step"}
348 WHY: The path method is called which called path_info_map_base
349 which matched $ENV{'PATH_INFO'} using the default regex
350 of qr{^/(\w+)$} and place the result in
351 $self->form->{$self->step_key}. Path then looks in
352 $self->form->{$self->step_key} for the initial step. See
353 the path_info_map_base method for more information.
355 URI: /cgi-bin/my_app/my_step?foo=bar
357 FORM: {foo => "bar", step => "my_step"}
358 WHY: Same as before but other parameters were passed.
360 URI: /cgi-bin/my_app/my_step?step=other_step
362 FORM: {step => "other_step"}
363 WHY: The same procedure took place, but when the PATH_INFO
364 string was matched, the form key "step" already existed
365 and was not replaced by the value from PATH_INFO.
367 The remaining examples in this section are based on the assumption
368 that the following method is installed in your script.
370 sub my_step_path_info_map {
372 [qr{^/\w+/(\w+)/(\d+)$}, 'foo', 'id'],
373 [qr{^/\w+/(\w+)$}, 'foo'],
374 [qr{^/\w+/(.+)$}, 'anything_else'],
378 URI: /cgi-bin/my_app/my_step/bar
381 WHY: The step was matched as in previous examples using
382 path_info_map_base. However, the form key "foo"
383 was set to "bar" because the second regex returned
384 by the path_info_map hook matched the PATH_INFO string
385 and the corresponding matched value was placed into
386 the form using the keys specified following the regex.
388 URI: /cgi-bin/my_app/my_step/bar/1234
390 FORM: {foo => "bar", id => "1234"}
391 WHY: Same as the previous example, except that the first
392 regex matched the string. The first regex had two
393 match groups and two form keys specified. Note that
394 it is important to order your match regexes in the
395 order that will match the most data. The third regex
396 would also match this PATH_INFO.
398 URI: /cgi-bin/my_app/my_step/some/other/type/of/data
400 FORM: {anything_else => 'some/other/type/of/data'}
401 WHY: Same as the previous example, except that the third
404 URI: /cgi-bin/my_app/my_step/bar?bling=blang
406 FORM: {foo => "bar", bling => "blang"}
407 WHY: Same as the first sample, but additional QUERY_STRING
408 information was passed.
410 URI: /cgi-bin/my_app/my_step/one%20two?bar=three%20four
412 FORM: {anything_else => "one two", bar => "three four"}
413 WHY: The third path_info_map regex matched. Note that the
414 %20 in bar was unescaped by CGI::param, but the %20
415 in anything_else was unescaped by Apache. If you are
416 not using Apache, this behavior may vary. CGI::Ex::App
417 doesn't decode parameters mapped from PATH_INFO.
419 See the path method for more information about finding the initial step
422 The form method calls CGI::Ex::form which uses CGI::param to retrieve
423 GET and POST parameters. See the form method for more information on
424 how GET and POST parameters are parsed.
426 See the path_info_map_base method, and path_info_map hook for more information
427 on how the path_info maps function.
429 Using the following code is very useful for determing what hooks have
432 use CGI::Ex::Dump qw(debug);
436 debug $self->dump_history, $self->form;
439 =head1 ADDING DATA VALIDATION TO A STEP
441 CGI::Ex::App uses CGI::Ex::Validate for its data validation. See CGI::Ex::Validate
442 for more information about the many ways you can validate your data.
444 The default hash_validation hook returns an empty hashref. This means that passed
445 in data is all valid and the script will automatically call the step's finalize method.
447 The following shows how to add some contrived validation to a step called "my_step".
449 sub my_step_hash_validation {
453 match => 'm/^(\w+)$/',
454 match_error => 'The $field field may only contain word characters',
462 validate_if => 'password',
463 equals => 'password',
467 enum => [qw(animal vegetable mineral)],
472 The step will continue to display the html form until all of the fields pass
475 See the hash_validation hook and validate hook for more information about how
478 =head1 ADDING JAVASCRIPT DATA VALIDATION TO A STEP
480 You must first provide a hash_validation hook as explained in the previous section.
482 Once you have a hash_validation hook, you would place the following tags
483 into your HTML template.
485 <form name="[% form_name %]" method="post">
490 The "form_name" swap-in places a name on the form that the javascript returned by
491 the js_validation swap-in will be able to find and check for validity.
493 See the hash_validation, js_validation, and form_name hooks for more information.
495 Also, CGI::Ex::validate.js allows for inline errors in addition to or in replacement
496 of an alert message. To use inline errors, you must provide an element in your
497 HTML document where this inline message can be placed. The common way to do it is as
500 <input type="text" name="username"><br>
501 <span class="error" id="username_error">[% username_error %]</span>
503 The span around the error allows for the error css class and it provides a location
504 that the Javascript validation can populate with errors. The [% username_error %] provides
505 a location for errors generated on the server side to be swapped in. If there was no error
506 the [% username_error %] tag would default to "".
508 =head1 ADDING ADDITIONAL TEMPLATE VARIABLES
510 All variables returned by the hash_base, hash_common, hash_form, hash_swap, and
511 hash_errors hooks are available for swapping in templates.
513 The following shows how to add variables using the hash_swap hook on the step "main".
518 choices => [qw(one two three)],
519 "warn" => sub { warn @_ },
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
527 See the hash_base, hash_common, hash_form, hash_swap, hash_errors,
528 swap_template, and template_args hooks for more information.
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 L<Template::Alloy> documentation
535 for more information.
537 =head1 ADDING ADDITIONAL FORM FILL VARIABLES
539 All variables returned by the hash_base, hash_common, hash_form, and hash_fill hooks
540 are available for filling html fields in on templates.
542 The following shows how to add variables using the hash_fill hook on the step "main".
547 choices => [qw(one two three)],
551 You could also return the fields from the hash_common hook and they would be available
552 in both the form filling as well as in the template swapping.
554 See the hash_base, hash_common, hash_form, hash_swap, hash_errors, fill_template, and
555 fill_args hooks for more information.
557 The default form filler is CGI::Ex::Fill which is similar to HTML::FillInForm but
558 has several benefits. See the CGI::Ex::Fill module for the available options.
560 =head1 FINDING TEMPLATES AND VALIDATION FILES
562 CGI::Ex::App tries to help your applications use a good template directory layout, but allows
563 for you to override everything.
565 External template files are used for storing your html templates and
566 for storing your validation files (if you use externally stored
569 The default file_print hook will look for content on your file system,
570 but it can also be completely overridden to return a reference to a
571 scalar containing the contents of your file (beginning with version 2.14
572 string references can be cached which makes templates passed this way
573 "first class" citizens). Actually it can return
574 anything that Template::Alloy (Template::Toolkit compatible) will
575 treat as input. This templated html is displayed to the user during
576 any step that enters the "print" phase.
578 Similarly the default file_val hook will look for a validation file on
579 the file system, but it too can return a reference to a scalar
580 containing the contents of a validation file. It may actually return
581 anything that the CGI::Ex::Validate get_validation method is able to
582 understand. This validation is used by the default "info_complete"
583 method for verifying if the submitted information passes its specific
584 checks. A more common way of inlining validation is to return a
585 validation hash from a hash_validation hook override.
587 If the default file_print and file_val hooks are used, the following methods
588 are employed for finding templates and validation files on your filesystem (they
589 are also documented more in the HOOKS AND METHODS section.
595 Absolute path or arrayref of paths to the base templates directory. Defaults to
596 base_dir_abs which defaults to ['.'].
600 Relative path inside of the template_path directory where content can be found. Default "".
604 Directory inside of base_dir_rel where files for the current CGI (module) will be
605 stored. Default value is $ENV{SCRIPT_NAME} with path and extension removed.
609 Used with ext_print and ext_val for creating the filename that will be looked for
610 inside of the name_module directory. Default value is the current step.
612 =item ext_print and ext_val
614 Filename extensions added to name_step to create the filename looked for
615 inside of the name_module directory. Default is "html" for ext_print and "val"
620 It may be easier to understand the usage of each of these methods by showing
621 a contrived example. The following is a hypothetical layout for your templates:
623 /home/user/templates/
624 /home/user/templates/chunks/
625 /home/user/templates/wrappers/
626 /home/user/templates/content/
627 /home/user/templates/content/my_app/
628 /home/user/templates/content/my_app/main.html
629 /home/user/templates/content/my_app/step1.html
630 /home/user/templates/content/my_app/step1.val
631 /home/user/templates/content/another_cgi/main.html
633 In this example we would most likely set values as follows:
635 template_path /home/user/templates
639 The name_module method defaults to the name of the running program, but
640 with the path and extension removed. So if we were running
641 /cgi-bin/my_app.pl, /cgi-bin/my_app, or /anypath/my_app, then
642 name_module would default to "my_app" and we wouldn't have to
643 hard code the value. Often it is wise to set the value anyway so
644 that we can change the name of the cgi script without effecting
645 where template content should be stored.
647 Continuing with the example and assuming that name of the step that
648 the user has requested is "step1" then the following values would be
651 template_path /home/user/templates
658 file_print content/my_app/step1.html
659 file_val /home/user/templates/content/my_app/step1.val
661 The call to the template engine would look something like
664 my $t = $self->template_obj({
665 INCLUDE_PATH => $self->template_path, # defaults to base_dir_abs
668 $t->process($self->file_print($step), \%vars);
670 The template engine would then look for the relative file
671 inside of the absolute paths (from template_path).
673 The call to the validation engine would pass the absolute
674 filename that is returned by file_val.
676 The name_module and name_step methods can return filenames with
677 additional directories included. The previous example could
678 also have been setup using the following values:
680 template_path /home/user/templates
682 name_module content/my_app
684 In this case the same values would be returned for the file_print and file_val hooks
685 as were returned in the previous setup.
687 =head1 SYNOPSIS (A LONG "SYNOPSIS")
689 This example script would most likely be in the form of a cgi, accessible via
690 the path http://yourhost.com/cgi-bin/my_app (or however you do CGIs on
691 your system. About the best way to get started is to paste the following
692 code into a cgi script (such as cgi-bin/my_app) and try it out. A detailed
693 walk-through follows in the next section. There is also a longer recipe
694 database example at the end of this document that covers other topics including
695 making your module a mod_perl handler.
697 ### File: /var/www/cgi-bin/my_app (depending upon Apache configuration)
698 ### --------------------------------------------
702 use base qw(CGI::Ex::App);
703 use CGI::Ex::Dump qw(debug);
705 __PACKAGE__->navigate;
707 # my $obj = __PACKAGE__->new;
712 ###------------------------------------------###
716 debug shift->dump_history;
719 sub main_hash_validation {
721 'general no_alert' => 1,
722 'general no_confirm' => 1,
723 'group order' => [qw(username password password2)],
729 match_error => 'You may only use letters and numbers.',
736 equals => 'password',
741 sub main_file_print {
742 # reference to string means ref to content
743 # non-reference means filename
744 return \ "<h1>Main Step</h1>
745 <form method=post name=[% form_name %]>
746 <input type=hidden name=step>
749 <td><b>Username:</b></td>
750 <td><input type=text name=username><span style='color:red' id=username_error>[% username_error %]</span></td>
752 <td><b>Password:</b></td>
753 <td><input type=text name=password><span style='color:red' id=password_error>[% password_error %]</span></td>
755 <td><b>Verify Password:</b></td>
756 <td><input type=text name=password2><span style='color:red' id=password2_error>[% password2_error %]</span></td>
758 <tr><td colspan=2 align=right><input type=submit></td></tr>
768 if ($self->form->{'username'} eq 'bar') {
769 $self->add_errors(username => 'A trivial check to say the username cannot be "bar"');
773 debug $self->form, "Do something useful with form here in the finalize hook.";
776 $self->add_to_swap({success_msg => "We did something"});
777 $self->append_path('success');
778 $self->set_ready_validate(0);
782 sub success_file_print {
783 \ "<div style=background:lightblue>
784 <h1>Success Step - [% success_msg %]</h1>
785 Username: <b>[% username %]</b><br>
786 Password: <b>[% password %]</b><br>
793 Note: This example would be considerably shorter if the html file
794 (file_print) and the validation file (file_val) had been placed in
795 separate files. Though CGI::Ex::App will work "out of the box" as
796 shown it is more probable that any platform using it will customize
797 the various hooks to their own tastes (for example, switching print to
798 use a templating system other than Template::Alloy).
800 =head1 SYNOPSIS STEP BY STEP
802 This section goes step by step over the previous example.
804 Well - we start out with the customary CGI introduction.
809 use base qw(CGI::Ex::App);
810 use CGI::Ex::Dump qw(debug);
812 Note: the "use base" is not normally used in the "main" portion of a script.
813 It does allow us to just do __PACKAGE__->navigate.
815 Now we need to invoke the process:
817 __PACKAGE__->navigate;
819 # my $obj = __PACKAGE__->new;
823 Note: the "exit" isn't necessary - but it is kind of nice to infer
824 that process flow doesn't go beyond the ->navigate call.
826 The navigate routine is now going to try and "run" through a series of
827 steps. Navigate will call the ->path method which should return an
828 arrayref containing the valid steps. By default, if path method has
829 not been overridden, the path method will default first to the step
830 found in form key named ->step_name, then it will fall to the contents
831 of $ENV{'PATH_INFO'}. If navigation runs out of steps to run it will
832 run the step found in ->default_step which defaults to 'main'. So the
833 URI '/cgi-bin/my_app' would run the step 'main' first by default. The
834 URI '/cgi-bin/my_app?step=foo' would run the step 'foo' first. The
835 URI '/cgi-bin/my_app/bar' would run the step 'bar' first.
837 CGI::Ex::App allows for running steps in a preset path or each step may
838 choose the next step that should follow. The navigate
839 method will go through one step of the path at a time and see if it is
840 completed (various methods determine the definition of "completed").
841 This preset type of path can also be automated using the CGI::Path
842 module. Rather than using a preset path, CGI::Ex::App also has
843 methods that allow for dynamic changing of the path, so that each step
844 can determine which step to do next (see the goto_step, append_path,
845 insert_path, and replace_path methods).
847 During development it would be nice to see what happened during the
848 course of our navigation. This is stored in the arrayref contained in
849 ->history. There is a method that is called after all of the navigation
850 has taken place called "post_navigate". This chunk will display history after we
851 have printed the content.
854 debug shift->dump_history;
855 } # show what happened
857 Ok. Finally we are looking at the methods used by each step of the path. The
858 hook mechanism of CGI::Ex::App will look first for a method ${step}_${hook_name}
859 called before falling back to the method named $hook_name. Internally in the
860 code there is a call that looks like $self->run_hook('hash_validation', $step). In
861 this case the step is main. The dispatch mechanism finds our method at the following
864 sub main_hash_validation { ... }
866 The process flow will see if the data is ready to validate. Once it is ready
867 (usually when the user presses the submit button) the data will be validated. The
868 hash_validation hook is intended to describe the data and will be tested
869 using CGI::Ex::Validate. See the CGI::Ex::Validate perldoc for more
870 information about the many types of validation available.
872 sub main_file_print { ... }
874 The navigation process will see if user submitted information (the form)
875 is ready for validation. If not, or if validation fails, the step needs to
876 be printed. Eventually the file_print hook is called. This hook should
877 return either the filename of the template to be printed, or a reference
878 to the actual template content. In this example we return a reference
879 to the content to be printed (this is useful for prototyping applications
880 and is also fine in real world use - but generally production applications
881 use external html templates).
883 A few things to note about the template:
885 First, we add a hidden form field called step. This will be filled in
886 automatically at a later point with the current step we are on.
888 We provide locations to swap in inline errors.
890 <span style="color:red" id="username_error">[% username_error %]</span>
892 As part of the error html we name each span with the name of the error. This
893 will allow for us to have Javascript update the error spots when the javascript
896 At the very end we add the TT variable [% js_validation %]. This swap in is
897 provided by the default hash_base hook and will provide for form data to be
898 validated using javascript.
900 Once the process flow has deemed that the data is validated, it then calls
901 the finalize hook. Finalize is where the bulk of operations should go.
902 We'll look at it more in depth.
906 my $form = $self->form;
908 At this point, all of the validated data is in the $form hashref.
910 if ($form->{'username'} eq 'bar') {
911 $self->add_errors(username => 'A trivial check to say the username cannot be "bar"');
915 It is most likely that though the data is of the correct type and formatting,
916 it still isn't completely correct. This previous section shows a hard coded
917 test to see if the username was 'bar'. If it was then an appropriate error will
918 be set, the routine returns 0 and the run_step process knows that it needs to
919 redisplay the form page for this step. The username_error will be shown inline.
920 The program could do more complex things such as checking to see if the username
921 was already taken in a database.
923 debug $form, "Do something useful with form here in the finalize hook.";
925 This debug $form piece is simply a place holder. It is here that the program would
926 do something useful such as add the information to a database.
929 $self->add_to_swap({success_msg => "We did something"});
931 Now that we have finished finalize, we add a message that will be passed to the template
934 $self->append_path('success');
935 $self->set_ready_validate(0);
937 The program now needs to move on to the next step. In this case we want to
938 follow with a page that informs us we succeeded. So, we append a step named "success".
939 We also call set_ready_validate(0) to inform the navigation control that the
940 form is no longer ready to validate - which will cause the success page to
941 print without trying to validate the data. It is normally a good idea
942 to set this as leaving the engine in a "ready to validate" state can result
943 in an recursive loop (that will be caught).
948 We then return 1 which tells the engine that we completed this step successfully
949 and it needs to move on to the next step.
951 Finally we run the "success" step because we told it to. That step isn't
952 ready to validate so it prints out the template page.
954 For more of a real world example, it would be good to read the sample recipe db
955 application included at the end of this document.
957 =head1 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
961 is called, CGI::Ex::App will look for a corresponding method call for
962 that hook for the current step name. It is perhaps easier to show than
965 If we are calling the "print" hook for the step "edit" we would call
968 $self->run_hook('print', 'edit', $template, \%swap, \%fill);
970 This would first look for a method named "edit_print". If it is unable to
971 find a method by that name, it will look for a method named "print". If it
972 is unable to find this method - it will die.
974 If allow_morph is set to true, the same methods are searched for but it becomes
975 possible to move some of those methods into an external package.
977 See the discussions under the methods named "find_hook" and "run_hook" for more details.
979 The following is the alphabetical list of methods and hooks.
983 =item allow_morph (hook)
985 Should return true if this step is allowed to "morph" the current App
986 object into another package. Default is false. It is passed a single
987 argument of the current step. For more granularity, if true value is
988 a hash, the step being morphed to must be in the hash.
990 If the returned value is "1", and the module doesn't exist, then the
991 App will continue to run blessed into the current package. If there
992 is an error requiring the module or if the module doesn't exist and
993 the return value is "2" (true but not 1), then App will die with the
996 To enable morphing for all steps, add the following:
997 (Packages that don't exists won't be morphed to)
999 sub allow_morph { 1 }
1001 To force morphing for all steps add the following:
1003 sub allow_morph { 2 }
1005 To enable morph on specific steps, do either of the following:
1010 delete => 2, # must morph
1017 my ($self, $step) = @_;
1018 return 1 if $step eq 'edit';
1019 return 2 if $step eq 'delete';
1023 See the morph "hook" for more information.
1025 =item append_path (method)
1027 Arguments are the steps to append. Can be called any time. Adds more
1028 steps to the end of the current path.
1030 =item auth_args (method)
1032 Should return a hashref that will be passed to the auth_obj method
1033 which should return a CGI::Ex::Auth compatible object.
1034 It is augmented with arguments that integrate it into CGI::Ex::App.
1036 See the get_valid_auth method and the CGI::Ex::Auth documentation.
1040 login_header => '<h1>My login header</h1>',
1041 login_footer => '[% TRY %][% INCLUDE login/login_footer.htm %][% CATCH %]<!-- [% error %] -->[% END %]',
1042 secure_hash_keys => [qw(aaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbb ccccccccccccccccccccccc 2222222222222)],
1043 # use_blowfish => 'my_blowfish_key',
1047 =item auth_data (method)
1049 Contains authentication data stored during the get_valid_auth method.
1050 The data is normally blessed into the CGI::Ex::Auth::Data package which
1051 evaluates to false if there was an error and true if the authentication
1052 was successful - so this data can be defined but false.
1054 See the get_valid_auth method.
1056 =item auth_obj (method)
1058 Passed auth_args. Should return a CGI::Ex::Auth compatible object. Default
1059 is to call CGI::Ex::Auth->new with the passed args.
1061 =item base_dir_abs (method)
1063 Used as the absolute base directory to find template, validation and conf files.
1064 It may return a single value or an arrayref of values, or a coderef that
1065 returns an arrayref or coderef of values. You may pass base_dir_abs
1066 as a parameter in the arguments passed to the "new" method.
1068 Default value is ['.'].
1070 For example, to pass multiple paths, you would use something
1071 similar to the following:
1074 return ['/my/path/one', '/some/other/path'];
1077 The base_dir_abs value is used by template_path along with the
1078 base_dir_rel, name_module, name_step, ext_print and ext_values for
1079 determining the values returned by the default file_print and file_val
1080 hooks. See those methods for further discussion.
1082 See the section on FINDING TEMPLATES for further discussion.
1084 The base_dir_abs method is also used as the default value for conf_path and vob_path.
1086 =item base_dir_rel (method)
1088 Added as a relative base directory to content under the base_dir_abs directory.
1090 Default value is "".
1092 The template_path method is used as top level where template includes may
1093 pull from, while the base_dir_rel is directory relative to the template_path
1094 where the content files will be stored.
1096 A value for base_dir_rel may passed as a parameter in the arguments passed
1099 See the template_path and base_dir_abs methods for more discussion.
1101 See the section on FINDING TEMPLATES for further discussion.
1103 =item cleanup_user (method)
1105 Used as a hook during get_valid_auth. Allows for cleaning
1106 up the username. See the get_valid_auth method.
1109 my ($self, $user) = @_;
1113 =item clear_app (method)
1115 If the same CGI::Ex::App based object is used to run multiple
1116 navigate sessions, the clear_app method should be called which
1117 will attempt to clear as much session information as it can.
1118 The following items will be cleared:
1128 _morph_lineage_start_index
1137 Used by default in init_from_conf if load_conf returns true.
1138 Will try to read the file returned by the conf_file method
1139 using the object returned by conf_obj using that object's read
1140 method. If conf_validation returns a non-empty hashref, the
1141 conf hash will be validated using $self->vob->validate (see the
1144 This method may be used for other purposes as well (including when
1145 load_conf is false)..
1147 Caches results in $self->{'conf'}.
1149 If the conf_file can't be found, the method will die unless
1150 conf_die_on_fail returns 0 (defaults to true).
1156 Defaults to $self->{'conf_args'} which defaults to {}. Will have
1157 paths => $self->conf_path added before passing to CGI::Ex::Conf->new.
1159 =item conf_file (method)
1161 Used by conf for finding the configuration file to load. Defaults
1162 to $self->{'conf_file'} which defaults $self->name_module with the extention
1163 returned by $self->ext_conf added on. For example, if name_module
1164 returns "my_app" and ext_conf returns "ini" the value returned will
1167 The value returned can absolute. If the value will be searched for
1168 in the paths passed to conf_obj.
1170 The ext_conf may be any of those extentions understood by CGI::Ex::Conf.
1174 Used by the conf method to load the file returned by conf_file. Defaults
1175 to conf_obj which defaults to loading args from conf_args, adding in paths
1176 returned by conf_path, and calling CGI::Ex::Conf->new.
1178 Any object that provides a read method that returns a hashref can be used.
1182 Defaults to $self->{'conf_path'} which defaults to base_dir_abs. Should be
1183 a path or an arrayref of paths to look the configuration file returned by
1184 conf_file when that file is not absolute.
1186 =item conf_validation
1188 Used by default conf method.
1189 Defaults to an empty hashref. If non-empty hashref is passed, the
1190 hashref returned by conf_obj->read will be validated using the hashref
1191 returned by conf_validation.
1193 =item current_step (method)
1195 Returns the current step that the nav_loop is functioning on.
1197 =item default_step (method)
1199 Step to show if the path runs out of steps. Default value is the
1200 'default_step' property which defaults to 'main'.
1202 If nav_loop runs of the end of the path (runs out of steps), this
1203 method is called, the step is added to the path, and nav_loop calls
1206 =item destroy (method)
1208 Called at the end of navigate after all other actions have run. Can
1209 be used for undoing things done in the ->init method called during
1212 =item dump_history (method)
1214 Show simplified trace information of which steps were called, the
1215 order they were called in, the time they took to run, and a brief list
1216 of the output (to see the full response returned by each hook, pass a
1217 true value as the only argument to dump_history -
1218 $self->dump_history(1)). Indentation is also applied to show which
1219 hooks called other hooks.
1222 The first line shows the amount of time elapsed for the entire
1223 navigate execution. Subsequent lines contain:
1225 Step - the name of the current step.
1226 Hook - the name of the hook being called.
1227 Found - the name of the method that was found.
1228 Time - the total elapsed seconds that method took to run.
1229 Output - the response of the hook - shown in shortened form.
1231 Note - to get full output responses - pass a true value to
1232 dump_history - or just call ->history. Times displayed are to 5
1233 decimal places - this accuracy can only be provided if the Time::HiRes
1234 module is installed on your system (it will only be used if installed).
1236 It is usually best to print this history during the post_navigate
1237 method as in the following:
1239 use CGI::Ex::Dump qw(debug);
1240 sub post_navigate { debug shift->dump_history }
1242 The following is a sample output of dump_history called from the
1243 sample recipe application at the end of this document. The step
1246 debug: admin/Recipe.pm line 14
1247 shift->dump_history = [
1249 "view - require_auth - require_auth - 0.00001 - 0",
1250 "view - run_step - run_step - 0.00488 - 1",
1251 " view - pre_step - pre_step - 0.00003 - 0",
1252 " view - skip - view_skip - 0.00004 - 0",
1253 " view - prepare - prepare - 0.00003 - 1",
1254 " view - info_complete - info_complete - 0.00010 - 0",
1255 " view - ready_validate - ready_validate - 0.00004 - 0",
1256 " view - prepared_print - prepared_print - 0.00441 - 1",
1257 " view - hash_base - hash_base - 0.00009 - HASH(0x84ea6ac)",
1258 " view - hash_common - view_hash_common - 0.00148 - HASH(0x8310a20)",
1259 " view - hash_form - hash_form - 0.00004 - HASH(0x84eaa78)",
1260 " view - hash_fill - hash_fill - 0.00003 - {}",
1261 " view - hash_swap - hash_swap - 0.00003 - {}",
1262 " view - hash_errors - hash_errors - 0.00003 - {}",
1263 " view - print - print - 0.00236 - 1",
1264 " view - file_print - file_print - 0.00024 - recipe/view.html",
1265 " view - name_module - name_module - 0.00007 - recipe",
1266 " view - name_step - name_step - 0.00004 - view",
1267 " view - swap_template - swap_template - 0.00161 - <html> ...",
1268 " view - template_args - template_args - 0.00008 - HASH(0x865abf8)",
1269 " view - fill_template - fill_template - 0.00018 - 1",
1270 " view - fill_args - fill_args - 0.00003 - {}",
1271 " view - print_out - print_out - 0.00015 - 1",
1272 " view - post_print - post_print - 0.00003 - 0"
1275 =item error_step (method)
1277 Defaults to "__error". The name of a step to run should a dying error
1278 be caught by the default handle_error method. See the handle_error method.
1280 =item exit_nav_loop (method)
1282 This method should not normally used but there is no problem with
1283 using it on a regular basis. Essentially it is a "goto" that allows
1284 for a long jump to the end of all nav_loops (even if they are
1285 recursively nested). This effectively short circuits all remaining
1286 hooks for the current and remaining steps. It is used to allow the
1287 ->goto_step functionality. If the application has morphed, it will be
1288 unmorphed before returning. Also - the post_navigate method will
1293 Used by the default conf_file method. Defaults to $self->{'ext_conf'} which
1294 defaults to 'pl' meaning that the read configuration file should return a
1297 =item ext_print (method)
1299 Added as suffix to "name_step" during the default file_print hook.
1301 Default value is 'html'.
1303 For example, if name_step returns "foo" and ext_print returns "html"
1304 then the file "foo.html" will be searched for.
1306 See the section on FINDING TEMPLATES for further discussion.
1308 =item ext_val (method)
1310 Added as suffix to "name_step" during the default file_val hook.
1312 Default value is 'val'.
1314 For example, if name_step returns "foo" and ext_val returns "val"
1315 then the file "foo.val" will be searched for.
1317 See the section on FINDING TEMPLATES for further discussion.
1319 =item fill_args (hook)
1321 Returns a hashref of args that will be passed to the CGI::Ex::Fill::fill.
1322 It is augmented with the template to swap and the fill hash. This
1323 could be useful if you needed to only swap a particular form on the template
1324 page. Arguments are passed directly to the fill function.
1326 sub fill_args { {target => 'my_form'} }
1328 =item fill_template (hook)
1330 Arguments are a template and a hashref. Takes the template that was
1331 prepared using swap_template, and swaps html form fields using the
1332 passed hashref. Overriding this method can control the fill behavior.
1334 Calls the fill_args hook prior to calling CGI::Ex::Fill::fill
1336 =item file_print (hook)
1338 Returns a filename of the content to be used in the default print
1339 hook. Adds method base_dir_rel to hook name_module, and name_step and
1340 adds on the default file extension found in $self->ext_print which
1341 defaults to the property $self->{ext_print} which will default to
1342 ".html". Should return a filename relative to template_path that can be
1343 swapped using Template::Alloy, or should be a scalar reference to
1344 the template content that can be swapped. This will be used by the
1347 sub template_path { '/var/www/templates' }
1348 sub base_dir_rel { 'content' }
1349 sub name_module { 'recipe' }
1350 sub ext_print { 'html' } # default
1352 # ->file_print('this_step')
1353 # would return 'content/recipe/this_step.html'
1354 # the template engine would look in '/var/www/templates'
1355 # for a file by that name
1357 It may also return a reference to a string containing the html template.
1358 This is useful for prototyping applications and/or keeping all of
1359 the data for the application in a single location.
1361 =item 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). If
1368 vob_path returns an arrayref of paths, then each path is checked for
1369 the existence of the file.
1371 The file should be readable by CGI::Ex::Validate::get_validation.
1373 This hook is only necessary if the hash_validation hook has not been
1376 This method an also return a hashref containing the validation - but
1377 then you may have wanted to override the hash_validation hook.
1379 =item finalize (hook)
1381 Defaults to true. Used to do whatever needs to be done with the data once
1382 prepare has returned true and info_complete has returned true. On failure
1383 the print operations are ran. On success navigation moves on to the next
1386 This is normally were there core logic of a script will occur (such as
1387 adding to a database, or updating a record). At this point, the data
1388 should be validated. It is possible to do additional validation
1389 and return errors using code such as the following.
1391 if (! $user_is_unique) {
1392 $self->add_errors(username => 'The username was already used');
1396 =item find_hook (method)
1398 Called by run_hook. Arguments are a hook name, a step name. It
1399 should return an arrayref containing the code_ref to run, and the
1400 name of the method looked for. It uses ->can to find the appropriate
1403 my $code = $self->hook('finalize', 'main');
1404 ### will look first for $self->main_finalize;
1405 ### will then look for $self->finalize;
1407 This system is used to allow for multiple steps to be in the same
1408 file and still allow for moving some steps out to external sub classed
1409 packages (if desired).
1411 If the application has successfully morphed via the morph method and
1412 allow_morph then it is not necessary to add the step name to the
1413 beginning of the method name as the morphed packages method will
1414 override the base package (it is still OK to use the full method name
1415 "${step}_hookname").
1417 See the run_hook method and the morph method for more details.
1419 =item first_step (method)
1421 Returns the first step of the path. Note that first_step may not be the same
1422 thing as default_step if the path was overridden.
1424 =item forbidden_step (method)
1426 Defaults to "__forbidden". The name of a step to run should the current
1427 step name be invalid, or if a step found by the default path method
1428 is invalid. See the path method.
1432 Returns a hashref of the items passed to the CGI. Returns
1433 $self->{form} which defaults to CGI::Ex::get_form.
1435 =item form_name (hook)
1437 Return the name of the form to attach the js validation to. Used by
1440 =item get_pass_by_user (method)
1442 This method is passed a username and the authentication object. It
1443 should return the password for the given user. See the get_pass_by_user
1444 method of CGI::Ex::Auth for more information. Installed as a hook
1445 to the authentication object during the get_valid_auth method.
1447 =item get_valid_auth (method)
1449 If require_auth hook returns true on any given step then get_valid_auth will be called.
1451 It will call auth_args to get some default args to pass to
1452 CGI::Ex::Auth->new. It augments the args with sensible defaults that
1453 App already provides (such as form, cookies, and template facilities).
1454 It also installs hooks for the get_pass_by_user, cleanup_user, and verify_user
1455 hooks of CGI::Ex::Auth.
1457 It stores the $auth->last_auth_data in $self->auth_data for later use. For
1458 example, to get the authenticated user:
1460 sub require_auth { 1 }
1463 my ($self, $user) = @_;
1467 sub get_pass_by_user {
1468 my ($self, $user) = @_;
1469 my $pass = $self->some_method_to_get_the_pass($user);
1475 login_header => '<h1>My login header</h1>',
1476 login_footer => '[% TRY %][% INCLUDE login/login_footer.htm %][% CATCH %]<!-- [% error %] -->[% END %]',
1480 sub main_hash_swap {
1482 my $user = $self->auth_data->{'user'};
1483 return {user => $user};
1486 Successful authentication is cached for the duration of the
1487 nav_loop so multiple steps will run the full authentication routine
1490 Full customization of the login process and the login template can
1491 be done via the auth_args hash. See the auth_args method and
1492 CGI::Ex::Auth perldoc for more information.
1494 =item goto_step (method)
1496 This method is not normally used but can solve some difficult issues.
1497 It provides for moving to another step at any point during the
1498 nav_loop. Once a goto_step has been called, the entire nav_loop will
1499 be exited (to simply replace a portion of a step, you can simply
1500 run_hook('run_step', 'other_step')). The method goto_step effectively
1501 short circuits the remaining hooks for the current step. It does
1502 increment the recursion counter (which has a limit of ->recurse_limit
1503 - default 15). Normally you would allow the other hooks in the loop
1504 to carry on their normal functions and avoid goto_step. (Essentially,
1505 this hook behaves like a goto method to bypass everything else and
1506 continue at a different location in the path - there are times when it
1507 is necessary or useful to do this).
1509 The method jump is an alias for this method.
1511 Goto_step takes a single argument which is the location in the path to
1512 jump to. This argument may be either a step name, the special strings
1513 "FIRST, LAST, CURRENT, PREVIOUS, OR NEXT" or the number of steps to
1514 jump forward (or backward) in the path. The default value, 1,
1515 indicates that CGI::Ex::App should jump to the next step (the default
1516 action for goto_step). A value of 0 would repeat the current step
1517 (watch out for recursion). A value of -1 would jump to the previous
1518 step. The special value of "LAST" will jump to the last step. The
1519 special value of "FIRST" will jump back to the first step. In each of
1520 these cases, the path array returned by ->path is modified to allow
1521 for the jumping (the path is modified so that the path history is not
1522 destroyed - if we were on step 3 and jumped to one, that path would
1523 contain 1, 2, 3, *1, 2, 3, 4, etc and we would be at the *). If a
1524 step name is not currently on the path, it will be replace any remaining
1527 # goto previous step (repeat it)
1528 $self->goto_step($self->previous_step);
1529 $self->goto_step('PREVIOUS');
1530 $self->goto_step(-1);
1533 $self->goto_step($self->next_step);
1534 $self->goto_step('NEXT');
1535 $self->goto_step(1);
1538 # goto current step (repeat)
1539 $self->goto_step($self->current_step);
1540 $self->goto_step('CURRENT');
1541 $self->goto_step(0);
1544 $self->goto_step($self->last_step);
1545 $self->goto_step('LAST');
1547 # goto first step (repeat it)
1548 $self->goto_step($self->first_step);
1549 $self->goto_step('FIRST');
1551 =item handle_error (method)
1553 If anything dies during execution, handle_error will be called with
1554 the error that had happened. Default action is to try running the
1555 step returned by the error_step method.
1557 =item hash_base (hook)
1559 A hash of base items to be merged with hash_form - such as pulldown
1560 menus, javascript validation, etc. It will now also be merged with
1561 hash_fill, so it can contain default fillins as well. It can be
1562 populated by passing a hash to ->add_to_base. By default a sub
1563 similar to the following is what is used for hash_common. Note the
1564 use of values that are code refs - so that the js_validation and
1565 form_name hooks are only called if requested:
1568 my ($self, $step) = @_;
1569 return $self->{hash_base} ||= {
1570 script_name => $ENV{SCRIPT_NAME},
1571 js_validation => sub { $self->run_hook('js_validation', $step) },
1572 form_name => sub { $self->run_hook('form_name', $step) },
1576 =item hash_common (hook)
1578 Almost identical in function and purpose to hash_base. It is
1579 intended that hash_base be used for common items used in various
1580 scripts inheriting from a common CGI::Ex::App type parent. Hash_common
1581 is more intended for step level populating of both swap and fill.
1583 =item hash_errors (hook)
1585 Called in preparation for print after failed prepare, info_complete,
1586 or finalize. Should contain a hash of any errors that occurred. Will
1587 be merged into hash_form before the pass to print. Each error that
1588 occurred will be passed to method format_error before being added to
1589 the hash. If an error has occurred, the default validate will
1590 automatically add {has_errors =>1}. To the error hash at the time of
1591 validation. has_errors will also be added during the merge in case the
1592 default validate was not used. Can be populated by passing a hash to
1593 ->add_to_errors or ->add_errors.
1595 =item hash_fill (hook)
1597 Called in preparation for print after failed prepare, info_complete,
1598 or finalize. Should contain a hash of any items needed to be filled
1599 into the html form during print. Items from hash_form, hash_base, and
1600 hash_common will be layered together. Can be populated by passing a
1601 hash to ->add_to_fill.
1603 By default - forms are sticky and data from previous requests will try
1604 and populate the form. You can use the fill_template hook to disable
1605 templating on a single page or on all pages.
1607 This method can be used to pre-populate the form as well (such as on an
1608 edit step). If a form fails validation, hash_fill will also be called
1609 and will only want the submitted form fields to be sticky. You can
1610 use the ready_validate hook to prevent pre-population in these cases as
1613 sub edit_hash_fill {
1616 return {} if $self->run_hook('ready_validate', $step);
1620 ### get previous values from the database
1625 =item hash_form (hook)
1627 Called in preparation for print after failed prepare, info_complete,
1628 or finalize. Defaults to ->form. Can be populated by passing a hash
1631 =item hash_swap (hook)
1633 Called in preparation for print after failed prepare, info_complete,
1634 or finalize. Should contain a hash of any items needed to be swapped
1635 into the html during print. Will be merged with hash_base,
1636 hash_common, hash_form, and hash_errors. Can be populated by passing
1637 a hash to ->add_to_swap.
1639 The hash will be passed as the second argument to swap_template.
1641 =item hash_validation (hook)
1643 Returns a hash of the validation information to check form against.
1644 By default, will look for a filename using the hook file_val and will
1645 pass it to CGI::Ex::Validate::get_validation. If no file_val is
1646 returned or if the get_validation fails, an empty hash will be returned.
1647 Validation is implemented by ->vob which loads a CGI::Ex::Validate object.
1649 =item history (method)
1651 Returns an arrayref which contains trace history of which hooks of
1652 which steps were ran. Useful for seeing what happened. In general -
1653 each line of the history will show the current step, the hook
1654 requested, and which hook was actually called.
1656 The dump_history method shows a short condensed version of this
1657 history which makes it easier to see what path was followed.
1659 In general, the arrayref is free for anything to push onto which will
1660 help in tracking other occurrences in the program as well.
1662 =item info_complete (hook)
1664 Calls the ready_validate hook to see if data is ready to validate. If
1665 so it calls the validate hook to validate the data. Should make
1666 sure the data is ready and valid. Will not be run unless
1667 prepare returns true (default).
1671 Called by the default new method. Allows for any object
1672 initilizations that may need to take place. Default action does
1675 =item init_from_conf (method)
1677 Called by the default new method. If load_conf is true, then the
1678 conf method will be called and the keys returned will be added to
1681 This method is called after the init method. If you need to further
1682 fix up values added during init_from_conf, you can use the pre_navigate
1685 =item insert_path (method)
1687 Arguments are the steps to insert. Can be called any time. Inserts
1688 the new steps at the current path location.
1690 =item is_authed (method)
1692 Returns true if the object has successful authentication data. It
1693 returns false if the object has not been authenticated.
1695 =item js_uri_path (method)
1697 Return the URI path where the CGI/Ex/yaml_load.js and
1698 CGI/Ex/validate.js files can be found. This will default to
1699 "$ENV{SCRIPT_NAME}/js" if the path method has not been overridden,
1700 otherwise it will default to "$ENV{SCRIPT_NAME}?step=js&js=" (the
1701 latter is more friendly with overridden paths). A default handler for
1702 the "js" step has been provided in "js_run_step" (this handler will
1703 nicely print out the javascript found in the js files which are
1704 included with this distribution. js_run_step will work properly with the
1705 default "path" handler.
1707 =item js_validation (hook)
1709 Will return Javascript that is capable of validating the form. This
1710 is done using the capabilities of CGI::Ex::Validate and
1711 CGI::Ex::JSONDump. This will call the hook hash_validation which will
1712 then be encoded into json and placed in a javascript string. It will
1713 also call the hook form_name to determine which html form to attach
1714 the validation to. The method js_uri_path is called to determine the
1715 path to the appropriate validate.js files. In order to make use of
1716 js_validation, it must be added to the variables returned by either
1717 the hash_base (default), hash_common, hash_swap or hash_form hook (see
1718 examples of hash_base used in this doc).
1722 Alias for the goto_step method.
1724 =item last_step (method)
1726 Returns the last step of the path.
1728 =item load_conf (method)
1730 Defaults to ->{load_conf} which defaults to false. If true, will
1731 allow keys returned by the conf method to be added to $self during
1732 the init_from_conf method.
1734 Enabling this method allows for out-of-the-box file based configuration.
1736 =item morph (method)
1738 Allows for temporarily "becoming" another object type for the
1739 execution of the current step. This allows for separating some steps
1740 out into their own packages.
1742 Morph will only run if the method allow_morph returns true.
1743 Additionally if the allow_morph returns a hash ref, morph will only
1744 run if the step being morphed to is in the hash. Morph also passes
1745 the step name to allow_morph.
1747 The morph call occurs at the beginning of the step loop. A
1748 corresponding unmorph call occurs before the loop is exited. An
1749 object can morph several levels deep. For example, an object running
1750 as Foo::Bar that is looping on the step "my_step" that has allow_morph
1751 = 1, will do the following:
1753 Call the morph_package hook (which would default to returning
1754 Foo::Bar::MyStep in this case)
1756 Translate this to a package filename (Foo/Bar/MyStep.pm) and try
1757 and require it, if the file can be required, the object is blessed
1760 Call the fixup_after_morph method.
1762 Continue on with the run_step for the current step.
1764 At any exit point of the loop, the unmorph call is made which
1765 re-blesses the object into the original package.
1767 Samples of allowing morph:
1769 sub allow_morph { 1 } # value of 1 means try to find package, ok if not found
1771 sub allow_morph { {edit => 1} }
1773 sub allow_morph { my ($self, $step) = @_; return $step eq 'edit' }
1775 =item morph_package (hook)
1777 Used by morph. Return the package name to morph into during a morph
1778 call. Defaults to using the current object type as a base. For
1779 example, if the current object running is a Foo::Bar object and the
1780 step running is my_step, then morph_package will return
1783 Because of the way that run_hook works, it is possible that several
1784 steps could be located in the same external file and overriding morph_package
1785 could allow for this to happen.
1787 See the morph method.
1789 =item name_module (hook)
1791 Return the name (relative path) that should be pre-pended to name_step
1792 during the default file_print and file_val lookups. Defaults to
1793 the value in $self->{name_module} which in turn defaults to the name
1794 of the current script.
1796 cgi-bin/my_app.pl => my_app
1797 cgi/my_app => my_app
1799 This method is provided so that each cgi or mod_perl application can
1800 have its own directory for storing html for its steps.
1802 See the file_print method for more information.
1804 See the section on FINDING TEMPLATES for further discussion.
1806 =item name_step (hook)
1808 Return the step (appended to name_module) that should used when
1809 looking up the file in file_print and file_val lookups. Defaults to
1812 See the section on FINDING TEMPLATES for further discussion.
1814 =item nav_loop (method)
1816 This is the main loop runner. It figures out the current path
1817 and runs all of the appropriate hooks for each step of the path. If
1818 nav_loop runs out of steps to run (which happens if no path is set, or if
1819 all other steps run successfully), it will insert the ->default_step into
1820 the path and run nav_loop again (recursively). This way a step is always
1821 assured to run. There is a method ->recurse_limit (default 15) that
1822 will catch logic errors (such as inadvertently running the same
1823 step over and over and over because there is either no hash_validation,
1824 or the data is valid but the set_ready_validate(0) method was not called).
1826 =item navigate (method)
1828 Takes a class name or a CGI::Ex::App object as arguments. If a class
1829 name is given it will call the "new" method to instantiate an object
1830 by that class (passing any extra arguments to the new method). All
1831 returns from navigate will return the object.
1833 The method navigate is essentially a safe wrapper around the ->nav_loop
1834 method. It will catch any dies and pass them to ->handle_error.
1836 This starts the process flow for the path and its steps.
1838 =item navigate_authenticated (method)
1840 Same as the method navigate but calls ->require_auth(1) before
1841 running. It will only work if the navigate_authenticated method
1842 has not been overwritten. See the require_auth method.
1844 =item new (class method)
1846 Object creator. Takes a hashref of arguments that will become the
1847 initial properties of the object. Calls the init method once the
1848 object has been blessed to allow for any other initilizations.
1850 my $app = MyApp->new({name_module => 'my_app'});
1852 =item next_step (hook and method)
1854 As a method it returns the next step in the path - if the path
1855 has more steps left.
1857 It is also used as a hook by the refine_path hook. If there is no
1858 more steps, it will call the next_step hook to try and find a step to
1863 Return an arrayref (modifiable) of the steps in the path. For each
1864 step the run_step hook and all of its remaining hooks will be run.
1866 Hook methods are looked up and ran using the method "run_hook" which
1867 uses the method "find_hook" to lookup the hook. A history of ran
1868 hooks is stored in the array ref returned by $self->history.
1870 If path has not been defined, the method will look first in the form
1871 for a key by the name found in ->step_key. It will then look in
1872 $ENV{'PATH_INFO'}. It will use this step to create a path with that
1873 one step as its contents. If a step is passed in via either of these
1874 ways, the method will call valid_steps to make sure that the step
1875 is valid (by default valid_steps returns undef - which means that
1876 any step is valid). Any step beginning with _ can not be passed in
1877 and are intended for use on private paths. If a non-valid step is
1878 found, then path will be set to contain a single step of ->forbidden_step.
1880 For the best functionality, the arrayref returned should be the same
1881 reference returned for every call to path - this ensures that other
1882 methods can add to the path (and will most likely break if the
1883 arrayref is not the same).
1885 If navigation runs out of steps to run, the default step found in
1886 default_step will be run. This is what allows for us to default
1887 to the "main" step for many applications.
1889 =item path_info_map (hook)
1891 Used to map path_info parts to form variables. Similar to the
1892 path_info_map_base method. See the path_info_map_base method
1893 for a discussion of how to use this hook.
1895 =item path_info_map_base (method)
1897 Called during the default path method. It is used to custom map portions
1898 of $ENV{'PATH_INFO'} to form values. If should return an arrayref of
1899 arrayrefs where each child arrayref contains a regex qr with match parens
1900 as the first element of the array. Subsequent elements of the array are
1901 the key names to store the corresponding matched value from the regex under.
1902 The outer arrayref is iterated until it one of child arrayrefs matches
1903 against $ENV{'PATH_INFO'}. The matched values are only added to the form if
1904 there is not already a defined value for that key in the form.
1906 The default value returned by this method looks something like the following:
1908 sub path_info_map_base {
1909 return [[qr{^/(\w+)}, $self->step_key]];
1912 This example would map the following PATH_INFO string as follows:
1916 # $self->form->{'step'} now equals "my_step"
1918 The following is another example:
1920 sub path_info_map_base {
1922 [qr{^/([^/]+)/(\w+)}, 'username', $self->step_key],
1923 [qr{^/(\w+)}, $self->step_key],
1927 # the PATH_INFO /my_step
1929 # $self->form->{'step'} now equals "my_step"
1931 # but with the PATH_INFO /my_user/my_step
1932 # $self->form->{'step'} now equals "my_step"
1933 # and $self->form->{'username'} equals "my_user"
1935 In most cases there is not a need to override the path_info_map_base
1936 method, but rather override the path_info_map hook for a particular step.
1937 When the step is being run, just before the run_step hook is called, the
1938 path_info_map hook is called. The path_info_map hook is similar to
1939 the path_info_map_base method, but is used to allow step level manipulation
1940 of form based on elements in the $ENV{'PATH_INFO'}.
1942 sub my_step_path_info_map {
1943 return [[qr{^/my_step/(\w+)$}, 'username']];
1946 # the PATH_INFO /my_step/my_user
1948 # $self->form->{'step'} equal to "my_step" because of default path_info_map_base
1949 # and $self->form->{'username'} equals "my_user" because of my_step_path_info_map
1951 The section on mapping URIs to steps has additional examples.
1953 =item post_loop (method)
1955 Ran after all of the steps in the loop have been processed (if
1956 prepare, info_complete, and finalize were true for each of the steps).
1957 If it returns a true value the navigation loop will be aborted. If it
1958 does not return true, navigation continues by then inserting the step
1959 $self->default_step and running $self->nav_loop again (recurses) to
1960 fall back to the default step.
1962 =item post_navigate (method)
1964 Called from within navigate. Called after the nav_loop has finished
1965 running but within the eval block to catch errors. Will only run if
1966 there were no errors which died during the nav_loop process.
1968 It can be disabled from running by setting the _no_post_navigate
1971 If per-step authentication is enabled and authentication fails,
1972 the post_navigate method will still be called (the post_navigate
1973 method can check the ->is_authed method to change behavior). If
1974 application level authentication is enabled and authentication
1975 fails, none of the pre_navigate, nav_loop, or post_navigate methods
1978 =item post_print (hook)
1980 A hook which occurs after the printing has taken place. Is only run
1981 if the information was not complete. Useful for cases such as
1982 printing rows of a database query after displaying a query form.
1984 =item post_step (hook)
1986 Ran at the end of the step's loop if prepare, info_complete, and
1987 finalize all returned true. Allows for cleanup. If a true value is
1988 returned, execution of navigate is returned and no more steps are
1991 =item pre_loop (method)
1993 Called right before the navigation loop is started (at the beginning
1994 of nav_loop). At this point the path is set (but could be modified).
1995 The only argument is a reference to the path array. If it returns a
1996 true value - the navigation routine is aborted.
1998 =item pre_navigate (method)
2000 Called at the very beginning of the navigate method, but within the
2001 eval block to catch errors. Called before the nav_loop method is
2002 started. If a true value is returned then navigation is skipped (the
2003 nav_loop is never started).
2005 =item pre_step (hook)
2007 Ran at the beginning of the loop before prepare, info_compelete, and
2008 finalize are called. If it returns true, execution of nav_loop is
2009 returned and no more steps are processed..
2011 =item prepare (hook)
2013 Defaults to true. A hook before checking if the info_complete is true.
2014 Intended to be used to cleanup the form data.
2016 =item prepared_print (hook)
2018 Called when any of prepare, info_complete, or finalize fail. Prepares
2019 a form hash and a fill hash to pass to print. The form hash is primarily
2020 intended for use by the templating system. The fill hash is intended
2021 to be used to fill in any html forms.
2023 =item previous_step (method)
2025 List the step previous to this one. Will return '' if there is no previous step.
2029 Take the information generated by prepared_print, format it using
2030 swap_template, fill it using fill_template and print it out using
2031 print_out. Default incarnation uses Template::Alloy which is
2032 compatible with Template::Toolkit to do the swapping. Arguments are:
2033 step name (used to call the file_print hook), swap hashref (passed to
2034 call swap_template), and fill hashref (passed to fill_template).
2036 During the print call, the file_print hook is called which should
2037 return a filename or a scalar reference to the template content is
2039 =item print_out (hook)
2041 Called with the finished document. Should print out the appropriate headers.
2042 The default method calls $self->cgix->print_content_type and then
2045 The print_content_type is passed $self->mimetype (which defaults to
2046 $self->{'mimetype'} which defaults to 'text/html') and $self->charset
2047 (which defaults to $self->{'charset'} which defaults to '').
2049 =item ready_validate (hook)
2051 Should return true if enough information is present to run validate.
2052 Default is to look if $ENV{'REQUEST_METHOD'} is 'POST'. A common
2053 usage is to pass a common flag in the form such as 'processing' => 1
2054 and check for its presence - such as the following:
2056 sub ready_validate { shift->form->{'processing'} }
2058 Changing the behavior of ready_validate can help in making wizard type
2061 You can also use the validate_when_data hook to change the behavior of
2062 ready_validate. If valiate_when_data returns true, then
2063 ready_validate will look for keys in the form matching keys that are
2064 in hash_validation - if they exist ready_validate will be true. If
2065 there are no hash_validation keys, ready_validate uses its default
2068 =item refine_path (hook)
2070 Called at the end of nav_loop. Passed a single value indicating
2071 if there are currently more steps in the path.
2073 The default implementation returns if there are still more steps
2074 in the path. Otherwise, it calls the next_step hook and appends
2075 it to the path with the append_path method, and then calls
2076 the set_ready_validate hook and passes it 0.
2078 This allows you to simply put
2080 sub edit_next_step { '_edit_success' }
2082 In your code and it will automatically do the right thing and
2083 go to the _edit_success step.
2085 =item recurse_limit (method)
2087 Default 15. Maximum number of times to allow nav_loop to call itself.
2088 The recurse level will increase every time that ->goto_step is called, or if
2089 the end of the nav_loop is reached and the process tries to add the
2090 default_step and run it again.
2092 If ->goto_step is used often - the recurse_limit will be reached more
2093 quickly. It is safe to raise this as high as is necessary - so long
2094 as it is intentional.
2096 Often the limit is reached if a step did not have a validation hash,
2097 or if the set_ready_validate(0) method was not called once the data
2098 had been successfully validated and acted upon.
2100 =item replace_path (method)
2102 Arguments are the steps used to replace. Can be called any time.
2103 Replaces the remaining steps (if any) of the current path.
2105 =item require_auth (hook)
2107 Defaults to self->{require_auth} which defaults to undef.
2108 If called as a method and passed a single value of 1, 0, or undef it will
2109 set the value of $self->{require_auth} to that value. If set to a true
2110 value then any subsequent step will require authentication (unless its
2111 hook has been overwritten).
2113 Any of the following ways can be used to require authentication on
2120 sub require_auth { 1 }
2124 __PACKAGE__->navigate_authenticated; # instead of __PACKAGE__->navigate;
2128 __PACKAGE__->new({require_auth => 1}->navigate;
2132 sub init { shift->require_auth(1) }
2136 Because it is called as a hook, the current step is passed as the
2137 first argument. If the hook returns false, no authentication will be
2138 required on this step. If the hook returns a true, non-hashref value,
2139 authentication will be required via the get_valid_auth method. If the
2140 method returns a hashref of stepnames to require authentication on,
2141 the step will require authentication via the get_valid_auth method if
2142 the current step is in the hashref. If authentication is required and
2143 succeeds, the step will proceed. If authentication is required and
2144 fails at the step level the current step will be aborted,
2145 authentication will be asked for (the post_navigate method will still
2148 For example you could add authentication to the add, edit, and delete
2149 steps in any of the following ways:
2155 sub require_auth { {add => 1, edit => 1, delete => 1} }
2159 sub add_require_auth { 1 }
2160 sub edit_require_auth { 1 }
2161 sub delete_require_auth { 1 }
2166 my ($self, $step) = @_;
2167 return 1 if $step && $step =~ /^(add|edit|delete)$/;
2173 If however you wanted to require authentication on all but one or two methods
2174 (such as requiring authentication on all but a forgot_password step) you could do
2175 either of the following:
2182 my ($self, $step) = @_;
2183 return 0 if $step && $step eq 'forgot_password';
2184 return 1; # require auth on all other steps
2189 sub require_auth { 1 } # turn it on for all steps
2191 sub forgot_password_require_auth { 0 } # turn it off
2195 See the get_valid_auth method for what occurs should authentication be required.
2197 There is one key difference from the 2.14 version of App. In 2.14 and
2198 previous versions, the pre_navigate and post_navigate methods would
2199 not be called if require_auth returned a true non-hashref value. In
2200 version 2.15 and later, the 2.15 pre_navigate and post_navigate
2201 methods are always called - even if authentication fails. Also in 2.15
2202 and later, the method is called as a hook meaning the step is passed in.
2204 =item run_hook (method)
2206 Arguments are a hook name and the step to find the hook for. Calls
2207 the find_hook method to get a code ref which it then calls and returns
2208 the result passing any extra arguments to run_hook as arguments to the
2211 Each call to run_hook is logged in the arrayref returned by the
2212 history method. This information is summarized in the dump_history
2213 method and is useful for tracing the flow of the program.
2215 The run_hook method is part of the core of CGI::Ex::App. It allows
2216 for an intermediate layer in normal method calls. Because of
2217 run_hook, it is possible to logically override methods on a step by
2218 step basis, or override a method for all of the steps, or even to
2219 break code out into separate modules.
2221 =item run_hook_as (method)
2223 Similar to run_hook - but allows for temporarily running a
2224 hook in another package.
2226 sub blah_morph_package { 'SomeOther::Module' }
2227 my $hash = $self->run_hook_as('hash_swap', 'blah'); # runs as SomeOther::Module
2231 my $hash = $self->run_hook_as('hash_swap', 'SomeOther::Module');
2233 Note that the second form will use 'SomeOther::Module' as the step name
2234 which will be somewhat misleading in looking up names.
2236 =item run_step (hook)
2238 Runs all of the hooks specific to each step, beginning with pre_step
2239 and ending with post_step (for a full listing of steps, see the
2240 section on process flow). Called after ->morph($step) has been run.
2241 If this hook returns true, the nav_loop is exited (meaning the
2242 run_step hook displayed a printed page). If it returns false, the
2243 nav_loop continues on to run the next step.
2245 This hook performs the same base functionality as a method defined in
2246 CGI::Applications ->run_modes. The default run_step method provides
2247 much more granular control over the flow of the CGI.
2249 =item set_path (method)
2251 Arguments are the steps to set. Should be called before navigation
2252 begins. This will set the path arrayref to the passed steps.
2254 This method is not normally used.
2256 =item set_ready_validate (hook and method)
2258 Sets that the validation is ready (or not) to validate. Should set the value
2259 checked by the hook ready_validate. Has no affect if validate_when_data
2262 The following would complement the "processing" flag example given in
2263 ready_validate description:
2265 sub set_ready_validate {
2267 my ($step, $is_ready) = (@_ == 2) ? @_ : (undef, shift);
2269 $self->form->{'processing'} = 1;
2271 delete $self->form->{'processing'};
2276 Note that for this example the form key "processing" was deleted. This
2277 is so that the call to fill in any html forms won't swap in a value of
2278 zero for form elements named "processing."
2280 Also note that this method may be called as a hook as in
2282 $self->run_hook('set_ready_validate', $step, 0)
2284 $self->set_ready_validate($step, 0);
2286 Or it can take a single argument and should set the ready status
2287 regardless of the step as in:
2289 $self->set_ready_validate(0);
2293 Ran at the beginning of the loop before prepare, info_complete, and
2294 finalize are called. If it returns true, nav_loop moves on to the
2295 next step (the current step is skipped).
2297 =item stash (method)
2299 Returns a hashref that can store arbitrary user space data without
2300 worrying about overwriting the internals of the application.
2302 =item step_key (method)
2304 Should return the keyname that will be used by the default "path"
2305 method to look for in the form. Default value is 'step'.
2307 =item swap_template (hook)
2309 Takes the template and hash of variables prepared in print, and
2310 processes them through the current template engine Template::Alloy.
2312 Arguments are the template and the swap hashref. The template can be
2313 either a scalar reference to the actual content, or the filename of
2314 the content. If the filename is specified - it should be relative to
2315 template_path (which will be used to initialize INCLUDE_PATH by
2318 The default method will create a template object by calling the
2319 template_args hook and passing the returned hashref to the
2320 template_obj method. The default template_obj method returns a
2321 Template::Alloy object, but could easily be swapped to use a
2322 Template::Toolkit based object. If a non-Template::Toolkit compatible
2323 object is to be used, then the swap_template hook can be overridden to
2324 use another templating engine.
2326 For example to use the HTML::Template engine you could override the swap_template
2332 my ($self, $step, $file, $swap) = @_;
2334 my $type = UNIVERSAL::isa($file, 'SCALAR') ? 'scalarref'
2335 : UNIVERSAL::isa($file, 'ARRAY') ? 'arrayref'
2336 : ref($file) ? 'filehandle'
2339 my $t = HTML::Template->new(source => $file,
2341 path => $self->template_path,
2342 die_on_bad_params => 0,
2350 Uou could also simply do the following to parse the templates using
2351 HTML::Template::Expr syntax.
2354 return {SYNTAX => 'hte'};
2357 For a listing of the available syntaxes, see the current L<Template::Alloy> documentation.
2359 =item template_args (hook)
2361 Returns a hashref of args that will be passed to the "new" method of Template::Alloy
2362 The method is normally called from the swap_template hook. The swap_template hook
2363 will add a value for INCLUDE_PATH which is set equal to template_path, if the INCLUDE_PATH
2364 value is not already set.
2366 The returned hashref can contain any arguments that Template::Alloy
2372 WRAPPER => 'wrappers/main_wrapper.html',
2376 See the L<Template::Alloy> documentation for a listing of all possible configuration arguments.
2378 =item template_obj (method)
2380 Called from swap_template. It is passed the result of template_args
2381 that have had a default INCLUDE_PATH added via template_path. The
2382 default implementation uses Template::Alloy but can easily be changed
2383 to use Template::Toolkit by using code similar to the following:
2388 my ($self, $args) = @_;
2389 return Template->new($args);
2392 =item template_path (method)
2394 Defaults to $self->{'template_path'} which defaults to base_dir_abs. Used by
2395 the template_obj method.
2397 =item unmorph (method)
2399 Allows for returning an object back to its previous blessed state if
2400 the "morph" method was successful in morphing the App object. This
2401 only happens if the object was previously morphed into another object
2402 type. Before the object is re-blessed the method fixup_before_unmorph
2405 See allow_morph and morph.
2407 =item valid_steps (method)
2409 Called by the default path method. Should return a hashref of path
2410 steps that are allowed. If the current step is not found in the hash
2411 (or is not the default_step or js_step) the path method will return a
2412 single step of ->forbidden_step and run its hooks. If no hash or undef is
2413 returned, all paths are allowed (default). A key "forbidden_step"
2414 containing the step that was not valid will be placed in the stash.
2415 Often the valid_steps method does not need to be defined as arbitrary
2416 method calls are not possible with CGI::Ex::App.
2418 Any steps that begin with _ are also "not" valid for passing in via the form
2419 or path info. See the path method.
2421 Also, the pre_step, skip, prepare, and info_complete hooks allow for validating
2422 the data before running finalize.
2424 =item validate (hook)
2426 Passed the form from $self->form. Runs validation on the information
2427 contained in the passed form. Uses CGI::Ex::Validate for the default
2428 validation. Calls the hook hash_validation to load validation hashref
2429 (an empty hash means to pass validation). Should return true if the
2430 form passed validation and false otherwise. Errors are stored as a
2431 hash in $self->{hash_errors} via method add_errors and can be checked
2432 for at a later time with method has_errors (if the default validate
2435 There are many ways and types to validate the data. Please see the
2436 L<CGI::Ex::Validate> module.
2438 Upon success, it will look through all of the items which were
2439 validated, if any of them contain the keys append_path, insert_path,
2440 or replace_path, that method will be called with the value as
2441 arguments. This allows for the validation to apply redirection to the
2442 path. A validation item of:
2444 {field => 'foo', required => 1, append_path => ['bar', 'baz']}
2446 would append 'bar' and 'baz' to the path should all validation succeed.
2448 =item validate_when_data (hook)
2450 Defaults to "validate_when_data" property which defaults to false. Called
2451 during the ready_validate hook. If returns true, ready_validate will look
2452 for keys in the form matching keys that are in hash_validation - if they exist
2453 ready_validate will be true. If there are no hash_validation keys, ready_validate
2454 uses its default behavior.
2456 =item verify_user (method)
2458 Installed as a hook to CGI::Ex::App during get_valid_auth. Should return
2459 true if the user is ok. Default is to always return true. This can be
2460 used to abort early before the get_pass_by_user hook is called.
2463 my ($self, $user) = @_;
2464 return 0 if $user eq 'paul'; # don't let paul in
2465 return 1; # let anybody else in
2470 =head1 HOW DO I SET COOKIES, REDIRECT, ETC
2472 Often in your program you will want to set cookies or bounce to a differnt URL.
2473 This can be done using either the builtin CGI::Ex object or the built in
2474 CGI object. It is suggested that you only use the CGI::Ex methods as it will
2475 automatically send headers and method calls under cgi, mod_perl1, or mod_perl2.
2476 The following shows how to do basic items using the CGI::Ex object returned by
2481 =item printing content-type headers
2483 ### CGI::Ex::App prints headers for you,
2484 ### but if you are printing custom types, you can send your own
2485 $self->cgix->print_content_type;
2487 # $self->cgix->print_content_type('text/html');
2489 =item setting a cookie
2491 $self->cgix->set_cookie({
2493 -value => 'Some Value',
2498 =item redirecting to another URL
2500 $self->cgix->location_bounce("http://somewhereelse.com");
2501 $self->exit_nav_loop; # normally should do this to long jump out of navigation
2503 =item making a QUERY_STRING
2505 my $data = {foo => "bar", one => "two or three"};
2506 my $query = $self->cgix->make_form($data);
2507 # $query now equals "foo=bar&one=two%20or%20three"
2509 =item getting form parameters
2511 my $form = $self->form;
2513 In this example $form would now contain a hashref of all POST and GET parameters
2514 passed to the server. The form method calls $self->cgix->get_form
2515 which in turn uses CGI->param to parse values. Fields with multiple passed
2516 values will be in the form of an arrayref.
2518 =item getting cookies
2520 my $cookies = $self->cookies;
2522 In this example $cookies would be a hashref of all passed in cookies. The
2523 cookies method calls $self->cgix->get_cookies which in turn uses CGI->cookie
2528 See the CGI::Ex and CGI documentation for more information.
2530 =head1 COMPARISON TO OTHER APPLICATION MODULES
2532 The concepts used in CGI::Ex::App are not novel or unique. However, they
2533 are all commonly used and very useful. All application builders were
2534 built because somebody observed that there are common design patterns
2535 in CGI building. CGI::Ex::App differs in that it has found more common design
2536 patterns of CGI's than other application builders and tries to get in the way
2539 CGI::Ex::App is intended to be sub classed, and sub sub classed, and each step
2540 can choose to be sub classed or not. CGI::Ex::App tries to remain simple
2541 while still providing "more than one way to do it." It also tries to avoid
2542 making any sub classes have to call ->SUPER:: (although that is fine too).
2544 And if what you are doing on a particular is far too complicated or custom for
2545 what CGI::Ex::App provides, CGI::Ex::App makes it trivial to override all behavior.
2547 There are certainly other modules for building CGI applications. The
2548 following is a short list of other modules and how CGI::Ex::App is
2553 =item C<CGI::Application>
2555 Seemingly the most well know of application builders.
2556 CGI::Ex::App is different in that it:
2558 * Uses Template::Toolkit compatible Template::Alloy by default.
2559 CGI::Ex::App can easily use another toolkit by simply
2560 overriding the ->swap_template method.
2561 CGI::Application uses HTML::Template.
2562 * Offers integrated data validation.
2563 CGI::Application has had custom plugins created that
2564 add some of this functionality. CGI::Ex::App has the benefit
2565 that validation is automatically available in javascript as well.
2566 * Allows the user to print at any time (so long as proper headers
2567 are sent. CGI::Application requires data to be pipelined.
2568 * Offers hooks into the various phases of each step ("mode" in
2569 CGI::Application lingo). CGI::Application provides only ->runmode
2570 which is only a dispatch.
2571 * Support for easily jumping around in navigation steps.
2572 * Support for storing some steps in another package.
2573 * Integrated authentication
2574 * Integrated form filling
2575 * Integrated PATH_INFO mapping
2577 CGI::Ex::App and CGI::Application are similar in that they take care
2578 of handling headers and they allow for calling other "runmodes" from
2579 within any given runmode. CGI::Ex::App's ->run_step is essentially
2580 equivalent to a method call defined in CGI::Application's ->run_modes.
2581 The ->run method of CGI::Application starts the application in the same
2582 manner as CGI::Ex::App's ->navigate call. Many of the hooks around
2583 CGI::Ex::App's ->run_step call are similar in nature to those provided by
2586 =item C<CGI::Prototype>
2588 There are actually many similarities. One of the nicest things about
2589 CGI::Prototype is that it is extremely short (very very short). The
2590 ->activate starts the application in the same manner as CGI::Ex::App's
2591 ->navigate call. Both use Template::Toolkit as the default template
2592 system (CGI::Ex::App uses Template::Alloy which is TT compatible).
2593 CGI::Ex::App is differrent in that it:
2595 * Offers more hooks into the various phases of each step.
2596 * Support for easily jumping around in navigation steps.
2597 * Support for storing only some steps in another package.
2598 * Integrated data validation
2599 * Integrated authentication
2600 * Integrated form filling
2601 * Integrated PATH_INFO mapping
2606 =head1 SIMPLE EXTENDED EXAMPLE
2608 The following example shows the creation of a basic recipe
2609 database. It requires the use of DBD::SQLite, but that is all.
2610 Once you have configured the db_file and template_path methods
2611 of the "recipe" file, you will have a working script that
2612 does CRUD for the recipe table. The observant reader may ask - why
2613 not use Catalyst or Ruby on Rails? The observant programmer will
2614 reply that making a framework do something simple is easy, but making
2615 it do something complex is complex and any framework that tries to
2616 do the those complex things for you is too complex. CGI::Ex::App
2617 lets you write the complex logic but gives you the ability to
2618 not worry about the boring details such as template engines,
2619 or sticky forms, or cgi parameters, or data validation. Once
2620 you are setup and are running, you are only left with providing
2621 the core logic of the application.
2623 ### File: /var/www/cgi-bin/recipe (depending upon Apache configuration)
2624 ### --------------------------------------------
2627 use lib qw(/var/www/lib);
2632 ### File: /var/www/lib/Recipe.pm
2633 ### --------------------------------------------
2637 use base qw(CGI::Ex::App);
2638 use CGI::Ex::Dump qw(debug);
2643 ###------------------------------------------###
2646 # show what happened
2647 debug shift->dump_history;
2650 sub template_path { '/var/www/templates' }
2652 sub base_dir_rel { 'content' }
2654 sub db_file { '/var/www/recipe.sqlite' }
2658 if (! $self->{'dbh'}) {
2659 my $file = $self->db_file;
2660 my $exists = -e $file;
2661 $self->{'dbh'} = DBI->connect("dbi:SQLite:dbname=$file", '', '',
2663 $self->create_tables if ! $exists;
2665 return $self->{'dbh'};
2671 $self->dbh->do("CREATE TABLE recipe (
2672 id INTEGER PRIMARY KEY AUTOINCREMENT,
2673 title VARCHAR(50) NOT NULL,
2674 ingredients VARCHAR(255) NOT NULL,
2675 directions VARCHAR(255) NOT NULL,
2676 date_added VARCHAR(20) NOT NULL
2680 ###----------------------------------------------------------------###
2682 sub main_info_complete { 0 }
2684 sub main_hash_swap {
2687 my $s = "SELECT id, title, date_added
2689 ORDER BY date_added";
2690 my $data = $self->dbh->selectall_arrayref($s);
2691 my @data = map {my %h; @h{qw(id title date_added)} = @$_; \%h} @$data;
2698 ###----------------------------------------------------------------###
2700 sub add_name_step { 'edit' }
2702 sub add_hash_validation {
2704 'group order' => [qw(title ingredients directions)],
2722 my $form = $self->form;
2724 my $s = "SELECT COUNT(*) FROM recipe WHERE title = ?";
2725 my ($count) = $self->dbh->selectrow_array($s, {}, $form->{'title'});
2727 $self->add_errors(title => 'A recipe by this title already exists');
2731 $s = "INSERT INTO recipe (title, ingredients, directions, date_added)
2732 VALUES (?, ?, ?, ?)";
2733 $self->dbh->do($s, {}, $form->{'title'},
2734 $form->{'ingredients'},
2735 $form->{'directions'},
2738 $self->add_to_form(success => "Recipe added to the database");
2743 ###----------------------------------------------------------------###
2745 sub edit_skip { shift->form->{'id'} ? 0 : 1 }
2747 sub edit_hash_common {
2749 return {} if $self->ready_validate;
2751 my $sth = $self->dbh->prepare("SELECT * FROM recipe WHERE id = ?");
2752 $sth->execute($self->form->{'id'});
2753 my $hash = $sth->fetchrow_hashref;
2758 sub edit_hash_validation { shift->add_hash_validation(@_) }
2762 my $form = $self->form;
2764 my $s = "SELECT COUNT(*) FROM recipe WHERE title = ? AND id != ?";
2765 my ($count) = $self->dbh->selectrow_array($s, {}, $form->{'title'}, $form->{'id'});
2767 $self->add_errors(title => 'A recipe by this title already exists');
2771 $s = "UPDATE recipe SET title = ?, ingredients = ?, directions = ? WHERE id = ?";
2772 $self->dbh->do($s, {}, $form->{'title'},
2773 $form->{'ingredients'},
2774 $form->{'directions'},
2777 $self->add_to_form(success => "Recipe updated in the database");
2782 ###----------------------------------------------------------------###
2784 sub view_skip { shift->edit_skip(@_) }
2786 sub view_hash_common { shift->edit_hash_common(@_) }
2788 ###----------------------------------------------------------------###
2790 sub delete_skip { shift->edit_skip(@_) }
2792 sub delete_info_complete { 1 }
2794 sub delete_finalize {
2796 $self->dbh->do("DELETE FROM recipe WHERE id = ?", {}, $self->form->{'id'});
2798 $self->add_to_form(success => "Recipe deleted from the database");
2808 File: /var/www/templates/content/recipe/main.html
2809 ### --------------------------------------------
2812 <title>Recipe DB</title>
2816 [% IF success %]<span style="color:darkgreen"><h2>[% success %]</h2></span>[% END %]
2818 <table style="border:1px solid blue">
2819 <tr><th>#</th><th>Title</th><th>Date Added</th></tr>
2821 [% FOR row IN recipies %]
2823 <td>[% loop.count %].</td>
2824 <td><a href="[% script_name %]/view?id=[% row.id %]">[% row.title %]</a>
2825 (<a href="[% script_name %]/edit?id=[% row.id %]">Edit</a>)
2827 <td>[% row.date_added %]</td>
2831 <tr><td colspan=2 align=right><a href="[% script_name %]/add">Add new recipe</a></td></tr>
2837 File: /var/www/templates/content/recipe/edit.html
2838 ### --------------------------------------------
2841 <title>[% step == 'add' ? "Add" : "Edit" %] Recipe</title>
2843 <h1>[% step == 'add' ? "Add" : "Edit" %] Recipe</h1>
2845 <form method=post name=[% form_name %]>
2846 <input type=hidden name=step>
2850 [% IF step != 'add' ~%]
2852 <td><b>Id:</b></td><td>[% id %]</td></tr>
2853 <input type=hidden name=id>
2856 <td><b>Date Added:</b></td><td>[% date_added %]</td></tr>
2861 <td valign=top><b>Title:</b></td>
2862 <td><input type=text name=title>
2863 <span style='color:red' id=title_error>[% title_error %]</span></td>
2866 <td valign=top><b>Ingredients:</b></td>
2867 <td><textarea name=ingredients rows=10 cols=40 wrap=physical></textarea>
2868 <span style='color:red' id=ingredients_error>[% ingredients_error %]</span></td>
2871 <td valign=top><b>Directions:</b></td>
2872 <td><textarea name=directions rows=10 cols=40 wrap=virtual></textarea>
2873 <span style='color:red' id=directions_error>[% directions_error %]</span></td>
2876 <td colspan=2 align=right>
2877 <input type=submit value="[% step == 'add' ? 'Add' : 'Update' %]"></td>
2882 (<a href="[% script_name %]">Main Menu</a>)
2883 [% IF step != 'add' ~%]
2884 (<a href="[% script_name %]/delete?id=[% id %]">Delete this recipe</a>)
2892 File: /var/www/templates/content/recipe/view.html
2893 ### --------------------------------------------
2896 <title>[% title %] - Recipe DB</title>
2898 <h1>[% title %]</h1>
2899 <h3>Date Added: [% date_added %]</h3>
2901 <h2>Ingredients</h2>
2908 (<a href="[% script_name %]">Main Menu</a>)
2909 (<a href="[% script_name %]/edit?id=[% id %]">Edit this recipe</a>)
2913 ### --------------------------------------------
2917 The dbh method returns an SQLite dbh handle and auto creates the
2918 schema. You will normally want to use MySQL or Oracle, or Postgres
2919 and you will want your schema to NOT be auto-created.
2921 This sample uses hand rolled SQL. Class::DBI or a similar module
2922 might make this example shorter. However, more complex cases that
2923 need to involve two or three or four tables would probably be better
2924 off using the hand crafted SQL.
2926 This sample uses SQL. You could write the application to use whatever
2927 storage you want - or even to do nothing with the submitted data.
2929 We had to write our own HTML (Catalyst and Ruby on Rails do this for
2930 you). For most development work - the HTML should be in a static
2931 location so that it can be worked on by designers. It is nice that
2932 the other frameworks give you stub html - but that is all it is. It
2933 is worth about as much as copying and pasting the above examples. All
2934 worthwhile HTML will go through a non-automated design/finalization
2937 The add step used the same template as the edit step. We did
2938 this using the add_name_step hook which returned "edit". The template
2939 contains IF conditions to show different information if we were in
2940 add mode or edit mode.
2942 We reused code, validation, and templates. Code and data reuse is a
2945 The edit_hash_common returns an empty hashref if the form was ready to
2946 validate. When hash_common is called and the form is ready to
2947 validate, that means the form failed validation and is now printing
2948 out the page. To let us fall back and use the "sticky" form fields
2949 that were just submitted, we need to not provide values in the
2952 We use hash_common. Values from hash_common are used for both
2953 template swapping and filling. We could have used hash_swap and
2954 hash_fill independently.
2956 The hook main_info_complete is hard coded to 0. This basically says
2957 that we will never try and validate or finalize the main step - which
2958 is most often the case.
2960 =head1 SEPARATING STEPS INTO SEPARATE FILES
2962 It may be useful sometimes to separate some or all of the steps of an
2963 application into separate files. This is the way that CGI::Prototype
2964 works. This is useful in cases were some steps and their hooks are
2965 overly large - or are seldom used.
2967 The following modifications can be made to the previous "recipe db"
2968 example that would move the "delete" step into its own file. Similar
2969 actions can be taken to break other steps into their own file as well.
2972 ### File: /var/www/lib/Recipe.pm
2973 ### Same as before but add the following line:
2974 ### --------------------------------------------
2976 sub allow_morph { 1 }
2979 ### File: /var/www/lib/Recipe/Delete.pm
2980 ### Remove the delete_* subs from lib/Recipe.pm
2981 ### --------------------------------------------
2982 package Recipe::Delete;
2985 use base qw(Recipe);
2987 sub skip { shift->edit_skip(@_) }
2989 sub info_complete { 1 }
2993 $self->dbh->do("DELETE FROM recipe WHERE id = ?", {}, $self->form->{'id'});
2995 $self->add_to_form(success => "Recipe deleted from the database");
3002 The hooks that are called (skip, info_complete, and finalize) do not
3003 have to be prefixed with the step name because they are now in their
3004 own individual package space. However, they could still be named
3005 delete_skip, delete_info_complete, and delete_finalize and the
3006 run_hook method will find them (this would allow several steps with
3007 the same "morph_package" to still be stored in the same external
3010 The method allow_morph is passed the step that we are attempting to
3011 morph to. If allow_morph returns true every time, then it will try
3012 and require the extra packages every time that step is ran. You could
3013 limit the morphing process to run only on certain steps by using code
3014 similar to the following:
3016 sub allow_morph { return {delete => 1} }
3021 my ($self, $step) = @_;
3022 return ($step eq 'delete') ? 1 : 0;
3025 The CGI::Ex::App temporarily blesses the object into the
3026 "morph_package" for the duration of the step and re-blesses it into the
3027 original package upon exit. See the morph method and allow_morph for more
3030 =head1 RUNNING UNDER MOD_PERL
3032 The previous samples are essentially suitable for running under flat CGI,
3033 Fast CGI, or mod_perl Registry or mod_perl PerlRun type environments. It
3034 is very easy to move the previous example to be a true mod_perl handler.
3036 To convert the previous recipe example, simply add the following:
3038 ### File: /var/www/lib/Recipe.pm
3039 ### Same as before but add the following lines:
3040 ### --------------------------------------------
3048 ### File: apache2.conf - or whatever your apache conf file is.
3049 ### --------------------------------------------
3051 SetHandler perl-script
3057 Both the /cgi-bin/recipe version and the /recipe version can co-exist.
3058 One of them will be a normal cgi and the other will correctly use
3059 mod_perl hooks for headers.
3061 Setting the location to /recipe means that the $ENV{SCRIPT_NAME} will
3062 also be set to /recipe. This means that name_module method will
3063 resolve to "recipe". If a different URI location is desired such as
3064 "/my_cool_recipe" but the program is to use the same template content
3065 (in the /var/www/templates/content/recipe directory), then we would
3066 need to explicitly set the "name_module" parameter. It could be done
3067 in either of the following ways:
3069 ### File: /var/www/lib/Recipe.pm
3070 ### Same as before but add the following line:
3071 ### --------------------------------------------
3073 sub name_module { 'recipe' }
3079 $self->{'name_module'} = 'recipe';
3082 In most use cases it isn't necessary to set name_module, but it also
3083 doesn't hurt and in all cases it is more descriptive to anybody who is
3084 going to maintain the code later.
3086 =head1 ADDING AUTHENTICATION TO THE ENTIRE APPLICATION
3088 Having authentication is sometimes a good thing. To force
3089 the entire application to be authenticated (require a valid username
3090 and password before doing anything) you could do the following.
3092 ### File: /var/www/lib/Recipe.pm
3093 ### Same as before but add
3094 ### --------------------------------------------
3096 sub get_pass_by_user {
3099 my $pass = $self->lookup_and_cache_the_pass($user);
3104 ### File: /var/www/cgi-bin/recipe (depending upon Apache configuration)
3105 ### Change the line with ->navigate; to
3106 ### --------------------------------------------
3108 Recipe->navigate_authenticated;
3112 ### File: /var/www/lib/Recipe.pm
3113 ### Same as before but add
3114 ### --------------------------------------------
3116 sub require_auth { 1 }
3120 ### File: /var/www/lib/Recipe.pm
3121 ### Same as before but add
3122 ### --------------------------------------------
3124 sub init { shift->require_auth(1) }
3126 See the require_auth, get_valid_auth, and auth_args methods for more information.
3127 Also see the L<CGI::Ex::Auth> perldoc.
3129 =head1 ADDING AUTHENTICATION TO INDIVIDUAL STEPS
3131 Sometimes you may only want to have certain steps require
3132 authentication. For example, in the previous recipe example we
3133 might want to let the main and view steps be accessible to anybody,
3134 but require authentication for the add, edit, and delete steps.
3136 To do this, we would do the following to the original example (the
3137 navigation must start with ->navigate. Starting with ->navigate_authenticated
3138 will cause all steps to require validation):
3140 ### File: /var/www/lib/Recipe.pm
3141 ### Same as before but add
3142 ### --------------------------------------------
3144 sub get_pass_by_user {
3147 my $pass = $self->lookup_and_cache_the_pass($user);
3151 sub require_auth { {add => 1, edit => 1, delete => 1} }
3153 We could also enable authentication by using individual hooks as in:
3155 sub add_require_auth { 1 }
3156 sub edit_require_auth { 1 }
3157 sub delete_require_auth { 1 }
3159 Or we could require authentication on everything - but let a few steps in:
3161 sub require_auth { 1 } # turn authentication on for all
3162 sub main_require_auth { 0 } # turn it off for main and view
3163 sub view_require_auth { 0 }
3165 That's it. The add, edit, and delete steps will now require authentication.
3166 See the require_auth, get_valid_auth, and auth_args methods for more information.
3167 Also see the L<CGI::Ex::Auth> perldoc.
3171 The following corporation and individuals contributed in some part to
3172 the original versions.
3174 Bizhosting.com - giving a problem that fit basic design patterns.
3176 Earl Cahill - pushing the idea of more generic frameworks.
3178 Adam Erickson - design feedback, bugfixing, feature suggestions.
3180 James Lance - design feedback, bugfixing, feature suggestions.
3182 Krassimir Berov - feedback and some warnings issues with POD examples.
3186 This module may be distributed under the same terms as Perl itself.
3190 Paul Seamons <perl at seamons dot com>