Skip to content

Introduction

In its original version from 2017, this tutorial described the first steps with the newly introduced TYPO3 Form Framework: from the basic configuration in your own site package to individual form templates, for which I had decided to use a new prototype.

The current version focuses on how to assign form-specific templates using custom prototypes, and how you (and your editors) can work with multiple form prototypes.
However, I decided not to remove the basic configuration from the tutorial altogether.

This tutorial describes one of three solutions of assigning different templates. See a comparison of these approaches with advantages/disadvantages and applicable use cases.

1. Basic configuration of the Form Framework

The form extension is configured entirely with YAML – this markup language was established in the TYPO3 universe with 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.

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.

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/Backend/Templates/. Please remember to respect the inner file structure of the templates: The small Partial to mark mandatory fields has to be saved inside Resources/Private/Frontend/Partials/Field/Required.html.

Note: The extension configuration required for a sitepackage (e.g. composer.json) is not covered here.

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:

  1. allowedExtensionPaths allows us to save forms inside on or more site packages and folders.
  2. 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.

CustomFormSetup.yaml:

TYPO3:
  CMS:
    Form:
      persistenceManager:
        allowedExtensionPaths:
          10: EXT:my_extension/Resources/Private/Forms/
        allowSaveToExtensionPaths: true
        allowDeleteFromExtensionPaths: true

From this moment we can create new forms in the backend and save them in the sitepackage.

2. Custom form prototypes

Each form is based on a so-called prototype. For this prototype, all necessary form fields, validators, and finishers are configured. The paths to frontend templates and XLIFF language files are also defined in the prototype.

All configurations provided in the Form Framework refer to the standard prototype.

Configuring your own prototypes has several advantages. Prototypes affect not only the frontend, but also the Form Editor in the backend and plugin overrides.
For forms based on a custom prototype, you can, for example:

  • define template paths and CSS classes
  • make only text fields and checkboxes available in the Form Editor and
  • remove all finishers except the SaveToDatabase finisher;
  • allow the override of a new finisher in the plugin

Configuration of a custom form prototype

The basic setup is completed, in the next step we add our own prototype in the CustomFormSetup.yaml:

TYPO3:
  CMS:
    Form:
      prototypes:
        complaintForm:
          __inheritances:
            10: 'TYPO3.CMS.Form.prototypes.standard'
          formElementsDefinition:
            Form:
              renderingOptions:
                templateRootPaths:
                  100: 'EXT:form_examples/Resources/Private/Frontend/Templates/ComplaintForm/'
                partialRootPaths:
                  100: 'EXT:form_examples/Resources/Private/Frontend/Partials/ComplaintForm/'
                layoutRootPaths:
                  100: 'EXT:form_examples/Resources/Private/Frontend/Layouts/ComplaintForm/'
            SingleSelect:
              properties:
                elementClassAttribute: 'custom-select'

This new prototype is given the (freely selectable) name complaintForm. Using the __inheritances operator, we copy the current configuration of the standard prototype. Alternatively, we could selectively add the form fields, validators and finishers to be available in the custom prototype.

We then define the desired template paths and a special CSS class for select fields.

As of now, TYPO3 integrators could assign the new form prototype manually in YAML.

Create a form template

Since we will provide the prototype in the backend further down, we have to define a start template for newly created forms. It is a usual form definition that will then be added as a selection in the Form Manager.

renderingOptions:
  submitButtonLabel: Submit
identifier: CustomPrototypeExample
label: 'Example - Custom prototype (complaint form)'
type: Form
prototypeName: complaintForm
finishers:
  -
    options:
      message: 'Oops! No email was sent. Anyway, have a great day! ????'
    identifier: Confirmation
renderables:
  -
    renderingOptions:
      previousButtonLabel: 'Previous step'
      nextButtonLabel: 'Next step'
    identifier: page-1
    label: Complaint
    type: Page
    renderables:
      -
        defaultValue: ''
        identifier: name
        label: Name
        type: Text
        properties:
          fluidAdditionalAttributes:
            required: required
        validators:
          -
            identifier: NotEmpty
      -
        defaultValue: ''
        identifier: email
        label: Email
        type: Text
        properties:
          fluidAdditionalAttributes:
            required: required
        validators:
          -
            identifier: NotEmpty
          -
            identifier: EmailAddress
      -
        properties:
          options:
            'This form is ridiculous': 'This form is ridiculous'
          prependOptionLabel: 'Please select …'
          fluidAdditionalAttributes:
            required: required
        type: SingleSelect
        identifier: issue
        label: Issue
        validators:
          -
            identifier: NotEmpty
  -
    renderingOptions:
      previousButtonLabel: 'Previous step'
      nextButtonLabel: 'Next step'
    identifier: summarypage
    label: 'Summary page'
    type: SummaryPage

Prototype selection for editors

To allow editors to use alternative prototypes, we need to register the prototypes available for selection in the Form Manager.

TYPO3:
  CMS:
    Form:
      formManager:
        selectablePrototypesConfiguration:
          200:
            identifier: complaintForm
            label: 'Complaint form'
            newFormTemplates:
              100:
                templatePath: 'EXT:form_examples/Resources/Private/Forms/CustomPrototypeExample.form.yaml'
                label: 'Complaint form (Start template)'

Let's take a look at the configuration in detail:

  • Below selectablePrototypesConfiguration, we assign a new key. For the standard prototype, the key 100 is used.
  • As identifier, we have to enter the exact name of our custom prototype.
  • Below newFormTemplates we again assign a freely chosen key.
  • The templatePath points to the template form with the prototype complaintForm.
  • label: Here, we could also use XLIFF keys for multilingual labels.

With these settings, the new prototype is available with a (required) form template in the backend module. You can also provide multiple form templates for a prototype. In the Form Framework, this concept is called "Start templates".

Editors can now create a new form in the backend module "Forms" and select "Predefined form" in the first modal. In the subsequent modal, he first selects the desired form prototype, then the provided form template.
The select field "Form prototype" is only displayed in the backend if more than the standard prototype was registered.

Demo

You can find the prototype, the form template, and the configuration in the TYPO3 extension "form_examples". I have added further prototypes and form templates there for the Form Manager. The recently updated version of this extension is available for TYPO3 v10 to v12 in separate, optimized branches.

form_examples on GitHub

Conclusion

The concept of form prototypes is a powerful tool. However, it will depend on the project whether you need more than just the standard prototype and whether you make them available to editors.

If it's only a matter of differing form styling, there are also two other options - which I compared in this article.