]> git.decadent.org.uk Git - maypole.git/blobdiff - lib/Maypole/Manual/StandardTemplates.pod
+ Updated manual, thanks to Dave Howorth
[maypole.git] / lib / Maypole / Manual / StandardTemplates.pod
index 3c8bc69ab9936b1573e48c591d397b6db3f42b87..35f9a8a86cca5befa0347d1808cc4a4643727af6 100644 (file)
@@ -1,7 +1,8 @@
 
 =head1 Maypole's Standard Templates and Actions
 
-As we saw in our CRUD example, Maypole does all it can to make your life
+As we saw in our Create-Read-Update-Delete (CRUD) example,
+Maypole does all it can to make your life
 easier; this inclues providing a set of default actions and
 factory-supplied templates. These are written in such a generic way,
 making extensive use of class metadata, that they are more or less
@@ -12,8 +13,18 @@ actions do their stuff, and how the default templates are put together.
 Once we have an understanding of what Maypole does for us automatically,
 we can begin to customize and create our own templates and actions.
 
+Although the standard templates can be applied in many situations,
+they're really provided just as examples,
+as a starting point to create your own templates to suit your needs.
+The goal of templating is to keep templates simple so the presentation
+can be changed easily when you desire.
+We're not trying to build a single set of reusable templates that cover
+every possible situation.
+
 =head2 The standard actions
 
+Remember that actions are just subroutines in the model classes with an
+I<Exported> attribute.
 A simple, uncustomized Maypole model class, such as one of the classes
 in the beer database application, provides the following default actions
 - that is, provides access to the following URLs:
@@ -32,9 +43,11 @@ web form to edit the object; it submits to C<do_edit>.
 
 =item C</[table]/do_edit/[id]>
 
+When called with an ID, the C<do_edit> action provides row editing.
+
 =item C</[table]/do_edit/>
 
-This provides both editing and row creation facilities. 
+When called without an ID, the C<do_edit> action provides row creation.
 
 =item C</[table]/delete/id>
 
@@ -61,7 +74,7 @@ into an object, and hand it to the template to be displayed. However, as
 taking the first argument and turning it into an object is such a common
 action, it is handled directly by the model class's C<process> method.
 Similarly, the default template name provided by the C<process> method
-is the name of the acction, and so will be C<view> or C<edit>
+is the name of the action, and so will be C<view> or C<edit>
 accordingly. 
 
 So the code required to make these two actions work turns out to be:
@@ -76,7 +89,7 @@ separated out the concerns of "acting" and displaying. Both of these
 "actions" are purely concerned with displaying a record, and don't need
 to do any "acting". Remember that the "edit" method doesn't actually do
 any editing - this is provided by C<do_edit>; it is just another view of
-the data, albeit once which allows the data to be modified later. These
+the data, albeit one which allows the data to be modified later. These
 two methods don't need to modify the row in any way, they don't need to
 do anything clever. They just are.
 
@@ -109,7 +122,7 @@ mode, acting upon that object. If not, we're in create mode.
 
     sub do_edit :Exported {
         my ($self, $r) = @_;
-        my $h = CGI::Untaint->new(%{$r->{params}});
+        my $h = CGI::Untaint->new(%{$r->params});
         my ($obj) = @{$r->objects || []};
         if ($obj) {
             # We have something to edit
@@ -118,15 +131,42 @@ mode, acting upon that object. If not, we're in create mode.
             $obj = $self->create_from_cgi($h);
         }
 
-The C<CDBI> model uses L<Class::DBI::FromCGI> to turn C<POST> parameters
-into database table data. This in turn uses C<CGI::Untaint> to ensure
+The C<CDBI> model uses the C<update_from_cgi> and C<create_from_cgi>
+methods of L<Class::DBI::FromCGI> to turn C<POST> parameters
+into database table data. This in turn uses L<CGI::Untaint> to ensure
 that the data coming in is suitable for the table. If you're using the
 default C<CDBI> model, then, you're going to need to set up your tables
 in a way that makes C<FromCGI> happy.
 
-=over 
+The data is untainted, and any errors are collected into a hash which is
+passed to the template. We also pass back in the parameters, so that the
+template can re-fill the form fields with the original values. The user
+is then sent back to the C<edit> template.
 
-=item Digression on C<Class::DBI::FromCGI>
+        if (my %errors = $obj->cgi_update_errors) {
+            # Set it up as it was:
+            $r->template_args->{cgi_params} = $r->params;
+            $r->template_args->{errors} = \%errors;
+            $r->template("edit");
+        }
+
+Otherwise, the user is taken back to viewing the new object:
+
+    } else {
+        $r->template("view");
+    }
+    $r->objects([ $obj ]);
+
+Notice that this does use hard-coded names for the templates to go to next.
+Feel free to override this in your subclasses:
+
+    sub do_edit :Exported {
+        my ($class, $r) = @_;
+        $class->SUPER::do_edit($r);
+        $r->template("my_edit");
+    }
+
+=head3 Digression on C<Class::DBI::FromCGI>
 
 C<CGI::Untaint> is a mechanism for testing that incoming form data
 conforms to various properties. For instance, given a C<CGI::Untaint>
