Custom finisher
Important
Finishers are executed in the order defined in your form definition.
Table of contents
Write a custom finisher
To make your finisher configurable by users in the backend form editor, see here.
Add a new finisher to the form configuration prototype by defining a
finishers. Set the implementation property to your new implementation class.
prototypes:
standard:
finishersDefinition:
CustomFinisher:
implementationClassName: 'MyVendor\MySitePackage\Domain\Finishers\CustomFinisher'
Register your custom form definition.
Add options to your finisher with the options property. Options
are default values which can be overridden in the form definition.
Define default values
Override options using the form definition
identifier: sample-form
label: 'Simple Contact Form'
prototype: standard
type: Form
finishers:
-
identifier: CustomFinisher
options:
yourCustomOption: 'Björn'
renderables:
# ...
A finisher must implement
Finisher
and should extend
Abstract.
In doing so, in the logic of the
finisher the method execute will be called first.
Accessing finisher options
If your finisher class extends
Abstract,
you can access the option values in the finisher using method parse:
$yourCustomOption = $this->parseOption('yourCustomOption');
parse looks for 'yourCustomOption' in your
form definition.
prototypes:
standard:
finishersDefinition:
CustomFinisher:
implementationClassName: 'MyVendor\MySitePackage\Domain\Finishers\CustomFinisher'
options:
yourCustomOption: 'Ralf'
If it can't find it, parse checks
- for a default value in the
prototypeconfiguration, - for
$defaultinside your finisher class:Options
If it doesn't find anything, parse returns null.
If it finds the option, the process checks whether the option value will
access FormRuntime values.
If the Form returns a positive result, it is checked whether the
option value can access values of preceding finishers.
At the end, it translates the finisher options.
Accessing form runtime values
You can populate finisher options with
submitted form values using the parse method.
You can access values of the Form and therefore values in every
form element by encapsulating option values with {}. Below, if there is a
form element with the identifier 'subject', you can access the value
in the finisher configuration:
identifier: simple-contact-form
label: 'Simple Contact Form'
prototype: standard
type: Form
finishers:
-
identifier: Custom
options:
yourCustomOption: '{subject}'
renderables:
-
identifier: subject
label: 'Subject'
type: Text
// $yourCustomOption contains the value of the form element with the
// identifier 'subject'
$yourCustomOption = $this->parseOption('yourCustomOption');
You can use {__ as an option value to return the
current UNIX timestamp.
Finisher Context
The
Finisher class takes care of
transferring a finisher context to each finisher. If your finisher class extends
Abstract the
finisher context will be available via:
$this->finisherContext
The cancel method prevents the execution of successive finishers:
$this->finisherContext->cancel();
The method get returns the submitted form values.
$this->finisherContext->getFormValues();
The method get returns the Form:
$this->finisherContext->getFormRuntime();
Add finisher to backend UI
After registering a new finisher in the yaml form definition file, you can also
add it to the backend form editor for your backend users ( form
section below) to work with in the GUI:
prototypes:
standard:
formElementsDefinition:
Form:
formEditor:
editors:
900:
# Extend finisher drop down
selectOptions:
35:
value: 'CustomFinisher'
label: 'Custom Finisher'
propertyCollections:
finishers:
# add finisher fields
25:
identifier: 'CustomFinisher'
editors:
100:
identifier: header
templateName: Inspector-CollectionElementHeaderEditor
label: "Custom Finisher"
# custom field (input, required)
110:
identifier: 'customField'
templateName: 'Inspector-TextEditor'
label: 'Custom Field'
propertyPath: 'options.customField'
propertyValidators:
10: 'NotEmpty'
# email field
120:
identifier: 'email'
templateName: 'Inspector-TextEditor'
label: 'Subscribers email'
propertyPath: 'options.email'
enableFormelementSelectionButton: true
propertyValidators:
10: 'NotEmpty'
20: 'FormElementIdentifierWithinCurlyBracesInclusive'
9999:
identifier: removeButton
templateName: Inspector-RemoveElementEditor
finishersDefinition:
CustomFinisher:
formEditor:
iconIdentifier: 'form-finisher'
label: 'Custom Finisher'
predefinedDefaults:
options:
customField: ''
email: ''
# displayed when overriding finisher settings
FormEngine:
label: 'Custom Finisher'
elements:
customField:
label: 'Custom Field'
config:
type: 'text'
email:
label: 'Subscribers email'
config:
type: 'text'
Important
Make sure to define an icon in the finishers of your
finisher, otherwise the button to remove the finisher from the
form will not be visible.
Configuration registration
Register the form configuration yaml file in EXT::
<?php
declare(strict_types=1);
use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
defined('TYPO3') or die();
ExtensionManagementUtility::addTypoScriptSetup('
# for the backend
module.tx_form.settings.yamlConfigurations {
123456789 = EXT:yourExtension/Configuration/Form/CustomFormSetup.yaml
}
# for the frontend - otherwise the custom finisher class is not found
# because of the missing "implementationClassName"
plugin.tx_form.settings.yamlConfigurations {
123456789 = EXT:yourExtension/Configuration/Form/Backend.yaml
}
');
See also
Changed in version 13.0
Registration of global TypoScript for the TYPO3 backend has to be done in
an extensions ext_ using method Extension.
Former methods for registering global TypoScript are not compatible with site sets.