CGI-XMLApplication
view release on metacpan or search on metacpan
XMLApplication.pm view on Meta::CPAN
debug_msg( 1, "$str" );
if ( $CGI::XMLApplication::Quiet == 1 ) {
$str = "Application Panic";
}
if ( $CGI::XMLApplication::Quiet == 2 ) {
$str = "";
}
my $status = $pid < 3 ? 404 : 500; # default is the application error ...
print $self->header( -status => $status ) , $str ,"\n";
}
1;
# ################################################################
__END__
=head1 NAME
CGI::XMLApplication -- Object Oriented Interface for CGI Script Applications
=head1 SYNOPSIS
use CGI::XMLApplication;
$script = new CGI::XMLApplication;
$script->setStylesheetPath( "the/path/to/the/stylesheets" );
# either this for simple scripts
$script->run();
# or if you need more control ...
$script->run(%context_hash); # or a context object
=head1 DESCRIPTION
CGI::XMLApplication is a CGI application class, that intends to enable
perl artists to implement CGIs that make use of XML/XSLT
functionality, without taking too much care about specialized
errorchecking or even care too much about XML itself. It provides the
power of the L<XML::LibXML>/ L<XML::LibXSLT> module package for
content deliverment.
As well CGI::XMLApplication is designed to support project management
on code level. The class allows splitting web applications into several
simple parts. Through this most of the code stays simple and easy to
maintain. Throughout the whole runtime of a script
CGI::XMLApplication tries to keep the application stable. As well a
programmer has not to bother about some of XML::LibXML/ XML::LibXSLT
transformation pitfalls.
The class module extends the CGI class. While all functionality of the
original CGI package is still available, it should be not such a big
problem, to port existing scripts to CGI::XMLApplication, although
most functions used here are the access function for client data
such as I<param()>.
CGI::XMLApplication, intended to be an application class should make
writing of XML enabled CGI scripts more easy. Especially because of
the use of object orientated concepts, this class enables much more
transparent implemententations with complex functionality compared to
what is possible with standard CGI-scripts.
The main difference with common perl CGI implementation is the fact,
that the client-output is not done from perl functions, but generated
by an internally build XML DOM that gets processed with an XSLT
stylesheet. This fact helps to remove a lot of the HTML related
functions from the core code, so a script may be much easier to read,
since only application relevant code is visible, while layout related
information is left out (commonly in an XSLT file).
This helps to write and test a complete application faster and less
layout related. The design can be appended and customized later
without effecting the application code anymore.
Since the class uses the OO paradigma, it does not force anybody to
implement a real life application with the complete overhead of more
or less redundant code. Since most CGI-scripts are waiting for
B<events>, which is usually the code abstraction of a click of a
submit button or an image, CGI::XMLApplication implements a simple
event system, that keeps event related code separated from other events.
Therefore, a final application class is not meant to have a constructor
anymore. All functionality should be encapsulated into implicit or
explicit event handlers. Because of a lack in Perl's OO implementation
the call of a superclass constructor before the current constructor
call is not default behavior in Perl. For that reason I decided to
have special B<events> to enable the application to initialize
correctly, excluding the danger of leaving important variables
undefined. Also this forces the programmer to implement
scripts more problem orientated, rather than class or content focused.
Another design aspect for CGI::XMLApplication is the strict
differentiation between CODE and PRESENTATION. IMHO this, in fact
being one of the major problems in traditional CGI programming. To
implement this, the XML::LibXML and XML::LibXSLT modules are used by
default but may be replaced easily by any other XML/XSLT capable
modules. Each CGI Script should generate an XML-DOM, that can be
processed with a given stylesheet.
B<Pay attention: In this Document XML-DOM means the DOM of XML::LibXML
and not XML::DOM!>
=head2 Programflow of a CGI::XMLApplication
The following Flowchart illustratrates how CGI::XMLApplication behaves
during runtime. Also chart shows where specialized application code gets
control during script runtime.
------- CGI Script ------->|<--------- CGI::XMLApplication --------
.---------------------. .--------------------.
| app-class creation |--- | event registration |
`---------------------' | registerEvents() |
`--------------------'
.------------------------. |
| context initialization |------------'
| ( optional ) |
`------------------------'
|
.-----------------------. .------------------------.
| run() function called |--| application initialize |
XMLApplication.pm view on Meta::CPAN
@ISA = qw(CGI::XMLApplication);
sub registerEvents { qw( dummy ); } # list of event names
# ...
sub event_dummy {
my ( $self, $context ) = @_;
# your event code goes here
return 0;
}
During the lifecircle of a CGI script, often the implementation starts
with ordinary submit buttons, which get often changed to so called
input images, to fit into the UI of the Website. One does not need to
change the code to make the scripts fit to these changes;
CGI::XMLApplication already did it. The code has not to be changed if
the presentation of the form changes. Therefore there is no need to
declare separate events for input images. E.g. an event called evname
makes CGI::XMLApplication tests if evname B<or> evname.x exist in the
querystring.
So a perl artist can implement and test his code without caring if the
design crew have done their job, too ;-)
In many cases an web application is also confronted with events that
can not be represented in with querystring arguments. For these cases
CGI::XMLApplication offers the possibility to send B<special events>
from the B<event_init()> function for example in case of application
errors. This is done with the B<sendEvent()> Function. This will set a
new parameter to the CGI's querystring after removing all other
events. B<One can only send events that are already registred!>.
Although a sendEvent function exists, CGI::XMLApplication doesn't
implement an event queqe. For GUI programmers this seems like a
unnessecary restriction. In terms of CGI it makes more sense to think
of a script as a program, that is only able to scan its event queqe
only once during runtime and stopped before the next event can be
thrown. The only chance to stop the script from handling a certain
event is to send a new event or delete this (or even all) events from
inside the event_init() function. This function is always called at
first from the run method. If another event uses the sendEvent
function, the call will have no effect.
=over 4
=item method registerEvents
This method is called by the class constructor - namely
CGI::XMLApplication's B<new()> function . Each application should
register the events it likes to handle with this function. It should
return an array of eventnames such as eg. 'remove' or 'store'. This
list is used to find which event a user caused on the client side.
=item method run
Being the main routine this should be the only method called by the
script apart from the constructor. All events are handled inside the
method B<run()>. Since this method is extremly simple and transparent
to any kind of display type, there should be no need to override this
function. One can pass a context hash or context object, to pass external
or prefetched information to the application. This context will be
available and accessible in all events and most extra functions.
This function does all event and serialization related work. As well
there is some validation done as well, so catched events, that are not
implemented, will not cause any harm.
=back
=head2 The Event System
A CGI::XMLApplication is split into two main parts: 1) The executable
script called by the webserver and 2) the application module which has
to be loaded, initialized and called by the script.
Commonly applications that make use of CGI::XMLApplication, will not
bother about the B<run> function too much. All functionality is kept
inside B<event>- and (pseudo-)B<callback functions>. This forces one
to implement much more strict code than common perl would allow. What
first looks like a drawback, finally makes the code much easier to
understand, maintain and finally to extend.
CGI::XMLApplication knows two types of event handlers: implicit
events, common to all applications and explicit events, reflecting the
application logic. The class assumes that implicit events are
implemented in any case. Those events have reserved names and need not
be specified through B<registerEvents>. Since the class cannot know
something about the application logic by itself, names of events have
to be explicitly passed to be handled by the application. As well all
event functions have to be implemented as member methods of the
application class right now. Because of perls OO interface a class has
to be written inside its own module.
An event may return a integer value. If the event succeeds (no fatal
errors, e.g. database errors) the explicit or common event function
should return a value greater or eqal than 0. If the value is less
than 0, CGI::XMLApplication assumes an application panic, and will not
try to generate a DOM or render it with a stylesheet.
There are 4 defined panic levels:
=over 4
=item -1
Stylesheet missing
=item -2
Stylesheet not available
=item -3
Event not implemented
=item -4
Application panic
( run in 1.030 second using v1.01-cache-2.11-cpan-39bf76dae61 )