]> Dogcows Code - chaz/p5-CGI-Ex/blobdiff - lib/CGI/Ex/App.pod
CGI::Ex 2.15
[chaz/p5-CGI-Ex] / lib / CGI / Ex / App.pod
index f44f9602b38d1274a4875699f0efe82bbba930fe..6fe97464e0e828e7d241fff509c46dcfe814ffd8 100644 (file)
@@ -4,6 +4,10 @@ CGI::Ex::App - Anti-framework application framework.
 
 =head1 SYNOPSIS
 
+A basic example:
+
+    -------- File: /cgi-bin/my_cgi --------
+
     #!/usr/bin/perl -w
 
     use strict;
@@ -13,22 +17,137 @@ CGI::Ex::App - Anti-framework application framework.
     exit;
 
     sub main_file_print {
-        return \ "Hello World";
+        return \ "Hello World!";
+    }
+
+Well, you should put your content in an external file...
+
+    -------- File: /cgi-bin/my_cgi --------
+
+    #!/usr/bin/perl -w
+
+    use strict;
+    use base qw(CGI::Ex::App);
+
+    __PACKAGE__->navigate;
+
+    sub base_dir_abs { '/var/www/templates' }
+
+
+    -------- File: /var/www/templates/my_cgi/main.html --------
+
+    Hello World!
+
+How about if we want to add substitutions...
+
+    -------- File: /cgi-bin/my_cgi --------
+
+    #!/usr/bin/perl -w
+
+    use strict;
+    use base qw(CGI::Ex::App);
+
+    __PACKAGE__->navigate;
+
+    sub base_dir_abs { '/var/www/templates' }
+
+    sub main_hash_swap {
+        my $self = shift;
+        return {
+            greeting => 'Hello',
+            date     => sub { scalar localtime },
+        };
+    }
+
+
+    -------- File: /var/www/templates/my_cgi/main.html --------
+
+    [% greeting %] World! ([% date %])
+
+
+How about a form with validation (inluding javascript validation)...
+
+    -------- File: /cgi-bin/my_cgi --------
+
+    #!/usr/bin/perl -w
+
+    use strict;
+    use base qw(CGI::Ex::App);
+
+    __PACKAGE__->navigate;
+
+    sub base_dir_abs { '/var/www/templates' }
+
+    sub main_hash_swap { {date => sub { scalar localtime }} }
+
+    sub main_hash_fill {
+        return {
+            guess => 50,
+        };
+    }
+
+    sub main_hash_validation {
+        return {
+            guess => {
+                required => 1,
+                compare1       => '<= 100',
+                compare1_error => 'Please enter a value less than 101',
+                compare2       => '>  0',
+                compare2_error => 'Please enter a value greater than 0',
+            },
+        };
     }
 
