]> git.decadent.org.uk Git - maypole.git/blob - lib/Maypole/Manual/About.pod
6f48663e45787434fd658b00ebfc863b1fd344f8
[maypole.git] / lib / Maypole / Manual / About.pod
1
2 =head1 NAME
3
4 Maypole::Manual::About - Introduction to Maypole
5
6 =head1 DESCRIPTION
7
8 This chapter serves as a gentle introduction to Maypole and setting up
9 Maypole applications. We look at what Maypole is, how to get it up and
10 running, and how to start thinking about building Maypole applications.
11
12 =head2 What is Maypole?
13
14 Presumably you have some idea of what Maypole is all about, or otherwise
15 you wouldn't be reading this manual. But Maypole is good at many
16 different things, and you may have accidentally focussed on one aspect
17 of Maypole while missing the big picture.
18
19 For instance, you may know that Maypole is extremely good at putting web
20 front-ends onto databases. This is true, but it's only a part of what
21 Maypole does. You may have heard that Maypole is a web application
22 framework, which is true, but it doesn't mean very much. There are a
23 huge number of things that Maypole can do, because it's very much a
24 blank slate. You can make it do what you will. In this manual, we'll be
25 making it act as a front-end to a database, as a social network site, as
26 an intranet portal, and many other things besides. It is a framework.
27
28 I like to think that Maypole is a way of going from a URL to a method
29 call to some output. If you have a URL like C</product/order/12>,
30 Maypole is a way of having it load up product number 12, call an
31 C<order> method, and produce a page about what it's just done. The
32 reason Maypole is such a big deal is because it does all this for you.
33 You no longer have to care about your web server. You hardly have to
34 care about your database. You don't have to care about templating
35 modules, parsing CGI parameters, or anything else. You only need to care
36 about business logic, and the business logic in this instance is how you
37 C<order> a product, and what you need to display about it once you've
38 done so. This is what programming should be: only caring about the work
39 that distinguishes one program from another.
40
41 It does this using a technique called MVC for web applications.
42
43 =head2 What is MVC for web applications?
44
45 Maypole was originally called C<Apache::MVC>, reflecting its basis in
46 the Model-View-Controller design pattern. (I had to change it firstly
47 because Maypole isn't tied to Apache, and secondly because
48 C<Apache::MVC> is a really dull name.) It's the same design pattern that
49 forms the foundation of similar projects in other languages, such as
50 Java's Struts framework.
51
52 This design pattern is found primarily in graphical applications; the
53 idea is that you have a Model class which represents and manipulates
54 your data, a View class which is responsible for displaying that data to
55 the user, and a Controller class which controls the other classes in
56 response to events triggered by the user. This analogy doesn't
57 correspond precisely to a web-based application, but we can take an
58 important principle from it. As Template Toolkit author Andy Wardley explains:
59
60     What the MVC-for-the-web crowd are really trying to achieve is a clear
61     separation of concerns.  Put your database code in one place, your 
62     application code in another, your presentation code in a third place.  
63     That way, you can chop and change different elements at will,
64     hopefully without affecting the other parts (depending on how well your
65     concerns are separated, of course).  This is common sense and good practice.
66     MVC achieves this separation of concerns as a by-product of clearly 
67     separating inputs (controls) and outputs (views). 
68
69 This is what Maypole does. It has a number of database drivers, a number
70 of front-end drivers and a number of templating presentation drivers.
71 In common cases, Maypole provides precisely what you need for all of
72 these areas, and you get to concentrate on writing just the business
73 logic of your application. This is one of the reasons why Maypole lets
74 you develop so rapidly: because most of the time, you don't need to do
75 any development at all.
76
77
78 =head2 The Beer Database example
79
80 Throughout this manual, we're going to be referring back to a particular
81 application so that we can give concrete examples for the concepts we're
82 talking about. We could say "C<related_accessors> returns a list of
83 accessors which can be called to return a list of objects in a has-a
84 relationship to the original", or we could say "if we call
85 C<related_accessors> while viewing a C<brewery>, it returns C<beers>,
86 because we can call C<beers> on a C<brewery> object to get a list of
87 that brewery's beers." 
88
89 Because Maypole is all about beer. If you look carefully, you can
90 probably see men playing cricket on the village green. The first
91 ever Maypole application was written to help me keep track of the many
92 different ales available in my area - their styles, their tastes, their
93 breweries, prices and so on. Then the more I thought about it, the more
94 I thought it was a particularly good data model for demonstrating
95 different kinds of database relationships.
96
97 We have a C<brewery> table, which has several C<beer>s. We'll call this
98 a has-many relationship. The beers each have a C<style>; styles are
99 stored in a separate table, so C<beer> has-a C<style>. Beers are in
100 several pubs and a pub has several beers, so beers and pubs are in a
101 many-to-many relationship. We use a link table called C<handpump> to
102 relate pubs to beers.
103
104 All in all, this gives us a schema like the following:
105
106     create table brewery (
107         id int not null auto_increment primary key,
108         name varchar(30),
109         url varchar(50),
110         notes text
111     );
112
113     create table beer (
114         id int not null auto_increment primary key,
115         brewery integer,
116         style integer, 
117         name varchar(30),
118         url varchar(120),
119         score integer(2),
120         price varchar(12),
121         abv varchar(10),
122         notes text
123     );
124
125     create table handpump (
126         id int not null auto_increment primary key,
127         beer integer,
128         pub integer
129     );
130
131     create table pub (
132         id int not null auto_increment primary key,
133         name varchar(60),
134         url varchar(120),
135         notes text
136     );
137
138     create table style (
139         id int not null auto_increment primary key,
140         name varchar(60),
141         notes text
142     );
143
144 If you have C<DBD::SQLite> available, then a database like this will
145 be created when Maypole was installed. Let's now see how to set it up
146 with a web interface.
147
148 =head2 Setting up Maypole
149
150 The first thing we need for a Maypole interface to a database is to
151 have a database. If you don't have one, now would be a good time to
152 create one, using the schema above. If you're creating a database
153 by hand, don't forget to grant permissions for your Apache server to
154 access it as well as yourself (typically a user name like C<www-data>
155 or C<wwwrun>).
156
157 The next thing we need is a module which is going to do all the work.
158 Thankfully, it doesn't need to do B<all> the work itself. It's going to be a 
159 subclass of C<Maypole> or a Maypole front-end like C<Apache::MVC>. 
160 It roughly corresponds to the controller in an MVC design, and is
161 also referred to as the driver, handler or request.
162
163 Here's the driver class for our beer database application. We're not
164 going to go into much detail about it here; we'll do that in the
165 L<Beer Database|Maypole::Manual::Beer> chapter.
166 For now, simply admire its brevity, as you realise this is all the code
167 you need to write for a simple database front-end:
168
169     package BeerDB;
170     use Maypole::Application;
171     BeerDB->setup("dbi:SQLite:t/beerdb.db");
172     BeerDB->config->uri_base("http://localhost/beerdb");
173     BeerDB->config->template_root("/path/to/templates");
174     BeerDB->config->rows_per_page(10);
175     BeerDB->config->display_tables([qw[beer brewery pub style]]);
176     BeerDB::Brewery->untaint_columns( printable => [qw/name notes url/] );
177     BeerDB::Style->untaint_columns( printable => [qw/name notes/] );
178     BeerDB::Beer->untaint_columns(
179         printable => [qw/abv name price notes/],
180         integer => [qw/style brewery score/],
181         date => [ qw/date/],
182     );
183
184     use Class::DBI::Loader::Relationship;
185     BeerDB->config->{loader}->relationship($_) for (
186         "a brewery produces beers",
187         "a style defines beers",
188         "a pub has beers on handpumps");
189     1;
190
191 There's a version of this program in the F<ex/> directory in the Maypole
192 files that you downloaded in the F<~root/.cpan/> build area.
193 This defines the C<BeerDB> application.
194 To set it up as a mod_perl handler, just tell the Apache configuration
195 about it:
196
197     <Location /beerdb>
198         SetHandler perl-script
199         PerlHandler BeerDB
200     </Location>
201
202 To use it as a CGI script, put it in your F<cgi-bin> directory,
203 together with a small file called F<beer.cgi>:
204
205     #!/usr/bin/perl
206     use strict;
207     use warnings;
208     use BeerDB;
209     BeerDB->run();
210
211 and change one line in C<BeerDB.pm>:
212
213     BeerDB->config->uri_base("http://localhost/cgi-bin/beer.cgi");
214
215 And now we need some templates. As we'll see in the chapter on
216 L<views|Maypole::Manual::View>, there are several types of template.
217 We're going to copy
218 the whole lot from the F<templates/> directory of the Maypole source
219 package into the F</beerdb> directory under our web root.
220 Make the C<template_root> in C<BeerDB> agree with your path.
221
222 And that's it. We should now be able to go to C<http://localhost/beerdb/>
223 or C<http://localhost/cgi-bin/beer.cgi/>
224 and see a menu of things to browse; C<http://localhost/beerdb/beer/list>
225 will give a list of beers. There might not be any yet. There's a box
226 that lets you add them.
227
228 If you have any problems getting to this point, you might want to look at
229 L<http://maypole.perl.org>. There's a FAQ and a link to a mailing
230 list.
231
232 Play about with the site. Add some beers. Maybe go out and buy some beers
233 to review if you need some inspiration. Don't be ill on my carpet.
234
235 =head2 Phases of a Maypole request
236
237 Now you should have a feel for what Maypole can do. The important thing
238 to know at this point is that this is by no means B<all> that Maypole
239 can do. What you've seen in the beer database example is all that Maypole
240 can do if you don't customize it at all.
241
242 Remember that, for instance, we don't ever tell Maypole what tables our
243 database has, or what columns each table has. We don't tell Maypole what
244 those tables should be called or how to display them. We don't tell Maypole
245 what to do - that we want to list, search, edit and delete beers and breweries.
246 Maypole just works that out for itself. We can customize it and have Maypole
247 do all sorts of interesting things with our database, and most of the rest
248 of this manual will be about how to do that.
249
250 In order to do that, we need to look at what Maypole's actually doing.
251 Here's a quick overview, there's more detail in the
252 L<Workflow|Maypole::Manual::Workflow> chapter.
253
254 As mentioned, Maypole is responsible for turning a URL into an object, a
255 method call, and some templated output.
256
257 =for html
258 Here's a handy diagram to explain how it does that:
259
260 =for html
261 <IMG SRC="maypole_process2.png">
262
263 Maypole's process revolves around the concept of the Maypole request
264 object. This is a little like Apache's request object, but at a much
265 higher level - in fact, in C<mod_perl>-based Maypole front-ends, the
266 Apache request object is incorporated in the Maypole request object. All
267 that Maypole does is gradually flesh out this object until it contains
268 something in the C<output> member, and then it is dispatched back to the
269 front-end for output.
270
271 So to start with, we take the Apache request (or CGI object, or other
272 way of isolating what's going on) and break it down. For instance, we
273 turn the URL C</beer/view/1> into
274
275     {
276         table => "beer",
277         action => "view",
278         args => [ 1 ]
279     }
280
281 Then Maypole will check that C<beer> is a real table, and find the class
282 that models it. It also checks whether or not we're allowed to call the
283 C<view> method over the network:
284
285     {
286         table => "beer",
287         action => "view",
288         args => [ 1 ],
289         model_class => "BeerDB::Beer"
290     }
291
292 Then there's a user-defined authentication method, which by default just
293 lets us do anything. Now we hand over to the model class, which loads up
294 the object, and decides what template we want to use:
295
296     {
297         table => "beer",
298         action => "view",
299         args => [ ],
300         objects => [ BeerDB::Beer->retrieve(1) ],
301         model_class => "BeerDB::Beer",
302         template => "view"
303     }
304
305 Then it calls C<BeerDB::Beer-E<gt>view>, passing in the request object
306 as a parameter, and passes the whole lot to the view class for templating.
307 In the next two chapters, we'll look at how Maypole's default model and
308 view classes generally do what you want them to do.
309
310 =head2 Links
311
312 L<Contents|Maypole::Manual>,
313 Next L<Maypole Model Classes|Maypole::Manual::Model>