]> git.decadent.org.uk Git - maypole.git/blob - lib/Maypole/Manual/View.pod
01745ed8a5f6c6c15778f9fea03a4572c6917794
[maypole.git] / lib / Maypole / Manual / View.pod
1 =head1 Maypole View Classes
2
3 In a large application, you will almost certainly want to customize the
4 layout and design of the output pages. This task may even be the purview
5 of a separate team of HTML designers rather than the programmers. Since
6 a typical programmer will try to avoid touching HTML as much as possible
7 and a typical designer will try to avoid touching Perl code, programmers
8 have evolved a system of templating to separate the concerns of
9 programming and designing. 
10
11 One of the core concepts in Maypole is the I<view class>, and this is
12 responsible for routing the data produced in the model class into the
13 templates produced by the designers. Of course, there are a great many
14 possible templating systems and styles, and so there can be a great many
15 possible Maypole view classes. Each view class will take the data from
16 the controller, locate a template to be processed, and hand the whole
17 lot to its preferred templating module, which will then do the hard work
18 of filling in the template and coming up with the output.
19
20 You can choose whatever Maypole view class you want, but the default
21 view class is L<Maypole::View::TT>, and it feeds its data and templates
22 to a module called the Template Toolkit.
23
24 =head2 The Template Toolkit
25
26 The Template Toolkit, written by Andy Wardley, is a very powerful and
27 generic templating system. It provides its own little formatting language
28 which supports loops, conditionals, hash and array dereferences and
29 method calls, macro processing and a plug-in system to connect it to
30 external Perl modules.
31 Its homepage is C<http://www.template-toolkit.org/>.
32 There are several good introductions to the
33 Template Toolkit available: you should have one installed as
34 L<Template::Tutorial::Datafile>; there's one at
35 L<http://www.perl.com/pub/a/2003/07/15/nocode.html>, and of course
36 there's the "Badger Book" - I<The Perl Template Toolkit>, by Andy et al.
37 C<http://www.oreilly.com/catalog/perltt/index.html>
38
39 We'll present a brief introduction here by deconstructing some of the 
40 templates used by Maypole applications. For more deconstruction, see
41 L<Standard Templates and Actions|Maypole::Manual::StandardTemplates>,
42 which is an entire chapter dealing with the
43 factory supplied templates.
44
45 Here's a template that could be called for the front page of the example
46 beer database application, C<custom/frontpage>.
47
48     [% INCLUDE header %]
49
50     <h2> The beer database </h2>
51
52     <TABLE BORDER="0" ALIGN="center" WIDTH="70%">
53     [% FOR table = config.display_tables %]
54     <TR>
55     <TD>
56     <A HREF="[%table%]/list">List by [%table %]</A>
57     </TD>
58     </TR>
59     [% END %]
60     </TABLE>
61
62 The first thing to note about this is that everything outside of the
63 Template Toolkit tags (C<[%> and C<%]>) is output verbatim. That is,
64 somewhere in the output you're guaranteed to see 
65
66     <h2> The beer database </h2>
67
68     <TABLE BORDER="0" ALIGN="center" WIDTH="70%">
69
70 Inside the tags, magic happens. The first piece
71 of magic is the C<[% INCLUDE header %]> directive. This goes away and
72 finds a file called F<header> - don't worry about how it finds that yet,
73 we'll come to that later on - and processes the file's contents as
74 though they were right there in the template. Our F<header> file happens
75 not to contain any C<[% %]> tags, but if it did, they would be processed
76 in the same way as the ones in F<frontpage>. 
77
78 The next piece of magic is this line:
79
80     [% FOR table = config.display_tables %]
81
82 We're seeing a lot of things here at once. C<config> is where we should
83 start looking. This is a template variable, which is what templates are
84 all about - templating means getting data from somewhere outside and
85 presenting it to the user in a useful way, and C<config> is a
86 prime example of data that we want to use. It's actually an object
87 containing configuration parameters for this Maypole application, and
88 one of the methods is C<display_tables>, which returns a list of the
89 database tables that we're supposed to show. In the application, we
90 probably said something like
91
92     BeerDB->config->display_tables([qw[beer brewery pub style]]);
93
94 This stores the four values - C<beer>, C<brewery>, C<pub> and C<style> -
95 in an array, which is placed in the config object using the
96 accessor/mutator method C<display_tables>. Now we're getting them back
97 again. Note that we're not going to show the handpump table.
98
99 The Template Toolkit's dot operator is a sort of do-the-right-thing
100 operator; we can say C<array.0> to get the first element of an array,
101 C<hash.key> to look up the C<key> key in a hash, and C<object.method> to
102 call C<method> on an object. So, for instance, if we said
103 C<config.display_tables.2>, we'd look up the C<display_tables> method in
104 the configuration object and get our array back, then look up the 3rd
105 element and get C<pub>.
106 Thing is, you don't have to care whether C<display_tables> is an object
107 or a hash. You can pretend it's a hash if you want. The syntax is the
108 same, and Template Toolkit knows the right thing to do.
109
110 The C<FOR> loop will repeat the code four times, setting our new
111 variable C<table> to the appropriate array element. This code:
112
113     [% FOR table = config.display_tables %]
114         Hello [% table %]!
115     [% END %]
116
117 will produce something like
118
119     Hello beer!
120     Hello brewery!
121     Hello pub!
122     Hello style!
123
124 In our case, though, we're printing out a table element linking to each
125 database table in turn.
126
127 Here's a slightly more complicated example, adapted from F<factory/pager>.
128 This template is responsible for printing the little page menu at the
129 bottom of a listing if there are more rows in the listing than we want
130 on a single page.
131
132     [% PROCESS macros %]
133     <P ALIGN="center">Pages:
134     [%
135          FOREACH num = [pager.first_page .. pager.last_page];
136               IF num == pager.current_page;
137                 "["; num; "] ";
138               ELSE;
139                 SET args = "?page=" _ num;
140                 SET label = "[" _ num _ "]";
141                 link(classmetadata.table, "list", args, label);
142               END;
143          END;
144     %]
145     </P>
146
147 Maypole will be providing a whole bunch of variables to this template,
148 and we'll look at them all in a moment, but the only ones we need to care
149 about are C<pager> and C<classmetadata>. 
150
151 We start by loading in a bunch of macros. Macros are Template Toolkit's
152 functions - you can provide them some parameters and they'll run a little
153 sub-template based on them. The C<macros> file contains some handy macros
154 that I've found useful for constructing Maypole templates; again, these
155 will be covered in full detail in
156 L<Standard Templates and Actions|Maypole::Manual::StandardTemplates>.
157
158 We're going to be displaying something like this:
159
160     Pages: [1] [2] [3] [4]
161
162 with most of those numbers being a link to the appropriate page. This
163 mean we're going to have to have a list of numbers, and the C<FOREACH> loop
164 provides this: (C<FOREACH> and C<FOR> are identical, just like in Perl.)
165
166          FOREACH num = [pager.first_page .. pager.last_page];
167
168 Here we're manually constructing an array of numbers, using the range
169 operator (C<..>) to fill in all the numbers from the C<first_page> (1)
170 to the C<last_page> (4). The same dot operator is used to ask the C<pager>
171 object what its C<first_page> and C<last_page> are.
172
173 Now we're going to be executing this loop four times, once each for C<num>
174 being set to 1, 2, 3, and 4. At some point, we'll come across the page
175 that we're actually on right now:
176
177       IF num == pager.current_page;
178
179 and in that case, we don't want to produce a link to it. We just want
180 to output it as text, surrounded by square brackets:
181
182                 "["; num; "] ";
183
184 We're using string literals to output the brackets. We don't have to
185 do that. We could say it this way:
186
187     [% ...
188       IF num == pager.current_page;
189     %]
190         [ [% num %] ] 
191     [% ELSE %]
192        ...
193     [% END %]
194
195 But you know, I quite like it my way.
196
197 Now if the number we're printing isn't the number of the current page,
198 we want to make a link. Here's how we do it:
199
200     SET args = "?page=" _ num;
201     SET label = "[" _ num _ "]";
202     link(classmetadata.table, "list", args, label);
203
204 C<SET> declares a new variable of our own. If there was anything called
205 C<args> before, there isn't now. It's going to be the result of our
206 statement C<"?page=" _ num>. C<_> is the concatenation operator, and
207 glues C<?page=> onto the front of our number. So if we want to link to
208 page 4, then the C<args> variable will contain C<?page=4>. Similarly,
209 the C<label> variable will be C<[4]>.
210
211 Now we call a macro, C<link> with these two variables and the value of
212 C<classmetadata.table>. This macro takes four arguments, C<table>, 
213 C<action>, C<args> and C<label>, and constructs a link of the form
214
215     <A HREF="[% base %]/[% table %]/[% action %][% args %]">
216     [% label %]
217     </A>
218
219 In our case, it'll be filled in like so:
220
221     <A HREF="[% base %]/[% classmetadata.table %]/list?page=4">
222     [ 4 ]
223     </A>
224
225 Where C<classmetadata.table> will actually be the name of the current
226 table, and C<base> will be replaced by the appropriate URL for
227 this application.
228
229 =head2 Locating Templates
230
231 Another feature of C<Maypole::View::TT> which may not be present in
232 alternate view class implementations - although they are strongly
233 encouraged to provide it - is the way that templates are located.
234 (Remember, I B<did> say I'd tell you about that later.) Template Toolkit
235 allows whatever uses it to provide a path for template files to be
236 located in. C<Maypole::View::TT> feeds it up to three possible
237 directories to look things up in, and it will try to find a template in
238 each of these in turn.
239
240 When you configure a Maypole application, you can tell it the base
241 directory of your templates like so:
242
243     BeerDB->config->template_root("/var/www/beerdb/templates");
244
245 If you don't do this, most Maypole front-ends will use the current
246 directory, which may be what you want anyway. Off this directory,
247 Maypole will look for a set of subdirectories.
248
249 For instance, I said we were in the middle of processing the front page
250 and looking up a template file called F<header>. Maypole will first look
251 for this file in the F<custom> subdirectory. (say,
252 F</var/www/beerdb/templates/custom>) If it doesn't find one, then it
253 looks in the F<factory> subdirectory. If it doesn't find one there, then
254 it gives up and dies with an error. But that's your fault, since you've
255 called for a template which doesn't exist. Don't do that. 
256
257 This behaviour means that you can provide your own site-specific
258 templates, but if you don't do so, then you get to use a generic one
259 provided by Maypole. Maypole's "factory setting" templates are written
260 in such a way as to try and do the right thing no matter what your
261 application does. They are occasionally successful at this. 
262
263 Now the front page was a pretty simple example, since Maypole only looks
264 up two directories. In most cases, it checks an additional directory,
265 and this directory depends entirely on what Maypole is doing.
266
267 If you're writing an e-commerce application, for example, you may well
268 have a table which represents the product catalogue and all the products
269 you can buy. Let's call this the C<product> table. You'll also have a
270 data source which is specific to the user which contains all the
271 products that they're buying on this particular visit to the site. In
272 time-honoured tradition, we'll call this the C<basket> table.
273
274 Now it ought to be reasonably apparent that you don't want the basket
275 to be displayed in exactly the same way as the product catalogue. The
276 templates for C<product/list> and C<basket/list> need to be different.
277 This is where the third directory comes in. The other directory, which
278 Maypole checks very first of all, is specific to the table that you're
279 viewing. So if you go to C<http://your.shop.com/basket/list>, Maypole
280 will look in the F<basket> directory first for a file called F<list>,
281 and second in the F<custom> directory for a site-wide list template,
282 and then fall-back to the F<factory> directory for a generic list
283 template. It should be obvious that you probably want to provide all
284 of F<basket/list>, F<basket/view>, F<product/list>, F<product/view>
285 and any other combination of classes and actions that you can think of.
286
287 =head2 What Maypole provides to a template
288
289 C<Maypole::View::TT> provides quite a variety of template variables to
290 the template. As these are the building blocks of your pages, it's worth
291 looking at precisely what variables are available.
292
293 =head3 objects
294
295 The most important variable is called C<objects>, and is a list of all
296 the objects that this page is going to deal with. For instance,
297 if the URL is C<http://localhost/beerdb/beer/view/23>, then
298 in the template F</beer/view>, C<objects> will contain the C<BeerDB::Beer>
299 object for the 23rd item in the database, while for the F</brewery/list>
300 template, the view will fill C<objects> with all the breweries; or at
301 least, all the breweries on the current page.
302
303 =head3 breweries!
304
305 This variable is so important that to help design templates with it,
306 C<Maypole::View::TT> provides a helpful alias to it depending on
307 context. For instance, if you're writing your own F</brewery/list>
308 template, the data in C<objects> is also available in a template
309 variable called C<breweries>. If you're working on F</brewery/view>,
310 though, it's available in C<brewery>, since there's only one brewery to
311 be displayed.
312
313 =head3 base
314
315 Additionally, you can get the base URL for the application from the
316 C<base> template variable; this allows you to construct links, as we
317 saw earlier:
318
319     <A HREF="[% base %]/brewery/edit/[% brewery.id %]">Edit this brewery</A>
320
321 =head3 config
322
323 You can also get at the rest of the configuration for the site with the
324 C<config> variable as we saw above.
325
326 =head3 request
327
328 The entire request object is made available in 
329 C<request>, should you really need to poke at it. (I've only found this
330 useful when working with authentication modules which stash a current user
331 object in C<request.user>.)
332
333 =head3 classmetadata
334
335 To allow the construction of the "generic" templates which live in
336 F<factory>, Maypole also passes in a hash called C<classmetadata>,
337 which contains all sorts of useful information about the class under
338 examination:
339
340 =over 3
341
342 =item C<table>
343
344 This is the name of the table that is represented by the class.
345
346 =item C<name>
347
348 This is the Perl's idea of the class; you don't need this unless you're
349 doing really tricky things.
350
351 =item C<moniker>
352
353 This is a more human-readable version of the table name, that can be
354 used for display. "brewery" for example.
355
356 =item C<plural>
357
358 The same, but a correctly-formed plural. For instance, "breweries".
359
360 =item C<columns>
361
362 The list of columns for display; see the
363 L<hard way|Maypole::Manual::Beer/"The hard way"> section in the Beer
364 Database chapter.
365
366 =item C<list_columns>
367
368 As for C<columns>, but these are the columns to be displayed on a
369 F<list> page.
370
371 =item C<colnames>
372
373 This is a hash mapping the database's name for a column to a more
374 human-readable name. Again, see "Customizing Generic CRUD Applications".
375
376 =item C<cgi>
377
378 This is a slightly trickier one. It is a hash mapping column names to
379 a C<HTML::Element> suitable for entering data into a new instance of
380 that class. That is, for the C<beer> table, C<classmetadata.cgi.style>
381 should be a C<HTML::Element> object containing a drop-down list of
382 beer styles.
383
384 TODO =item C<description>
385 TODO
386 TODO This is the human-readable description provided by a class.
387
388 =item C<related_accessors>
389
390 This is a list of accessors which can be called on an object to get
391 lists of other things that this object "has". For instance, on a
392 brewery, it would return C<beers>, since calling C<brewery.beers> would
393 give you a list of beers produced by the brewery. Note that this only
394 caters for accessors defining one-to-many relationships, not the
395 ordinary one-to-one relationships, such as C<style>.
396
397 =back
398
399 =head3 Additional variables and overrides
400
401 You can pass additional data to templates by creating new variables.
402 You'd typically do this in your view class.
403 Just add the name of your template variable as a key to the
404 C<template_args> hash in the request object, and supply its value:
405
406   $r->template_args->{your_variable_name} = 'some_value';
407
408 You can also override the value of any of the standard variables by
409 giving their name as the key.
410
411 =head2 Other view classes
412
413 Please note that these template variables, C<config>, C<classmetadata>,
414 C<objects> and its user-friendly alias, as well as the rest of them are
415 a function of one particular view class, the default
416 C<Maypole::View::TT> class. Other view classes may need to present an
417 entirely different set of template variables, since the default ones
418 might not make sense. The templates may look wildly different in other
419 view class implementations. But that's OK, because you couldn't
420 necessarily use the same templates with a different templating system
421 anyway.
422
423 For instance, in really dumb templating languages which can't handle
424 dereferencing hashes or arrays - no wait, that's most of them - passing
425 in a hash reference like C<classmetadata> won't help you since you can't
426 get at any of its elements. So you'll need to take a look at the
427 documentation for the appropriate view class to see what template
428 variables it provides.
429
430 So if, for some perverse reason, the Template Toolkit just isn't good
431 enough for you, then you can set your own view class while configuring
432 your application:
433
434    package BeerDB;
435    use base Maypole::Application;
436    ...
437    BeerDB->setup("dbi:SQLite:t/beerdb.db");
438    BeerDB->config->uri_base(http://localhost/beerdb/");
439    BeerDB->config->rows_per_page(10);
440    BeerDB->config->view("Maypole::View::Mason"); 
441
442 Where do these alternate view classes come from? Gentle reader, they
443 come from B<you>.
444
445 =head2 Building your own view class
446
447 I<You should probably skip this section for the first few readings of this manual. It's only intended for people extending Maypole.>
448
449 Imagine you've found a brand new templating system that's B<much better>
450 than the Template Toolkit. I know I'm stretching your imagination a bit
451 here, but try. You'd like to use it with Maypole, which means writing your
452 own view class. How is it done?
453
454 We'll demonstrate by implementing a view class for L<HTML::Mason>,
455 although no value judgement is implied. C<HTML::Mason> is a templating
456 system which embeds pure Perl code inside its magic tags. The good side
457 of this is that it can get into hash references and objects, and so
458 providing C<classmetadata>, C<config> and the Maypole request object
459 will work out just fine. The down side is that C<HTML::Mason> is used to
460 running more or less standalone, and having all the template variables
461 it wants already at its disposal through CGI parameters and the like, so
462 we have to fiddle a bit to get these variables into our template.
463
464 The key to building view classes is L<Maypole::View::Base>. This is the
465 base class that you're going to inherit from and, to be honest, it does
466 pretty much everything you need. It provides a method called C<vars>
467 which returns a hash of all the template variables described above, so
468 it would be good to feed those into C<HTML::Mason>. It also provides a
469 C<paths> method which turns returns the full filesystem path of the
470 three possible template paths as shown above. Again, it would be good to
471 use this as our component paths if we can. It also has some methods we
472 can override if we want to, but they're not massively important, so you
473 can see L<Maypole::View::Base> for more about them. 
474
475 The module will do the right thing for us if we agree to provide a
476 method called C<template>. This is responsible for taking the Maypole
477 request object C<$r> (of which more later) and putting the appropriate output
478 either into C<$r-E<gt>output> or C<$r-E<gt>error>, depending, of
479 course, whether things are OK or whether we got an error.
480
481 Thankfully, C<HTML::Mason> makes things really easy for us. We B<can>
482 use multiple template roots, so we can use the C<paths> method; we
483 B<can> pass in a hash full of interesting data structures, so we can use
484 the C<vars> method too. In fact, we have to do very little to make
485 C<Maypole::View::Mason> work. Which is somewhat annoying, because it
486 makes a boring example. But it means I can leave the fun ones to you!
487
488 The doing-the-templating, in Mason and in any templating system, depends on
489 three things: the paths that we're going to use to find our templates, the
490 template name that we've been asked to fill out, and the set of variables that
491 are going to be fed to the template. We'll assemble these for reference:
492
493     sub template {
494         my ($self, $r) = @_;
495         my @paths = $self->paths($r);
496         my $template = $r->template;
497         my %vars = $self->args($r);
498
499 We'll also declare somewhere to temporarily store the output:
500
501         my $output;
502
503 Now comes the part where we have to actually do something
504 templating-language specific, so we open up our copy of "Embedding Perl
505 in HTML with Mason" and find the bit where it talks about running Mason
506 standalone. We find that the first thing we need to do is create a
507 C<HTML::Mason::Interp> object which knows about the component roots.
508 There's a slight subtlety in that the component roots have to be
509 specified as an array of arrays, with each array being a two-element
510 list of label and path, like so:
511
512     comproot => [
513         [ class   => "/var/www/beerdb/templates/brewery" ],
514         [ custom  => "/var/www/beerdb/templates/custom" ],
515         [ factory => "/var/www/beerdb/templates/factory" ],
516     ]
517
518 We also find that we can set the output method here to capture Mason's
519 output into a scalar, and also that we can tell Mason to generate
520 sensible error messages itself, which saves us from having to worry
521 about catching errors. At the end of all this, we come up with a
522 constructor for our C<HTML::Mason::Interp> object which looks like this:
523
524     my $label = "path0";
525     my $mason = HTML::Mason::Interp->new(
526         comproot => [ map { [ $label++ => $_ ] } @paths ],
527         output_method => \$output,
528         error_mode => "output" 
529     );
530
531 The next thing we need to do is run the template with the appropriate
532 template variables. This turns out to be really easy:
533
534     $mason->exec($template, %vars);
535
536 Now we've got the data in C<$output>, we can put it into the request object,
537 and return a true value to indicate that we processed everything OK. (If there
538 was an error, then Mason will have produced some suitable output, so we can
539 pretend that everything's OK anyway.)
540
541     $r->output($output);
542     return 1;
543
544 And that's all we need to do. Barely twenty lines of code for the finished
545 product. Wasn't that easy? Don't you feel inspired to write Maypole view
546 classes for your favourite templating language? Well, don't let me stop you!
547 Patches are always welcome!
548
549 =head2 Links
550
551 L<Contents|Maypole::Manual>,
552 Next L<Standard Templates and Actions|Maypole::Manual::StandardTemplates>,
553 Previous L<Maypole Model Classes|Maypole::Manual::Model>,