-There is a longer "SYNOPSIS" after the process flow discussion.
+    sub main_finalize {
+        my $self   = shift;
+        my $form   = $self->form;
+
+        $self->add_to_form({was_correct => ($form->{'guess'} == 23)});
+
+        return 0; # indicate to show the page without trying to move along
+    }
+
+
+    -------- File: /var/www/templates/my_cgi/main.html --------
+
+    <h2>Hello World! ([% date %])</h2>
+
+    [% IF was_correct %]
+       <b>Correct!</b> - The number was [% guess %].<br>
+    [% ELSIF guess %]
+       <b>Incorrect</b> - The number was not [% guess %].<br>
+    [% END %]
+
+    <form name="[% form_name %]" method="post">
+
+    Enter a number between 1 and 100: <input type="text" name="guess"><br>
+    <span id="guess_error" style="color:red">[% guess_error %]</span><br>
+
+    <input type="submit">
+    </form>
+
+    [% js_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.
 
 =head1 DESCRIPTION
 
-Fill in the blanks and get a ready made web application.  This module
-is somewhat similar in spirit to CGI::Application, CGI::Path, and
-CGI::Builder and any other "CGI framework."  As with the others,
-CGI::Ex::App tries to do as much of the mundane things, in a simple
-manner, without getting in the developer's way.  However, there are
-various design patterns for CGI applications that CGI::Ex::App handles
-for you that the other frameworks require you to bring in extra support.
-The entire CGI::Ex suite has been taylored to work seamlessly together.
-Your mileage in building applications may vary.
+Fill in the blanks and get a ready made web application.
+
+This module is somewhat similar in spirit to CGI::Application,
+CGI::Path, and CGI::Builder and any other "CGI framework."  As with
+the others, CGI::Ex::App tries to do as much of the mundane things, in
+a simple manner, without getting in the developer's way.  However,
+there are various design patterns for CGI applications that
+CGI::Ex::App handles for you that the other frameworks require you to
+bring in extra support.  The entire CGI::Ex suite has been taylored to
+work seamlessly together.  Your mileage in building applications may
+vary.
 
 If you build applications that submit user information, validate it,
 re-display it, fill in forms, or separate logic into separate modules,
@@ -40,8 +159,8 @@ to write any code, this module will help - but you still need to
 provide your key actions and html.
 
 One of the great benefits of CGI::Ex::App vs. Catalyst or Rails style
-frameworks is that the model of CGI::Ex::App can be much more abstract
-as models often are.
+frameworks is that the model of CGI::Ex::App can be much more abstract.
+And models often are abstract.
 
 =head1 DEFAULT PROCESS FLOW
 
@@ -83,6 +202,9 @@ The nav_loop method will run as follows:
 
         foreach step of path {
 
+            ->require_auth (hook)
+                # exits nav_loop if true
+
             ->morph
                 # check ->allow_morph
                 # check ->allow_nested_morph
@@ -184,7 +306,7 @@ Because of the hook based system, and because CGI::Ex::App uses
 sensible defaults, it is very easy to override a little or a lot which
 ends up giving the developer a lot of flexibility.
 
-Consequently, it should be possible to use CGI::Ex::App with the other
+Additionally, it should be possible to use CGI::Ex::App with the other
 frameworks such as CGI::Application or CGI::Prototype.  For these you
 could simple let each "runmode" call the run_step hook of CGI::Ex::App
 and you will instantly get all of the common process flow for free.
@@ -193,33 +315,33 @@ and you will instantly get all of the common process flow for free.
 
 The default out of the box configuration will map URIs to steps as follows:
 
-    # Assuming /cgi-bin/my_cgi is the program being run
+    # Assuming /cgi-bin/my_app is the program being run
 
-    URI:  /cgi-bin/my_cgi
+   URI:  /cgi-bin/my_app
     STEP: main
     FORM: {}
     WHY:  No other information is passed.  The path method is
           called which eventually calls ->default_step which
           defaults to "main"
 
-    URI:  /cgi-bin/my_cgi?foo=bar
+   URI:  /cgi-bin/my_app?foo=bar
     STEP: main
     FORM: {foo => "bar"}
     WHY:  Same as previous example except that QUERY_STRING
           information was passed and placed in form.
 
-    URI:  /cgi-bin/my_cgi?step=my_step
+   URI:  /cgi-bin/my_app?step=my_step
     STEP: my_step
     FORM: {step => "my_step"}
     WHY:  The path method is called which looks in $self->form
           for the key ->step_key (which defaults to "step").
 
-    URI:  /cgi-bin/my_cgi?step=my_step&foo=bar
+   URI:  /cgi-bin/my_app?step=my_step&foo=bar
     STEP: my_step
     FORM: {foo => "bar", step => "my_step"}
-    WHY:  Same as before but has other parameters were passed.
+    WHY:  Same as before but another parameter was passed.
 
-    URI:  /cgi-bin/my_cgi/my_step
+   URI:  /cgi-bin/my_app/my_step
     STEP: my_step
     FORM: {step => "my_step"}
     WHY:  The path method is called which called path_info_map_base
@@ -229,12 +351,12 @@ The default out of the box configuration will map URIs to steps as follows:
           $self->form->{$self->step_key} for the initial step. See
           the path_info_map_base method for more information.
 
-    URI:  /cgi-bin/my_cgi/my_step?foo=bar
+   URI:  /cgi-bin/my_app/my_step?foo=bar
     STEP: my_step
     FORM: {foo => "bar", step => "my_step"}
     WHY:  Same as before but other parameters were passed.
 
-    URI:  /cgi-bin/my_cgi/my_step?step=other_step
+   URI:  /cgi-bin/my_app/my_step?step=other_step
     STEP: other_step
     FORM: {step => "other_step"}
     WHY:  The same procedure took place, but when the PATH_INFO
@@ -252,7 +374,7 @@ that the following method is installed in your script.
         ];
     }
 
