Rendering can be done in many different ways,
from forms rendered entirely in templates with no information from FormHandler (except possibly the fill-in-the-form values) to forms that are completely rendered by FormHandler.

For most situations,
something in between hand-built and completely generated will probably be the best solution.
For admin forms that don't need a lot of styling or special HTML,
FormHandler's automatic rendering may be appropriate.
FormHandler rendering may also be a good solution if you have enough forms that putting time into creating rendering widgets and themes is worthwhile.

The automatic rendering is also useful when developing a new form.
You can get an idea of what it looks like,
and then customize it.

Another situation in which FormHandler rendering may be useful is when the form is complex enough that working in Perl is a better idea than putting lots of logic into templates.

All of the rendering is designed to be easily replaced with elements of your own,
or to be replaced entirely.
You can create your own rendering 'widgets' and load them into the fields by designating the directory in the 'widget_name_space'.
You could also create a completely separate renderer that's a separate object or class that takes a form object,
or a role that is applied to your form.

Note that unless you set 'no_widgets' in the form,
the rendering roles are automatically applied.
You don't need to include anything else,
unless you want to use a different renderer.

You can also use the 'render_element' method, if you want to leave the wrapper in place, but sometimes render 'bare' html elements:

<div class="my_class">
[% form.field('foo').render_element %]
</div>

If you wish to loop through the fields yourself, use the 'sorted_fields' method, since it skips inactive fields and handles the 'order' attribute.

A set of Template Toolkit templates is also provided in the 'share' directory. There are individual templates for each 'widget', such as a checkbox, and there is also an all-in-one template that includes blocks for the various 'widgets'. If you want to use these templates you can just copy them to your template directory and specify the form template in your controller.

For the 'Table' form widget, you will also need to set the matching Table widget_wrapper.

A widget role, providing the 'render' method, and a widget wrapper role, providing the 'wrap_field' method, are applied to each field when the form is built. Each field has a default widget, but you can change that by setting 'widget' to a different widget role:

has_field 'foxy' => ( widget => 'MyWidget' );

Default widget roles are found in the HTML::FormHandler::Widget directory. The name space used to look for the widget roles can be specified on a form or field basis by setting 'widget_name_space' to an arrayref of name spaces:

For the above widget ('MyWidget') and widget_name_space, you need to have a package named 'MyApp::Form::Widget::Field::MyWidget'.

The HTML::FormHandler::Widget name space is always searched as the last name space. This means that you can set up an application or form specific set of widgets. Widgets in a widget directory (specified in widget_name_space) are located in either a 'Field', 'Wrapper', or 'Form' subdirectory. (Blocks are in a 'Blocks' subdirectory.)

You can also create an 'all-in-one' type rendering role, using HTML::FormHandler::Render::Simple as a basis. It used the method name 'render_field' on the form ( $form->render_field('field_name') ) instead of the 'render' method on the field.

In addition to the 'Simple' wrapper, there is a 'Bootstrap' wrapper which creates HTML formatted to use the Twitter Bootstrap 2.0 CSS. There's also a sample "theme", HTML::FormHandler::Widget::Theme::Bootstrap, which is a role that sets the widget_wrapper to 'Bootstrap', and provides Bootstrap-type formatting of the form error message.

There are a lot of different settings that control the rendering. Some of them are attributes in the form or field, and some of them are set using the 'tags' hashref in the field or the 'form_tags' hashref in the form.

You can make your own copy of an existing wrapper and add features to it. However, there are so many different ways to render the HTML around a field, that it's very difficult to handle more than a short list of standard presentations in one 'wrapper'. It may be better to make a number of more atomic widget wrappers and use those rather than complicate the already fairly complicated "Simple" and "Bootstrap" wrappers more.

Arbitrary HTML attributes on form elements (such as 'input' elements) can be specified with 'element_attr' on the field. You can also set attributes for the label with 'label_attr' and attributes for the wrapper with 'wrapper_attr'. The 'class' attributes are handled separately, and are arrayrefs (element_class, wrapper_class, label_class):

Hashref of arbitrary HTML attributes to include in the element. Note that this does not include the 'id' and 'type' attributes, which are handled separately. The 'id' can be changed with the field's 'id' attribute.

The form has an 'html_attributes' callback which can be used to customize, localize, or modify the various attributes when used. Types: element, wrapper, label, form_element, form_wrapper, checkbox_label

