CGI-XMLApplication
view release on metacpan or search on metacpan
XMLApplication.pm view on Meta::CPAN
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
=back
Apart from B<Application Panic> the panic levels are set
internally. An Application Panic should be set if the application
catches an error, that does not allow any XML/XSLT processing. This
can be for example, that a required perl module is not installed on
the system.
To make it clear: If CGI::XMLApplication throws a panic, the
application is broken, not completely implemented or stylesheets are
missing or broken. Application panics are meant for debugging purposes
and to avoid I<Internal Server Errors>. They are B<not> meant as a
replacement of a propper error handling!
But how does CGI::XMLApplication know about the correct event handler?
One needs to register the names of the events the application handles.
This is done by implmenting a registerEvents() function that simply
returns an B<array> of event names. Through this function one prepares
the CGI::XMLApplication to catch the listed names as events from the
query string the client browser sends back to the
script. CGI::XMLApplication tries to call a event handler if a name of
a registred event is found. The coresponding function-name of an event
has to have the following format:
event_<eventname>
E.g. event_init handles the init event described below.
Each event has a single Parameter, the context. This can be an unblessed
hash reference or an object, where the user can store whatever needed.
This context is useful to pass scriptwide data between callbacks and
event functions around. The callback is even available and useable if
the script does not initialize the application context as earlier shown
in the program flow chart.
If such a function is not implemented in the application module,
CGI::XMLApplication sets the I<Event not implemented> panic state.
All events have to return an integer that tells about their execution
state as already described.
By default CGI::XMLApplication does not test for other events if it
already found one. The most significant event is the first name of an
event found in the query string - all other names are simply ignored.
One may change this behaviour by overriding the B<testEvent()>
function.
But still it is a good idea to choose the event names carefully and do
not mix them with ordinary datafield names.
=over 4
=item function testEvent
If it is nesseccary to check which event is relevant for the current
script one can use this function to find out in event_init(). If this
function returns I<undef>, the default event is active, otherwise it
returns the eventname as defined by B<registerEvents>.
In case one needs a special algorithm for event selection one can
override this function. If done so, one can make use of the
application context inside this function since it is passed to
B<testEvent()> by the B<run()> function.
=item method sendEvent SCALAR
Sometimes it could be necessary to send an event by your own (the
script's) initiative. A possible example could be if you don't have
client input but path_info data, which determinates how the script
should behave or session information is missing, so the client should
not even get the default output.
This can only be done during the event_init() method call. Some coders
would prefer the constructor, which is not a very good idea in this
case: While the constructor is running, the application is not
completely initialized. This can be only ashured in the event_init
function. Therefore all application specific errorhandling and
initializing should be done there.
B<sendEvent> only can be called from event_init, because any
CGI::XMLApplication will handle just one event, plus the B<init> and
the B<exit event>. If B<sendEvent> is called from another event than
B<event_init()> it will take not effect.
It is possible through sendEvent() to keep the script logic clean.
Example:
package myApp;
use CGI::XMLApplication;
@ISA = qw(CGI::XMLApplication);
XMLApplication.pm view on Meta::CPAN
processed, but just before the rendering is done. This should be used,
if you need to do something independend from all events before the
data is send to the user.
=item event_default
This event is called as a fallback mechanism if CGI::XMLApplication
did not receive a stylesheet id by another event handler, for example
if no event is matched.
=back
=head2 the XML Serialization
The presentation is probably the main part of a CGI script. By using
XML and XSLT this can be done in a standartised manner. From the
application view all this can be isolated in a separate subsystem as
well. In CGI::XMLApplication this subsystem is implemented inside the
B<serialize()> function.
For XML phobic perl programmers it should be cleared, that
CGI::XMLApplication makes real use of XML/XSLT functionalty only
inside this function. For all code explained above it is not required
to make use of XML at all.
The XML serialization subsystem of CGI::XMLApplication tries to hide
most of non application specific code from the application programmer.
This method renders the data stored in the DOM with the stylesheet
returned by the event handler. You should override this function if
you like to use a different way of displaying your data.
If the serialization should be skipped, CGI::XMLApplication will not
print any headers. In such case the application is on its own to pass
all the output.
The algorithm used by serialization is simple:
=over 4
=item * request the appplication DOM through B<getDOM()>
=item * test for XML passthru
=item * get the stylesheet the application preferes through B<selectStylesheet()>
=item * parse the stylesheet
=item * transform the DOM with the stylesheet
=item * set Content-Type and headers
=item * return the content to the client
=back
If errors occour on a certain stage of serialization, the application
is stopped and the generated error messages are returned.
CGI::XMLApplication provides four pseudo-callbacks, that are used to
get the application specific information during serialization. In
order of being called by CGI::XMLApplication::serialization() they
are:
=over 4
=item * getDOM
=item * setHttpHeader
=item * getStylesheet
=item * getXSLTParameter
=back
In fact only getStylesheet has to be implemented. In most cases it
will be a good idea to provide the getDOM function as well. The other
functions provider a interface to make the CGI output more
generic. For example one can set cookies or pass XSL parameters to
XML::LibXSLT's xsl processor.
These methods are used by the serialization function, to create the
content related datastructure. Like event functions these functions
have to be implemented as class member, and like event funcitons the
functions will have the context passed as the single parameter.
=over 4
=item getDOM()
getDOM() should return the application data as
XML-DOM. CGI::XMLApplication is quite lax if this function does not
return anything - its simply assumed that an empty DOM should be
rendered. In this case a dummy root element is created to avoid error
messages from XML::LibXSLT.
=item setHttpHeader()
B<setHttpHeader> should return a hash of headers (but not the
Content-Type). This can be used to set the I<nocache> pragma, to set
or remove cookies. The keys of the hash must be the same as the named
parameters of CGI.pm's header method. One does not need to care about
the output of these headers, this is done by CGI::XMLApplication
automatically.
The content type of the returned data is usually not required to be
set this way, since the XSLT processor knows about the content type,
too.
=item getStylesheet()
If the B<getStylesheet> is implemented the CGI::XMLApplication will
assume the returned value either as a filename of a stylesheet or as a
XML DOM representation of the same. If Stylesheets are stored in a
folder accessible for the the web-server, a common path for the
stylesheets should be set and B<CGI::XMLApplication> will initiate
the parsing job.
In cases the stylesheet is already present as a string (e.g. as a
( run in 0.817 second using v1.01-cache-2.11-cpan-cdf2f3d4e48 )