-    URI:  /cgi-bin/my_cgi/my_step/bar
+   URI:  /cgi-bin/my_app/my_step/bar
     STEP: my_step
     FORM: {foo => "bar"}
     WHY:  The step was matched as in previous examples using
@@ -262,7 +384,7 @@ that the following method is installed in your script.
           and the corresponding matched value was placed into
           the form using the keys specified following the regex.
 
-    URI:  /cgi-bin/my_cgi/my_step/bar/1234
+   URI:  /cgi-bin/my_app/my_step/bar/1234
     STEP: my_step
     FORM: {foo => "bar", id => "1234"}
     WHY:  Same as the previous example, except that the first
@@ -272,19 +394,19 @@ that the following method is installed in your script.
           order that will match the most data.  The third regex
           would also match this PATH_INFO.
 
-    URI:  /cgi-bin/my_cgi/my_step/some/other/type/of/data
+   URI:  /cgi-bin/my_app/my_step/some/other/type/of/data
     STEP: my_step
     FORM: {anything_else => 'some/other/type/of/data'}
     WHY:  Same as the previous example, except that the third
           regex matched.
 
-    URI:  /cgi-bin/my_cgi/my_step/bar?bling=blang
+   URI:  /cgi-bin/my_app/my_step/bar?bling=blang
     STEP: my_step
     FORM: {foo => "bar", bling => "blang"}
-    WHY:  Same as the first step, but additional QUERY_STRING
+    WHY:  Same as the first sample, but additional QUERY_STRING
           information was passed.
 
-    URI:  /cgi-bin/my_cgi/my_step/one%20two?bar=three%20four
+   URI:  /cgi-bin/my_app/my_step/one%20two?bar=three%20four
     STEP: my_step
     FORM: {anything_else => "one two", bar => "three four"}
     WHY:  The third path_info_map regex matched.  Note that the
@@ -303,8 +425,15 @@ how GET and POST parameters are parsed.
 See the path_info_map_base method, and path_info_map hook for more information
 on how the path_info maps function.
 
-A Dumper($self->dump_history) is very useful for determing what hooks have
-taken place.
+Using the following code is very useful for determing what hooks have
+taken place:
+
+   use CGI::Ex::Dump qw(debug);
+
+   sub post_navigate {
+       my $self = shift;
+       debug $self->dump_history, $self->form;
+   }
 
 =head1 ADDING DATA VALIDATION TO A STEP
 
@@ -314,7 +443,7 @@ for more information about the many ways you can validate your data.
 The default hash_validation hook returns an empty hashref.  This means that passed
 in data is all valid and the script will automatically call the step's finalize method.
 
-The following shows how to some contrived validation to a step called "my_step".
+The following shows how to add some contrived validation to a step called "my_step".
 
     sub my_step_hash_validation {
         return {
@@ -390,15 +519,19 @@ The following shows how to add variables using the hash_swap hook on the step "m
         };
     }
 
-You could also return the fields from the hash_common hook and they would be available
-in both the template swapping as well as form filling.
+You could also return the fields from the hash_common hook and they
+would be available in both the template swapping as well as form
+filling.
 
-See the hash_base, hash_common, hash_form, hash_swap, hash_errors, swap_template, and
-template_args hooks for more information.
+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 Template::Toolkit compatible.
-See the CGI::Ex::Template or Template::Toolkit documentation for the types of data
-that can be passed, and for the syntax that can be used.
+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<Template::Alloy> documentation
+for more information.
 
 =head1 ADDING ADDITIONAL FORM FILL VARIABLES
 
@@ -423,6 +556,132 @@ fill_args hooks for more information.
 The default form filler is CGI::Ex::Fill which is similar to HTML::FillInForm but
 has several benefits.  See the CGI::Ex::Fill module for the available options.
 
