X-Git-Url: https://git.decadent.org.uk/gitweb/?a=blobdiff_plain;f=doc%2FRequest.pod;h=bc2b303555fedc51257a4e446fefc499def7aba8;hb=4ab33d12a514e0531e16f3d2812b15258de258c5;hp=fc51d1ba854ea87900250ce5a6f90d83bf96e602;hpb=43d50fc6cf12e98c44f485eea46ac35637dcce06;p=maypole.git diff --git a/doc/Request.pod b/doc/Request.pod index fc51d1b..bc2b303 100644 --- a/doc/Request.pod +++ b/doc/Request.pod @@ -17,6 +17,38 @@ These hacks deal with changing the way Maypole relates to the outside world; alternate front-ends to the Apache and CGI interfaces, or subclassing chunks of the front-end modules to alter Maypole's behaviour in particular ways. +=head3 Separate model class modules + +You want to put all the C routines in a separate module, +so you say: + + package BeerDB::Beer; + BeerDB::Beer->has_a(brewery => "BeerDB::Brewery"); + sub foo :Exported {} + +And in F, you put: + + use BeerDB::Beer; + +It doesn't work. + +B: It doesn't work because of the timing of the module +loading. C will try to set up the C relationships +at compile time, when the database tables haven't even been set up, +since they're set up by + + BeerDB->setup("...") + +which does its stuff at runtime. There are two ways around this; you can +either move the C call to compile time, like so: + + BEGIN { BeerDB->setup("...") } + +or move the module loading to run-time (my preferred solution): + + BeerDB->setup("..."); + BeerDB::Beer->require; + =head3 Debugging with the command line You're seeing bizarre problems with Maypole output, and you want to test it in @@ -577,6 +609,82 @@ on an ISBN: The request will carry on as though it were a normal C POST, but with the additional fields we have provided. +=head3 Catching errors in a form + +A user has submitted erroneous input to an edit/create form. You want to +send him back to the form with errors displayed against the erroneous +fields, but have the other fields maintain the values that the user +submitted. + +B: This is basically what the default C template and +C method conspire to do, but it's worth highlighting again how +they work. + +If there are any errors, these are placed in a hash, with each error +keyed to the erroneous field. The hash is put into the template as +C, and we process the same F template again: + + $r->{template_args}{errors} = \%errors; + $r->{template} = "edit"; + +This throws us back to the form, and so the form's template should take +note of the errors, like so: + + FOR col = classmetadata.columns; + NEXT IF col == "id"; + "

"; + ""; classmetadata.colnames.$col; ""; + ": "; + item.to_field(col).as_HTML; + "

"; + IF errors.$col; + ""; errors.$col; ""; + END; + END; + +If we're designing our own templates, instead of using generic ones, we +can make this process a lot simpler. For instance: + + + First name: + + + Last name: + + + [% IF errors.forename OR errors.surname %] + + [% errors.forename %] + [% errors.surname %] + + [% END %] + +The next thing we want to do is to put the originally-submitted values +back into the form. We can do this relatively easily because Maypole +passes the Maypole request object to the form, and the POST parameters +are going to be stored in a hash as C. Hence: + + + First name: + + + Last name: + + +Finally, we might want to only re-fill a field if it is not erroneous, so +that we don't get the same bad input resubmitted. This is easy enough: + + + First name: + + + Last name: + + =head3 Uploading files and other data You want the user to be able to upload files to store in the database.