File Coverage

lib/CGI/FormBuilder/Template/HTML.pm
Criterion Covered Total %
statement 16 18 88.8
branch n/a
condition n/a
subroutine 6 6 100.0
pod n/a
total 22 24 91.6


line stmt bran cond sub pod time code
1              
2             ###########################################################################
3             # Copyright (c) Nate Wiger http://nateware.com. All Rights Reserved.
4             # Please visit http://formbuilder.org for tutorials, support, and examples.
5             ###########################################################################
6              
7             package CGI::FormBuilder::Template::HTML;
8              
9             =head1 NAME
10              
11             CGI::FormBuilder::Template::HTML - FormBuilder interface to HTML::Template
12              
13             =head1 SYNOPSIS
14              
15             my $form = CGI::FormBuilder->new(
16             fields => \@fields,
17             template => 'form.tmpl',
18             );
19              
20             =cut
21              
22 1     1   4 use Carp;
  1         2  
  1         63  
23 1     1   5 use strict;
  1         1  
  1         29  
24 1     1   5 use warnings;
  1         2  
  1         31  
25 1     1   4 no warnings 'uninitialized';
  1         2  
  1         27  
26              
27 1     1   4 use CGI::FormBuilder::Util;
  1         1  
  1         144  
28 1     1   533 use HTML::Template;
  0            
  0            
29             use base 'HTML::Template';
30              
31              
32             our $VERSION = '3.09';
33              
34             #
35             # For legacy reasons, and due to its somewhat odd interface,
36             # HTML::Template vars use a completely different naming scheme.
37             #
38             our %FORM_VARS = (
39             'js-head' => 'jshead',
40             'form-title' => 'title',
41             'form-start' => 'start',
42             'form-submit' => 'submit',
43             'form-reset' => 'reset',
44             'form-end' => 'end',
45             'form-invalid' => 'invalid',
46             'form-required' => 'required',
47             );
48              
49             our %FIELD_VARS = map { $_ => "$_-%s" } qw(
50             field
51             value
52             label
53             type
54             comment
55             required
56             error
57             invalid
58             missing
59             nameopts
60             cleanopts
61             );
62              
63             sub new {
64             my $self = shift;
65             my $class = ref($self) || $self;
66             my $opt = arghash(@_);
67              
68             $opt->{die_on_bad_params} = 0; # force to avoid blow-ups
69             $opt->{engine} = HTML::Template->new(%$opt);
70              
71             return bless $opt, $class; # rebless
72             }
73              
74             sub engine {
75             return shift()->{engine};
76             }
77              
78             sub render {
79             my $self = shift;
80             my $tvar = shift || puke "Missing template expansion hashref (\$form->prepare failed?)";
81              
82             while(my($to, $from) = each %FORM_VARS) {
83             debug 1, "renaming attr $from to: ";
84             $tvar->{$to} = "$tvar->{$from}";
85             }
86              
87             #
88             # For HTML::Template, each data struct is manually assigned
89             # to a separate and tag
90             #
91             my @fieldlist;
92             for my $field (@{$tvar->{fields}}) {
93              
94             # Field name is usually a good idea
95             my $name = $field->{name};
96             debug 1, "expanding field: $name";
97              
98             # Get all values
99             my @value = @{$tvar->{field}{$name}{values} || []};
100             my @options = @{$tvar->{field}{$name}{options} || []};
101              
102             #
103             # Auto-expand all of our field tags, such as field, label, value
104             # comment, error, etc, etc
105             #
106             my %all_loop;
107             while(my($key, $str) = each %FIELD_VARS) {
108             my $var = sprintf $str, $name;
109             $all_loop{$key} = $tvar->{field}{$name}{$key};
110             $tvar->{$var} = "$tvar->{field}{$name}{$key}"; # fuck Perl
111             debug 2, " = " . $all_loop{$str};
112             }
113              
114             #
115             # Create a for multi-values/multi-opts
116             # we can't include the field, really, since this would involve
117             # too much effort knowing what type
118             #
119             my @tmpl_loop = ();
120             for my $opt (@options) {
121             # Since our data structure is a series of ['',''] things,
122             # we get the name from that. If not, then it's a list
123             # of regular old data that we _toname if nameopts => 1
124             debug 2, "looking at field $name option $opt";
125             my($o,$n) = optval $opt;
126             $n ||= $tvar->{"nameopts-$name"} ? toname($o) : $o;
127             my($slct, $chk) = ismember($o, @value) ? ('selected', 'checked') : ('','');
128             debug 2, " = adding { label => $n, value => $o }";
129             push @tmpl_loop, {
130             label => $n,
131             value => $o,
132             checked => $chk,
133             selected => $slct,
134             };
135             }
136              
137             # Now assign our loop-field
138             $tvar->{"loop-$name"} = \@tmpl_loop;
139              
140             # Finally, push onto a top-level loop named "fields"
141             push @fieldlist, {
142             field => $all_loop{field},
143             value => $all_loop{value},
144             values => [ @value ],
145             options => [ @options ],
146             label => $all_loop{label},
147             comment => $all_loop{comment},
148             error => $all_loop{error},
149             required=> $all_loop{required},
150             missing => $all_loop{missing},
151             fieldset=> $all_loop{fieldset},
152             loop => [ @tmpl_loop ],
153             };
154             }
155             # kill our previous fields list
156             $tvar->{fields} = \@fieldlist;
157              
158             # loop thru each field we have and set the tmpl_param
159             while(my($param, $tag) = each %$tvar) {
160             $self->{engine}->param($param => $tag);
161             }
162              
163             # template output
164             return $self->{engine}->output;
165             }
166              
167             1;
168             __END__