+=head1 FINDING TEMPLATES AND VALIDATION FILES
+
+CGI::Ex::App tries to help your applications use a good template directory layout, but allows
+for you to override everything.
+
+External template files are used for storing your html templates and
+for storing your validation files (if you use externally stored
+validation files).
+
+The default file_print hook will look for content on your file system,
+but it can also be completely overridden to return a reference to a
+scalar containing the contents of your file (beginning with version 2.14
+string references can be cached which makes templates passed this way
+"first class" citizens).  Actually it can return
+anything that Template::Alloy (Template::Toolkit compatible) will
+treat as input.  This templated html is displayed to the user during
+any step that enters the "print" phase.
+
+Similarly the default file_val hook will look for a validation file on
+the file system, but it too can return a reference to a scalar
+containing the contents of a validation file.  It may actually return
+anything that the CGI::Ex::Validate get_validation method is able to
+understand.  This validation is used by the default "info_complete"
+method for verifying if the submitted information passes its specific
+checks.  A more common way of inlining validation is to return a
+validation hash from a hash_validation hook override.
+
+If the default file_print and file_val hooks are used, the following methods
+are employed for finding templates and validation files on your filesystem (they
+are also documented more in the HOOKS AND METHODS section.
+
+=over 4
+
+=item base_dir_abs
+
+Absolute path or arrayref of paths to the base templates directory.  Default "".
+
+=item base_dir_rel
+
+Relative path inside of the base_dir_abs directory where content can be found.  Default "".
+
+=item name_module
+
+Directory inside of base_dir_rel where files for the current CGI (module) will be
+stored.  Default value is $ENV{SCRIPT_NAME} with path and extension removed.
+
+=item name_step
+
+Used with ext_print and ext_val for creating the filename that will be looked for
+inside of the name_module directory.  Default value is the current step.
+
+=item ext_print and ext_val
+
+Filename extensions added to name_step to create the filename looked for
+inside of the name_module directory.  Default is "html" for ext_print and "val"
+for ext_val.
+
+=back
+
+It may be easier to understand the usage of each of these methods by showing
+a contrived example.  The following is a hypothetical layout for your templates:
+
+    /home/user/templates/
+    /home/user/templates/chunks/
+    /home/user/templates/wrappers/
+    /home/user/templates/content/
+    /home/user/templates/content/my_app/
+    /home/user/templates/content/my_app/main.html
+    /home/user/templates/content/my_app/step1.html
+    /home/user/templates/content/my_app/step1.val
+    /home/user/templates/content/another_cgi/main.html
+
+In this example we would most likely set values as follows:
+
+    base_dir_abs  /home/user/templates
+    base_dir_rel  content
+    name_module   my_app
+
+The name_module method defaults to the name of the running program, but
+with the path and extension removed.  So if we were running
+/cgi-bin/my_app.pl, /cgi-bin/my_app, or /anypath/my_app, then
+name_module would default to "my_app" and we wouldn't have to
+hard code the value.  Often it is wise to set the value anyway so
+that we can change the name of the cgi script without effecting
+where template content should be stored.
+
+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
+    base_dir_rel  content
+    name_module   my_app
+    name_step     step1
+    ext_print     html
+    ext_val       val
+
+    file_print    content/my_app/step1.html
+    file_val      /home/user/templates/content/my_app/step1.val
+
+The call to the template engine would look something like
+the following:
+
+    my $t = $self->template_obj({
+        INCLUDE_PATH => $self->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).
+
+The call to the validation engine would pass the absolute
+filename that is returned by file_val.
+
+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
+    base_dir_rel
+    name_module   content/my_app
+
+In this case the same values would be returned for the file_print and file_val hooks
+as were returned in the previous setup.
+
 =head1 SYNOPSIS (A LONG "SYNOPSIS")
 
 This example script would most likely be in the form of a cgi, accessible via
@@ -534,7 +793,7 @@ Note: This example would be considerably shorter if the html file
 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 templating system other than CGI::Ex::Template).
+use a templating system other than Template::Alloy).
 
 =head1 SYNOPSIS STEP BY STEP
 
@@ -789,15 +1048,55 @@ was successful - so this data can be defined but false.
 
 See the get_valid_auth method.
 
