|
|
| |
Maypole(3) |
User Contributed Perl Documentation |
Maypole(3) |
Maypole - MVC web application framework
The canonical example used in the Maypole documentation is the beer database:
package BeerDB;
use strict;
use warnings;
# choose a frontend, initialise the config object, and load a plugin
use Maypole::Application qw/Relationship/;
# set everything up
__PACKAGE__->setup("dbi:SQLite:t/beerdb.db");
# get the empty config object created by Maypole::Application
my $config = __PACKAGE__->config;
# basic settings
$config->uri_base("http://localhost/beerdb");
$config->template_root("/path/to/templates");
$config->rows_per_page(10);
$config->display_tables([qw/beer brewery pub style/]);
# table relationships
$config->relationships([
"a brewery produces beers",
"a style defines beers",
"a pub has beers on handpumps",
]);
# validation
BeerDB::Brewery->untaint_columns( printable => [qw/name notes url/] );
BeerDB::Pub->untaint_columns( printable => [qw/name notes url/] );
BeerDB::Style->untaint_columns( printable => [qw/name notes/] );
BeerDB::Beer->untaint_columns(
printable => [qw/abv name price notes/],
integer => [qw/style brewery score/],
date => [ qw/date/],
);
# note : set up model before calling this method
BeerDB::Beer->required_columns([qw/name/]);
1;
This documents the Maypole request object. See the Maypole::Manual, for a
detailed guide to using Maypole.
Maypole is a Perl web application framework similar to Java's
struts. It is essentially completely abstracted, and so doesn't know
anything about how to talk to the outside world.
To use it, you need to create a driver package which represents
your entire application. This is the
"BeerDB" package used as an example in the
manual.
This needs to first use Maypole::Application which will make your
package inherit from the appropriate platform driver such as
"Apache::MVC" or
"CGI::Maypole". Then, the driver calls
"setup". This sets up the model classes
and configures your application. The default model class for Maypole uses
Class::DBI to map a database to classes, but this can be changed by altering
configuration (before calling setup.)
Note that some details in some of these resources may be out of date.
- The Maypole Manual
- The primary documentation is the Maypole manual. This lives in the
"Maypole::Manual" pod documents included
with the distribution.
- Embedded POD
- Individual packages within the distribution contain (more or less)
detailed reference documentation for their API.
- Mailing lists
- There are two mailing lists - maypole-devel and maypole-users - see
http://maypole.perl.org/?MailingList
- The Maypole Wiki
- The Maypole wiki provides a useful store of extra documentation -
http://maypole.perl.org
In particular, there's a FAQ (http://maypole.perl.org/?FAQ)
and a cookbook (http://maypole.perl.org/?Cookbook). Again, certain
information on these pages may be out of date.
- Web applications with Maypole
- A tutorial written by Simon Cozens for YAPC::EU 2005 -
http://www.aarontrevena.co.uk/opensource/maypole/maypole-tutorial.pdf
[228KB].
- A Database-Driven Web Application in 18 Lines of Code
- By Paul Barry, published in Linux Journal, March 2005.
http://www.linuxjournal.com/article/7937
"From zero to Web-based database application in eight
easy steps".
Maypole won a 2005 Linux Journal Editor's Choice Award
(http://www.linuxjournal.com/article/8293) after featuring in this
article.
- Build Web apps with Maypole
- By Simon Cozens, on IBM's DeveloperWorks website, May 2004.
http://www-128.ibm.com/developerworks/linux/library/l-maypole/
- Rapid Web Application Deployment with Maypole
- By Simon Cozens, on O'Reilly's Perl website, April 2004.
http://www.perl.com/pub/a/2004/04/15/maypole.html
- Authentication
- Some notes written by Simon Cozens. A little bit out of date, but still
very useful:
http://www.aarontrevena.co.uk/opensource/maypole/authentication.html
- CheatSheet
- There's a refcard for the Maypole (and Class::DBI) APIs on the wiki -
http://maypole.perl.org/?CheatSheet. Probably a little out of date now -
it's a wiki, so feel free to fix any errors!
- Plugins and add-ons
- There are a large and growing number of plugins and other add-on modules
available on CPAN -
http://search.cpan.org/search?query=maypole&mode=module
- del.icio.us
- You can find a range of useful Maypole links, particularly to several
thoughtful blog entries, starting here:
http://del.icio.us/search/?all=maypole
- CPAN ratings
- There are a couple of short reviews here:
http://cpanratings.perl.org/dist/Maypole
As a framework, Maypole provides a number of hooks - methods that are
intended to be overridden. Some of these methods come with useful default
behaviour, others do nothing by default. Hooks include:
Class methods
-------------
debug
setup
setup_model
load_model_subclass
init
Instance methods
----------------
start_request_hook
is_model_applicable
get_session
authenticate
exception
additional_data
preprocess_path
- debug
-
sub My::App::debug {1}
Returns the debugging flag. Override this in your application
class to enable/disable debugging.
You can also set the "debug"
flag via Maypole::Application.
Some packages respond to higher debug levels, try increasing
it to 2 or 3.
- config
- Returns the Maypole::Config object
- setup
-
My::App->setup($data_source, $user, $password, \%attr);
Initialise the Maypole application and plugins and model
classes. Your application should call this after setting up
configuration data via "config".
It calls the hook
"setup_model" to setup the model. The
%attr hash contains options and arguments used
to set up the model. See the particular model's documentation. However
here is the most usage of setup where Maypole::Model::CDBI is the base
class.
My::App->setup($data_source, $user, $password,
{ options => { # These are DB connection options
AutoCommit => 0,
RaiseError => 1,
...
},
# These are Class::DBI::Loader arguments.
relationships => 1,
...
}
);
Also, see Maypole::Manual::Plugins.
- setup_model
- Called by "setup". This method builds
the Maypole model hierarchy.
A likely target for over-riding, if you need to build a
customised model.
This method also ensures any code in custom model classes is
loaded, so you don't need to load them in the driver.
- load_model_subclass($subclass)
- This method is called from
"setup_model()". It attempts to load the
$subclass package, if one exists. So if you make a
customized "BeerDB::Beer" package, you
don't need to explicitly load it.
If automatic loading causes problems, Override
load_model_subclass in your driver.
sub load_model_subclass {};
Or perhaps during development, if you don't want to load up
custom classes, you can override this method and load them manually.
- init
- Loads the view class and instantiates the view object.
You should not call this directly, but you may wish to
override this to add application-specific initialisation - see
Maypole::Manual::Plugins.
- new
- Constructs a very minimal new Maypole request object.
- view_object
- Get/set the Maypole::View object
- handler
- This method sets up the class if it's not done yet, sets some defaults and
leaves the dirty work to
"handler_guts".
- component
-
Run Maypole sub-requests as a component of the request
[% request.component("/beer/view_as_component/20") %]
Allows you to integrate the results of a Maypole request into an existing
request. You'll need to set up actions and templates
which return fragments of HTML rather than entire pages, but once you've
done that, you can use the C<component> method of the Maypole request object
to call those actions. You may pass a query string in the usual URL style.
You should not fully qualify the Maypole URLs.
Note: any HTTP POST or URL parameters passed to the parent are
not passed to the component sub-request, only what is included in the
url passed as an argument to the method
- handler_guts
- This is the main request handling method and calls various methods to
handle the request/response and defines the workflow within Maypole.
- warn
- $r->warn('its all gone pete tong');
Warn must be implemented by the backend, i.e. Apache::MVC and
warn to stderr or appropriate logfile.
You can also over-ride this in your Maypole driver, should you
want to use something like Log::Log4perl instead.
- build_form_elements
- $r->build_form_elements(0);
Specify (in an action) whether to build HTML form elements and
populate the cgi element of classmetadata in the view.
You can set this globally using the accessor of the same name
in Maypole::Config, this method allows you to over-ride that setting per
action.
- get_request
- You should only need to define this method if you are writing a new
Maypole backend. It should return something that looks like an Apache or
CGI request object, it defaults to blank.
- parse_location
- Turns the backend request (e.g. Apache::MVC, Maypole, CGI) into a Maypole
request. It does this by setting the
"path", and invoking
"parse_path" and
"parse_args".
You should only need to define this method if you are writing
a new Maypole backend.
- start_request_hook
- This is called immediately after setting up the basic request. The default
method does nothing.
The value of "$r->status"
is set to "OK" before this hook is
run. Your implementation can change the status code, or leave it
alone.
After this hook has run, Maypole will check the value of
"status". For any value other than
"OK", Maypole returns the
"status" immediately.
This is useful for filtering out requests for static files,
e.g. images, which should not be processed by Maypole or by the
templating engine:
sub start_request_hook
{
my ($r) = @_;
$r->status(DECLINED) if $r->path =~ /\.jpg$/;
}
Multiple plugins, and the driver, can define this hook -
Maypole will call all of them. You should check for and probably not
change any non-OK "status" value:
package Maypole::Plugin::MyApp::SkipFavicon;
sub start_request_hook
{
my ($r) = @_;
# check if a previous plugin has already DECLINED this request
# - probably unnecessary in this example, but you get the idea
return unless $r->status == OK;
# then do our stuff
$r->status(DECLINED) if $r->path =~ /favicon\.ico/;
}
- is_applicable
- This method is deprecated as of version 2.11. If you have
overridden it, please override
"is_model_applicable" instead, and
change the return type from a Maypole:Constant to a true/false value.
Returns a Maypole::Constant to indicate whether the request is
valid.
- is_model_applicable
- Returns true or false to indicate whether the request is valid.
The default implementation checks that
"$r->table" is publicly accessible
and that the model class is configured to handle the
"$r->action".
- get_session
- Called immediately after
"start_request_hook()".
This method should return a session, which will be stored in
the request's "session" attribute.
The default method is empty.
- get_user
- Called immediately after "get_session".
This method should return a user, which will be stored in the
request's "user" attribute.
The default method is empty.
- call_authenticate
- This method first checks if the relevant model class can authenticate the
user, or falls back to the default authenticate method of your Maypole
application.
- authenticate
- Returns a Maypole::Constant to indicate whether the user is authenticated
for the Maypole request.
The default implementation returns
"OK"
- call_exception
- This model is called to catch exceptions, first after authenticate, then
after processing the model class, and finally to check for exceptions from
the view class.
This method first checks if the relevant model class can
handle exceptions the user, or falls back to the default exception
method of your Maypole application.
- exception
- This method is called if any exceptions are raised during the
authentication or model/view processing. It should accept the exception as
a parameter and return a Maypole::Constant to indicate whether the request
should continue to be processed.
- additional_data
- Called before the model processes the request, this method gives you a
chance to do some processing for each request, for example, manipulating
"template_args".
- send_output
- Sends the output and additional headers to the user.
- path
- Returns the request path
- parse_path
- Parses the request path and sets the
"args",
"action" and
"table" properties. Calls
"preprocess_path" before parsing path
and setting properties.
- preprocess_path
- Sometimes when you don't want to rewrite or over-ride parse_path but want
to rewrite urls or extract data from them before it is parsed, the
preprocess_path/location methods allow you to munge paths and urls before
maypole maps them to actions, classes, etc.
This method is called after parse_location has populated the
request information and before parse_path has populated the model and
action information, and is passed the request object.
You can set action, args or table in this method and
parse_path will then leave those values in place or populate them based
on the current value of the path attribute if they are not present.
- preprocess_location
- This method is called at the start of parse_location, after the headers
in, and allows you to rewrite the url used by maypole, or dynamically set
configuration like the base_uri based on the hostname or path.
- make_path( %args or \%args or @args )
- This is the counterpart to "parse_path".
It generates a path to use in links, form actions etc. To implement your
own path scheme, just override this method and
"parse_path".
%args = ( table => $table,
action => $action,
additional => $additional, # optional - generally an object ID
);
\%args = as above, but a ref
@args = ( $table, $action, $additional ); # $additional is optional
"id" can be used as an
alternative key to "additional".
$additional can be a string, an
arrayref, or a hashref. An arrayref is expanded into extra path
elements, whereas a hashref is translated into a query string.
- make_uri( @segments )
- Make a URI object given table, action etc. Automatically adds the
"uri_base".
If the final element in @segments is a
hash ref, "make_uri" will render it as
a query string.
- parse_args
- Turns post data and query string paramaters into a hash of
"params".
You should only need to define this method if you are writing
a new Maypole backend.
- get_template_root
- Implementation-specific path to template root.
You should only need to define this method if you are writing
a new Maypole backend. Otherwise, see "template_root" in
Maypole::Config
- model_class
- Returns the perl package name that will serve as the model for the
request. It corresponds to the request
"table" attribute.
- objects
- Get/set a list of model objects. The objects will be accessible in the
view templates.
If the first item in
"$self->args" can be
"retrieve()"d by the model class, it
will be removed from "args" and the
retrieved object will be added to the
"objects" list. See Maypole::Model for
more information.
- object
- Alias to get/set the first/only model object. The object will be
accessible in the view templates.
When used to set the object, will overwrite the request
objects with a single object.
- template_args
-
$self->template_args->{foo} = 'bar';
Get/set a hash of template variables.
Maypole reserved words for template variables will over-ride
values in template_variables.
Reserved words are : r, request, object, objects, base, config
and errors, as well as the current class or object name.
- stash
- A place to put custom application data. Not used by Maypole itself.
- template
- Get/set the template to be used by the view. By default, it returns
"$self->action"
- error
- Get/set a request error
- output
- Get/set the response output. This is usually populated by the view class.
You can skip view processing by setting the
"output".
- table
- The table part of the Maypole request path
- action
- The action part of the Maypole request path
- args
- A list of remaining parts of the request path after table and action have
been removed
- headers_in
- A Maypole::Headers object containing HTTP headers for the request
- headers_out
- A HTTP::Headers object that contains HTTP headers for the output
- document_encoding
- Get/set the output encoding. Default: utf-8.
- content_type
- Get/set the output content type. Default: text/html
- get_protocol
- Returns the protocol the request was made with, i.e. https
The source of the parameters may vary depending on the Maypole backend, but they
are usually populated from request query string and POST data.
Maypole supplies several approaches for accessing the request
parameters. Note that the current implementation (via a hashref) of
"query" and
"params" is likely to change in a future
version of Maypole. So avoid direct access to these hashrefs:
$r->{params}->{foo} # bad
$r->params->{foo} # better
$r->{query}->{foo} # bad
$r->query->{foo} # better
$r->param('foo') # best
- param
- An accessor (get or set) for request parameters. It behaves similarly to
CGI::param() for accessing CGI parameters, i.e.
$r->param # returns list of keys
$r->param($key) # returns value for $key
$r->param($key => $value) # returns old value, sets to new value
- params
- Returns a hashref of request parameters.
Note: Where muliple values of a parameter were
supplied, the "params" value will be
an array reference.
- query
- Alias for "params".
Utility methods
- redirect_request
- Sets output headers to redirect based on the arguments provided
Accepts either a single argument of the full url to redirect
to, or a hash of named parameters :
$r->redirect_request('http://www.example.com/path');
or
$r->redirect_request(protocol=>'https',
domain=>'www.example.com', path=>'/path/file?arguments',
status=>'302', url=>'..');
The named parameters are protocol, domain, path, status and
url
Only 1 named parameter is required but other than url, they
can be combined as required and current values (from the request) will
be used in place of any missing arguments. The url argument must be a
full url including protocol and can only be combined with status.
- make_random_id
- returns a unique id for this request can be used to prevent or detect
repeat submissions.
See Maypole::Manual::Workflow for a detailed discussion of the sequence of calls
during processing of a request. This is a brief summary:
INITIALIZATION
Model e.g.
BeerDB Maypole::Model::CDBI
| |
setup | |
o-------->|| |
|| setup_model | setup_database() creates
||------+ | a subclass of the Model
|||<----+ | for each table
||| | |
||| setup_database | |
|||--------------------->|| 'create' *
||| ||----------> $subclass
||| | |
||| load_model_subclass | |
foreach |||------+ ($subclass) | |
$subclass ||||<----+ | require |
||||--------------------------------------->|
||| | |
||| adopt($subclass) | |
|||--------------------->|| |
| | |
| | |
|-----+ init | |
||<---+ | |
|| | new | view_object: e.g.
||---------------------------------------------> Maypole::View::TT
| | | |
| | | |
| | | |
| | | |
| | | |
HANDLING A REQUEST
BeerDB Model $subclass view_object
| | | |
handler | | | |
o-------->| new | | |
|-----> r:BeerDB | | |
| | | | |
| | | | |
| || | | |
| ||-----+ parse_location | | |
| |||<---+ | | |
| || | | |
| ||-----+ start_request_hook | | |
| |||<---+ | | |
| || | | |
| ||-----+ get_session | | |
| |||<---+ | | |
| || | | |
| ||-----+ get_user | | |
| |||<---+ | | |
| || | | |
| ||-----+ handler_guts | | |
| |||<---+ | | |
| ||| class_of($table) | | |
| |||------------------------->|| | |
| ||| $subclass || | |
| |||<-------------------------|| | |
| ||| | | |
| |||-----+ is_model_applicable| | |
| ||||<---+ | | |
| ||| | | |
| |||-----+ call_authenticate | | |
| ||||<---+ | | |
| ||| | | |
| |||-----+ additional_data | | |
| ||||<---+ | | |
| ||| process | | |
| |||--------------------------------->|| fetch_objects
| ||| | ||-----+ |
| ||| | |||<---+ |
| ||| | || |
| ||| | || $action
| ||| | ||-----+ |
| ||| | |||<---+ |
| ||| process | | |
| |||------------------------------------------->|| template
| ||| | | ||-----+
| ||| | | |||<---+
| ||| | | |
| || send_output | | |
| ||-----+ | | |
| |||<---+ | | |
$status | || | | |
<------------------|| | | |
| | | | |
| X | | |
| | | |
| | | |
| | | |
There's more documentation, examples, and information on our mailing lists at
the Maypole web site:
<http://maypole.perl.org/>
Maypole::Application, Apache::MVC, CGI::Maypole.
Maypole is currently maintained by Aaron Trevena.
Simon Cozens, "simon#cpan.org"
Simon Flack maintained Maypole from 2.05 to 2.09
Sebastian Riedel, "sri#oook.de"
maintained Maypole from 1.99_01 to 2.04
Sebastian Riedel, Danijel Milicevic, Dave Slack, Jesse Sheidlower, Jody Belka,
Marcus Ramberg, Mickael Joanne, Randal Schwartz, Simon Flack, Steve Simms,
Veljko Vidovic and all the others who've helped.
You may distribute this code under the same terms as Perl itself.
Visit the GSP FreeBSD Man Page Interface. Output converted with ManDoc. |