@@ -167,36 +207,6 @@ This is usually integer, if you're using numeric IDs for your primary
 key. If not, you probably want C<printable>, but you probably know what
 you're doing anyway.
 
-=back
-
-The data is untainted, and any errors are collected into a hash which is
-passed to the template. We also pass back in the parameters, so that the
-template can re-fill the form fields with the original values. The user
-is then sent back to the C<edit> template.
-
-        if (my %errors = $obj->cgi_update_errors) {
-            # Set it up as it was:
-            $r->{template_args}{cgi_params} = $r->{params};
-            $r->{template_args}{errors} = \%errors;
-            $r->{template} = "edit";
-        }
-
-Otherwise, the user is taken back to viewing the new object:
-
-    } else {
-        $r->{template} = "view";
-    }
-    $r->objects([ $obj ]);
-
-Notice that this does use hard-coded names for the templates to go to next.
-Feel free to override this in your subclasses:
-
-    sub do_edit :Exported {
-        my ($class, $r) = @_;
-        $class->SUPER::do_edit($r);
-        $r->template("my_edit");
-    }
-
 =head3 delete
 
 The delete method takes a number of arguments and deletes those rows from the
@@ -218,8 +228,8 @@ URL, we want, by default, all the records in the table:
 However, things are slightly complicated by paging and ordering by
 column; the default implementation also provides a C<Class::DBI::Pager>
 object to the templates and uses that to retrieve the appropriate bit of
-the data, as specified by the C<page> URL query parameter. See the F<pager> 
-template below.
+the data, as specified by the C<page> URL query parameter. See the
+L<"pager"> template below.
 
 =head3 search
 
@@ -256,10 +266,12 @@ template view
 
 =head3 F<edit>
 
-The F<edit> template is pretty much the same as F<view>, but it uses the
+The F<edit> template is pretty much the same as F<view>, but it uses 
+L<Class::DBI::AsForm>'s
 C<to_field> method on each column of an object to return a C<HTML::Element>
 object representing a form element to edit that property. These elements
-are then rendered to HTML with C<as_HTML>. It expects to see a list of
+are then rendered to HTML with C<as_HTML> or to XHTML with C<as_XML>.
+It expects to see a list of
 editing errors, if any, in the C<errors> template variable:
 
      FOR col = classmetadata.columns;
@@ -285,4 +297,69 @@ The C<search> template argument is used to distinguish between the two cases:
     <h2> Listing of all [% classmetadata.plural %]</h2>
     [% END %]
 
-=head1 Customizing Generic CRUD Applications
+=head3 F<pager>
+
+The pager template controls the list of pages at the bottom (by default)
+of the list and search views. It expects a C<pager> template argument
+which responds to the L<Data::Page> interface.
+There's a description of how it works in
+L<the Template Toolkit section|Maypole::Manual::View/"The Template Toolkit">
+of the View chapter.
+
+=head3 F<macros>
+
+The F<macros> template is included at the start of most other templates
+and makes some generally-useful template macros available:
+
+=over
+
+=item C<link(table, command, additional, label)>
+
+This makes an HTML link pointing to C</base/table/command/additional>
+labelled by the text in I<label>. C<base> is the template variable that
+contains the base URL of this application.
+
+=item C<maybe_link_view(object)>
+
+C<maybe_link_view> takes something returned from the database - either
+some ordinary data, or an object in a related class expanded by a
+has-a relationship. If it is an object, it constructs a link to the view
+command for that object. Otherwise, it just displays the data.
+
+=item C<display_line(object)>
+
+C<display_line> is used in the list template to display a row from the
+database, by iterating over the columns and displaying the data for each
+column. It misses out the C<id> column by default, and magically
+URLifies columns called C<url>. This may be considered too much magic
+for some.
+
+=item C<button(object, action)>
+
+This is a simple button that is submitted to C</base/table/action/id>,
+where C<table> and C<id> are those belonging to the database row C<object>.
+The button is labelled with the name of the action.
+You can see buttons on many pages, including lists.
+
+=item C<view_related(object)>
+
+This takes an object, and looks up its C<related_accessors>; this gives
+a list of accessor methods that can be called to get a list of related
+objects. It then displays a title for that accessor, (e.g. "Beers" for a
+C<brewery.beers>) calls the accessor, and displays a list of the results.
+You can see it in use at the bottom of the standard view pages.
+
+=back
+
+=begin TODO
+
+=head2 Customizing Generic CRUD Applications
+
+=end TODO
+
+=head2 Links
+
+L<Contents|Maypole::Manual>,
+Next L<The Request Workflow|Maypole::Manual::Workflow>,
+Previous L<Maypole View Classes|Maypole::Manual::View>,
+