+=item base_dir_abs (method)
+
+Used as the absolute base directory to find template files and validation 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 "".
+
+For example, to pass multiple paths, you would use something
+similar to the following:
+
+    sub base_dir_abs {
+        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.
+
+See the section on FINDING TEMPLATES for further discussion.
+
+=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
+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 section on FINDING TEMPLATES for further discussion.
+
 =item cleanup_user (method)
 
-Installed as a hook during get_valid_auth.  Allows for cleaning
+Used as a hook during get_valid_auth.  Allows for cleaning
 up the username.  See the get_valid_auth method.
 
-     sub cleanup_user {
-         my ($self, $user) = @_;
-         return lc $user;
-     }
+    sub cleanup_user {
+        my ($self, $user) = @_;
+        return lc $user;
+    }
 
 =item clear_app (method)
 
@@ -877,6 +1176,7 @@ called is "view".
     debug: admin/Recipe.pm line 14
     shift->dump_history = [
             "Elapsed: 0.00562",
+            "view - require_auth - require_auth - 0.00001 - 0",
             "view - run_step - run_step - 0.00488 - 1",
             "    view - pre_step - pre_step - 0.00003 - 0",
             "    view - skip - view_skip - 0.00004 - 0",
@@ -913,6 +1213,28 @@ hooks for the current and remaining steps.  It is used to allow the
 unmorphed before returning.  Also - the post_navigate method will
 still be called.
 
+=item ext_print (method)
+
+Added as suffix to "name_step" during the default file_print hook.
+
+Default value is 'html'.
+
+For example, if name_step returns "foo" and ext_print returns "html"
+then the file "foo.html" will be searched for.
+
+See the section on FINDING TEMPLATES for further discussion.
+
+=item ext_val (method)
+
+Added as suffix to "name_step" during the default file_val hook.
+
+Default value is 'val'.
+
+For example, if name_step returns "foo" and ext_val returns "val"
+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
@@ -971,7 +1293,7 @@ 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
-swapped using CGI::Ex::Template, or should be a scalar reference to
+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.
 
@@ -994,7 +1316,9 @@ the data for the application in a single location.
 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)
+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.
 
 The file should be readable by CGI::Ex::Validate::get_validation.
 
@@ -1064,8 +1388,7 @@ to the authentication object during the get_valid_auth method.
 
 =item get_valid_auth (method)
 
-If require_auth is true at either the application level or at the
-step level, get_valid_auth will be called.
+If require_auth hook returns true on any given step then get_valid_auth will be called.
 
 It will call auth_args to get some default args to pass to
 CGI::Ex::Auth->new.  It augments the args with sensible defaults that
@@ -1418,12 +1741,16 @@ have its own directory for storing html for its steps.
 
 See the file_print method for more information.
 
+See the section on FINDING TEMPLATES for further discussion.
+
 =item name_step (hook)
 
 Return the step (appended to name_module) that should used when
 looking up the file in file_print and file_val lookups.  Defaults to
 the current step.
 
+See the section on FINDING TEMPLATES for further discussion.
+
 =item nav_loop (method)
 
 This is the main loop runner.  It figures out the current path
@@ -1450,8 +1777,9 @@ This starts the process flow for the path and its steps.
 
 =item navigate_authenticated (method)
 
-Same as the method navigate but sets require_auth(1) before
-running.  See the require_auth method.
+Same as the method navigate but calls ->require_auth(1) before
+running.  It will only work if the navigate_authenticated method
+has not been overwritten. See the require_auth method.
 
 =item new (class method)
 
@@ -1641,11 +1969,12 @@ 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 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, 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).
 
 During the print call, the file_print hook is called which should
 return a filename or a scalar reference to the template content is
@@ -1699,45 +2028,104 @@ had been successfully validated and acted upon.
 Arguments are the steps used to replace.  Can be called any time.
 Replaces the remaining steps (if any) of the current path.
 
-=item require_auth (method)
+=item require_auth (hook)
 
-Default undef.  Can return either a true value or a hashref of step names.
+Defaults to self->{require_auth} which defaults to undef.
+If called as a method and passed a single value of 1, 0, or undef it will
+set the value of $self->{require_auth} to that value.  If set to a true
+value then any subsequent step will require authentication (unless its
+hook has been overwritten).
 
