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