Introduction
The TYPO3 Form Framework configures the available fields and their properties with YAML. This applies to the form fields in the frontend, but also the Form Editor in the TYPO3 backend.
If the existing form properties are no longer sufficient, we can easily add our own. I will demonstrate this by adding a new select field within the Form Editor, which we will use to render an additional CSS class to design the form in the frontend.
identifier: myContactForm
label: 'Contact us'
type: Form
prototypeName: standard
renderingOptions:
submitButtonLabel: Submit
# Added manually:
myCustomOption: custom-value
renderables:
-
renderingOptions:
previousButtonLabel: 'Previous step'
nextButtonLabel: 'Next step'
identifier: page-1
label: 'Contact Form'
type: Page
renderables:
-
defaultValue: ''
identifier: subject
label: Subject
type: Text
properties:
# Added manually:
myCustomProperty: 'custom property'
Thankfully, these manually inserted properties are preserved when we subsequently edit the form using the Form Editor in the TYPO3 backend.
These properties are immediately available in the Fluid templates! In the case of our two examples above: {form.renderingOptions.
Note: The first level of each form element is limited to certain properties. New properties can be added below renderingOptions or properties. If this is disregarded, you will get an exception:
The options "example" were not allowed (allowed were: "label, defaultValue, properties, renderingOptions, validators, formEditor, variants").
If the properties are frequently used, it certainly is convenient for the editor (or integrator) to be able to maintain them directly in the backend.
Our objective: A new select field for the CSS class
In the following, we will configure the field shown in the screenshot(s).
The selected option should render a CSS class in the frontend. In our example, we'll extend the form template with a surrounding div element. The second class will then be set with the value of our select field:
<div class="form form--subscription">
You can use this classes afterwards to style a form differently.
This tutorial describes one of three solutions to realize individual form styling. See a comparison of these approaches with advantages/disadvantages and applicable use cases.
Adding the field to the Form Editor
The graphical user interface of the Form Editor can be extended through the Form Configuration.
As a reminder, the Form Configuration contains the general settings of the Form Framework. This includes the available form elements and finishers or the sources for language files and templates.
In TYPO3 v10 the configuration of the Form Framework has been neatly split into Partials, which makes it much easier to read. You can find them in the TYPO3 core under typo3/sysext/form/
If you have already created your custom Form Configuration, you only need the following additions. If not, I explain the preliminary work here.
Resources/Private/Forms/Frontend/Templates/Form.html
In the Form.html template, we only add the div wrapper with our desired classes. The if condition checks whether a value is given: in our example, the value will be empty for the common contact form (but this is not a prerequisite). This will render the second class only for special forms.
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" xmlns:formvh="http://typo3.org/ns/TYPO3/CMS/Form/ViewHelpers" data-namespace-typo3-fluid="true">
<div class="form {f:if(condition: form.renderingOptions.formStyleClass, then: ' form--{form.renderingOptions.formStyleClass}')}">
<formvh:renderRenderable renderable="{form}">
<formvh:form
object="{form}"
action="{form.renderingOptions.controllerAction}"
method="{form.renderingOptions.httpMethod}"
id="{form.identifier}"
section="{form.identifier}"
enctype="{form.renderingOptions.httpEnctype}"
addQueryString="{form.renderingOptions.addQueryString}"
argumentsToBeExcludedFromQueryString="{form.renderingOptions.argumentsToBeExcludedFromQueryString}"
additionalParams="{form.renderingOptions.additionalParams}"
additionalAttributes="{formvh:translateElementProperty(element: form, property: 'fluidAdditionalAttributes')}"
>
<f:render partial="{form.currentPage.templateName}" arguments="{page: form.currentPage}" />
<div class="actions">
<f:render partial="Form/Navigation" arguments="{form: form}" />
</div>
</formvh:form>
</formvh:renderRenderable>
</div>
</html>
YAML configuration
TYPO3:
CMS:
Form:
prototypes:
standard:
formElementsDefinition:
Form:
renderingOptions:
templateRootPaths:
90: 'EXT:my_sitepackage/Resources/Private/Forms/Frontend/Templates/'
formEditor:
editors:
500:
identifier: formStyleClass
templateName: Inspector-SingleSelectEditor
label: 'Form styling'
propertyPath: renderingOptions.formStyleClass
selectOptions:
10:
value: ''
label: 'Contact form'
20:
value: survey
label: 'Survey'
30:
value: subscription
label: 'Newsletter subscription'
Explanation of the configuration
templateRootPaths
As we use a customized version of the Form.html template, we need to define the path where it can be found. It will be located in our sitepackage.
formEditor / editors
Below this property, we add the new field with the arbitrary key "500". Which keys are already assigned for existing fields can be found in the backend module "Configuration" under "Form: YAML configuration".
identifier
This is the unique identifier of your new property.
templateName
Here we use one of the existing Inspector components of the Form Framework. The Inspector-SingleSelectEditor will render the new field as a <select> field.
propertyPath
The identifier is assigned to the renderingOptions of the form here.
selectOptions
Here we can define all desired options of the select field. The label will be visible in the form editor and could also be translated via translation key. The value will be stored in the YAML definition of our forms and can be accessed in our Form.html template as a Fluid variable.