-If a hashref of stepnames is returned, authentication will be turned on
-at the step level.  In this mode if any step is accessed, the get_valid_auth
-method will be called.  If it fails, then the nav_loop will be stopped
-(the post_navigate method will be called - use the is_authed method to perform
-different functions).  Any step of the path not in the hash will not require
-authentication.  For example, to add authentication to add authentication
-to the add, edit and delete steps you could do:
+Any of the following ways can be used to require authentication on
+every step.
 
-    sub require_auth { {add => 1, edit => 1, delete => 1} }
+=over 4
 
-If a non-hash true value is returned from the require_auth method then
-authentication will take place before the pre_navigation or the nav_loop methods.
-If authentication fails the navigation process is exited (the post_navigate
-method will not be called).
+=item
 
     sub require_auth { 1 }
 
-Alternatively you can also could do either of the following:
+=item
 
     __PACKAGE__->navigate_authenticated; # instead of __PACKAGE__->navigate;
 
-    # OR
+=item
+
+    __PACKAGE__->new({require_auth => 1}->navigate;
+
+=item
 
     sub init { shift->require_auth(1) }
 
-    # OR
+=back
 
-    __PACKAGE__->new({require_auth => 1}->navigate;
+Because it is called as a hook, the current step is passed as the
+first argument.  If the hook returns false, no authentication will be
+required on this step.  If the hook returns a true, non-hashref value,
+authentication will be required via the get_valid_auth method.  If the
+method returns a hashref of stepnames to require authentication on,
+the step will require authentication via the get_valid_auth method if
+the current step is in the hashref.  If authentication is required and
+succeeds, the step will proceed.  If authentication is required and
+fails at the step level the current step will be aborted,
+authentication will be asked for (the post_navigate method will still
+be called).
+
+For example you could add authentication to the add, edit, and delete
+steps in any of the following ways:
 
-If get_valid_auth returns true, in either case, the is_authed method will
-return true and the auth_data will contain the authenticated user's data.
-If it returns false, auth_data may possibly contain a defined but false
-data object with details as to why authentication failed.
+=over 4
 
-See the get_valid_auth method.
+=item
+
+    sub require_auth { {add => 1, edit => 1, delete => 1} }
+
+=item
+
+    sub add_require_auth    { 1 }
+    sub edit_require_auth   { 1 }
+    sub delete_require_auth { 1 }
+
+=item
+
+    sub require_auth {
+        my ($self, $step) = @_;
+        return 1 if $step && $step =~ /^(add|edit|delete)$/;
+        return 0;
+    }
+
+=back
+
+If however you wanted to require authentication on all but one or two methods
+(such as requiring authentication on all but a forgot_password step) you could do
+either of the following:
+
+=over 4
+
+=item
+
+    sub require_auth {
+        my ($self, $step) = @_;
+        return 0 if $step && $step eq 'forgot_password';
+        return 1; # require auth on all other steps
+    }
+
+=item
+
+    sub require_auth { 1 } # turn it on for all steps
+
+    sub forgot_password_require_auth { 0 } # turn it off
+
+=back
+
+See the get_valid_auth method for what occurs should authentication be required.
+
+There is one key difference from the 2.14 version of App.  In 2.14 and
+previous versions, the pre_navigate and post_navigate methods would
+not be called if require_auth returned a true non-hashref value.  In
+version 2.15 and later, the 2.15 pre_navigate and post_navigate
+methods are always called - even if authentication fails.  Also in 2.15
+and later, the method is called as a hook meaning the step is passed in.
 
 =item run_hook (method)
 
@@ -1826,25 +2214,90 @@ 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).
+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).
+
+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
+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::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.
+
+For example to use the HTML::Template engine you could override the swap_template
+method as follows:
+
+    use HTML::Template;
+
+    sub swap_template {
+        my ($self, $step, $file, $swap) = @_;
+
+        my $type = UNIVERSAL::isa($file, 'SCALAR') ? 'scalarref'
+                 : UNIVERSAL::isa($file, 'ARRAY')  ? 'arrayref'
+                 : ref($file)                      ? 'filehandle'
+                 :                                   'filename';
+
+        my $t = HTML::Template->new(source => $file,
+                                    type   => $type,
+                                    path   => $self->base_dir_abs,
+                                    die_on_bad_params => 0,
+                                    );
 
-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.
+        $t->param($swap);
+
+        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.
+
+    sub template_args {
+        return {SYNTAX => 'hte'};
+    }
+
+For a listing of the available syntaxes, see the current L<Template::Alloy> documentation.
 
 =item template_args (hook)
 
 Returns a hashref of args that will be passed to the "new" method of CGI::Ex::Template.
-By default this hashref contains INCLUDE_PATH which is set equal to base_dir_abs.
-It can be augmented with any arguments that CGI::Ex::Template would understand.
-
-   sub template_args {
-       return {
-           INCLUDE_PATH => '/my/own/include/path',
-           WRAPPER => 'wrappers/main_wrapper.html',
-       };
-   }
+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
+value is not already set.
+
+The returned hashref can contain any arguments that CGI::Ex::Template (a subclass of Template::Alloy)
+would understand.
+
+    sub template_args {
+        return {
+            PRE_CHOMP => 1,
+            WRAPPER   => 'wrappers/main_wrapper.html',
+        };
+    }
+
+See the L<Template::Alloy> documentation for a listing of all possible configuration arguments.
+
+=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:
+
+    use Template;
+
+    sub template_obj {
+        my ($self, $args) = @_;
+        return Template->new($args);
+    }
 
 =item unmorph (method)
 
@@ -1999,7 +2452,8 @@ different.
 Seemingly the most well know of application builders.
 CGI::Ex::App is different in that it:
 
-  * Uses Template::Toolkit compatible CGI::Ex::Template by default
+  * Uses Template::Toolkit compatible CGI::Ex::Template (a
+      subclass of Template::Alloy) by default.
       CGI::Ex::App can easily use another toolkit by simply
       overriding the ->swap_template method.
       CGI::Application uses HTML::Template.
@@ -2212,7 +2666,7 @@ the core logic of the application.
             return 0;
         }
 
