- debug $self->form, "Do something useful with form here";
-
- ### add success step
- $self->add_to_swap({success_msg => "We did something"});
- $self->append_path('success');
- $self->set_ready_validate(0);
- return 1;
- }
-
- sub success_file_print {
- \ "<h1>Success Step</h1> All done.<br>
- ([% success_msg %])<br>
- (foo = [% foo %])";
- }
-
- ### not necessary - this is the default hash_base
- sub hash_base { # used to include js_validation
- my ($self, $step) = @_;
- return $self->{hash_base} ||= {
- script_name => $ENV{SCRIPT_NAME} || '',
- js_validation => sub { $self->run_hook('js_validation', $step) },
- form_name => sub { $self->run_hook('form_name', $step) },
- };
- }
-
- __END__
-
-Note: This example would be considerably shorter if the html file
-(file_print) and the validation file (file_val) had been placed in
-separate files. Though CGI::Ex::App will work "out of the box" as
-shown it is more probable that any platform using it will customize
-the various hooks to their own tastes (for example, switching print to
-use a system other than Template::Toolkit).
-
-=head1 HOOKS / METHODS
-
-CGI::Ex::App works on the principles of hooks which are essentially
-glorified method lookups. When a hook is called, CGI::Ex::App will
-look for a corresponding method call for that hook for the current
-step name. See the discussion under the method named "hook" for more
-details. The methods listed below are normal method calls.
-Hooks and methods are looked for in the following order:
-
-=over 4
-
-=item Method C<-E<gt>new>
-
-Object creator. Takes a hash or hashref.
-
-=item Method C<-E<gt>init>
-
-Called by the default new method. Allows for any object
-initilizations.
-
-=item Method C<-E<gt>form>
-
-Returns a hashref of the items passed to the CGI. Returns
-$self->{form}. Defaults to CGI::Ex::get_form.
-
-=item Method C<-E<gt>navigate>
-
-Takes a class name or a CGI::Ex::App object as arguments. If a class
-name is given it will instantiate an object by that class. All returns
-from navigate will return the object.
-
-The method navigate is essentially a safe wrapper around the ->nav_loop
-method. It will catch any dies and pass them to ->handle_error.
-
-=item Method C<-E<gt>nav_loop>
-
-This is the main loop runner. It figures out the current path
-and runs all of the appropriate hooks for each step of the path. If
-nav_loop runs out of steps to run (which happens if no path is set, or if
-all other steps run successfully), it will insert the ->default_step into
-the path and run nav_loop again (recursively). This way a step is always
-assured to run. There is a method ->recurse_limit (default 15) that
-will catch logic errors (such as inadvertently running the same
-step over and over and over).
-
-The basic outline of navigation is as follows (the default actions for hooks
-are shown):
-
- navigate {
- eval {
- ->pre_navigate
- ->nav_loop
- ->post_navigate
- }
- # dying errors will run the ->handle_error method
- }
-
-
- nav_loop {
- ->path (get the path steps)
- # DEFAULT ACTION
- # look in $ENV{'PATH_INFO'}
- # look in ->form for ->step_key
-
- ->pre_loop
- # navigation stops if true
-
- ->valid_steps (get list of valid paths)
-
- foreach step of path {
-
- # check that path is valid
-
- ->morph
- # DEFAULT ACTION
- # check ->allow_morph
- # check ->allow_nested_morph
- # ->morph_package (hook - get the package to bless into)
- # ->fixup_after_morph if morph_package exists
-
- ->run_step (hook)
-
- ->unmorph
- # DEFAULT ACTION
- # ->fixup_before_unmorph if blessed to previous package
-
- # exit loop if ->run_step returned true (intercepted)
-
- } end of step foreach
-
- ->post_loop
- # navigation stops if true
-
- ->default_step (inserted into path at current location)
- ->nav_loop (called again recursively)
-
- } end of nav_loop
-
-
- run_step {
- ->pre_step (hook)
- # exits nav_loop if true
-
- ->skip (hook)
- # skips this step if true (stays in nav_loop)
-
- ->prepare (hook - defaults to true)
-
- ->info_complete (hook - ran if prepare was true)
- # DEFAULT ACTION
- # ->ready_validate (hook)
- # return false if ! ready_validate
- # ->validate (hook)
- # ->hash_validation (hook)
- # ->file_val (hook - uses base_dir_rel, name_module, name_step, ext_val)
- # uses CGI::Ex::Validate to validate the hash
- # returns true if validate is true
-
- ->finalize (hook - defaults to true - ran if prepare and info_complete were true)
-
- if ! ->prepare || ! ->info_complete || ! ->finalize {
- ->prepared_print
- # DEFAULT ACTION
- # ->hash_base (hook)
- # ->hash_common (hook)
- # ->hash_form (hook)
- # ->hash_fill (hook)
- # ->hash_swap (hook)
- # ->hash_errors (hook)
- # merge form, base, common, and fill into merged fill
- # merge form, base, common, swap, and errors into merged swap
- # ->print (hook - passed current step, merged swap hash, and merged fill)
- # DEFAULT ACTION
- # ->file_print (hook - uses base_dir_rel, name_module, name_step, ext_print)
- # ->template_args
- # Processes the file with Template Toolkit
- # Fills the any forms with CGI::Ex::Fill
- # Prints headers and the content
-
- ->post_print (hook - used for anything after the print process)
-
- # return true to exit from nav_loop
- }
-
- ->post_step (hook)
- # exits nav_loop if true
-
- } end of run_step
-
-
-=item Method C<-E<gt>pre_navigate>
-
-Called from within navigate. Called before the nav_loop method is started.
-If a true value is returned then navigation is skipped (the nav_loop is never
-started).
-
-=item Method C<-E<gt>post_navigate>
-
-Called from within navigate. Called after the nav_loop has finished running.
-Will only run if there were no errors which died during the nav_loop
-process.
-
-=item Method C<-E<gt>handle_error>
-
-If anything dies during execution, handle_error will be called with
-the error that had happened. Default is to debug the error and path
-history.
-
-=item Method C<-E<gt>history>
-
-Returns an arrayref of which hooks of which steps of the path were ran.
-Useful for seeing what happened. In general - each line of the history
-will show the current step, the hook requested, and which hook was
-actually called. (hooks that don't find a method don't add to history)
-
-=item Method C<-E<gt>path>
-
-Return an arrayref (modifyable) of the steps in the path. For each
-step the remaining hooks can be run. Hook methods are looked up and
-ran using the method "run_hook" which uses the method "hook" to lookup
-the hook. A history of ran hooks is stored in the array ref returned
-by $self->history. Default will be a single step path looked up in
-$form->{path} or in $ENV{PATH_INFO}. By default, path will look for
-$ENV{'PATH_INFO'} or the value of the form by the key step_key. For
-the best functionality, the arrayref returned should be the same
-reference returned for every call to path - this ensures that other
-methods can add to the path (and will most likely break if the
-arrayref is not the same). If navigation runs out of steps to run,
-the default step found in default_step will be run.
-
-=item Method C<-E<gt>default_step>
-
-Step to show if the path runs out of steps. Default value is the
-'default_step' property or the value 'main'.
-
-=item Method C<-E<gt>step_key>
-
-Used by default to determine which step to put in the path. The
-default path will only have one step within it
-
-=item Method C<-E<gt>set_path>
-
-Arguments are the steps to set. Should be called before navigation
-begins. This will set the path arrayref to the passed steps.
-
-=item Method C<-E<gt>append_path>
-
-Arguments are the steps to append. Can be called any time. Adds more
-steps to the end of the current path.
-
-=item Method C<-E<gt>replace_path>
-
-Arguments are the steps used to replace. Can be called any time.
-Replaces the remaining steps (if any) of the current path.
-
-=item Method C<-E<gt>insert_path>
-
-Arguments are the steps to insert. Can be called any time. Inserts
-the new steps at the current path location.
-
-=item Method C<-E<gt>jump>
-
-This method should not normally be used. It provides for moving to the
-next step at any point during the nav_loop. It effectively short circuits
-the remaining hooks for the current step. It does increment the recursion
-counter (which has a limit of ->recurse_limit - default 15). It is normally
-better to allow the other hooks in the loop to carry on their normal functions
-and avoid jumping. (Essentially, this hook behaves like a goto method to
-bypass everything else and continue at a different location in the path - there
-are times when it is necessary or useful - but most of the time should be
-avoided)
-
-Jump takes a single argument which is the location in the path to jump
-to. This argument may be either a step name, the special words
-"FIRST, LAST, CURRENT, PREVIOUS, OR NEXT" or the number of steps to
-jump forward (or backward) in the path. The default value, 1,
-indicates that CGI::Ex::App should jump to the next step (the default action for
-jump). A value of 0 would repeat the current step (watch out for
-recursion). A value of -1 would jump to the previous step. The
-special value of "LAST" will jump to the last step. The special value
-of "FIRST" will jump back to the first step. In each of these cases,
-the path array retured by ->path is modified to allow for the jumping.
-
- ### goto previous step
- $self->jump($self->previous_step);
- $self->jump('PREVIOUS');
- $self->jump(-1);
-
- ### goto next step
- $self->jump($self->next_step);
- $self->jump('NEXT');
- $self->jump(1);
- $self->jump;
-
- ### goto current step (repeat)
- $self->jump($self->current_step);
- $self->jump('CURRENT');
- $self->jump(0);
-
- ### goto last step
- $self->jump($self->last_step);
- $self->jump('LAST');
-
- ### goto first step
- $self->jump($self->first_step);
- $self->jump('FIRST');
-
-=item Method C<-E<gt>exit_nav_loop>
-
-This method should not normally used. It allows for a long jump to the
-end of all nav_loops (even if they are recursively nested). This
-effectively short circuits all remaining hooks for the current and
-remaining steps. It is used to allow the ->jump functionality. If the
-application has morphed, it will be unmorphed before returning.
-
-=item Method C<-E<gt>recurse_limit>
-
-Default 15. Maximum number of times to allow nav_loop to call itself.
-If ->jump is used alot - the recurse_limit will be reached more quickly.
-It is safe to raise this as high as is necessary - so long as it is intentional.
-
-=item Method C<-E<gt>valid_steps>
-
-Returns a hashref of path steps that are allowed. If step found in
-default method path is not in the hash, the method path will return a
-single step "forbidden" and run its hooks. If no hash or undef is
-returned, all paths are allowed (default). A key "forbidden_step"
-containing the step that was not valid will be placed in the stash.
-Often the valid_steps method does not need to be defined as arbitrary
-method calls are not possible with CGI::Ex::App.
-
-=item Method C<-E<gt>previous_step, -E<gt>current_step, -E<gt>next_step, -E<gt>last_step, -E<gt>first_step>
-
-Return the previous, current, next, last, and first step name - useful for figuring
-out where you are in the path. Note that first_step may not be the same
-thing as default_step if the path was overridden.
-
-=item Method C<-E<gt>pre_loop>
-
-Called right before the navigation loop is started. At this point the
-path is set (but could be modified). The only argument is a reference
-to the path array. If it returns a true value - the navigation
-routine is aborted.
-
-=item Method C<-E<gt>run_hook>
-
-Calls "hook" to get a code ref which it then calls and returns the
-result. Arguments are the same as that for "hook".
-
-=item Method C<-E<gt>hook>
-
-Arguments are a hook name, a pathstep name, and an optional code sub
-or default value (default value will be turned to a sub) (code sub
-will be called as method of $self).
-
- my $code = $self->hook('main', 'info_complete', sub {return 0});
- ### will look first for $self->main_info_complete;
- ### will then look for $self->info_complete;
- ### will then run $self->$default_passed_sub; # sub {return 0}
-
-This system is used to allow for multiple steps to be in the same
-file and still allow for moving some steps out to external sub classed
-packages. If the application has successfully morphed then it is not
-necessary to add the step name to the beginning of the method name as
-the morphed packages method will override the base package (it is still
-OK to use the full method name "${step}_hookname").
-
-If a hook is found (or a default value is found) then an entry is added
-to the arrayref contained in ->history.
-
-=item Method C<-E<gt>morph>
-
-Allows for temporarily "becoming" another object type for the
-execution of the current step. This allows for separating some steps
-out into their own packages. Morph will only run if the method
-allow_morph returns true. Additionally if the allow_morph returns a hash
-ref, morph will only run if the step being morphed to is in the hash.
-The morph call occurs at the beginning of the step loop. A
-corresponding unmorph call occurs before the loop is exited. An
-object can morph several levels deep if allow_nested_morph returns
-true. For example, an object running as Foo::Bar that is looping on
-the step "my_step" that has allow_morph = 1, will do the following:
-call the hook morph_package (which would default to returning
-Foo::Bar::MyStep in this case), translate this to a package filename
-(Foo/Bar/MyStep.pm) and try and require it, if the file can be
-required, the object is blessed into that package. If that package
-has a "fixup_after_morph" method, it is called. The navigate loop
-then continues for the current step. At any exit point of the loop,
-the unmorph call is made which reblesses the object into the original
-package.
-
-It is possible to call morph earlier on in the program. An example of
-a useful early use of morph would be as in the following code:
-
- sub allow_morph { 1 }
-
- sub pre_navigate {