Input from the client typically comes in 3 ways:
- POST data (forms)
Forms typically send their data as POST data, which is a set of
parameter names and values. We convert this to a hash of names =>
values.
- GET data (query string)
Query strings are treated similarly to forms by default; that is, they
are presumed to contain parameterized values such as
/cgi/page.cgi?parameter=value&less=more
Note that the separator character ``&'' can be changed to ``;'' or any
other charcter in your configuration file. For example, if you use a
CSV format such as
/cgi/page.cgi?value,more
then you can set your separator character to ``,'' and the values will
come through as parameter names. More on this is given below. If you
use an entirely different format, then you can always fetch the raw
GET data and parse it yourself.
PATH_INFO
Path info data is a list of values separated by the ``/'' character.
This list can be broken down into named sub-lists. The sub-list names
are treated as parameter values, and the sub-list data are treated as
simple arrays. Any remaining trailing part of the path info is kept
in an unnamed sub-list. For example, a PATH_INFO like
/exsite/index.html/blog/my_article
might break down into two sub-lists:
CMS -> exsite, index.html
Zine -> blog, my_article
Unlike POST and GET data, these parameter names are not provided by
the input data; they are defined after the fact by code that reads
from the path.
To begin working with inputs of any of these types, declare an Input
object to work with:
my $in = new ExSite::Input;
Input is returned as a hash reference of parameters names => values.
my $querydata = $in->query();
Reads input passed via GET method (ie. QUERY_STRING)
my $postdata = $in->post();
Reads input passed via POST method.
my $data = $in->query_or_post();
Reads from query preferentially, but if the query contains no data, it will
read from post data as a backup.
my $data = $in->post_or_query();
Reads from post data preferentially, but if the post contains no data, it
will read from the query string as a backup.
Usage: my $data = $in->combine()
Combines the post data and query data into a single hash. Post data
is taken preferentially.
If your query string is not formatted as a sequence of parameter=value
settings, you can try one of these:
# fetch a list of the parameter names
my @parameter_list = $in->fetch("get","keys");
# fetch the raw QUERY_STRING to be parsed by another program
my $raw_input = $in->fetch("get","raw");
my $data = $in->path_info();
Returns the complete PATH_INFO, as a string.
The path info can be comprised of a number of different sub-paths that
are concantenated together. For example:
/exsite/page.html/blog/my_article
The first two elements of this path might refer to a path in the CMS
(eg. /SECTION/PAGE), while the last two refer to a path in the Zine
subsystem. The complete path info is a concatenation of these two
subpaths, but we will often want to deal with the subpaths
individually.
my $data = $in->path($id);
my @data = $in->path($id);
Returns a sub-path as a string, or as an array of path elements. The
complete path can be divided into any number of sub-paths, each with
an ID. Any remaining path with no ID is called the remainder. If no
ID is given, the remainder is returned.
$in->path($id,$data);
$in->path($id,@data);
Sets a sub-path to a string, or as an array of path elements. With
the string form, the $data must begin with ``/''. To delete a sub-path,
use:
$in->path($id,"");
To set the remainder, use:
$in->path("",$data);
This method defines a new sub-path. It is called automatically from
path() if the id passed to path has not yet been defined.
$in->new_path($id,$data);
$in->new_path($id,@data);
Defines a new sub-path, which follows all other sub-paths that have
already been defined. The path data can be passed as a simple string
(starting with ``/''), or as an array of path elements. If the path
data matches the start of the remainder, the subpath will be removed
from the remainder. For example, if the remainder is ``/foo/bar/baz'',
and you define a new subpath as ``/foo/bar'', then the remainder will
change to ``/baz''. If, however, you define a new subpath like
``/bar/foo'' which does not match the remainder, then the new subpath
will be inserted into the path, and the remainder will be left
unchanged, resulting in ``/bar/foo/foo/bar/baz'' as the complete path.
The raw input is also saved, and can be retrieved using:
my $raw = $in->fetch("post","raw"); # or, use "get" instead of "post"
If the order of the inputs is important, you can fetch the raw key order
using:
my $keylist_ref = $in->fetch("post","keylist"); # or "get"...
The Input class is a replacement for the generic input parsing routines in
ExSite::Misc::, which are deprecated for processing inputs to page.cgi.
The main purpose in having an Input class is so that POST input can
be shared by multiple modules working independently. Without an Input
class, the first module to get its mitts on STDIN gobbles all the input,
and the remaining modules see nothing.
Multipart-encoding is handled automatically using the CGI:: class.
Multipart-encoding is normally only enabled by ExSite when the form
accepts file uploads.
To fetch the decoded file data directly, use:
my $raw_file = $in->fetch_file("input_name","raw"); # binary file data
$my $encoded_file = $in->fetch_file("input_name"); # encoded file data
ExSite encoded file data looks like this:
filename.jpg#MIMEDATA....
To convert this back to a regular file, split on the separator character
('#' by default) to get the file name, and the mime-encoded data. Then use
use Mime::Base64;
decode_base64($mimedata);
If you request the raw input data from a multipart-encoded form, you
will receive a CGI:: object.
ExSite::Input stores all input data in %share, where other modules
will find it if they also play nice and use ExSite::Input. The input
is parsed and cached automatically, and ExSite::Input is smart enough not
to redo this work once it has been done.
Input is saved in the following structure:
$share{input}{get|post|combine|path}{raw|data|keylist}
where get/post/combine/path selects the input stream, and raw/data/keylist
selects the format you would like to view the data in.
Get and post data are the parameter/value pairs found in the get and
post input streams, respectively. Combined data is the merged get and
post data, where post data is taken preferentially if the same
parameter appears in both.
Path data are stored as a hash of subpath IDs mapped to path element
arrays. The raw data is the scalar version of the subpath; the data
is the array version of the subpath, and the keylist is the order of
the subpaths.
Typical usage involves passively reading the input data that has been
passed from the web server. In some cases, however, you want to modify the
input data, or define your own input data.
To modify a single input parameter:
$in->set("parameter","newvalue","post"); # changes the parameter in the POST data
$in->set("parameter","newvalue","get"); # changes the parameter in the GET data
To remove a form parameter from the input cache, use:
$in->delete("parameter");
To change part of the path, see the section on path(), above.
To define the entire set of input data, you can pass the raw data in when
defining your Input object:
my $preset_input = new ExSite::Input( { post=>"foo=bar&bat=baz",
get=>"x=1&y=2",
path=>"/some/path" } );