-        my $s = "UPDATE recipe SET title = ?, ingredients = ?, directions = ? WHERE id = ?";
+        $s = "UPDATE recipe SET title = ?, ingredients = ?, directions = ? WHERE id = ?";
         $self->dbh->do($s, {}, $form->{'title'},
                                $form->{'ingredients'},
                                $form->{'directions'},
@@ -2594,6 +3048,18 @@ will cause all steps to require validation):
 
     sub require_auth { {add => 1, edit => 1, delete => 1} }
 
+We could also enable authentication by using individual hooks as in:
+
+    sub add_require_auth    { 1 }
+    sub edit_require_auth   { 1 }
+    sub delete_require_auth { 1 }
+
+Or we could require authentication on everything - but let a few steps in:
+
+    sub require_auth { 1 }      # turn authentication on for all
+    sub main_require_auth { 0 } # turn it off for main and view
+    sub view_require_auth { 0 }
+
 That's it.  The add, edit, and delete steps will now require authentication.
 See the require_auth, get_valid_auth, and auth_args methods for more information.
 Also see the L<CGI::Ex::Auth> perldoc.
@@ -2603,16 +3069,22 @@ Also see the L<CGI::Ex::Auth> perldoc.
 The following corporation and individuals contributed in some part to
 the original versions.
 
-    Bizhosting.com - giving a problem that fit basic design patterns.
+    Bizhosting.com  - giving a problem that fit basic design patterns.
 
-    Earl Cahill    - pushing the idea of more generic frameworks.
+    Earl Cahill     - pushing the idea of more generic frameworks.
 
-    Adam Erickson  - design feedback, bugfixing, feature suggestions.
+    Adam Erickson   - design feedback, bugfixing, feature suggestions.
 
-    James Lance    - design feedback, bugfixing, feature suggestions.
+    James Lance     - design feedback, bugfixing, feature suggestions.
+
+    Krassimir Berov - feedback and some warnings issues with POD examples.
 
 =head1 AUTHOR
 
 Paul Seamons <paul at seamons dot com>
 
+=head1 LICENSE
+
+This module may be distributed under the same terms as Perl itself.
+
 =cut
This page took 0.046704 seconds and 4 git commands to generate.