The 'tags' are settings and strings which may vary by the particular widget that implements them. The best place to look for documentation on them is in the field widget, field wrapper, and form widgets that you are using. The 'tags' allow customizing rendering behavior on a per-field basis. FormHandler has a number of flags/settings that it uses; you can add your own for your custom rendering code.

wrapper_tag -- the tag to use in the wrapper, default 'div'
label_tag -- tag to use for label (default 'label')
label_after -- string to append to label, for example ': ' to append a colon

Tags can be used to switch the Simple wrapper from divs to using paragraphs instead, or to add a colon in label formatting:

Tags can be set for all fields in the form by using a 'build_update_subfields' sub, or 'widget_tags'. The 'update_subfields' hashref takes general-purpose keys 'all', 'by_flag' (compound, repeatable, contains), and 'by_type'. You can also set specific field attributes by using the field name as a key. For example, if you don't want errors to be displayed next to the fields, you need to set the 'no_errors' tag:

The 'widget_tags' attribute only handles the 'tags' hashref, so if you also want to set classes or attributes, then build_update_subfields is more useful. You can also use 'build_update_subfields' in a custom compound field class.

If you have defaults that are set in 'build_update_subfields' in a base class, in order to use hashrefs from both base and current classes, you will need to merge the hashes:

The repeatable field instances are constructed internally, so it's trickier to set things like wrapper tags. There are two ways to do it, using the 'init_contains' attribute on the repeatable field, and using the 'update_subfields' builder:

If you want to implement the 'render' method in a custom field, you can set 'widget' to 'None' and no widget will be applied. Setting the 'widget_wrapper' to 'None' will apply the 'None' wrapper, which simply returns the widget rendering.

The default is currently to display error messages next to the rendered fields, if you're doing $form->render. If you don't want messages next to fields, you can set the 'no_errors' tag, as discussed in the section on 'Tags and other settings...'.

Note that the 'None' widget wrapper, since it doesn't render anything except the form element (input, select, etc), will not render errors next to the field. Setting the 'do_wrapper' and 'do_label' flags to 0 will still render errors.

When rendering, FormHandler loops through the sorted fields in the form and executes the 'render' method on each field. Fields in FormHandler forms, particularly those that interface with a database, are usually structured in a way that matches the data structure. This doesn't always fit with the way that you want to display the form.

'Blocks' provide an alternative way of structuring the display. A 'block' is a fairly basic object that contains a 'render' method. The standard block class, HTML::FormHandler::Widget::Block, has Moose attributes to set the HTML tag, the label, the classes, etc, plus a 'render_list' which contains the names of a list of fields or other blocks to render.

Many of the flags and settings necessary for rendering can now be moved out into a role. Whether you want to do that or not is a matter of style and preference. The advantage is that it leaves the form class itself cleaner and easier to read. The disadvantage is that your settings come from more different places.

Here's an example of a form rendering 'theme', taken from the t/bootstrap/basic.t test:

The default for most fields is a 'div' wrapper and a label. If you don't want the wrapper, set do_wrapper => 0. If you don't want the label, set do_label => 0.

Checkboxes are most complicated, in that the default is to have two labels. The outer label, the one that's in the same place as the label for other input elements, is set with label => '...'. The inner label, which is the equivalent of the label => '...' in the options array used for selects and checkbox groups, is set with option_label => '...'. There are a number of other 'tags' to control the presentation. See HTML::FormHandler::Widget::Field::Checkbox for more information, and t/render/checkbox.t for examples.

Some fields by default do not render a label: Button, Submit, Reset, ButtonTag. If you do want a label with these fields, you must set the 'do_label' flag to 1:

has_field 'foo' ( type => 'Button', do_label => 1 );

Select fields are also fairly complicated. They can be rendered with the 'Select', 'RadioGroup', and 'CheckboxGroup' widgets. Option groups are also supported. See HTML::FormHandler::Field::Select;

The base field class has a 'render_filter' attribute which is a coderef used to clean the values used to fill in the form for Render::Simple and the Widgets, and for some of the labels.. The default filter changes quote, ampersand, <, and > to the equivalent html entities. If you wish to use some other sort of filtering, you can use the 'render_filter' method in your form, or set a coderef on individual field objects. A 'render_filter' function in your form will be used by all fields. Setting it for a field will just be for that field.

You can supply an HTML string to this field, to be displayed directly. There is no 'value' associated with this field; it's a field for rendering only. The HTML string can be built with a form or field method.