|
|
| |
CGI::Framework(3) |
User Contributed Perl Documentation |
CGI::Framework(3) |
CGI::Framework - A simple-to-use, lightweight web CGI framework
It is primarily a glue between HTML::Template, CGI::Session, CGI,
Locale::Maketext and some magic :)
use CGI::Framework;
use vars qw($f);
#
# Setup the initial framework instance
#
$f = new CGI::Framework (
sessions_dir => "/tmp",
templates_dir => "/home/stuff/myproject/templates",
initial_template => "enterusername",
)
|| die "Failed to create a new CGI::Framework instance: $@\n";
#
# Get the instance to "do it's magic", including handling the verification of the
# just-submitting form, preparing the data for the upcoming template to be sent, and any cleanup
#
$f->dispatch();
#
# This sub is automatically called after the "enterusername" template is submitted by the client
#
sub validate_enterusername {
my $f = shift;
if (!$f->form("username")) {
$f->add_error("You must enter a username");
}
elsif (!$f->form("password")) {
$f->add_error("You must enter your password");
}
else {
if ($f->form("username") eq "mina" && $f->form("password") eq "verysecret") {
$f->session("username", "mina");
$f->session("authenticated", "1");
}
else {
$f->add_error("Authentication failed");
}
}
}
#
# This sub is automatically called before the "mainmenu" template is sent
#
sub pre_mainmenu {
my $f = shift;
$f->assert_session("authenticated");
$f->html("somevariable", "somevalue");
$f->html("name", $f->session("username"));
}
#
# This sub is automatically called after the "logout" template is sent
#
sub post_logout {
my $f = shift;
$f->clear_session();
}
CGI::Framework is a simple and lightweight framework for building web-based CGI
applications. It features complete code-content separation (templating) by
utilizing the HTML::Template library, stateful file or database-based sessions
by utilizing the CGI::Session library, form parsing by utilizing the CGI
library, (optional) multi-lingual templates support, and an extremely easy to
use methodology for the validation, pre-preparation and post-cleanup
associated with each template. It also provides easy logging mechanisms,
graceful fatal error handling, including special templates and emails to
admins.
Before we jump into the technical details, let's skim over the top-level
philosophy for a web application:
- The client sends an initial GET request to the web server
- The CGI recognizes that this is a new client, creates a new session, sends
the session ID to the client in the form of a cookie, followed by sending
a pre-defined initial template
- The user interacts with the template, filling out any form elements, then
re-submits the form back to the CGI
- The CGI reloads the session based on the client cookie, validates the form
elements the client is submitting. If any errors are found, the client is
re-sent the previous template along with error messages. If no errors were
found, the form values are either acted on, or stored into the session
instance for later use. The client is then sent the next template.
- The flow of templates can either be linear, where there's a straight
progression from template 1 to template 2 to template 3 (such as a simple
ordering form) or can be non-linear, where the template shown will be
based on one of many buttons a client clicks on (such as a main-menu
always visible in all the templates)
- Sessions should automatically expire if not loaded in X amount of time to
prevent unauthorized use.
Implementing this module usually consists of:
- Writing the stub code as per the SYNOPSIS. This entails creating a new
CGI::Framework instance, then calling the dispatch() method.
- Creating your templates in the templates_dir supplied earlier. Templates
should have the .html extension and can contain any templating variables,
loops, and conditions described in the HTML::Template documentation.
- For each template created, you can optionally write none, some or all of
the needed perl subroutines to interact with it. The possible subroutines
that, if existed, will be called automatically by the dispatch()
method are:
- validate_templatename()
- This sub will be called after a user submits the form from template
templatename. In this sub you should use the assert_session() and
assert_form() methods to make sure you have a sane environment
populated with the variables you're expecting.
After that, you should inspect the supplied input from the
form in that template. If any errors are found, use the
add_error() method to record your objections. If no errors are
found, you may use the session() or remember() methods to
save the form variables into the session for later utilization.
- pre_templatename()
- This sub will be called right before the template templatename is sent to
the browser. It's job is to call the html() method, giving it any
dynamic variables that will be interpolated by HTML::Template inside the
template content.
- post_templatename()
- This sub will be called right after the template templatename has been
sent to the browser and right before the CGI finishes. It's job is to do
any clean-up necessary after displaying that template. For example, on a
final-logout template, this sub could call the clear_session()
method to delete any sensitive information.
There are also 4 special sub names you can create:
- pre__pre__all()
- This sub will be called before any template is sent (and before
pre_templatename() is called). It is rarely needed to write or use
such a sub.
- post__pre__all()
- This sub will be called before any template is sent (and after
pre_templatename() is called). It is rarely needed to write or use
such a sub.
- pre__post__all()
- This sub will be called after any template is sent (and before
post_templatename() is called). It is rarely needed to write or use
such a sub.
- post__post__all()
- This sub will be called after any template is sent (and after
post_templatename() is called). It is rarely needed to write or use
such a sub.
If any of the above subroutines are found and called, they will be
passed 2 arguments: The CGI::Framework instance itself, and the name of the
template about to be/just sent.
If you're impatient, skip to the STARTING A NEW PROJECT FOR THE IMPATIENT
section below, however it is recommended you at least skim-over this detailed
section, especially if you've never used this module before.
The following steps should be taken to start a new project:
- SETUP DIRECTORY STRUCTURE
- This is the recommended directory structure for a new project:
- cgi-bin/
- This is where your CGI that use()es CGI::Framework will be placed.
CGIs placed there will be very simple, initializing a new CGI::Framework
instance and calling the dispatch() method. The CGIs should also
add lib/ to their 'use libs' path, then require pre_post and
validate.
- lib/
- This directory will contain 2 important files require()ed by the
CGIs, pre_post.pm and validate.pm. pre_post.pm should
contain all pre_templatename() and post_templatename()
routines, while validate.pm should contain all
validate_templatename() routines. This seperation is not
technically necessary, but is recommended. This directory will also
possibly contain localization.pm which will be a base sub-class of
Locale::Maketext if you decide to make your errors added via
add_error() localized to the use's language (refer to the
"INTERNATIONALIZATION AND LOCALIZATION" section). This directory
will also hold any custom .pm files you write for your project.
- templates/
- This directory will contain all the templates you create. Templates should
end in the .html extension to be found by the show_template() or
return_template() methods. More on how you should create the actual
templates in the CREATE TEMPLATES section
- sessions/
- If you decide to use file-based sessions storage (the default), this
directory will be the holder for all the session files. It's permissions
should allow the user that the web server runs as (typically
"nobody") to write to it.
The other alternative is for you to use MySQL-based sessions
storage, in which case you won't need to create this directory, but
instead initialize the database. More info about this in the
CONSTRUCTOR/INITIALIZER documentation section.
- public_html/
- This directory should contain any static files that your templates
reference, such as images, style sheets, static html links, multimedia
content, etc...
- CONFIGURE YOUR WEB SERVER
- How to do this is beyond this document due to the different web servers
out there, but in summary, you want to create a new virtual host, alias
the document root to the above public_html/ directory, alias
/cgi-bin/ to the above cgi-bin/ directory and make sure the server
will execute instead of serve files there, and in theory you're done.
- CREATE TEMPLATES
- You will need to create a template for each step you want your user to
see. Templates are regular HTML pages with the following additions:
- CGI::Framework required tags
- The CGI::Framework absolutely requires you insert these tags into the
templates. No ands, iffs or butts about it. The framework will NOT work if
you do not place these tags in your template:
- <cgi_framework_header>
- Place this tag right under the <body> tag
- <TMPL_INCLUDE NAME="errors.html">
- Place this tag wherever you want errors added with the add_error()
method to appear
- <cgi_framework_footer>
- Place this tag right before the </body> tag
It is recommended that you utilize HTML::Template's powerful
<TMPL_INCLUDE> tag to create base templates that are included at the
top and bottom of every template (similar to Server-Side Includes, SSIs).
This has the benefit of allowing you to change the layout of your entire
site by modifying only 2 files, as well as allows you to insert the above 3
required tags into the shared header and footer templates instead of having
to put them inside every content template.
- HTML::Template tags
- All tags mentioned in the documentation of the HTML::Template module may
be used in the templates. This allows dynamic variable substitutions,
conditionals, loops, and a lot more.
To use a variable in the template (IFs, LOOPs, etc..) , it
must either:
- Have just been added using the html() method, probably in the
pre_templatename() routine.
- Has just been submitted from the previous template
- Has been added in the past to the session using the session()
method.
- Has been added automatically for you by CGI::Framework. Refer to the
"PRE-DEFINED TEMPLATE VARIABLES" section.
- CGI::Framework language tags
- If you supplied a "valid_languages" arrayref to the new()
constructor of CGI::Framework, you can use any of the languages in that
arrayref as simple HTML tags. Refer to the "INTERNATIONALIZATION AND
LOCALIZATION" section.
- The process() javascript function
- This javascript function will become available to all your templates and
will be sent to the client along with the templates. Your templates should
call this function whenever the user has clicked on something that
indicates they'd like to move on to the next template. For example, if
your templates offer a main menu at the top with 7 options, each one of
these options should cause a call to this process() javascript
function. Every next, previous, logout, etc.. button should cause a call
to this function.
This javascript function accepts the following parameters:
- templatename
- MANDATORY
This first parameter is the name of the template to show. For
example, if the user clicked on an option called "show my account
info" that should load the accountinfo.html template, the
javascript code could look like this:
<a href="#" onclick="return process('accountinfo');">Show my account info</a>
or
<input type="button" value=" LIST MY ACCOUNT BALANCES >> " onclick="return process('accountbalances');">
- item
- OPTIONAL
If this second parameter is supplied to the process()
call, it's value will be available back in your perl code as key
"_item" through the form() method.
This is typically used to distinguish between similar choices.
For example, if you're building a GUI that allows the user to change the
password of any of their accounts, you could have something similar to
this:
bob@domain.com <input type="button" value="CHANGE PASSWORD" onclick="return process('changepassword', 'bob@domain.com');">
<br>
mary@domain.com <input type="button" value="CHANGE PASSWORD" onclick="return process('changepassword', 'mary@domain.com');">
<br>
john@domain.com <input type="button" value="CHANGE PASSWORD" onclick="return process('changepassword', 'john@domain.com');">
- skipvalidation
- OPTIONAL
If this third parameter is supplied to the process()
call with a true value such as '1', it will cause CGI::Framework to send
the requested template without first calling
validate_templatename() on the previous template and forcing the
correction of errors.
- The errors template
- It is mandatory to create a special template named errors.html.
This template will be included in all the served pages, and it's job is to
re-iterate over all the errors added with the add_error() method
and display them. A simple errors.html template looks like
this:
- errors.html sample:
-
<TMPL_IF NAME="_errors">
<font color=red><b>The following ERRORS have occurred:</b></font>
<blockquote>
<TMPL_LOOP NAME="_errors">
* <TMPL_VAR NAME="error"><br>
</TMPL_LOOP>
</blockquote>
<font color=red>Please correct below and try again.</font>
<p>
</TMPL_IF>
- The missing info template
- It is recommended, although not mandatory, to create a special template
named missinginfo.html. This template will be shown to the client
when an assertion made through the assert_form() or
assert_session() methods fail. It's job is to explain to the client
that they're probably using a timed-out session or submitting templates
out of logical order (possibly a cracking attempt), and invites them to
start from the beginning.
If this template is not found, the above error will be
displayed to the client in a text mode.
When this template is called due to a failed assertion by
assert_form() or assert_session(), 2 special variables:
_missing_info and _missing_info_caller, are available for use in the
missinginfo template. Refer to the "PRE-DEFINED TEMPLATE
VARIABLES" section for details.
- The fatal error template
- It is recommended, although not mandatory, to create a special template
called fatalerror.html and specify that name as the
fatal_error_template constructor key. Usually when a fatal error occurs it
will be caught by CGI::Carp and a trace will be shown to the browser. This
is often technical and is always an eyesore since it does not match your
site design. If you'd like to avoid that and show a professional
apologetic message when a fatal error occurs, make use of this fatal error
template feature.
See the "PRE-DEFINED TEMPLATE VARIABLES" section
below for an elaboration on the fatal error template and the special
variable _fatal_error that you could use in it.
- ASSOCIATE THE CODE WITH THE TEMPLATES
- For each template you created, you might need to write a
pre_templatename() sub, a post_templatename() sub and a
validate_templatename() sub as described earlier. None of these
subs are mandatory.
For clarity and consistency purposes, the
pre_templatename() and post_templatename() subs should go
into the pre_post.pm file, and the validate_templatename()
subs should go into the validate.pm file.
There are also 4 special sub names. pre__pre__all(),
post__pre__all(), pre__post__all() and
post__post__all(). If you create these subs, they will be called
before pre_templatename(), after pre_templatename(),
before post_templatename() and after post_templatename()
respectively for all templates.
- WRITE YOUR CGI
- Copying the SYNOPSIS into a new CGI file in the cgi-bin/ directory
is usually all that's needed unless you have some advanced requirements
such as making sure the user is authenticated first before allowing them
access to certain templates.
- TEST, FINE TUNE, ETC . . .
- Every developer does this part, right :) ?
This module allows you to use an object-oriented or a function-based approach
when using it. The only drawback to using the function-based mode is that
there's a tiny bit of overhead during startup, and that you can only have one
instance of the object active within the interpreter (which is not really a
logical problem since that is never a desirable thing. It's strictly a
technical limitation).
- THE OBJECT-ORIENTED WAY
- As the examples show, this is the object-way of doing things:
use CGI::Framework;
my $instance = new CGI::Framework (
this => that,
foo => bar,
);
$instance->dispatch();
sub validate_templatename {
my $instance = shift;
if (!$instance->form("country")) {
$instance->add_error("You must select a country");
}
else {
$instance->remember("country");
}
}
sub pre_templatename {
my $instance = shift;
$instance->html("country", [qw(CA US BR)]);
}
- THE FUNCTION-BASED WAY
- The function-based way is very similar (and slightly less cumbersome to
use due to less typing) than the OO way. The differences are: You have to
use the ":nooop" tag in the use() line to signify that
you want the methods exported to your namespace, as well as use the
initialize_cgi_framework() method to initialize the instance
instead of the new() method in OO mode. An example of the
function-based way of doing things:
use CGI::Framework ':nooop';
initialize_cgi_framework (
this => that,
foo => bar,
);
dispatch();
sub validate_templatename {
if (!form("country")) {
add_error("You must select a country");
}
else {
remember("country");
}
}
sub pre_templatename {
html("country", [qw(CA US BR)]);
}
- new(%hash)
- This is the standard object-oriented constructor. When called, will return
a new CGI::Framework instance. It accepts a hash (or a hashref) with the
following keys:
- action
- OPTIONAL
If this key is supplied, it should contain the value to be
used in the <form> HTML element's "action" parameter. If
not supplied, it will default to environment variable SCRIPT_NAME
- callbacks_namespace
- OPTIONAL
This key should have a scalar value with the name of the
namespace that you will put all the validate_templatename(),
pre_templatename(), post_templatename(),
pre__pre__all(), post__pre__all(), pre__post__all()
and post__post__all() subroutines in. If not supplied, it will
default to the caller's namespace. Finally if the caller's namespace
cannot be determined, it will default to "main".
The main use of this option is to allow you, if you so choose,
to place your callbacks subs into any arbitrary namespace you decide on
(to avoid pollution of your main namespace for example).
- cookie_domain
- OPTIONAL
The key should have a scalar value with the domain that
cookie_name is set to. If not supplied the cookie will not be assigned
to a specific domain, essentially making tied to the current
hostname.
- cookie_name
- OPTIONAL
This key should have a scalar value with the name of the
cookie to use when communicating the session ID to the client. If not
supplied, will default to "sessionid_" and a simplified
representation of the URL.
- disable_back_button
- OPTIONAL
This key should have a scalar value that's true (such as 1) or
false (such as 0). Setting it to true will instruct the framework not to
allow the user to use their browser's back button. This is done by
setting no-cache pragmas on every page served, setting a past expiry
date, as well as detecting submissions from previously-served templates
and re-showing the last template sent.
This behaviour is often desired in time-sensitive web
applications.
- expire
- OPTIONAL
Set this to a value that will be passed to CGI::Session's
expire() method. If supplied and contains non-digits (such as
"+2h") it will be passed verbatim. If supplied and is digits
only, it will be passed as minutes. If not supplied will default to
"+15m"
- fatal_error_email
- OPTIONAL
If you would like to receive an email when a fatal error
occurs, supply this key with a value of either a scalar email address,
or an arrayref of multiple email addresses. You will also need to supply
the smtp_host key and/or the sendmail key.
- fatal_error_template
- OPTIONAL
Normally fatal errors (caused by a die() anywhere in
the program) are captured by CGI::Carp and sent to the browser along
with the web server's error log file. If this key is supplied, it's
value should be a template name. That template would then be showed
instead of the normal CGI::Carp error message. When the template is
called, the special template variable _fatal_error will be set. This
will allow you to optionally show or not show it by including it in the
template content.
- initial_template
- MANDATORY
This key should have a scalar value with the name of the first
template that will be shown to the client when the dispatch()
method is called. It can be changed after initialization with the
initial_template() method before the dispatch() method is
called.
- import_form
- OPTIONAL
This variable should have a scalar value with the name of a
namespace in it. It imports all the values of the just-submitted form
into the specified namespace. For example:
import_form => "FORM",
You can then use form elements like:
$error = "Sorry $FORM::firstname, you may not $FORM::action at this time.";
It provides a more flexible alternative to using the
form() method since it can be interpolated inside double-quoted
strings, however costs more memory. I am also unsure about how such a
namespace would be handled under mod_perl and if it'll remain persistent
or not, possibly causing "variable-bleeding" problems across
sessions.
- log_filename
- OPTIONAL
This variable should have a scalar value with a
fully-qualified filename in it. It will be used by the log_this()
method as the filename to log messages to. If supplied, make sure that
it is writeable by the user your web server software runs as.
- maketext_class_name
- OPTIONAL
If you wish to localize errors you add via the
add_error() method, this key should contain the name of the class
you created as the Locale::Maketext localization class, such as for
example "MyProject::L10N" or
"MyProjectLocalization". Refer to the
"INTERNATIONALIZATION AND LOCALIZATION" section. You must also
set the "valid_languages" key if you wish to set this key.
- output_filter
- OPTIONAL
If you would like to do any manual hacking to the content just
before it's sent to the browser, this key should contain the name of a
sub (or a reference to a sub) that you'd like to have the framework
call. The sub will be passed 2 argumets: The CGI::Framework instance
itself, and a reference to a scalar containing the content about to be
sent.
- sendmail
- OPTIONAL
If you supplied the fatal_error_email key, you must also
supply this key and/or the smtp_host key. If you'd like to deliver the
mail using sendmail, supply this key with a value of the fully qualified
path to your sendmail binary.
- sessions_dir
- OPTIONAL
This key should have a scalar value holding a directory name
where the session files will be stored. If not supplied, a suitable
temporary directory will be picked from the system.
Note: You may not supply this if you supply the
sessions_mysql_dbh key.
- sessions_mysql_dbh
- OPTIONAL
This key should have a value that's a MySQL DBH (DataBase
Handle) instance created with the DBI and DBD::Mysql modules. If
supplied then the session data will be stored in the mysql table instead
of text files. For more information on how to prepare the database,
refer to the CGI::Session::MySQL documentation.
Note: You may not supply this if you supply the sessions_dir
key.
- sessions_serializer_default
- OPTIONAL
This key should be set to true if you wish to use the default
serialization method for your sessions. This requires the perl module
Data::Dumper. For more information refer to the
CGI::Session::Serialize::Default documentation.
Note: You may not supply this if you supply the
sessions_serializer_storable or sessions_serializer_freezethaw keys.
- sessions_serializer_freezethaw
- OPTIONAL
This key should be set to true if you wish to use the
FreezeThaw serialization method for your sessions. This requires the
perl module FreezeThaw. For more information refer to the
CGI::Session::Serialize::FreezeThaw documentation.
Note: You may not supply this if you supply the
sessions_serializer_default or sessions_serializer_storable keys.
- sessions_serializer_storable
- OPTIONAL
This key should be set to true if you wish to use the Storable
serialization method for your sessions. This requires the perl module
Storable. For more information refer to the
CGI::Session::Serialize::Storable documentation.
Note: You may not supply this if you supply the
sessions_serializer_default or sessions_serializer_freezethaw keys.
- smtp_from
- OPTIONAL
If your mail server supplied in smtp_host is picky about the
"from" address it accepts emails from, set this key to a
scalar email address value. If not set, the email address
'cgiframework@localhost' will be set as the from-address.
- smtp_host
- OPTIONAL
If you supplied the fatal_error_email key, you must also
supply this key and/or the sendmail key. If you'd like to deliver the
mail using direct SMTP transactions (and have Net::SMTP installed),
supply this key with a value of the hostname of the mailserver to
connect to.
If your mailserver is picky about the "from" address
it accepts mail from, you should also supply the smtp_from key when
using this key, otherwise 'cgiframework@localhost' will be supplied as
the from address.
- templates_dir
- OPTIONAL
This key should have a scalar value holding a directory name
which contains all the template files. If not supplied, it will be
guessed based on the local directory.
- valid_languages
- OPTIONAL
This key should have an arrayref value. The array should
contain all the possible language tags you've used in the templates.
Refer to the "INTERNATIONALIZATION AND LOCALIZATION" section.
You must set this key if you wish to also set the
"maketext_class_name" key.
- initialize_cgi_framework(%hash)
- Just like the above new() constructor, except used in the
function-based approach instead of the object-oriented approach.
- add_error($scalar [, @array ] )
- This method accepts a scalar error and adds it to the list of errors that
will be shown to the client. It should only be called from a
validate_templatename() subroutine for each error found during
validating the form. This will cause the dispatch() method to
re-display the previous template along with all the errors added.
If you specified the "valid_languages" and the
"maketext_class_name" keys to the initializer, the error
message you give to this method will be localized to the user's
preferred language (or the default language) before being showed to the
user. Refer to the "INTERNATIONALIZATION AND LOCALIZATION"
section. If this is the case, you may specify extra arguments after the
main $scalar, and they will be passed verbatim
to Locale::Maketext's maketext() method - this is often used to
localize variables within a sentence.
- assert_form(@array)
- This method accepts an array of scalar values. Each element will be
checked to make sure that it has been submitted in the just-submitted form
and has a true value. If any elements aren't found or have a false value,
the missinginfo template is shown to the client. The missinginfo template
will be passed special variables _missing_info and _missing_info_caller
which you can use to display details about the failed assertions. Refer to
the "PRE-DEFINED TEMPLATE VARIABLES" section for more info.
- assert_session(@array)
- Just like the assert_form() method, except it checks the values
against the session instead of the submitted form.
- clear_session
- This method deletes all the previously-stored values using the
session() or remember() methods.
- dispatch
- This method is the central dispatcher. It calls validate_templatename on
the just-submitted template, checks to see if any errors were added with
the add_error() method. If any errors were added, re-sends the
client the previous template, otherwise sends the client the template they
requested.
- finalize
- This method undefs some internal references that prevent the object from
being destroyed. It's called automatically for you when
show_template() is done or if there's a fatal error, so there is
usually no need to call it manually.
This method exit()s when done - it does not return.
- form($scalar)
- This method accepts an optional scalar as it's first argument, and returns
the value associated with that key from the just-submitted form from the
client. If no scalar is supplied, returns all entries from the
just-submitted form.
- get_cgi_object
- Returns the underlying CGI object. To be used if you'd like to do anything
fancy this module doesn't provide methods for, such as processing extra
cookies, etc...
- get_cgi_session_object
- Returns the underlying CGI::Session object. To be used if you'd like to do
anything fancy this module doesn't provide methods for.
- html($scalar, $scalar)
- This method accepts a scalar key as it's first argument and a scalar value
as it's second. It associates the key with the value in the upcoming
template. This method is typically called inside a pre_template()
subroutine to prepare some dynamic variables/loops/etc in the templatename
template.
- html_push($scalar, $scalar)
- Very similar to the above html() method, except it treats the key's
value as an arrayref (creates it as an arrayref if it didn't exist), and
push()es the value into that array. This method is typically used
to append to a key that will be used in a template loop with
HTML::Template's <TMPL_LOOP> tag, the value in which case is
normally a hashref.
- html_unshift($scalar, $scalar)
- Very similar to the above html_push() method, except it
unshift()s instead of push()es the value.
- log_this($scalar)
- This method accepts a scalar message and logs it to the filename specified
in the log_filename parameter in the new constructor. You can not use this
method if you have not supplied a log_filename setting to the
constructor.
- remember($scalar [, $scalar])
- This method accepts a mandatory scalar source key name as it's first
argument and an optional scalar destination key name as it's second
argument . It then treats that source scalar as a key in the
just-submitted form, and saves that key-value pair into the session. This
method is simply shorthand for saying:
$instance->session($sourcekeyname, $instance->form($sourcekeyname));
If the second optional parameter is supplied, then that
destination key is used in the session. This allows the key saved in the
session to have a different name than the one submitted in the form. In
that case, this method becomes a shorthand for:
$instance->session($destinationekeyname, $instance->form($sourcekeyname));
It is frequently used to premanently save a submitted form
key+value inside the validate_templatename() sub after it has
been checked for correctness.
- return_template($scalar)
- This method accepts a scalar template name, and returns the content parsed
from that template suitable for sending to the client. Internally it takes
care of language substitution, and the <cgi_framework_header>,
<cgi_framework_footer> tags.
In scalar context it returns the content suitable for sending
to the client. In array context it returns the content and the
content-type.
- session($scalar [, $scalar])
- This method accepts a scalar key as it's first argument and an optional
scalar value as it's second. If a value is supplied, it saves the
key+value pair into the session for future retrieval. If no value is
supplied, it returns the previously-saved value associated with the given
key.
- show_template($scalar [, $nofinalize])
- This method accepts a scalar template name, calls the
pre__pre__all() sub if found, calls the pre_templatename()
sub if found, calls the post__pre__all() sub if found, sends the
template to the client, calls the pre__post__all() sub if found,
calls the post_templatename() sub if found, calls the
post__post__all() sub if found, then exits. Internally uses the
return_template() method to calculate actual content to send.
Note: This method calls finalize() when done unless
$nofinalize is set to true. You probably never
want to do this, in which case the call to finalize() will cause
this method to never return.
Aside from variables added through the html() method, the submitted form
and the current session, these pre-defined variables will be automatically set
for you to use in your templates:
- _current_template
- This variable will contain the name of the current template
- _fatal_error
- This variable will contain the error message that caused a fatal error. It
will only be available when a fatal error occurs and the fatal error
template specified by the fatal_error_template constructor argument is
being shown.
- _form_action
- This variable will contain the URL to the current CGI
- _missing_info
- This variable will only be available when the missinginfo template is
being called from a call to assert_form() or
assert_session() methods. It's value will be an arrayref of hashes.
Each hash will have a key named "name", the value of which is
the name of a key supplied to assert_form() or
assert_session() that failed the assertion. This variable can be
used with HTML::Template's TMPL_LOOP macro to display the variables that
failed the assertion.
- _missing_info_caller
- This variable will only be available when the missinginfo template is
being called from a call to assert_form() or
assert_session() methods. It's value will be a scalar describing
the caller of assert_form() or assert_method().
One of this module's strengths is simplifying support for
multi-(human)languages. When the user is presented lingual pieces using this
module, it has usually originated from either:
- Content inside one of the templates
- Errors added via the add_error() method
Multi-language support is initiated by you by supplying the
"valid_languages" arrayref to the CGI::Framework constructor. This
arrayref should contain a list of language tags you wish to support in your
application. These tags are not necessarily the exact same tags as the
ISO-specified official language tag, and as a matter of fact it is
recommended that you use tags that are as short as possible for reasons that
will be apparent below.
As an example, if you intend to support English and French in your
application, supplying this to the constructor would indicate that:
"valid_languages" => ['en', 'fr'],
When the module sends output to the user, it will try to send the
"appropriate" language localization.
What is the "appropriate" language localization to
send ?
The module uses a fairly simple logic to determine which is the
language localization to send:
- The session variable "_lang"
- If the session variable "_lang" is set, it will be used as the
user's desired localization.
You can either populate this variable manually in your code,
such as by:
session("_lang", "en");
Or more conveniently, let CGI::Framework handle that job for
you by having the templates set a form element named "_lang".
This allows you to add to a top-header template a "Switch to
English" button that sets the form element "_lang" to
"en", and a "Switch to French" button that sets the
form element "_lang" to "fr".
When CGI::Framework is processing the submitted form and
notices that the form element "_lang" is set, it will update
the session's "_lang" correspondingly, hence setting that
user's language.
- The default language
- If the session variable "_lang" is not set as described above,
the default language that will be used is the first language tag listed in
the "valid_languages" arrayref.
Finally, this is how to actually define your multi-lingual
content:
- Localizing content inside the templates
- This is where pleasantness begins. The language tags you defined in the
"valid_languages" constructor key can be used as HTML tags
inside the templates! CGI::Framework will take care of parsing and
presenting the correct language and illiminating the others. An example in
a bilingual template:
<en>Good morning!</en>
<fr>Bonjour!</fr>
- Localizing errors added via the add_error() method
- By default, errors you add via the add_error() method will not be
localized and will be passed straight-through to the errors template and
shown as-is to the end user.
To enable localization for the errors, you will need to, aside
from supplying the "valid_languages" key, also supply the
"maketext_class_name" key to the constructor. This should be
the name of a class that you created. CGI::Framework will take care of
use()ing that class. For example:
"maketext_class_name" => "MyProjectLocalization",
Exactly what should be in that class ? This is where I direct
you to read Locale::Maketext. This class is your project's base
localization class. For the impatient, skip down in Locale::Maketext's
POD to the "HOW TO USE MAKETEXT" section. Follow it step by
step except the part about replacing all your print() statements
with print maketext() - this is irrelevant in our scenario.
After you do the above, your calls to the add_error()
method will be automatically localized, using Locale::Maketext and your
custom localization class. In our example here, you would end up
with:
- A file in your lib/ folder named
MyProjectLocalization.pm
- Inside that file, you should have created the following packages:
-
package MyProjectLocalization;
-
package MyProjectLocalization::en;
-
package MyProjectLocalization::fr;
I do not (knowingly) release buggy software. If this is the latest release, it's
probably bug-free as far as I know. If you do find a problem, please contact
me and let me know.
Mina Naguib
CPAN ID: MNAGUIB
mnaguib@cpan.org
http://mina.naguib.ca
This program is free software; you can redistribute it and/or modify it under
the same terms as Perl itself.
The full text of the license can be found in the LICENSE file
included with this module.
Copyright (C) 2003-2005 Mina Naguib.
HTML::Template, CGI::Session, CGI::Session::MySQL, CGI, Locale::Maketext,
CGI::Carp.
Visit the GSP FreeBSD Man Page Interface. Output converted with ManDoc. |