| ZForm User Manual | ||
|---|---|---|
| <<< Previous | Next >>> | |
The auto generated HTML is nice for the rapid development of a form, but you will probably want something different for production. This is where HTML::Template comes in. ZForm can use a template file to display the form. But if you are like me, you are lazy. I want a template file generated from the form definition which I can hand over to somebody with an eye for a nice looking web page!
Use the display_template() method to generate a nicy shiny HTML::Template compatible file. We'll continue with example 2, but create a new file called example2_gen.cgi:
use warnings; use CGI; use Example2; # Create a new cgi object my $q = new CGI; # Create an instance of our form and attach the cgi object my $f = new Example2(cgi => $q); # Generate the template print($q->header, $f->display_template()); |
When you execute this script, the output will look like the following:
<?xml version="1.0" encoding="iso-8859-1"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" lang="en-US"><head><title>Form</title> </head><body> <tmpl_unless name="display_data_only"> <form method="post" action="/hello/example2_gen.cgi" enctype="application/x-www-form-urlencoded"> </tmpl_unless> <table> <tr><td>Title</td> <td><tmpl_var name = "title"> </td> <td><tmpl_var name = "title_error"> </td></tr> <tr><td>Your name</td> <td><tmpl_var name = "name"> </td> <td><tmpl_var name = "name_error"> </td></tr> <tr><td>Description</td> <td><tmpl_var name = "descr"> </td> <td><tmpl_var name = "descr_error"> </td></tr> <tr><td>spam is evil</td> <td><tmpl_var name = "evilspam"> </td> <td><tmpl_var name = "evilspam_error"> </td></tr> <tr><td>Choose some</td> <td><tmpl_var name = "checkbox_group"> </td> <td><tmpl_var name = "checkbox_group_error"> </td></tr> </table> <tmpl_unless name="display_data_only"> <tmpl_var name = "rm"> <input type="submit" name=".submit" /> </form> </tmpl_unless> </body></html> |
You'll notice that there is no HTML to define the input fields. This is a good thing. That HTML is generated by ZForm and allows you to easily maintain the state of the form should validation fail. It also allows you to use the same template for a data-only view.
There is a special template variable called display_data_only. This template variable lets you know when we are just displaying data. There is another special template variable called absolute_url. This template variable is handy when referencing yourself, but can cause problems. You have been warned.
Well, that's just great, but how do we use this template? All shall be made clear in example 3.
Example3.pm. This looks just like Example2.pm, except we have replaced Example2.pm with Example3.pm and added a line near the end that specifies a template file.
package Example3;
use base ZForm;
sub setup {
my $self = shift();
# Define the form
my $fields = [
{'rm' => {
'type' => 'hidden',
'attr' => {
'default' => 'display_data'}}},
{'title' => {
'type' => 'popup_menu',
'label' => 'Title',
'attr' => {
'values' => ['Mr', 'Mrs', 'Ms', 'Dr'],
}}},
{'name' => {
'type' => 'textfield',
'label' => 'Your name',
'attr' => {
'size' => '30'}}},
{'descr' => {
'type' => 'textfield',
'label' => 'Description',
'required' => 'no',
'attr' => {
'size' => '30'}}},
{'evilspam' => {
'type' => 'checkbox',
'label' => 'spam is evil',
'required' => 'no',
'attr' => {}}},
{'checkbox_group' => {
'type' => 'scrolling_list',
'label' => 'Choose some',
'attr' => {
values => ['eenie','meenie','minie','moe'],
defaults => ['eenie','minie'],
multiple => 'true'}}},
];
$self->form_def($fields);
$self->template('example3.tmpl');
} |
example3.cgi looks just like example2.cgi, which all instances of Example2 replaced with Example3:
#!/usr/bin/perl
use lib '.';
use strict;
use warnings;
use CGI;
use Example3;
# Create a new cgi object
my $q = new CGI;
# Create an instance of our form and attach the cgi object
my $f = new Example3(cgi => $q);
# Placeholder for output
my $output = '';
my $title;
my $descr;
if(defined($q->param('rm')) &&
$q->param('rm') eq 'display_data') {
# User clicked submit, so validate the form
if($f->validate()) {
# It validated! Display the data
$output = $f->display_data_only();
} else {
# Didn't validate, so display the form with errors
$output = $f->display();
}
} else {
# The user has not yet clicked submit, so display the empty form
$output = $f->display();
}
# Display the output
print($q->header, $output);
|
Now, take the generated template, and save it as example3.tmpl. Then replace the following line:
<form method="post" action="/hello/example2_gen.cgi" enctype="application/x-www-form-urlencoded"> |
With:
<form method="post" action="/hello/example3.cgi" enctype="application/x-www-form-urlencoded"> |
And that's all there is to it! I highly recommend reading the HTML::Template documentation and using the <tmpl_include> directive to include headers, footers, and navigational menus.
| <<< Previous | Home | Next >>> |
| Beyond Hello World | Custom Error Messages |