DEPRECATION WARNING
This documentation is not using the current rendering mechanism and is probably outdated. The extension maintainer should switch to the new system. Details on how to use the rendering mechanism can be found here.
Layouts¶
During a form integration, one problem always comes back: setting up fields which have exactly the same template, meaning the container of a field will be almost identical from one field to another. In most cases, two fields answer the exact same HTML/CSS integration rules, which leads to huge code repetition, and breaks the “Don't Repeat Yourself” rule.
Problem¶
Why is block repetition annoying?¶
One of the first reasons is obvious: it makes code reading harder. It's possible that a field is made out of several HTML tags levels: if we multiply it by the number of fields in a form, we can quickly get to hundreds of lines of code.
Setting up a new field is also slow: adjust the container to the field, and modify all variables bound to the field: label, attributes (class
, id
), etc.
Finally, the maintainability becomes harder. Indeed, if a modification must be done in the HTML structure for every field of a form, the correction must be applied on each one of the fields. Worse case: if a site contains dozens of forms based on the same template, every form must be modified.
Solution¶
To solve this problem, FormZ allows to regroup templates for fields in standalone views. The code required to integrate a field is then much shorter and more understandable, but also more maintainable: when a modification is done in a field layout, it is done for every real field which actually uses this layout.
Usage¶
Declaring a new layout¶
To declare a new layout which can be used by the ViewHelper Field, you first have to write its TypoScript configuration, then bind a template file and finally create the layout file.
You are then able to use this new layout with any form field.
TypoScript Configuration¶
The TypoScript configuration of your layout must be inside a layout group. FormZ provides by default the group default
.
Tip
In a project, it's advised to use a group name for this very project, for instance my-project
, or my-company
.
You can find all needed information in the chapter “Layouts”.
Example:
config.tx_formz.view.layouts {
my-project {
templateFile = EXT:extension/Resources/Private/Templates/MyProject/Default.html
items {
one-column.layout = MyProject/OneColumn
two-columns.layout = MyProject/TwoColumns
}
}
}
Template file creation¶
The template file declared in the property templateFile
of the TypoScript configuration must be created, if it doesn't exist yet. You should try to use this template with as much layouts as you can.
It's advised to divide your template in several sections, which contain the important blocks that are used by your layout. By default, three sections are used: Label
, Field
and Message
.
The following variables can be used in your template:
layout
: contains the path to the layout used, for instanceMyProject/OneColumn
. You can use it with the ViewHelperf:layout
.formName
: name of the current form (the value of the propertyname
used in the ViewHelper Form).fieldName
: name of the current field (the value of the propertyname
used in the ViewHelper Field).fieldId
: if this argument was not declared before, it will be automatically filled with an identifier generated with the name of the form and the name of the field. Example for the fieldemail
of the formmyForm
:fz-my-form-email
.
Important
In order to be fully working with FormZ, your template must respect all the rules defined in the chapter “Configuration”.
Example:
EXT:extension/Resources/Private/Templates/MyProject/Default.html
<f:layout name="{layout}" />
{namespace fz=Romm\Formz\ViewHelpers}
<f:section name="Label">
<label class="{f:if(condition: '{required}', then: 'required')}" for="{fieldId}">{label}</label>
</f:section>
<f:section name="Field">
<div fz-field-container="{fieldName}">
<fz:slot.render slot="Field" />
</div>
</f:section>
<f:section name="Messages">
<div fz-field-message-container="{fieldName}">
<div fz-field-message-list="{fieldName}">
<f:for each="{validationResults.errors}" iteration="iteration" as="error">
<fz:formatMessage message="{error}" />
</f:for>
</div>
</div>
</f:section>
Layout file creation¶
The layout usage with the template is exactly the same as in a classic Fluid integration: you can render sections defined in the template.
Use the layout to get the wanted dividing, which may then be used by the form fields (see below).
Example:
EXT:extension/Resources/Private/Layouts/MyProject/OneColumn.html
<div class="row">
<div class="col-md-4">
<f:render section="Label" arguments="{_all}" />
</div>
<div class="col-md-4">
<f:render section="Field" arguments="{_all}" />
</div>
<div class="col-md-4">
<f:render section="Messages" arguments="{_all}" />
</div>
</div>
Using a layout¶
Once you registered your layouts, you can use them with the ViewHelper Field by filling the attribute layout
. The field will then use the wanted layout for its rendering, with chosen options.
This way, the field rendering stays completely outside your form integration.
If you need to know more, read the chapter “Field”.
Example:
1 2 3 4 5 6 7 8 9 10 11 12 13 | {namespace fz=Romm\Formz\ViewHelpers}
<fz:form action="submitForm" name="myForm">
<fz:field name="email" layout="my-project.one-column">
<fz:option name="required" value="1" />
<fz:slot name="Field">
<f:form.textfield property="{fieldName}" id="{fieldId}" placeholder="email" />
</fz:slot>
</fz:field>
</fz:form>
|