=head2 What is Maypole?
+=head2 The Beer Database example
+
+Throughout this manual, we're going to be referring back to a particular
+application so that we can give concrete examples for the concepts we're
+talking about. We could say "C<related_accessors> returns a list of
+accessors which can be called to return a list of objects in a has-a
+relationship to the original", or we could say "if we call
+C<related_accessors> on while viewing C<brewery>, it returns C<beers>,
+because we can call C<beers> on a C<brewery> object to get a list of
+that berwery's beers."
+
+Because Maypole is all about beer. If you look carefully, you can
+probably see men playing cricket on the village green. The first
+ever Maypole application was written to help me keep track of the many
+different ales available in my area - their styles, their tastes, their
+breweries, prices and so on. Then the more I thought about it, the more
+I thought it was a particularly good data model for demonstrating
+different kinds of database relationships.
+
+We have a C<brewery> table, which has several C<beer>s. We'll call this
+a has-many relationship. The beers each have a C<style>; styles are
+stored in a separate table, so C<beer> has-a C<style>. Beers are in
+several pubs and a pub has several beers, so beers and pubs are in a
+many-to-many relationship. We use a link table called C<handpump> to
+relate pubs to beers.
+
+All in all, this gives us a schema like the following:
+
+ create table brewery (
+ id int not null auto_increment primary key,
+ name varchar(30),
+ url varchar(50),
+ notes text
+ );
+
+ create table beer (
+ id int not null auto_increment primary key,
+ brewery integer,
+ style integer,
+ name varchar(30),
+ url varchar(120),
+ score integer(2),
+ price varchar(12),
+ abv varchar(10),
+ notes text
+ );
+
+ create table handpump (
+ id int not null auto_increment primary key,
+ beer integer,
+ pub integer
+ );
+
+ create table pub (
+ id int not null auto_increment primary key,
+ name varchar(60),
+ url varchar(120),
+ notes text
+ );
+
+ create table style (
+ id int not null auto_increment primary key,
+ name varchar(60),
+ notes text
+ );
+
+If you have C<DBD::SQLite> available, then a database like this will
+be created when Maypole was installed. Let's now see how to set it up
+with a web interface.
+
+=head2 Setting up Maypole
+
+The first thing we need for a Maypole interface to a database is to
+have a database. If you don't have one, now would be a good time to
+create one, using the schema above.
+
+The next thing we need is a module which is going to do all the work.
+Thankfully, it doesn't need to do B<all> the work itself. It's going to be a
+subclass of C<Maypole> or a Maypole front-end like C<Apache::MVC>.
+
+Here's the driver class for our beer database application. We're not
+going to go into much detail about it here; we'll do that in L<Beer.pod>.
+For now, simply admire its brevity, as you realise this is all the code
+you need to write for a simple database front-end:
+
+ package BeerDB;
+ use base 'Apache::MVC';
+ use Class::DBI::Loader::Relationship;
+ BeerDB->set_database("dbi:SQLite:t/beerdb.db");
+ BeerDB->config->{uri_base} = "http://localhost/beerdb/";
+ BeerDB->config->{rows_per_page} = 10;
+ BeerDB->config->{display_tables} = [qw[beer brewery pub style]];
+ BeerDB::Brewery->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/],
+ );
+ BeerDB->config->{loader}->relationship($_) for (
+ "a brewery produces beers",
+ "a style defines beers",
+ "a pub has beers on handpumps");
+ 1;
+
+This defines the C<BeerDB> application, which, as it inherits from
+C<Apache::MVC>, will be a mod_perl handler. This means we need to
+tell the Apache configuration about it:
+
+ <Location /beerdb>
+ SetHandler perl-script
+ PerlHandler BeerDB
+ </Location>
+
+And now we need some templates. As we'll see in the chapter on views,
+L<View.pod>, there are several types of template. We're going to copy
+the whole lot from the F<templates/> directory of the Maypole source
+package into the F</beerdb> directory under our web root.
+
+And that's it. We should now be able to go to C<http://localhost/beerdb/>
+and see a menu of things to browse; C<http://localhost/beerdb/beer/list>
+will give a list of beers. There might not be any yet. There's a box
+that lets you add them.
+
+If you have any problems getting to this point, you might want to look
+at L<http://wiki.simon-cozens.org/index.cgi?InstallationIssues>.
+
+Play about with the site. Add some beers. Maybe go out and buy some beers
+to review if you need some inspiration. Don't be ill on my carpet.
+
=head2 Phases of a Maypole request
+Now you should have a feel for what Maypole can do. The important thing
+to know at this point is that this is by no means B<all> that Maypole
+can do. What you've seen in the beer database example is all that Maypole
+can do if you don't customize it at all.
+
+Remember that, for instance, we don't ever tell Maypole what tables our
+database has, or what columns each table has. We don't tell Maypole what
+those tables should be called or how to display them. We don't tell Maypole
+what to do - that we want to list, search, edit and delete beers and breweries.
+Maypole just works that out for itself. We can customize it and have Maypole
+do all sorts of interesting things with our database, and most of the rest
+of this manual will be about how to do that.
+
+In order to do that, we need to look at what Maypole's actually doing.
+
+XXX
+
=head2 The model class
=head2 The view class