X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=lib%2FCGI%2FEx%2FApp.pod;h=536741bccad218d896733a2074ae9cf86f07ef6e;hb=febed4ec71f803b083c3e61b82b9464e9bfb0992;hp=6fe97464e0e828e7d241fff509c46dcfe814ffd8;hpb=419d9570723c210429e2be23875160f57dd36156;p=chaz%2Fp5-CGI-Ex diff --git a/lib/CGI/Ex/App.pod b/lib/CGI/Ex/App.pod index 6fe9746..536741b 100644 --- a/lib/CGI/Ex/App.pod +++ b/lib/CGI/Ex/App.pod @@ -31,7 +31,7 @@ Well, you should put your content in an external file... __PACKAGE__->navigate; - sub base_dir_abs { '/var/www/templates' } + sub template_path { '/var/www/templates' } -------- File: /var/www/templates/my_cgi/main.html -------- @@ -49,7 +49,7 @@ How about if we want to add substitutions... __PACKAGE__->navigate; - sub base_dir_abs { '/var/www/templates' } + sub template_path { '/var/www/templates' } sub main_hash_swap { my $self = shift; @@ -76,7 +76,7 @@ How about a form with validation (inluding javascript validation)... __PACKAGE__->navigate; - sub base_dir_abs { '/var/www/templates' } + sub template_path { '/var/www/templates' } sub main_hash_swap { {date => sub { scalar localtime }} } @@ -132,8 +132,10 @@ How about a form with validation (inluding javascript validation)... There are infinite possibilities. There is a longer "SYNOPSIS" after the process flow discussion and more examples near the end of this document. It is interesting to note that there have been no databases -so far. CGI::Ex::App is Controller/Viewer that is somewhat Model -agnostic. +so far. It is very, very difficult to find a single database +abstraction that fits every model. CGI::Ex::App is Controller/Viewer +that is somewhat Model agnostic and doesn't come with any default +database abstraction. =head1 DESCRIPTION @@ -205,9 +207,8 @@ The nav_loop method will run as follows: ->require_auth (hook) # exits nav_loop if true - ->morph - # check ->allow_morph - # check ->allow_nested_morph + ->morph (hook) + # check ->allow_morph (hook) # ->morph_package (hook - get the package to bless into) # ->fixup_after_morph if morph_package exists # if no package is found, process continues in current file @@ -221,8 +222,7 @@ The nav_loop method will run as follows: ->next_step (hook) # find next step and add to path ->set_ready_validate(0) (hook) - ->unmorph - # only called if morph worked + ->unmorph (hook) # ->fixup_before_unmorph if blessed to current package # exit loop if ->run_step returned true (page printed) @@ -245,25 +245,26 @@ during the run_step hook. run_step { ->pre_step (hook) - # exits nav_loop if true + # skips this step if true and exit nav_loop ->skip (hook) - # skips this step if true (stays in nav_loop) + # skips this step if true and stays in nav_loop ->prepare (hook - defaults to true) ->info_complete (hook - ran if prepare was true) ->ready_validate (hook) - return false if ! ready_validate + ->validate_when_data (hook) + # returns false from info_complete if ! ready_validate ->validate (hook - uses CGI::Ex::Validate to validate form info) ->hash_validation (hook) ->file_val (hook) - ->base_dir_abs + ->vob_path (defaults to template_path) ->base_dir_rel ->name_module ->name_step ->ext_val - returns true if validate is true or if nothing to validate + # returns true if validate is true or if nothing to validate ->finalize (hook - defaults to true - ran if prepare and info_complete were true) @@ -279,8 +280,8 @@ during the run_step hook. # merge form, base, common, swap, and errors into merged swap ->print (hook - passed current step, merged swap hash, and merged fill) ->file_print (hook - uses base_dir_rel, name_module, name_step, ext_print) - ->swap_template (hook - processes the file with CGI::Ex::Template) - ->template_args (hook - passed to CGI::Ex::Template->new) + ->swap_template (hook - processes the file with Template::Alloy) + ->template_args (hook - passed to Template::Alloy->new) ->fill_template (hook - fills the any forms with CGI::Ex::Fill) ->fill_args (hook - passed to CGI::Ex::Fill::fill) ->print_out (hook - print headers and the content to STDOUT) @@ -526,11 +527,11 @@ filling. See the hash_base, hash_common, hash_form, hash_swap, hash_errors, swap_template, and template_args hooks for more information. -The default template engine used is CGI::Ex::Template which is now a subclass -of Template::Alloy. The default interface used is TT which is the -Template::Toolkit interface. Template::Alloy allows for using TT documents, -HTML::Template documents, HTML::Template::Expr documents, Text::Tmpl documents, -or Velocity (VTL) documents. See the L documentation +The default template engine used is Template::Alloy. The default +interface used is TT which is the Template::Toolkit interface. +Template::Alloy allows for using TT documents, HTML::Template +documents, HTML::Template::Expr documents, Text::Tmpl documents, or +Velocity (VTL) documents. See the L documentation for more information. =head1 ADDING ADDITIONAL FORM FILL VARIABLES @@ -589,13 +590,14 @@ are also documented more in the HOOKS AND METHODS section. =over 4 -=item base_dir_abs +=item template_path -Absolute path or arrayref of paths to the base templates directory. Default "". +Absolute path or arrayref of paths to the base templates directory. Defaults to +base_dir_abs which defaults to ['.']. =item base_dir_rel -Relative path inside of the base_dir_abs directory where content can be found. Default "". +Relative path inside of the template_path directory where content can be found. Default "". =item name_module @@ -630,7 +632,7 @@ a contrived example. The following is a hypothetical layout for your templates: In this example we would most likely set values as follows: - base_dir_abs /home/user/templates + template_path /home/user/templates base_dir_rel content name_module my_app @@ -646,7 +648,7 @@ Continuing with the example and assuming that name of the step that the user has requested is "step1" then the following values would be returned: - base_dir_abs /home/user/templates + template_path /home/user/templates base_dir_rel content name_module my_app name_step step1 @@ -660,13 +662,13 @@ The call to the template engine would look something like the following: my $t = $self->template_obj({ - INCLUDE_PATH => $self->base_dir_abs, + INCLUDE_PATH => $self->template_path, # defaults to base_dir_abs }); $t->process($self->file_print($step), \%vars); The template engine would then look for the relative file -inside of the absolute paths (from base_dir_abs). +inside of the absolute paths (from template_path). The call to the validation engine would pass the absolute filename that is returned by file_val. @@ -675,7 +677,7 @@ The name_module and name_step methods can return filenames with additional directories included. The previous example could also have been setup using the following values: - base_dir_abs /home/user/templates + template_path /home/user/templates base_dir_rel name_module content/my_app @@ -839,7 +841,7 @@ completed (various methods determine the definition of "completed"). This preset type of path can also be automated using the CGI::Path module. Rather than using a preset path, CGI::Ex::App also has methods that allow for dynamic changing of the path, so that each step -can determine which step to do next (see the jump, append_path, +can determine which step to do next (see the goto_step, append_path, insert_path, and replace_path methods). During development it would be nice to see what happened during the @@ -978,23 +980,34 @@ The following is the alphabetical list of methods and hooks. =over 4 -=item allow_morph (method) +=item allow_morph (hook) Should return true if this step is allowed to "morph" the current App object into another package. Default is false. It is passed a single argument of the current step. For more granularity, if true value is a hash, the step being morphed to must be in the hash. +If the returned value is "1", and the module doesn't exist, then the +App will continue to run blessed into the current package. If there +is an error requiring the module or if the module doesn't exist and +the return value is "2" (true but not 1), then App will die with the +appropriate error. + To enable morphing for all steps, add the following: +(Packages that don't exists won't be morphed to) sub allow_morph { 1 } +To force morphing for all steps add the following: + + sub allow_morph { 2 } + To enable morph on specific steps, do either of the following: sub allow_morph { return { edit => 1, - delete => 1, + delete => 2, # must morph }; } @@ -1002,22 +1015,13 @@ To enable morph on specific steps, do either of the following: sub allow_morph { my ($self, $step) = @_; - return $step =~ /^(edit|delete)$/; + return 1 if $step eq 'edit'; + return 2 if $step eq 'delete'; + return; } See the morph "hook" for more information. -=item allow_nested_morph (method) - -Similar to the allow_morph hook, but allows for one more level of morphing. -This is useful in cases where the base class was morphed early on, or -if a step needs to call a sub-step but morph first. - -See the allow_morph and the morph method for more information. - -Should return a boolean value or hash of allowed steps - just as the -allow_morph method does. - =item append_path (method) Arguments are the steps to append. Can be called any time. Adds more @@ -1025,7 +1029,8 @@ steps to the end of the current path. =item auth_args (method) -Should return a hashref that will be passed to the new method of CGI::Ex::Auth. +Should return a hashref that will be passed to the auth_obj method +which should return a CGI::Ex::Auth compatible object. It is augmented with arguments that integrate it into CGI::Ex::App. See the get_valid_auth method and the CGI::Ex::Auth documentation. @@ -1048,14 +1053,19 @@ was successful - so this data can be defined but false. See the get_valid_auth method. +=item auth_obj (method) + +Passed auth_args. Should return a CGI::Ex::Auth compatible object. Default +is to call CGI::Ex::Auth->new with the passed args. + =item base_dir_abs (method) -Used as the absolute base directory to find template files and validation files. +Used as the absolute base directory to find template, validation and conf files. It may return a single value or an arrayref of values, or a coderef that returns an arrayref or coderef of values. You may pass base_dir_abs as a parameter in the arguments passed to the "new" method. -Default value is "". +Default value is ['.']. For example, to pass multiple paths, you would use something similar to the following: @@ -1064,27 +1074,29 @@ similar to the following: return ['/my/path/one', '/some/other/path']; } -The base_dir_abs value is used along with the base_dir_rel, name_module, -name_step, ext_print and ext_values for determining the values -returned by the default file_print and file_val hooks. See those methods -for further discussion. +The base_dir_abs value is used by template_path along with the +base_dir_rel, name_module, name_step, ext_print and ext_values for +determining the values returned by the default file_print and file_val +hooks. See those methods for further discussion. See the section on FINDING TEMPLATES for further discussion. +The base_dir_abs method is also used as the default value for conf_path and vob_path. + =item base_dir_rel (method) Added as a relative base directory to content under the base_dir_abs directory. Default value is "". -The base_dir_abs method is used as top level where template includes may -pull from, while the base_dir_rel is directory relative to the base_dir_abs +The template_path method is used as top level where template includes may +pull from, while the base_dir_rel is directory relative to the template_path where the content files will be stored. A value for base_dir_rel may passed as a parameter in the arguments passed to the new method. -See the base_dir_abs method for more discussion. +See the template_path and base_dir_abs methods for more discussion. See the section on FINDING TEMPLATES for further discussion. @@ -1113,13 +1125,71 @@ The following items will be cleared: path path_i history - __morph_lineage_start_index - __morph_lineage + _morph_lineage_start_index + _morph_lineage hash_errors hash_fill hash_swap hash_common +=item conf (method) + +Used by default in init_from_conf if load_conf returns true. +Will try to read the file returned by the conf_file method +using the object returned by conf_obj using that object's read +method. If conf_validation returns a non-empty hashref, the +conf hash will be validated using $self->vob->validate (see the +validate method). + +This method may be used for other purposes as well (including when +load_conf is false).. + +Caches results in $self->{'conf'}. + +If the conf_file can't be found, the method will die unless +conf_die_on_fail returns 0 (defaults to true). + +=item conf_args + +Used by conf_obj. + +Defaults to $self->{'conf_args'} which defaults to {}. Will have +paths => $self->conf_path added before passing to CGI::Ex::Conf->new. + +=item conf_file (method) + +Used by conf for finding the configuration file to load. Defaults +to $self->{'conf_file'} which defaults $self->name_module with the extention +returned by $self->ext_conf added on. For example, if name_module +returns "my_app" and ext_conf returns "ini" the value returned will +be "my_app.ini". + +The value returned can absolute. If the value will be searched for +in the paths passed to conf_obj. + +The ext_conf may be any of those extentions understood by CGI::Ex::Conf. + +=item conf_obj + +Used by the conf method to load the file returned by conf_file. Defaults +to conf_obj which defaults to loading args from conf_args, adding in paths +returned by conf_path, and calling CGI::Ex::Conf->new. + +Any object that provides a read method that returns a hashref can be used. + +=item conf_path + +Defaults to $self->{'conf_path'} which defaults to base_dir_abs. Should be +a path or an arrayref of paths to look the configuration file returned by +conf_file when that file is not absolute. + +=item conf_validation + +Used by default conf method. +Defaults to an empty hashref. If non-empty hashref is passed, the +hashref returned by conf_obj->read will be validated using the hashref +returned by conf_validation. + =item current_step (method) Returns the current step that the nav_loop is functioning on. @@ -1202,6 +1272,11 @@ called is "view". " view - post_print - post_print - 0.00003 - 0" ]; +=item error_step (method) + +Defaults to "__error". The name of a step to run should a dying error +be caught by the default handle_error method. See the handle_error method. + =item exit_nav_loop (method) This method should not normally used but there is no problem with @@ -1209,10 +1284,16 @@ using it on a regular basis. Essentially it is a "goto" that 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 +->goto_step functionality. If the application has morphed, it will be unmorphed before returning. Also - the post_navigate method will still be called. +=item ext_conf + +Used by the default conf_file method. Defaults to $self->{'ext_conf'} which +defaults to 'pl' meaning that the read configuration file should return a +valid perl hashref. + =item ext_print (method) Added as suffix to "name_step" during the default file_print hook. @@ -1235,40 +1316,6 @@ then the file "foo.val" will be searched for. See the section on FINDING TEMPLATES for further discussion. -=item first_step (method) - -Returns the first step of the path. Note that first_step may not be the same -thing as default_step if the path was overridden. - -=item form (method) - -Returns a hashref of the items passed to the CGI. Returns -$self->{form} which defaults to CGI::Ex::get_form. - -=item handle_error (method) - -If anything dies during execution, handle_error will be called with -the error that had happened. Default action is to die with that error. - -=item history (method) - -Returns an arrayref which contains trace history of which hooks of -which steps 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. - -The dump_history method shows a short condensed version of this -history which makes it easier to see what path was followed. - -In general, the arrayref is free for anything to push onto which will -help in tracking other occurrences in the program as well. - -=item init (method) - -Called by the default new method. Allows for any object -initilizations that may need to take place. Default action does -nothing. - =item fill_args (hook) Returns a hashref of args that will be passed to the CGI::Ex::Fill::fill. @@ -1292,15 +1339,15 @@ Returns a filename of the content to be used in the default print hook. Adds method base_dir_rel to hook name_module, and name_step and adds on the default file extension found in $self->ext_print which defaults to the property $self->{ext_print} which will default to -".html". Should return a filename relative to base_dir_abs that can be +".html". Should return a filename relative to template_path that can be swapped using Template::Alloy, or should be a scalar reference to the template content that can be swapped. This will be used by the hook print. - sub base_dir_abs { '/var/www/templates' } - sub base_dir_rel { 'content' } - sub name_module { 'recipe' } - sub ext_print { 'html' } # default + sub template_path { '/var/www/templates' } + sub base_dir_rel { 'content' } + sub name_module { 'recipe' } + sub ext_print { 'html' } # default # ->file_print('this_step') # would return 'content/recipe/this_step.html' @@ -1313,18 +1360,19 @@ the data for the application in a single location. =item file_val (hook) -Returns a filename containing the validation. Performs the same -as file_print, but uses ext_val to get the extension, and it adds -base_dir_abs onto the returned value (file_print is relative to -base_dir_abs, while file_val is fully qualified with base_dir_abs). -If base_dir_abs returns an arrayref of paths, then each path is -checked for the existence of the file. +Returns a filename containing the validation. Performs the same as +file_print, but uses ext_val to get the extension, and it adds +vob_path (which defaults to template_path which defaults to +base_dir_abs) onto the returned value (file_print is relative to +template_path, while file_val is fully qualified with vob_path). If +vob_path returns an arrayref of paths, then each path is checked for +the existence of the file. The file should be readable by CGI::Ex::Validate::get_validation. This hook is only necessary if the hash_validation hook has not been overridden. - +5B This method an also return a hashref containing the validation - but then you may have wanted to override the hash_validation hook. @@ -1368,12 +1416,22 @@ override the base package (it is still OK to use the full method name See the run_hook method and the morph method for more details. +=item first_step (method) + +Returns the first step of the path. Note that first_step may not be the same +thing as default_step if the path was overridden. + =item forbidden_step (method) Defaults to "__forbidden". The name of a step to run should the current step name be invalid, or if a step found by the default path method is invalid. See the path method. +=item form (method) + +Returns a hashref of the items passed to the CGI. Returns +$self->{form} which defaults to CGI::Ex::get_form. + =item form_name (hook) Return the name of the form to attach the js validation to. Used by @@ -1433,6 +1491,69 @@ Full customization of the login process and the login template can be done via the auth_args hash. See the auth_args method and CGI::Ex::Auth perldoc for more information. +=item goto_step (method) + +This method is not normally used but can solve some difficult issues. +It provides for moving to another step at any point during the +nav_loop. Once a goto_step has been called, the entire nav_loop will +be exited (to simply replace a portion of a step, you can simply +run_hook('run_step', 'other_step')). The method goto_step 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). Normally you would allow the other hooks in the loop +to carry on their normal functions and avoid goto_step. (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 to do this). + +The method jump is an alias for this method. + +Goto_step takes a single argument which is the location in the path to +jump to. This argument may be either a step name, the special strings +"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 goto_step). 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 returned by ->path is modified to allow +for the jumping (the path is modified so that the path history is not +destroyed - if we were on step 3 and jumped to one, that path would +contain 1, 2, 3, *1, 2, 3, 4, etc and we would be at the *). If a +step name is not currently on the path, it will be replace any remaining +steps of the path. + + # goto previous step (repeat it) + $self->goto_step($self->previous_step); + $self->goto_step('PREVIOUS'); + $self->goto_step(-1); + + # goto next step + $self->goto_step($self->next_step); + $self->goto_step('NEXT'); + $self->goto_step(1); + $self->goto_step; + + # goto current step (repeat) + $self->goto_step($self->current_step); + $self->goto_step('CURRENT'); + $self->goto_step(0); + + # goto last step + $self->goto_step($self->last_step); + $self->goto_step('LAST'); + + # goto first step (repeat it) + $self->goto_step($self->first_step); + $self->goto_step('FIRST'); + +=item handle_error (method) + +If anything dies during execution, handle_error will be called with +the error that had happened. Default action is to try running the +step returned by the error_step method. + =item hash_base (hook) A hash of base items to be merged with hash_form - such as pulldown @@ -1525,6 +1646,19 @@ pass it to CGI::Ex::Validate::get_validation. If no file_val is returned or if the get_validation fails, an empty hash will be returned. Validation is implemented by ->vob which loads a CGI::Ex::Validate object. +=item history (method) + +Returns an arrayref which contains trace history of which hooks of +which steps 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. + +The dump_history method shows a short condensed version of this +history which makes it easier to see what path was followed. + +In general, the arrayref is free for anything to push onto which will +help in tracking other occurrences in the program as well. + =item info_complete (hook) Calls the ready_validate hook to see if data is ready to validate. If @@ -1532,6 +1666,22 @@ so it calls the validate hook to validate the data. Should make sure the data is ready and valid. Will not be run unless prepare returns true (default). +=item init (method) + +Called by the default new method. Allows for any object +initilizations that may need to take place. Default action does +nothing. + +=item init_from_conf (method) + +Called by the default new method. If load_conf is true, then the +conf method will be called and the keys returned will be added to +the $self object. + +This method is called after the init method. If you need to further +fix up values added during init_from_conf, you can use the pre_navigate +method. + =item insert_path (method) Arguments are the steps to insert. Can be called any time. Inserts @@ -1556,76 +1706,32 @@ default "path" handler. =item js_validation (hook) -Requires JSON or YAML. Will return Javascript that is capable of -validating the form. This is done using the capabilities of -CGI::Ex::Validate. This will call the hook hash_validation which will -then be encoded either json or into yaml and placed in a javascript -string. It will also call the hook form_name to determine which html -form to attach the validation to. The method js_uri_path is called to -determine the path to the appropriate validate.js files. If the -method ext_val is htm, then js_validation will return an empty string -as it assumes the htm file will take care of the validation itself. -In order to make use of js_validation, it must be added to the -variables returned by either the hash_base, hash_common, hash_swap or -hash_form hook (see examples of hash_base used in this doc). - -By default it will try and use JSON first and then fail to YAML and -then will fail to returning an html comment that does nothing. +Will return Javascript that is capable of validating the form. This +is done using the capabilities of CGI::Ex::Validate and +CGI::Ex::JSONDump. This will call the hook hash_validation which will +then be encoded into json and placed in a javascript string. It will +also call the hook form_name to determine which html form to attach +the validation to. The method js_uri_path is called to determine the +path to the appropriate validate.js files. In order to make use of +js_validation, it must be added to the variables returned by either +the hash_base (default), hash_common, hash_swap or hash_form hook (see +examples of hash_base used in this doc). =item jump (method) -This method should not normally be used but is fine to use it on a -regular basis. 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 -to do this). - -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 strings -"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 returned by ->path is modified to allow for the -jumping (the path is modified so that the path history is not destroyed -- if we were on step 3 and jumped to one, that path would contain -1, 2, 3, *1, 2, 3, 4, etc and we would be at the *). - - ### 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'); +Alias for the goto_step method. =item last_step (method) -Returns the last step of the path. Can be used to jump to the last step. +Returns the last step of the path. + +=item load_conf (method) + +Defaults to ->{load_conf} which defaults to false. If true, will +allow keys returned by the conf method to be added to $self during +the init_from_conf method. + +Enabling this method allows for out-of-the-box file based configuration. =item morph (method) @@ -1640,9 +1746,9 @@ the step name to allow_morph. 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: +object can morph several levels deep. 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 morph_package hook (which would default to returning Foo::Bar::MyStep in this case) @@ -1660,58 +1766,12 @@ re-blesses the object into the original package. Samples of allowing morph: - sub allow_morph { 1 } + sub allow_morph { 1 } # value of 1 means try to find package, ok if not found sub allow_morph { {edit => 1} } sub allow_morph { my ($self, $step) = @_; return $step eq 'edit' } -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 { - my $self = shift; - if ($ENV{'PATH_INFO'} && $ENV{'PATH_INFO'} =~ s|^/(\w+)||) { - my $step = $1; - $self->morph($step); - $ENV{'PATH_INFO'} = "/$step"; - $self->stash->{'base_morphed'} = 1; - } - return 0; - } - - sub post_navigate { - my $self = shift; - $self->unmorph if $self->stash->{'base_morphed'}; - } - -If this code was in a module Base.pm and the cgi running was cgi/base -and called: - - Base->navigate; - -and you created a sub module that inherited Base.pm called -Base/Ball.pm -- you could then access it using cgi/base/ball. You -would be able to pass it steps using either cgi/base/ball/step_name or -cgi/base/ball?step=step_name - Or Base/Ball.pm could implement its -own path. It should be noted that if you do an early morph, it is -suggested to provide a call to unmorph. And if you want to let your -early morphed object morph again - you will need to provide - - sub allow_nested_morph { 1 } - -With allow_nested_morph enabled you could create the file -Base/Ball/StepName.pm which inherits Base/Ball.pm. The Base.pm, with -the custom init and default path method, would automatically morph us -first into a Base::Ball object (during init) and then into a -Base::Ball::StepName object (during the navigation loop). - -Since it is complicated to explain - it may be a bit complicated to -those who will try to follow your code later. CGI::Ex::App provides -many ways to do things, but use the best one for your situation. - =item morph_package (hook) Used by morph. Return the package name to morph into during a morph @@ -1791,11 +1851,8 @@ object has been blessed to allow for any other initilizations. =item next_step (hook and method) -Returns the next step in the path. If there is no next step, it -returns the default_step. - -It can be used as a method to return the next step in the path -to pass to a method such as ->jump. +As a method it returns the next step in the path - if the path +has more steps left. It is also used as a hook by the refine_path hook. If there is no more steps, it will call the next_step hook to try and find a step to @@ -1969,16 +2026,26 @@ List the step previous to this one. Will return '' if there is no previous step =item print (hook) -Take the information generated by prepared_print, format it, and print -it out. Default incarnation uses CGI::Ex::Template (a subclass of -Template::Alloy) which is compatible with Template::Toolkit. -Arguments are: step name (used to call the file_print hook), swap -hashref (passed to call swap_template), and fill hashref (passed to -fill_template). +Take the information generated by prepared_print, format it using +swap_template, fill it using fill_template and print it out using +print_out. Default incarnation uses Template::Alloy which is +compatible with Template::Toolkit to do the swapping. Arguments are: +step name (used to call the file_print hook), swap hashref (passed to +call swap_template), and fill hashref (passed to fill_template). During the print call, the file_print hook is called which should return a filename or a scalar reference to the template content is +=item print_out (hook) + +Called with the finished document. Should print out the appropriate headers. +The default method calls $self->cgix->print_content_type and then +prints the content. + +The print_content_type is passed $self->mimetype (which defaults to +$self->{'mimetype'} which defaults to 'text/html') and $self->charset +(which defaults to $self->{'charset'} which defaults to ''). + =item ready_validate (hook) Should return true if enough information is present to run validate. @@ -1991,6 +2058,13 @@ and check for its presence - such as the following: Changing the behavior of ready_validate can help in making wizard type applications. +You can also use the validate_when_data hook to change the behavior of +ready_validate. If valiate_when_data returns true, then +ready_validate will look for keys in the form matching keys that are +in hash_validation - if they exist ready_validate will be true. If +there are no hash_validation keys, ready_validate uses its default +behavior. + =item refine_path (hook) Called at the end of nav_loop. Passed a single value indicating @@ -2011,11 +2085,11 @@ go to the _edit_success step. =item recurse_limit (method) Default 15. Maximum number of times to allow nav_loop to call itself. -The recurse level will increase every time that ->jump is called, or if +The recurse level will increase every time that ->goto_step is called, or if the end of the nav_loop is reached and the process tries to add the default_step and run it again. -If ->jump is used often - the recurse_limit will be reached more +If ->goto_step is used often - 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. @@ -2144,6 +2218,21 @@ run_hook, it is possible to logically override methods on a step by step basis, or override a method for all of the steps, or even to break code out into separate modules. +=item run_hook_as (method) + +Similar to run_hook - but allows for temporarily running a +hook in another package. + + sub blah_morph_package { 'SomeOther::Module' } + my $hash = $self->run_hook_as('hash_swap', 'blah'); # runs as SomeOther::Module + + # OR + + my $hash = $self->run_hook_as('hash_swap', 'SomeOther::Module'); + +Note that the second form will use 'SomeOther::Module' as the step name +which will be somewhat misleading in looking up names. + =item run_step (hook) Runs all of the hooks specific to each step, beginning with pre_step @@ -2167,8 +2256,11 @@ This method is not normally used. =item set_ready_validate (hook and method) Sets that the validation is ready (or not) to validate. Should set the value -checked by the hook ready_validate. The following would complement the -processing flag above: +checked by the hook ready_validate. Has no affect if validate_when_data +flag is set. + +The following would complement the "processing" flag example given in +ready_validate description: sub set_ready_validate { my $self = shift; @@ -2215,19 +2307,18 @@ method to look for in the form. Default value is 'step'. =item swap_template (hook) Takes the template and hash of variables prepared in print, and -processes them through the current template engine (default engine is -CGI::Ex::Template a subclass of Template::Alloy). +processes them through the current template engine Template::Alloy. Arguments are the template and the swap hashref. The template can be either a scalar reference to the actual content, or the filename of the content. If the filename is specified - it should be relative to -base_dir_abs (which will be used to initialize INCLUDE_PATH by +template_path (which will be used to initialize INCLUDE_PATH by default). The default method will create a template object by calling the template_args hook and passing the returned hashref to the template_obj method. The default template_obj method returns a -CGI::Ex::Template object, but could easily be swapped to use a +Template::Alloy object, but could easily be swapped to use a Template::Toolkit based object. If a non-Template::Toolkit compatible object is to be used, then the swap_template hook can be overridden to use another templating engine. @@ -2247,7 +2338,7 @@ method as follows: my $t = HTML::Template->new(source => $file, type => $type, - path => $self->base_dir_abs, + path => $self->template_path, die_on_bad_params => 0, ); @@ -2256,8 +2347,8 @@ method as follows: return $t->output; } -As of version 2.13 of CGI::Ex::Template you could also simply do the -following to parse the templates using HTML::Template::Expr syntax. +Uou could also simply do the following to parse the templates using +HTML::Template::Expr syntax. sub template_args { return {SYNTAX => 'hte'}; @@ -2267,12 +2358,12 @@ For a listing of the available syntaxes, see the current L docu =item template_args (hook) -Returns a hashref of args that will be passed to the "new" method of CGI::Ex::Template. +Returns a hashref of args that will be passed to the "new" method of Template::Alloy The method is normally called from the swap_template hook. The swap_template hook -will add a value for INCLUDE_PATH which is set equal to base_dir_abs, if the INCLUDE_PATH +will add a value for INCLUDE_PATH which is set equal to template_path, if the INCLUDE_PATH value is not already set. -The returned hashref can contain any arguments that CGI::Ex::Template (a subclass of Template::Alloy) +The returned hashref can contain any arguments that Template::Alloy would understand. sub template_args { @@ -2287,10 +2378,9 @@ See the L documentation for a listing of all possible configura =item template_obj (method) Called from swap_template. It is passed the result of template_args -that have had a default INCLUDE_PATH added. The default -implementation uses CGI::Ex::Template (a subclass of Template::Alloy) -but can easily be changed to use Template::Toolkit by using code -similar to the following: +that have had a default INCLUDE_PATH added via template_path. The +default implementation uses Template::Alloy but can easily be changed +to use Template::Toolkit by using code similar to the following: use Template; @@ -2299,6 +2389,11 @@ similar to the following: return Template->new($args); } +=item template_path (method) + +Defaults to $self->{'template_path'} which defaults to base_dir_abs. Used by +the template_obj method. + =item unmorph (method) Allows for returning an object back to its previous blessed state if @@ -2350,6 +2445,14 @@ path. A validation item of: would append 'bar' and 'baz' to the path should all validation succeed. +=item validate_when_data (hook) + +Defaults to "validate_when_data" property which defaults to false. Called +during the ready_validate hook. If returns true, ready_validate will look +for keys in the form matching keys that are in hash_validation - if they exist +ready_validate will be true. If there are no hash_validation keys, ready_validate +uses its default behavior. + =item verify_user (method) Installed as a hook to CGI::Ex::App during get_valid_auth. Should return @@ -2452,8 +2555,7 @@ different. Seemingly the most well know of application builders. CGI::Ex::App is different in that it: - * Uses Template::Toolkit compatible CGI::Ex::Template (a - subclass of Template::Alloy) by default. + * Uses Template::Toolkit compatible Template::Alloy by default. CGI::Ex::App can easily use another toolkit by simply overriding the ->swap_template method. CGI::Application uses HTML::Template. @@ -2487,7 +2589,7 @@ There are actually many similarities. One of the nicest things about CGI::Prototype is that it is extremely short (very very short). The ->activate starts the application in the same manner as CGI::Ex::App's ->navigate call. Both use Template::Toolkit as the default template -system (CGI::Ex::App uses CGI::Ex::Template which is TT compatible). +system (CGI::Ex::App uses Template::Alloy which is TT compatible). CGI::Ex::App is differrent in that it: * Offers more hooks into the various phases of each step. @@ -2505,7 +2607,7 @@ CGI::Ex::App is differrent in that it: The following example shows the creation of a basic recipe database. It requires the use of DBD::SQLite, but that is all. -Once you have configured the db_file and base_dir_abs methods +Once you have configured the db_file and template_path methods of the "recipe" file, you will have a working script that does CRUD for the recipe table. The observant reader may ask - why not use Catalyst or Ruby on Rails? The observant programmer will @@ -2545,7 +2647,7 @@ the core logic of the application. debug shift->dump_history; } - sub base_dir_abs { '/var/www/templates' } + sub template_path { '/var/www/templates' } sub base_dir_rel { 'content' } @@ -3079,12 +3181,12 @@ the original versions. Krassimir Berov - feedback and some warnings issues with POD examples. -=head1 AUTHOR - -Paul Seamons - =head1 LICENSE This module may be distributed under the same terms as Perl itself. +=head1 AUTHOR + +Paul Seamons + =cut