]> git.decadent.org.uk Git - maypole.git/blob - lib/Maypole/Manual/StandardTemplates.pod
updated action names in manual for standard templates
[maypole.git] / lib / Maypole / Manual / StandardTemplates.pod
1
2 =head1 NAME
3
4 Maypole::Manual::StandardTemplates - Maypole's Standard Templates and Actions
5
6 =head1 DESCRIPTION
7
8 As we saw in our Create-Read-Update-Delete (CRUD) example,
9 Maypole does all it can to make your life
10 easier; this inclues providing a set of default actions and
11 factory-supplied templates. These are written in such a generic way,
12 making extensive use of class metadata, that they are more or less
13 applicable to any table or application. However, in order to progress
14 from automatically generated CRUD applications to real customized
15 applications, we need to begin by understanding how these default
16 actions do their stuff, and how the default templates are put together.
17 Once we have an understanding of what Maypole does for us automatically,
18 we can begin to customize and create our own templates and actions.
19
20 Although the standard templates can be applied in many situations,
21 they're really provided just as examples,
22 as a starting point to create your own templates to suit your needs.
23 The goal of templating is to keep templates simple so the presentation
24 can be changed easily when you desire.
25 We're not trying to build a single set of reusable templates that cover
26 every possible situation.
27
28 =head2 The standard actions
29
30 Remember that actions are just subroutines in the model classes with an
31 I<Exported> attribute.
32 A simple, uncustomized Maypole model class, such as one of the classes
33 in the beer database application, provides the following default actions
34 - that is, provides access to the following URLs:
35
36 =over 3
37
38 =item C</[table]/view/[id]>
39
40 This takes the ID of an object in a table, retrieves the object, and
41 presents it to the F<view> template.
42
43 =item C</[table]/edit/[id]>
44
45 This is the same as C<view>, but uses the F<edit> template to provide a
46 web form to edit the object; it submits to C<do_edit>.
47
48 =item C</[table]/do_edit/[id]>
49
50 When called with an ID, the C<do_edit> action provides row editing.
51
52 =item C</[table]/do_edit/>
53
54 When called without an ID, the C<do_edit> action provides row creation.
55
56 =item C</[table]/delete/id>
57
58 This deletes a row, returning to the C<list> page.
59
60 =item C</[table]/list/>
61
62 This provides a paged list of the table suitable for browsing.
63
64 =item C</[table]/do_search/>
65
66 This handles a search query and presents the search results back to the
67 F<list> template. Previously this was called search, but obviously that 
68 clashes with a lot of stuff, and that usage is now deprecated.
69
70 =back
71
72 We'll now look at how these actions are implemented, before moving on to
73 take a detailed look at the templates they drive.
74
75 =head3 C<view> and C<edit>
76
77 These actions are very simple; their job is to take a row ID, turn it
78 into an object, and hand it to the template to be displayed. However, as
79 taking the first argument and turning it into an object is such a common
80 action, it is handled directly by the model class's C<process> method.
81 Similarly, the default template name provided by the C<process> method
82 is the name of the action, and so will be C<view> or C<edit>
83 accordingly. 
84
85 So the code required to make these two actions work turns out to be:
86
87     sub view :Exported { }
88     sub edit :Exported { }
89
90 That's right - no code at all. This shows the power of the templating
91 side of the system. If you think about it for a moment, it is natural
92 that these actions should not have any code - after all, we have
93 separated out the concerns of "acting" and displaying. Both of these
94 "actions" are purely concerned with displaying a record, and don't need
95 to do any "acting". Remember that the "edit" method doesn't actually do
96 any editing - this is provided by C<do_edit>; it is just another view of
97 the data, albeit one which allows the data to be modified later. These
98 two methods don't need to modify the row in any way, they don't need to
99 do anything clever. They just are.
100
101 So why do we need the subroutines at all? If the subroutines did not exist,
102 we would be sent to the C<view> and C<edit> templates as would be
103 expected, but these templates would not be provided with the right
104 arguments; we need to go through the C<process> method in order to turn
105 the URL argument into a row and thence into an object to be fed to the
106 template. By exporting these methods, even though they contain no code
107 themselves, we force Maypole to call C<process> and provide the class
108 and object to the templates.
109
110 The moral of this story is that if you need to have an action which is
111 purely concerned with display, not acting, but needs to receive an ID
112 and turn it into an object, then create an empty method. For instance,
113 if we want to make an alternate view of a row which only showed the
114 important columns, we might create a method
115
116     sub short_view :Exported {}
117
118 This will cause the row to be turned into an object and fed to the
119 C<short_view> template, and that template would be responsible for
120 selecting the particular columns to be displayed.
121
122 =head3 C<do_edit>
123
124 This action, on the other hand, actually has to do something. If it's
125 provided with an ID, this is turned into an object and we're in edit
126 mode, acting upon that object. If not, we're in create mode. 
127
128     sub do_edit :Exported {
129         my ($self, $r) = @_;
130         my $h = CGI::Untaint->new(%{$r->params});
131         my ($obj) = @{$r->objects || []};
132         if ($obj) {
133             # We have something to edit
134             $obj->update_from_cgi($h);
135         } else {
136             $obj = $self->create_from_cgi($h);
137         }
138
139 The C<CDBI> model uses the C<update_from_cgi> and C<create_from_cgi>
140 methods of L<Class::DBI::FromCGI> to turn C<POST> parameters
141 into database table data. This in turn uses L<CGI::Untaint> to ensure
142 that the data coming in is suitable for the table. If you're using the
143 default C<CDBI> model, then, you're going to need to set up your tables
144 in a way that makes C<FromCGI> happy.
145
146 The data is untainted, and any errors are collected into a hash which is
147 passed to the template. We also pass back in the parameters, so that the
148 template can re-fill the form fields with the original values. The user
149 is then sent back to the C<edit> template.
150
151         if (my %errors = $obj->cgi_update_errors) {
152             # Set it up as it was:
153             $r->template_args->{cgi_params} = $r->params;
154             $r->template_args->{errors} = \%errors;
155             $r->template("edit");
156         }
157
158 Otherwise, the user is taken back to viewing the new object:
159
160     } else {
161         $r->template("view");
162     }
163     $r->objects([ $obj ]);
164
165 Notice that this does use hard-coded names for the templates to go to next.
166 Feel free to override this in your subclasses:
167
168     sub do_edit :Exported {
169         my ($class, $r) = @_;
170         $class->SUPER::do_edit($r);
171         $r->template("my_edit");
172     }
173
174 =head3 Digression on C<Class::DBI::FromCGI>
175
176 C<CGI::Untaint> is a mechanism for testing that incoming form data
177 conforms to various properties. For instance, given a C<CGI::Untaint>
178 object that encapsulates some C<POST> parameters, we can extract an
179 integer like so:
180
181     $h->extract(-as_integer => "score");
182
183 This checks that the C<score> parameter is an integer, and returns it if
184 it is; if not, C<< $h->error >> will be set to an appropriate error
185 message. Other tests by which you can extract your data are C<as_hex>
186 and C<as_printable>, which tests for a valid hex number and an ordinary
187 printable string respectively; there are other handlers available on
188 CPAN, and you can make your own, as documented in L<CGI::Untaint>.
189
190 To tell the C<FromCGI> handler what handler to use for each of your
191 columns, you need to use the C<untaint_columns> methods in the classes
192 representing your tables. For instance:
193
194     BeerDB::Beer->untaint_columns(
195         integer => ["score", ... ],
196     );
197
198 This must be done after the call to C<setup> in your handler, because
199 otherwise the model classes won't have been set up to inherit from
200 C<Class::DBI::FromCGI>.
201
202 Remember that if you want to use drop-downs to set the value of related
203 fields, such as the brewery for a beer, you need to untaint these as
204 something acceptable for the primary key of that table:
205
206     BeerDB::Beer->untaint_columns(
207         integer => ["score", "brewery", "style" ],
208         ...
209     );
210
211 This is usually integer, if you're using numeric IDs for your primary
212 key. If not, you probably want C<printable>, but you probably know what
213 you're doing anyway.
214
215 =head3 do_delete
216
217 The do_delete method takes a number of arguments and deletes those rows from the
218 database; it then loads up all rows and heads to the F<list> template.
219 You almost certainly want to override this to provide some kind of
220 authentication.
221
222 Previously this was called delete, but obviously that clashes with a lot of stuff,
223 and that usage is now deprecated.
224
225
226 =head3 list
227
228 Listing, like viewing, is a matter of selecting objects for
229 presentation. This time, instead of a single object specified in the
230 URL, we want, by default, all the records in the table:
231
232     sub list :Exported {
233         my ($class, $r) = @_;
234         $r->objects([ $self->retrieve_all ])
235     }
236
237 However, things are slightly complicated by paging and ordering by
238 column; the default implementation also provides a C<Class::DBI::Pager>
239 object to the templates and uses that to retrieve the appropriate bit of
240 the data, as specified by the C<page> URL query parameter. See the
241 L<"pager"> template below.
242
243 =head3 search
244
245 Searching also uses paging, and creates a query from the C<POST>
246 parameters. It uses the F<list> template to display the objects once
247 they've been selected from the database.
248
249 =head2 The templates and macros
250
251 Once these actions have done their work, they hand a set of objects to
252 the templates; if you haven't specified your own custom template
253 globally or for a given class, you'll be using the factory specified
254 template. Let's take a look now at each of these and how they're put
255 together.
256
257 The beauty of the factory specified templates is that they make use of
258 the classes' metadata as supplied by the view class. Although you're
259 strongly encouraged to write your own templates, in which you don't need
260 to necessarily be as generic, the factory templates will always do the
261 right thing for any class without further modification, and as such are
262 useful examples of how to build Maypole templates.
263
264 =head3 Commonalities
265
266 There are certain common elements to a template, and these are extracted
267 out. For instance, all the templates call the F<header> template to
268 output a HTML header, and nearly all include the F<macros> template to
269 load up some common template functions. We'll look at these common
270 macros as we come across them.
271
272 =head3 F<view> 
273
274 template view
275
276 =head3 F<edit>
277
278 The F<edit> template is pretty much the same as F<view>, but it uses 
279 L<Maypole::Model::CDBI::AsForm>'s
280 C<to_field> method on each column of an object to return a C<HTML::Element>
281 object representing a form element to edit that property. These elements
282 are then rendered to HTML with C<as_HTML> or to XHTML with C<as_XML>.
283 It expects to see a list of
284 editing errors, if any, in the C<errors> template variable:
285
286      FOR col = classmetadata.columns;
287         NEXT IF col == "id";
288         "<P>";
289         "<B>"; classmetadata.colnames.$col; "</B>";
290         ": ";
291             item.to_field(col).as_HTML;
292         "</P>";
293         IF errors.$col;
294             "<FONT COLOR=\"#ff0000\">"; errors.$col; "</FONT>";
295         END;
296     END;
297
298 =head3 F<list>
299
300 Browsing records and search results are both handled by the F<list> template.
301 The C<search> template argument is used to distinguish between the two cases:
302
303     [% IF search %]
304     <h2> Search results </h2>
305     [% ELSE %]
306     <h2> Listing of all [% classmetadata.plural %]</h2>
307     [% END %]
308
309 =head3 F<pager>
310
311 The pager template controls the list of pages at the bottom (by default)
312 of the list and search views. It expects a C<pager> template argument
313 which responds to the L<Data::Page> interface.
314 There's a description of how it works in
315 L<the Template Toolkit section|Maypole::Manual::View/"The Template Toolkit">
316 of the View chapter.
317
318 =head3 F<macros>
319
320 The F<macros> template is included at the start of most other templates
321 and makes some generally-useful template macros available:
322
323 =over
324
325 =item C<link(table, command, additional, label)>
326
327 This makes an HTML link pointing to C</base/table/command/additional>
328 labelled by the text in I<label>. C<base> is the template variable that
329 contains the base URL of this application.
330
331 =item C<maybe_link_view(object)>
332
333 C<maybe_link_view> takes something returned from the database - either
334 some ordinary data, or an object in a related class expanded by a
335 has-a relationship. If it is an object, it constructs a link to the view
336 command for that object. Otherwise, it just displays the data.
337
338 =item C<display_line(object)>
339
340 C<display_line> is used in the list template to display a row from the
341 database, by iterating over the columns and displaying the data for each
342 column. It misses out the C<id> column by default, and magically
343 URLifies columns called C<url>. This may be considered too much magic
344 for some.
345
346 =item C<button(object, action)>
347
348 This is a simple button that is submitted to C</base/table/action/id>,
349 where C<table> and C<id> are those belonging to the database row C<object>.
350 The button is labelled with the name of the action.
351 You can see buttons on many pages, including lists.
352
353 =item C<view_related(object)>
354
355 This takes an object, and looks up its C<related_accessors>; this gives
356 a list of accessor methods that can be called to get a list of related
357 objects. It then displays a title for that accessor, (e.g. "Beers" for a
358 C<brewery.beers>) calls the accessor, and displays a list of the results.
359 You can see it in use at the bottom of the standard view pages.
360
361 =back
362
363 =begin TODO
364
365 =head2 Customizing Generic CRUD Applications
366
367 =end TODO
368
369 =head2 Links
370
371 L<Contents|Maypole::Manual>,
372 Next L<The Request Workflow|Maypole::Manual::Workflow>,
373 Previous L<Maypole View Classes|Maypole::Manual::View>,
374