NAME
CGI::Application::Plus - CGI::Application rewriting with several pluses
VERSION 1.01
Included in CGI-Application-Plus 1.01 distribution. The distribution includes:
CGI::Application::Plus
CGI::Application rewriting with several pluses
CGI::Application::Magic
Template based framework for CGI applications
CGI::Application::CheckRM
Checks run modes using Data::FormValidator
INSTALLATION
- Prerequisites
-
Perl version >= 5.6.1 OOTools >= 1.52
- CPAN
-
perl -MCPAN -e 'install CGI::Application::Plus'
If you want to install also all the prerequisites to use
CGI::Application::Magic
), all in one easy step:perl -MCPAN -e 'install Bundle::CGI::Application::Magic'
- Standard installation
-
From the directory where this file is located, type:
perl Makefile.PL make make test make install
SYNOPSIS
In WebAppl.pm
# instead of "use base 'CGI::Application';"
use base 'CGI::Application::Plus' ;
# all the new possibilities are described below
DESCRIPTION
This module is a complete new stand alone reimplementation of CGI::Application
module (i.e. it is not a subclass). It adds several new features to your CGI::Application implementation, maintaining intact the old ones, so if some new feature is not useful to you, just use the old way that still works.
Since all the 'old-features' are excellently documented in CGI::Application, right now this documentation focuses only on the new features that this module implements exclusively. (please see also "CONTRIBUTION")
Since this documentation is not yet stand alone, you should integrate both documentation and please, be sure to understand that module before to switch to this one.
IMPORTANT NOTE: If you write any script that rely on this module, you better send me an e-mail so I will inform you in advance about eventual planned changes, new releases, and other relevant issues that could speed-up your work. (see also "CONTRIBUTION")
Why yet another CGI::Application?
I greatly apreciate the general philosophy of the cgiapp system but I wasn't satisfied with several aspect of its implementation, so I started to write a sub class. Very soon I realized that I would had to overriding at least the new, run and param methods. Then, after overriding all that, it would have been stupid to have to depend and to be limited from another module just for the few subs that remain original, so... I wrote this module that is a completely new and different approach to the same general metaphor. Just look at the source to see what I mean.
If you are thinking that this module is like reinventing the wheel... well... just think about how slow, unsure and unconfortable would be your car if it would use the first original hand-made-wooden wheels of several centuries ago :-).
CGI::Application::Plus Vs CGI::Application
Exclusive Features and Improvements
This is the list of all the improvements and new features that you gain by using CGI::Application::Plus
instead of CGI::Application
.
Properties
Most of the old CGI::Application
methods fit well into the category of 'object property', and so they are implemented in the CGI::Application::Plus
module by using OOTools pragmas.
Note: A property is simply an accessor to an object value, used by methods. All the CGI::Application::Plus
properties are lvalue accessors, that means that you can create a reference to them, assign to them and apply a regex to them, (some have a default value, some have validation entry rules, etc.)
$s->runmode = 'myStart' # 'runmode' is a property accessor
delete $s->param->{myParam} # 'param' is a property group accessor
new ()
The new() method accept more options: see new().
run ()
The run() method accept more options: see run().
param handling
The param()
accessor is a property group acccessor, that means that you can set, add, retrieve, delete, check for existance with only one method. You can use it as a parameter to the new() method as well. (see param())
# pass a parameter to the new object
$webapp = WebApp->new(param => {myPar => 'myPAR'})
# same thing using the AUTOLOAD method
$webapp = WebApp->new(myPar => 'myPAR')
$s->param(myPar1=>'myPARAM1',
myPar2=>'myPARAM2') ;
$s->param(\%other_param) ;
$P = $s->param ;
while ( my ($p, $v) = each %$P )
{ do_something_useful }
# check if exists a parameter
exists $s->param->{myPar} ;
# delete a parameter
delete $s->param->{myPar} ;
header handling
The header_props() is a property group acccessor, so you can set, add, retrieve, delete headers exactly like what you can do with the param() accessor. (No needs of any add_header()
method)
page property
Under old CGI::Application
implementation, a run method is espected to return the content of the page (or a reference to it) to send to the client.
CGI::Application::Plus
can work that way as well, but it adds the new page
property that can considerably improve the flexibility of your application. (see "page" property)
Note: Just completely ignore the page
property to exactly reproduce the same old CGI::Application
behaviour. Anyway, this possibility is here just for compatibility, and it is deprecated: please always use the page
property.
run method prefix
I hate to write twice the same information, because it is silly, annoying and error prone, so... unless you need to address a run mode to some particular method you can completely avoid the run_modes()
method and keep safe your application by using a prefixed name for your run mode methods:
# this run method does not need to be declared with run_modes()
# and will be executed automatically by run mode 'myRunmode'
sub RM_myRunmode
{
do_something_useful
}
Note: You can set the RM_prefix
property to change the default prefix.
run mode switching
You have an useful method to switch to a run mode (see switch_to())
overriding for power users
All the internal data have an accessor that you can override to have it changed across the whole class, and in the code there are no dirty statements like $self->{SOME_INTERNAL_STUFF} = 'something'
that bypass the accessor.
Efficiency
Under normal environment this module should load a little faster and use less memory than CGI::Application
thanks to the far shorter code and the use of OOTools pragmas, that implements efficient closure accessors at compile time. (see Object::props, Object::groups, Class::constr)
Super Classes
If you write a super class and need some more properties for your class, you can use the OOTools pragmas for free (memory). They are already loaded by this module and allows you to give a more consistent interface to your users, creating very efficient accessors at compile time with just a couple of lines. Take a look at the source of the modules in this distribution to understand what I mean.
CGI::Application compatibility
An old CGI::Application
implementation should run unchanged under CGI::Application::Plus
as well, taking the advantages of all the pluses of this module (this module pass all the test of CGI::Application 3.1, but if you found some incompatibilities, please tell me, and I will fix it).
Note: The compatibility could be compromised if your application used some dirty hack that bypass accessors (i.e. some statements that interacts with the internal hash structure of the CGI::Application
class, something like $self->{__PARAMS}
, because CGI::Application::Plus
implements a more consistent but different internal structure).
param()
This module implements on purpose a little but useful difference that should not break the code of anybody, that correct IMHO a weird and useless behaviour of CGI::Application::param()
:
# CGI::Application param() in scalar context
$par = $s->param() ; # $par == number of params || undef
$par = $s->param(myPar =>'myPARAM') ; # $par eq 'myPARAM'
$par = $s->param(myPar1=>'myPARAM1', # $par is undef
myPar2=>'myPARAM2') ;
$par = $s->param('myPar') ; # $par eq 'myPARAM'
# CGI::Application::Plus param() in scalar context
$par = $s->param() ; # ref $par eq 'HASH'
$par = $s->param(myPar =>'myPARAM') ; # ref $par eq 'HASH'
$par = $s->param(myPar1=>'myPARAM1', # ref $par eq 'HASH'
myPar2=>'myPARAM2') ;
$par = $s->param('myPar') ; # $par eq 'myPARAM'
As you see, in scalar context (no difference in list context) the param()
metod returns the reference to the underlying hash containing the parameters. This allows you to interact directly with the whole hash, or checking and deleting single parameters very easily:
$P = $s->param ;
while ( my ($p, $v) = each %$P )
{ do_something_useful }
# check if exists a parameter
exists $s->param->{myPar} ;
# delete a parameter
delete $s->param->{myPar} ;
cgiapp_postrun()
More than a difference this is a new possible situation that this method should be ready to handle. It will receive the reference to the output in $_[1] as usual, but, just in case you set the page property to a CODE reference (see "page" property), it will receive that reference. If your cgiapp_postrun() method need to collect the output it can capture the output using a couple of methods implemented for that purpose
sub cgiapp_postrun
{
my ($s, $ref) = @_ ; # $ref always the same as $s->page
if (ref $ref eq 'CODE')
{
$s->start_capture() ;
$ref->($s) ; # executes $ref CoDE (print)
$$ref = $s->stop_capture ; # now $ref is the ref to the content
}
# do something with $ref as usual
}
Useless but supported aliases
To maintain compatibility with the old CGI::Application
implementation, this module provides all the old - and now useless - aliases.
- QUERY
-
Used to pass a query object with the
new()
method. It's still working but deprecated usequery
property instead.$webapp = WebApp->new(query=>CGI->new)
- TMPL_PATH
-
Used to pass a template path with the
new()
method. It's still working but deprecated usetmpl_path
property instead$webapp = WebApp->new(tmpl_path=>'/mypath')
- PARAMS
-
Used to pass a reference to an hash (containing some parameters) with the
new()
method. It's still working but deprecated. You can use several alternatives withparam()
property group acccessor or accessing parameters directly. (see param() property group acccessor)$webapp = WebApp->new(param => { myParam => 'myPARAM'} ) # same thing $po = myAppl->new(myParam => 'myPARAM')
- start_mode ()
-
Used to set the start run mode. It's still working but deprecated use
runmode
property instead.$s->runmode = 'mystart'
- get_current_runmode ()
-
Used to get the current run mode. It's still working but deprecated use
runmode
property instead.$s->runmode # always returns the current run mode
- prerun_mode ()
-
Used to set the prerun mode. It's still working but deprecated use
switch_to()
method instead.$s->switch_to = 'myRunmode'
- header_add ()
-
Used to adds some headers after the
header_props()
method is called. It's still working but deprecated. Theheader_props()
property group accessor do it already, so use it instead.
METHODS
Please integrates the documentation in this section with CGI::Application
new ( [ properties ] )
The new() method accepts and sets any known object property, storing any unknow property as a new parameter. You can pass to the new() method all the property you usually set with the setup() or cgiapp_init() metods that can however set (override) them as usual. This just adds a new flexible possibility to configure your application not from inside the application module, but from the cgi script that uses it:
# not all useful here, but possible
$webapp = WebApp->new(runmode => 'mySpecialRunMode',
mode_param => 'mm' ,
runmodes => [ qw|one two| ] ,
myParam => 'myPARAM' , # sets param 'myParam'
... more here... )
run ( [ runmode ] )
You can directly pass a run mode to the run() method, so forceing the application to run that run mode (e.g. useful when testing a particular run mode):
$webapp->run('mySpecialRunmode');
Note for power users only: The run() method is splitted into 3 internal methods ( run(), _run_runmode(), _send() ) so you can eventually selectively override them in a more flexible way.
switch_to ( runmode [, arguments] )
This method allows you to switch to a run mode, e.g. useful when validating run modes.
sub RM_myRunmode
{
my $s = shift;
some_condition || return $s->switch_to('myOtherRunmode', @optional_arg)
...
}
You should use this method inside the cgiapp_prerun()
method too. (old way was to set the prerun_mode())
start_capture()
Use this method to start to capture the current selected filehandler (usually STDOUT). All the printed output will be captured and will not go in the selected filehandler until you use the Cstop_capture()> method.
Note: this method is internally called when $ENV{CGI_APP_RETURN_ONLY}
is set to a true value.
stop_capture()
This method will return the captured output and will stop the capture.
Note: this method is internally called when $ENV{CGI_APP_RETURN_ONLY}
is set to a true value.
AUTOLOAD
This method (not to be confused with the 'AUTOLOAD' run mode) implements an handy parameter accessor. You can store or retrieve a parameter as it where an object property:
# instead of do this
$s->param(myPar => 'some init value')
# you can do this
$s->myPar = 'some init value' ;
# same thing with the new() method
$webapp = WebApp->new(myPar => 'some init value')
# and to retrieve
$p = $s->myPar
If you don't like this feature, just override the AUTOLOAD method. If your application implements its own AUTOLOAD sub and you want to keep this possibility just fall back on the SUPER class method when needed.
OVERRIDE METHODS
Please refer to CGI::Application
PROPERTY GROUP ACCESSORS
With all the property group accessors you can set, add, retrieve, delete, check for existance with only one method. You can use them as a parameter to the new() method as well. See below for examples
param ( [ parameters ] )
This accessor handles the parameters of your application
# pass a parameter to the new object
$webapp = WebApp->new(param => {myPar => 'myPAR'})
$s->param(myPar1=>'myPARAM1',
myPar2=>'myPARAM2') ;
$s->param(\%other_param) ;
$P = $s->param ;
while ( my ($p, $v) = each %$P )
{ do_something_useful }
# check if exists a parameter
exists $s->param->{myPar} ;
# delete a parameter
delete $s->param->{myPar} ;
header_props( [ headers ] )
This accessor works for headers exactly like param() works for parameters. No need of any add_header() method.
run_modes( [ runmodes ] )
This accessor manages the declared run_modes. It works as all the other accessors but adds the possibility to receive reference to an ARRAY as argument, that will be expanded as this
$webapp->run_modes([ 'mode1', 'mode2', 'mode3' ]);
#same as this
$webapp->run_modes(
'mode1' => 'mode1',
'mode2' => 'mode2',
'mode3' => 'mode3'
);
Please, consider that in order to reduce redundancy in your code, you can use safely the RM_prefix
property, to avoid to declare run modes and run methods (see "run method prefix")
PROPERTY ACCESSORS
All the property accessors are lvalue method that means that you can create a reference to them, assign to them and apply a regex to them, (some have a default value, some have validation entry rules, etc.) Old assignation will work as well
$s->property = 'value'
#same thing
$s->property('value')
You can use them as a parameter to the new() method as well.
$webapp = WebApp->new(some_property => 'some_value')
runmode
This property allows you to access and set the runmode. The default for this property is 'start'.
Set the runmode
to redefine the default run mode. The default run mode will be used whenever the value of the CGI form parameter specified by the mode_param
property is not defined.
# in setup
$s->runmode = 'myStart' ;
$current_runmode = $s->runmode
query
This property allows you to access and set the query object. The default for this property is a CGI query object, but you can override this default if you redefine the cgiapp_get_query()
method.
If, for some reason, you want to use your own CGI query object, you can pass this property to the new() method, or you can also directly set it at same point in the process before the run() method (or in the cgiapp_prerun()
method).
$s->query = CGI->new({myOwnQuery => 'something'}) ;
mode_param
This property allows you to access and set the name of the query parameter used to retrieve the runmode. The default for this property is 'rm'.
tmpl_path
This property allows you to access and set the directory where the templates are stored. The default for this property is './tm'.
RM_prefix
This property allows you to access and set the prefix string used to find a not declared runmode. The default for this property is 'RM_'. (see also "run method prefix")
header_type
This property allows you to access and set the type of header your application will send. The default for this property is 'header'. You can chose 'header', 'redirect', 'none'.
page
This property allows you to access and set the content of the page (or a reference to it) to send to the client. A run method should set the page
property to some page content, to a reference to it or to a CODE reference that will print the output on its own. in this case the refereced code will be called after the printing of the headers.
sub RM_myRunMode
{
...do_something_useful...
$s->page = 'something'
$s->page .= 'something more'
}
sub RM_myOtherRunMode
{
...do_something_useful...
$s->page = \&print_the_content
}
The main advantage to set this property to a CODE reference (among others) is that you can avoid to charge the memory with the whole (and sometime huge) output and print it while it is produced.
This feature is fully utilized in CGI::Application::Magic, but you can also use it with your own subroutines (see also "page property")
__STEP
Internal property used to control exceptions.
TESTING
$ENV{CGI_APP_RETURN_ONLY}
When set to a true value it cause the capture of the output being printed, so it will not be sent to STDOUT, besides the run() method will return the captured output, so allowing you to eventually test your sub classes.
$ENV{CGI_APP_RETURN_ONLY} = 1
$captured_output = $webapp->run();
if ( $captured_output =~ /something to test/ )
{
print 'ÍT WORKS!'
}
TO DO
Improve exception handling
Make this documentation stand alone
SUPPORT and FEEDBACK
I would like to have just a line of feedback from everybody who tries or actually uses this module. PLEASE, write me any comment, suggestion or request. ;-)
More information at http://perl.4pro.net/?CGI::Application::Plus.
AUTHOR and COPYRIGHT
© 2004 by Domizio Demichelis.
All Rights Reserved. This module is free software. It may be used, redistributed and/or modified under the same terms as perl itself.
CREDITS
Thanks to anyone that contributes to the creation of the CGI::Application
metaphor: the merit of that great idea still belong to them.
CONTRIBUTION
I always answer to each and all the message i receive from users, but I have almost no time to find, install and organize a mailing list software that could improve a lot the support to people that use my modules. Besides I have too little time to write more detailed documentation, more examples and tests. Your contribution would be precious, so if you can and want to help, just contact me. Thank you in advance.
1 POD Error
The following errors were encountered while parsing the POD:
- Around line 720:
Non-ASCII character seen before =encoding in ''ÍT'. Assuming CP1252