Zum Inhalt springen

Einleitung

Das TYPO3 Form Framework konfiguriert die zur Verfügung stehenden Felder und deren Eigenschaften mit YAML. Das gilt für die Formularfelder im Frontend, aber auch für den Form Editor im TYPO3-Backend.

Wenn die vorhandenen Formular-Eigenschaften nicht mehr ausreichen, können wir leicht eigene ergänzen. Dies zeige ich hier am Beispiel eines neuen Auswahlfeldes im Form Editor, mit dem wir eine zusätzliche CSS-Klasse zur Gestaltung des Formulars im Frontend ausgeben werden.

Eigenschaften in YAML manuell ergänzen

Grundsätzlich können wir neue Eigenschaften händisch in der YAML-Datei hinzufügen:

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'

Praktischerweise bleiben diese manuell eingefügten Eigenschaften auch erhalten, wenn wir das Formular nachträglich über den Form Editor im TYPO3-Backend bearbeiten.

In den Fluid-Templates stehen diese Eigenschaften dann schon zur Verfügung! Im Falle der beiden obigen Beispiele: {form.renderingOptions.myCustomOption} im Form.html Template; {element.properties.myCustomProperty} im Partial Field.html bzw. im Partial des jeweiligen Element-type, hier: Text.html.

Zu beachten ist: Die erste Ebene eines jeden Formular-Elements ist auf bestimmte Eigenschaften begrenzt. Neue Eigenschaften lassen sich unterhalb von renderingOptions oder properties ergänzen. Wird das nicht beachtet, erhält man eine Exception:
The options "example" were not allowed (allowed were: "label, defaultValue, properties, renderingOptions, validators, formEditor, variants")

Handelt es sich um regelmäßig benötigte Eigenschaften, ist es für den Redakteur (oder Integrator) praktisch, diese direkt im Backend pflegen zu können.

Unser Ziel: Ein eigenes Auswahlfeld für CSS-Klasse

Nachfolgend werden wir das im Screenshot sichtbare Feld konfigurieren.

Im Frontend soll diese Auswahl eine CSS-Klasse setzen. In unserem Beispiel erweitern wir das Formular-Template um ein div-Element. Die zweite Klasse wird durch den Wert unseres Auswahlfeldes ergänzt:

<div class="form  form--subscription">

Diese Klassen können wir dann verwenden, um das Formular besonders zu gestalten.

Dieses Tutorial beschreibt eine von drei Lösungen für individuelle Formular-Gestaltung. Zum Vergleich der Lösungswege mit Vor-/Nachteilen und passenden Anwendungsfällen.

Ergänzen des Feldes im Form Editor

Die grafische Oberfläche des Form Editors lässt sich über die Form Configuration erweitern.

Zur Erinnerung: Die Form Configuration enthält die allgemeinen Einstellungen des Form Frameworks. Dazu gehören die verfügbaren Formular-Elemente und -Finisher oder auch die Quellen für Sprachdateien und Templates.
In TYPO3 v10 wurden die Konfiguration des Form Frameworks sauber in Partials aufgeteilt, was die Lesbarkeit deutlich erhöht. Ihr findet sie im TYPO3 Core unter typo3/sysext/form/Configuration/Yaml/.

Wenn ihr bereits eine eigene Form Configuration angelegt habt, benötigt ihr nur die folgenden Ergänzungen. Falls nicht, erläutere ich die Vorarbeiten hier.

Resources/Private/Forms/Frontend/Templates/Form.html

Im Form.html Template ergänzen wir lediglich den div-Wrapper mit unseren gewünschten Klassen. Mit der if-Condition fragen wir ab, ob es einen Wert gibt – der Value für das allgemeine Kontaktformular soll in unserem Beispiel nämlich leer sein (müsste es aber nicht zwingend). Dadurch wird die zweite Klasse nur für spezielle Formulare gerendert.

<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-Konfiguration

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'

Erläuterung der Konfiguration

templateRootPaths

Da wir die neue CSS-Klasse in unserem erweiterten Form.html Template ausgeben möchten, müssen wir dafür einen zusätzlichen Speicherort registrieren. Wir nutzen hierfür unser Sitepackage.

formEditor / editors

Unterhalb dieser Eigenschaft ergänzen wir das neue Feld mit dem frei gewählten Key "500". Welche Keys bereits für andere Felder vergeben sind, findet ihr ab TYPO3 v10 im Backend-Modul "Configuration" unter "Formular: YAML-Konfiguration".

identifier

Dies ist der eindeutige Bezeichner eurer neuen Eigenschaft.

templateName

Hier verwenden wir einen der vorhandenen Inspector Komponenten des Form Frameworks. Durch den Inspector-SingleSelectEditor wird das neue Feld als Auswahlfeld gerendert.

propertyPath

Der Identifier wird hier den renderingOptions des Formulars zugewiesen.

selectOptions

Hier pflegen wir nun alle gewünschten Optionen des Auswahlfeldes ein. Das label ist im Form Editor sichtbar und könnte per Translation Key auch übersetzt werden. Der value wird in der YAML-Definition unserer Formulare gespeichert und kann in unserem Form.html Template als Fluid-Variable ausgelesen werden.

Demo

Das Auswahlfeld habe ich meiner Demo-Extension "form_examples" hinzugefügt. Sie ist auf GitHub verfügbar. Für jede TYPO3-Version gibt es dort einen eigenen, kompatiblen Branch.