Maypole2

From Books

Jump to: navigation, search

Contents

[edit] Simple Applications

The Maypole web application framework can be used on two levels: first, as a simple way to add an interface to a database (and not much else besides), and second, as a toolkit for building more sophisticated web applications. In principle, there is a continuum of possible usages between these two levels, but it seems best for the purposes of teaching to entirely separate them.

In the first part of this tutorial, we're going to quickly dispatch the first level of operation, putting a front-end onto a database. Not only is this useful in its own right in many cases, it both gives a demonstration of the power and flexibility of Maypole, and provides a useful basis for showing how Maypole applications can be expanded.

[edit] The Scenario

As many of you know, I'm not really a Perl programmer any more; instead, I'm a missionary. It's a bit of a strange job, since I don't actually get paid, but I get funded by various supporters. I have a very bad memory, and need to be reminded who my supporters are, how much they pay me, and how I need to get in touch with them to let them know what I'm doing and how their money is being used.

This sounds like the ideal job for a little relational database, and so I drew up the following schema:

Figure 1.1. Supporters database

Image:Supporters.png

CREATE TABLE supporter (
    id integer auto_increment primary key,
    title varchar(5),
    first varchar(30),
    last varchar(50),
    email varchar(255),
    address text,
    email_newsletter integer(1),
    written_newsletter integer(1)
);
CREATE TABLE gift (
    id integer auto_increment primary key,
    supporter integer,
    amount decimal(6,2),
    gifted date
);

CREATE TABLE regular (
    id integer auto_increment primary key,
    supporter integer,
    amount decimal(6,2),
    recurrence integer,
    started date
);

CREATE table recurrence (
    id integer auto_increment primary key,
    name varchar(255),
    basic_method varchar(255),
    every integer
);

Now, to add and update supporters, what do I do? I don't really want to type in SQL all the time, so I wanted a web front-end to this database. This is where Maypole comes in.

[edit] Writing the "driver"

We're going to start with a very, very basic Maypole application, and then build it up to be a little more sophisticated. Here's the bare minimum we need:


package Supporters;
use Maypole::Application;
Supporters->setup("dbi:mysql:supporters");
Supporters->config->{uri_base} = "http://localhost/supporters/";
Supporters->config->{template_root} =
 "/home/simon/maypole-sites/supporters/templates/";

Supporters->config->{loader}->relationship($_) for (
    "a supporter has many gifts",
    "a supporter has many regulars",
    "a regular has a recurrence"
);
1

XXX Need to go through this in more detail.

This should be reasonably self-evident: we say that we're a Maypole application, set up the database DSN we want to use, tell the application where we're going to live on the web, and where our templates are going to be, and then define some relationships: a supporter gives one-off gifts and regular gifts, and a regular gift has a recurrence relation to tell us how regular it is.

The actual version I use has a few more niceties to make it work more smoothly, but we'll come to those in time.

[edit] Configuring Apache

Now we have the Perl module which is going to drive our Maypole application, we next need to tell Apache about it. First if we haven't installed this driver module and it's not sitting in Perl's @INC, then we need to tell Perl where to find it:


<Perl>
use lib qw(
          /home/simon/maypole-sites/supporters/
        );
</Perl>

And next we have to associate the driver with a location:


<Location /supporters>
    PerlHandler Supporters
    SetHandler perl-script
</Location>

Almost finally, we need to put Maypole's factory templates where we said we would:


% cp -r ~/maypole/templates/factory /home/simon/maypole-sites/supporters/templates/

And finally, we restart Apache. Now on going to the relevant URL, we should have an application up and running...

[edit] What we get

XXX Demonstrate

Those few lines of code have actually got us a long way. Here we can add and edit rows in the database, view relationships between various rows, and delete entries. Each table has a set of pages: view, list, edit, delete and so on.

For the supporters database project, I didn't actually need anything else - I just needed the ability to put rows into the database and see what was already there. For quick applications like this, Maypole is ideal. But Maypole comes into its own when you start to add "actions" to the application - for instance, if I wanted to have a page which totalled all donations from different sources, then I'd have to start writing some code. We'll see how that works in the next few chapters.

[edit] Behind the scenes

[edit] Warning

This is an advanced section which we're not going to go into during the tutorial, but which explains, for your benefit when rereading these notes afterwards, how all of this works. This should help you to learn about the continuum of Maypole applications, and how to go from simple application like this to the more complex application we see in the second part of the tutorial - that means this isn't going mean very much on the first reading. I'd encourage you to read all of the tutorial notes through before coming back to this; it'll make much more sense that way.

On the other hand, if you feel you understand everything so far and you're bored during the tutorial and want something to read, feel free to dig into this more challenging material.


So far we've just told Maypole about a database and its relationships, and it's come up with a reasonably useful web application all on its own. How?

There are three factors here: first, database introspection. Maypole's view class provides a lot of metadata about the selected model class to the templates. The classmetadata template variable is a hash, which contains the following elements:

Table 1.1. The classmetadata hash

Name Description name The Perl class name of the model class
table The name of the database table
columns A list of the columns we're allowed to display on this table
colnames A mapping between the column names and the same names formatted better for display
related_accessors Method names of the accessors of any has-a relationships
moniker / plural_moniker A "display name" for this model class. (e.g. "supporter" and "supporters")
cgi A hash of HTML elements to be used in constructing forms for this table

From this set of metadata, you can construct a set of templates which do the right thing for pretty much any table. For instance, this template snippet:


[% FOR col = classmetadata.columns %]
<p> [% classmetadata.colnames.$col %] : [% object.$col %] </p>
[% END %]

will list all the columns of a database row along with the value for this particular object.

This brings us to the second phase in the CRUD strategy: Maypole comes with a sufficiently generic set of templates (called the "factory templates") for the CRUD operations we've been using so far; it uses the class metadata to produce pages which look right for whatever shape of database you throw at it.

To finish off the process, there are default actions in each Model base class (for instance, Maypole::Model::CDBI for the default, Class::DBI-based applications) which use the CRUD methods of the underlying data representation to perform the appropriate edit, delete, or whatever actions. So actually, there are a lot of actions going on - both templates and code - but they're squirreled away inside the default model class.

[edit] Exercises

Exercise 1. So far we've got a web application which can handle relationships between tables, and add, display, update, search for and list records. Come up with three examples of a web application that sounds like it would be a complicated problem, but can actually be done as a simple Maypole application like the one we've just created, only with (a) changes to the way the data is displayed and (b) some sort of access control. One free example is a product catalogue for an online business.

Exercise 2. Come up with three examples of a web application which can't be done with these simple actions, and analyse what additional functionality would be required to make it work. Remember these, because we're going to use them later in the tutorial.

Personal tools