Introduction
The new form extension is configured entirely with YAML – this markup language was established in the TYPO3 universe with the new version 8. It is also used for the configuration of the new rich text editor CKEditor. Especially for the new form framework, a lot of configuration exists because the core developers wanted it to be as versatile as possible. TYPO3 integrators will have to adapt to this new configuration method. Thankfully, the backend module of EXT:form contains a quite helpful form editor which assists you with creating a new form.
One great advantage compared to proven form extensions like Powermail is the way forms are stored. Every form is saved as a separate YAML file including all form fields, validators and finishers, e.g. to send emails. By default these files are saved inside the fileadmin folder by the backend module, but it's possible to save to site packages (template extensions). This way you can easily version your generated forms and reuse them in other TYPO3 installations. You can configure the backend module so that you're able to modify forms that have been outsourced to an extension. I will add this setting further below.
The general concept of the form extension is described in great detail on this page. You can find the configuration reference and API reference on the subsequent pages.
The documentation mentioned above (working draft) contains an example how to add custom templates. But these templates would be used for every form on your website, which is not always desired. Using TypoScript conditions would be inconvenient. There is an elegant way to achieve custom templates for single forms, though. For that, we'll need at least two YAML configuration files:
- one YAML file to modify the basic configuration of EXT:form
- one YAML file for every created form
File structure
I'll use a site package in this tutorial to store my files. The file structure is based on a typical TYPO3 Extbase extension:
- ext_typoscript_setup.typoscript
After installing the extension, the TypoScript inside this file is automatically loaded. - Configuration/Yaml/CustomFormSetup.yaml
With this file we'll modify the Form Framework to our needs. - Resources/Private/Forms/
Here all created forms are stored. - Resources/Private/
Frontend/Partials/
Location for your customized frontend partials. - Resources/Private/
Frontend/Templates/
Location for your customized frontend templates.
If you wanted to adjust templates for the backend module, the location would be Resources/Private/
Register YAML configuration with TypoScript
First of all we'll set a link to the following YAML file which will contain our modifications of the basic config. As the numbers 10 to 30 are already reserved by form, we'll use a higher number like 100 to add our path to the array of file paths.
Since this file will be used to also configure the backend module, we'll set the link in both top level objects plugin and module:
ext_typoscript_setup.typoscript
plugin.tx_form.settings.yamlConfigurations {
100 = EXT:my_extension/Configuration/Yaml/CustomFormSetup.yaml
}
module.tx_form.settings.yamlConfigurations {
100 = EXT:my_extension/Configuration/Yaml/CustomFormSetup.yaml
}
Create the YAML configuration
Next we'll create the YAML file which we specified above and include the following modifications:
- allowedExtensionPaths allows us to save forms inside on or more site packages and folders.
- allowSaveToExtensionPaths and allowDeleteFromExtensionPaths are pretty much self explaining. They enable us to edit forms within the backend module. Please check if your editors should be able to to this. Otherwise restrict access to the backend module or don't use these configurations.
- Finally we'll create a new so-called prototype which I just called customStyling. The name is arbitrary. It it important to add the operator __inheritances to copy the definition of the standard prototype to our new prototype object. This operator behaves similar to the < operator in TypoScript. Subsequently we can set the rootPaths for our custom templates and partials.
CustomFormSetup.yaml
TYPO3:
CMS:
Form:
persistenceManager:
allowedExtensionPaths:
10: EXT:my_extension/Resources/Private/Forms/
allowSaveToExtensionPaths: true
allowDeleteFromExtensionPaths: true
prototypes:
customStyling:
__inheritances:
10: 'TYPO3.CMS.Form.prototypes.standard'
formElementsDefinition:
Form:
renderingOptions:
templateRootPaths:
100: 'EXT:my_extension/Resources/Private/Frontend/Templates/'
partialRootPaths:
100: 'EXT:my_extension/Resources/Private/Frontend/Partials/'
layoutRootPaths:
100: 'EXT:my_extension/Resources/Private/Frontend/Layouts/'
Create an example form
The following example form is shipped with the form extension and can be loaded inside the backend module. I only changed the prototypeName from standard to our new prototype customStyling.
BasicContactForm.yaml
renderingOptions:
submitButtonLabel: Submit
identifier: BasicContactForm
label: 'Basic contact form'
type: Form
prototypeName: customStyling
finishers:
-
options:
subject: 'Your message: {subject}'
recipients:
your.company@example.com: 'Your Company name'
senderAddress: '{email}'
senderName: '{name}'
format: html
attachUploads: true
translation:
language: default
title: 'Confirmation of your message'
identifier: EmailToReceiver
renderables:
-
renderingOptions:
previousButtonLabel: 'Vorherige Seite'
nextButtonLabel: 'Nächster Schritt'
identifier: page-1
label: 'Contact Form'
type: Page
renderables:
-
defaultValue: ''
identifier: name
label: Name
type: Text
properties:
fluidAdditionalAttributes:
placeholder: Name
validators:
-
identifier: NotEmpty
-
defaultValue: ''
identifier: subject
label: Subject
type: Text
properties:
fluidAdditionalAttributes:
placeholder: Subject
validators:
-
identifier: NotEmpty
-
defaultValue: ''
identifier: email
label: Email
type: Text
properties:
fluidAdditionalAttributes:
placeholder: 'Email address'
validators:
-
identifier: NotEmpty
-
identifier: EmailAddress
-
defaultValue: ''
identifier: message
label: Message
type: Textarea
properties:
fluidAdditionalAttributes:
placeholder: ''
validators:
-
identifier: NotEmpty
-
renderingOptions:
previousButtonLabel: 'Previous page'
nextButtonLabel: 'Next page'
identifier: summarypage
label: 'Summary page'
type: SummaryPage
Conclusion
What's so great about this simple configuration is that every form can get an individual template, even if more than one form exist on a single page.
By the way: If you only want to change CSS class names, custom templates aren't necessary – there are several configurations to change these. The default classes come from the Bootstrap framework. An example:
TYPO3:
CMS:
Form:
prototypes:
standard:
formElementsDefinition:
Textarea:
properties:
elementClassAttribute: 'xxlarge'