Maypole::Manual::Workflow - Maypole's Request Workflow |
Maypole::Manual::Workflow - Maypole's Request Workflow
This chapter describes the progress of a request through Maypole.
An application based on Maypole
provides an Apache or CGI handler,
and eventually delivers a page. This document explains how that happens,
and how to influence it. We'll use the BeerDB
project as our example.
Here's a diagram that gives an overview:
config $h | Maypole $r Apache::Request | +---- $r->get_request ---+ $ar | | $r->parse_location | $r->is_applicable | BeerDB::Beer $r->call_authenticate ->authenticate ------------+------------ $r->authenticate | $r->additional_data | $r->model_class->process($r) | $r->view_object->process($r)
When the first request comes in, the application class will call its own
init
method, inherited from Maypole.
This creates a new view object.
Once we have initialized, the handler obtains the configuration for your
class, and puts it into a new object. We'll call this a request
object for the purposes of this document; it will be a new BeerDB
object.
Next, the handler calls get_request
on the new object to have it
store a copy of the Apache::Request
. Of course, if you're not using
Apache, you might want to subclass this method to return something that
looks like an Apache::Request
object, and possibly also subclass the
next stage too to get more control over what methods are called on your
A::R
-lookalike. get_request
is expected to put the object in the
ar
slot of the request object.
Typically, the details of the request will be passed in the URL. This is
done with the parse_location
method, which is expected to populate
several slots of the request object. First, table
and action
should be populated with the name of the table and the action parts of
the URL. Any other arguments should be placed in a listref in the
args
slot, and GET and POST parameters should be arranged into a hash
and placed in the query
and params
slots, respectively.
Some people may not like the idea of passing everything around in the URL; this is the method to override for you. Of course, you'll also need to provide your own default templates to construct links using your preferred format.
Next, the is_applicable
method works out if this is actually
something that Maypole
should care about - whether the class
exists in the application, whether it supports the given action, and so
on. The action is ``supported'' if it exists in the model class (or its
ancestors) and is marked with the :Exported
attribute; this stops web
users from firing off random subroutines in your code.
This should return an Apache status code; OK
if the request should
proceed, DECLINED
if it should be passed on to the default handlers,
or whatever other codes for permissions problems.
We then look for an appropriate authenticate
method to call; first
it will try calling the authenticate
method of the model class, or,
if that does not exist, the authenticate
method on itself. By
default, this allows access to everyone for everything.
Your authenticate
methods must return an Apache status code: OK
or
DECLINED
. These codes are defined by the the Maypole::Constants manpage
module, which is automatically used by your application.
You can write an additional_data
method to do any additional fiddling
with the request object before it is despatched. Specifically, it allows
you to add to the template_args
slot, which is a hash of arguments to
be added to the template, like this:
sub additional_data { my $self = shift; $self->{template_args}{answer} = 42; }
which adds a new template variable answer
with the value 42.
Asking the model class to process
the current request allows it to do
any work it needs for the given command, and populate the objects
and
template
slots of the request.
The model's process
method is usually a thin wrapper around the
action that we have selected. It sets the template name to the name of
the action, fills objects
with an object of that class whose ID comes
from the URL arguments if there is one. For instance, /beer/foo/12
will do the moral equivalent of
$r->objects([ BeerDB::Beer->retrieve(12) ]);
Then it calls the right method: in this case, the foo
method with
the request object. This method will usually do any actions which are
required, including modifying the list of objects to be passed to the
template, or the name of the template to be called.
Now the view class has its process
method called. It finds the
appropriate templates and calls the Template Toolkit
processor.
The template processor is handed the objects, the template
name, and various other bits and pieces, and tries to find the right
template. It does this by looking first for /beer/foo
: that is, a
specific template appropriate to the class. Next, it looks at
/custom/foo
, a local modification, before looking for
/factory/foo
, one of the default templates that came with
Maypole
.
The view puts the template's output in the $r->{output}
slot. The
application's handler
method calls the send_output
method to push
it to the web server.
If you're looking for the list of variables that are passed to the Template Toolkit template by default, you'll find it in the View chapter.
Contents, Next The Beer Database Revisited, Previous Standard Templates and Actions
Maypole::Manual::Workflow - Maypole's Request Workflow |