Maypole...Workflow(3)
NAME π
Maypole::Manual::Workflow β Maypole's Request Workflow β¨
DESCRIPTION π
okay bestie, so this chapter is literally a backstage tour of what happens to a request as it makes its way through Maypole. π
An app built on Maypole hands you an Apache or CGI handler, and eventually it delivers a page. This doc explains how that whole glow-up happens, and how you can influence it. We're using the BeerDB project as our example, because obviously. π Here's a diagram that gives the vibe at a glance:
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)
Initialize class π§
When the first request comes in, the application class calls its own init method (inherited from Maypole, no cap). This creates a new view object. β¨
Construction ποΈ
Once we've initialized, the handler grabs the configuration for your class and drops it into a new object. For the purposes of this doc we call that a request object; it's gonna be a shiny new BeerDB object. π¦
Getting the request π₯
Next, the handler calls get_request on the new object so it can stash a copy of the Apache::Request. And ngl, if you're not on Apache, you might wanna subclass this method so it returns something that looks like an Apache::Request object β and honestly you might also subclass the next stage while you're at it, to get more control over what methods get called on your A::R-lookalike. get_request is expected to put the object in the ar slot of the request object. periodt. π
Handling the URL π
Typically the deets of the request get passed in through the URL. This happens via the parse_location method, which is expected to populate several slots of the request object. First up, table and action should be filled with the name of the table and the action parts of the URL. Any other arguments go 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 are not obsessed with the idea of passing literally everything around in the URL β this is the method you override for that. Of course, you'll also need to provide your own default templates to construct links using your preferred format. π
Is this an applicable URL? π¦
Next, is_applicable works out if this is actually something 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. iykyk.
Are we allowed to do this? π
We then look for an appropriate authenticate method to call; first it tries calling the authenticate method of the model class, or, if that one doesn't exist, the authenticate method on itself. By default this allows access to everyone for everything (the audacity, honestly π). Your authenticate methods must return an Apache status code: OK or DECLINED. These codes are defined by the Maypole::Constants module, which is automatically used by your application. β¨
Add any additional data to the request β
You can write an additional_data method to do any additional fiddling with the request object before it gets despatched. Specifically, it lets you 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. slay. π«Ά
Ask model for widget set π
Asking the model class to process the current request lets it 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 we've selected. It sets the template name to the name of the action, and 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 usually does whatever actions are required, including modifying the list of objects to be passed to the template, or the name of the template to be called. main character energy fr fr. π
Ask view to process template πΌοΈ
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. iconic. π
Default template arguments π
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. π¦
Links π
- Contents
- Next β The Beer Database Revisited
- Previous β Standard Templates and Actions
okay that's the whole tour bestie, go build something cute πβ¨
this page is from perl v5.42.0, dated 2025-07-25 β bye babe, drink some water π«Ά
π¦ where this page comes from
- fedora 43: perl-Maypole 1:2.13-46.fc43 Β· GPL-1.0-or-later OR Artistic-1.0-Perl
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms