1package HTML::FormHandler::Manual::Templates;
2# ABSTRACT: using templates
3
4__END__
5
6=pod
7
8=encoding UTF-8
9
10=head1 NAME
11
12HTML::FormHandler::Manual::Templates - using templates
13
14=head1 VERSION
15
16version 0.40068
17
18=head1 SYNOPSIS
19
20L<Manual Index|HTML::FormHandler::Manual>
21
22Documentation on templates to use with L<HTML::FormHandler>
23
24=head1 Using templates
25
26There is a FormHandler Template Toolkit rendering role at
27L<HTML::FormHandler::Render::WithTT>, with a testcase in t/render_withtt.t.
28Normally, however, it probably won't make much sense to use both a
29TT parser in FormHandler, and a separate one for the "complete" templates,
30so the TT renderer is mainly useful for tests,
31or as an example of how to do TT rendering with HFH. You should
32create a template to render your form and then pass the template name
33and a template variable containing your form object to your templating
34or view engine, in whatever way you normally do that. If you want
35to use the 'process_attrs' function, you need to set that in your
36template variables too.
37
38A common way of using FormHandler with templates is to use the template
39for layout, specifying the divs and spans and wrappers, and then
40use the form object to render just the input fields.
41
42In your form:
43
44    has '+widget_wrapper' => ( default => 'None' );
45
46In your Catalyst controller:
47
48    $c->stash( form => $form, template => 'form.tt' );
49
50..or do the equivalent for your web framework/view.
51
52In a form template (form.tt in the previous controller example):
53
54    <form id="myform" action="/myaction" method="post">
55        <div class="span9">
56            <span class="label">My Foo</span>
57            [% form.field('foo').render %]
58        </div>
59        <div class="span7">[% form.field('bar').render %]</div>
60        [% form.field('save').render %]
61    </form>
62
63However, you can also render entirely with templates.
64There are lots of different ways to set up templates. There are sample
65templates installed in FormHandler's 'share' directory. These templates
66are now organized more-or-less similarly to the widget roles, with 'field',
67'wrapper', and 'form' directories, but many other organizations are possible.
68
69There is also a template which combines the template rendering code into
70one file, 'share/templates/form/form_in_one.tt'. You can copy this template
71into your own TT directories, perhaps as form.tt, and then specify it
72as the template for your Catalyst actions. You can customize it by adding
73additional widget and widget_wrapper blocks, and then setting those in your
74field definitions.
75
76Note that widget names usually are camelcased, like the Moose roles that
77implement them in the Widget directory. You may want to use the
78non-camelcased widget/wrapper names in your TT templates, using
79the C<< $field->uwidget >> (un-camelcased widget name) and
80C<< $field->twidget >> (un-camelcased widget name + '.tt') convenience methods.
81('MySpecialWidget' is the equivalent of 'my_special_widget')
82
83   has_field 'my_field' => ( widget => 'MySpecialWidget' );
84   has_field 'another_field' => ( widget => 'YetAnotherWidget' );
85
86And include them in a generic template:
87
88   [% PROCESS widget/form_start.tt %]
89
90   [% FOREACH f IN form.sorted_fields %]
91      [% PROCESS widget/${f.twidget} %]
92   [% END %]
93
94   [% PROCESS widget/form_end.tt %]
95
96=head1 Field attributes
97
98If you want to use the 'process_attrs' function to pull in HTML attributes
99for the input elements, wrappers, and labels, you would need to pass that
100function into your TT setup. See L<HTML::FormHandler::Render::WithTT> for an
101example:
102
103    use HTML::FormHandler::Render::Util ('process_attrs');
104    $c->stash( process_attrs => &process_attrs ); # or add to TT vars in your view
105
106    <label [% process_attrs(f.label_attributes) %]for="[% f.html_name %]">
107    [% f.label %]: </label>
108    <input type="[% f.input_type %]" name="[% f.html_name %]" id="[% f.id %]"
109    [% process_attrs(f.attributes) %] value="[% f.fif %]">
110
111=head1 Sample templates
112
113The following is copied from the provided share/templates/form/form_in_one.tt file,
114as an example. Note that some fields, like form actions of 'submit' & 'reset', don't
115use the 'fif' value, but just the plain field value.
116
117    [% PROCESS form_start -%]
118    <div class="form_messages">
119    [% FOREACH err IN form.form_errors -%]
120      <span class="error_message">[% err %]</span>
121    [% END -%]
122    </div>
123    [% FOREACH f IN form.sorted_fields -%]
124      [% WRAPPER "wrapper_${f.uwrapper}" -%][% PROCESS "${f.uwidget}" -%][% END -%]
125    [% END -%]
126    [% PROCESS form_end -%]
127
128    [% BLOCK form_start -%]
129    <form[% process_attrs(form.attributes) %]>
130    [% END -%]
131
132    [% BLOCK form_end -%]
133    </form>
134    [% END -%]
135
136    [% BLOCK button -%]
137    <input type="button" name="[% f.html_name %]" id="[% f.id %]"
138        [% process_attrs(f.attributes) %] value="[% f.value %]" />
139    [% END -%]
140
141    [% BLOCK checkbox -%]
142    <input type="checkbox" name="[% f.html_name %]" id="[% f.id %]"
143       [% process_attrs(f.attributes) %] value="[% f.checkbox_value -%]"
144       [% IF f.fif == f.checkbox_value -%] checked="checked"[% END ~%] />[%~ ~%]
145    [% END -%]
146
147    [% BLOCK checkbox_group -%]
148    [% FOR option IN f.options -%]
149      <label class="checkbox" for="[% f.name %].[% loop.index %]">
150      <input type="checkbox" value="[% option.value %]" name="[% f.name %]"
151         id="[% f.name %].[% loop.index %]"
152         [% FOREACH selval IN f.fif -%]
153           [% IF selval == option.value %] checked="checked"[% END -%]
154         [% END -%]>
155      [% option.label | html %]
156      </label>
157    [% END -%]
158    [% END -%]
159
160    [% BLOCK compound -%]
161    [% FOREACH sf IN f.sorted_fields -%]
162      [% outerf = f; f = sf; -%]
163      [% WRAPPER "wrapper_${f.uwrapper}" %][% PROCESS "${f.uwidget}" -%][% END -%]
164      [% f = outerf -%]
165    [% END -%]
166    [% END -%]
167
168    [% BLOCK hidden -%]
169    <input type="hidden" name="[% f.html_name %]" id="[% f.id %]"
170        [% process_attrs(f.attributes) %] value="[% f.fif %]" />
171    [% END -%]
172
173    [% BLOCK password -%]
174    <input type="password" name="[% f.html_name %]" id="[% f.id %]"
175        [% process_attrs(f.attributes) %] value="[% f.fif %]" />
176    [% END -%]
177
178    [% BLOCK radio_group -%]
179    [% FOR option IN f.options -%]
180      <label for="[% f.id %].[% loop.index %]">
181      <input type="radio" value="[% option.value %]" name="[% f.name %]"
182        id="[% f.id %].[% loop.index %]"
183        [% IF option.value == f.fif %] checked="checked"[% END %] />
184      [% option.label %]
185      </label>
186    [% END -%]
187    [% END -%]
188
189    [% BLOCK repeatable -%]
190    [% FOREACH rf IN f.sorted_fields -%]
191      [% outerrf = f; f = rf; -%]
192      [% WRAPPER "wrapper_${f.uwrapper}" %][% PROCESS "${f.uwidget}" -%][% END -%]
193      [% f = outerrf -%]
194    [% END -%]
195    [% END -%]
196
197    [% BLOCK reset -%]
198    <input type="reset" name="[% f.html_name %]" id="[% f.id %]"
199        [% process_attrs(f.attributes) %] value="[% f.value %]" />
200    [% END -%]
201
202    [% BLOCK select -%]
203    <select name="[% f.html_name %]" id="[% f.id %]"[% process_attrs(f.attributes) %]
204      [% IF f.multiple %] multiple="multiple" size="[% f.size %]" [% END -%]>
205      [% FOR option IN f.options -%]
206      <option id="[% f.id %].[% loop.index %]" value="[% option.value -%]"
207          [% FOREACH selval IN f.fif -%]
208            [% IF selval == option.value %] selected="selected"[% END -%]
209          [% END -%]>
210          [% option.label | html %]
211      </option>
212      [% END -%]
213    </select>
214    [% END -%]
215
216    [% BLOCK submit -%]
217    <input type="submit" name="[% f.html_name %]" id="[% f.id %]"
218        [% process_attrs(f.attributes) %] value="[% f.value %]" />
219    [% END -%]
220
221    [% BLOCK text -%]
222    <input type="[% f.input_type %]" name="[% f.html_name %]" id="[% f.id %]"
223       [% process_attrs(f.attributes) %] value="[% f.fif %]" />
224    [% END -%]
225
226    [% BLOCK textarea -%]
227    <textarea name="[% f.html_name %]" id="[% f.id %]" rows="[% f.rows %]"
228       cols="[% f.cols %]" [% process_attrs(f.attributes) %]>[% f.fif %]</textarea>
229    [% END -%]
230
231    [% BLOCK upload -%]
232    <input type="file" name="[% f.html_name %]" id="[% f.html_name %]"
233        [% process_attrs(f.attributes) %] />
234    [% END -%]
235
236    [% BLOCK wrapper_simple -%]
237    <div[% process_attrs(f.wrapper_attributes) -%]>
238      [% IF f.do_label %][% PROCESS label %][% END -%]
239      [% content -%]
240    </div>
241    [% END -%]
242
243    [% BLOCK label -%]
244    <label [% process_attrs(f.label_attributes) %]for="[% f.html_name %]">[% f.label %]</label>
245    [% END -%]
246
247    [% BLOCK wrapper_wrap_label -%]
248    <div[% process_attrs(f.wrapper_attributes) %]>
249        <label[% process_attrs(f.label_attributes) %] for="[% f.html_name %]">
250           [%~ content ~%][%~ f.label %]
251        </label>
252    </div>
253    [% END -%]
254
255    [% BLOCK wrapper_none -%]
256    [% content %]
257    [% END -%]
258
259    [% BLOCK wrapper_fieldset -%]
260    <fieldset[% process_attrs(f.wrapper_attributes)%]><legend>[% f.label %]</legend>
261    [% content -%]
262    </fieldset>
263    [% END -%]
264
265=head1 AUTHOR
266
267FormHandler Contributors - see HTML::FormHandler
268
269=head1 COPYRIGHT AND LICENSE
270
271This software is copyright (c) 2017 by Gerda Shank.
272
273This is free software; you can redistribute it and/or modify it under
274the same terms as the Perl 5 programming language system itself.
275
276=cut
277