Neos Workshop Teil 4 - Formulare erstellen mit dem Neos Form Framework

Kontaktanfrage, Kommentar, Reservierung oder Bestellungen - einfache Webformulare werden an vielen Stellen der Webseite gebraucht. In diesem Tutorial zeige ich, wie mit dem Neos CMS Form-Plugin ein einfaches Mail-Formular erstellt werden kann.

Ich liebe es wenn ein Plan funktioniert!

Daniel Lienert
Daniel ist immer auf der Suche nach technologisch innovativen aber dennoch nachhaltig stablilen Lösungen für unsere Kunden.
Lesedauer: ca. 5 Minuten

Mit dem Neos Form Framework, welches bereits in der Neos Basisinstallation mit installiert wird, können einfache Kontaktformulare sowie auch komplexe, mehrseitige Formulare mit Validierungen durchgeführt werden. Außerdem bietet es diverse Erweiterungspunkte für die Anpassung an die eigene Anforderung.

In diesem Teil des Workshops zeige ich – passend zum bisherigen Thema – wie sich mit dem Form Framework ein Formular zur Buchung einer Weinprobe umsetzen lässt. Dabei baut auch dieser Workshop Teil auf die bisher erschienene Teile auf. Die Gesamtübersicht auf den hierfür nötigen Code findet sich wie immer im Github Repository zum Workshop.

Formulare definieren

Formulare werden mittels YAML Dateien konfiguriert. Jede Form Definition besteht dabei aus den folgenden Teilen:

  • Im Kopfbereich des Formulars werden grundlegende Angaben wie Identifier und Label der Form definiert. 
  • Der Bereich der "renderables" – definiert die Formularfelder, welche sich über mehrere Sections auf einer Seite und auf mehreren Formularseiten verteilen lassen.
  • Zum Schluss werden die "finishers" definiert – sie legen fest, wie nach Absenden des Formulars die eingegebenen Daten verarbeitet werden sollen.

Für die Definition unseres Formulars legen wir in einem zu erstellenden Verzeichnis Resources/Private/Form/, eine neue Datei registration-form.yaml an.

Die Definition der Form beginnt zunächst mit den allgemeinen Angaben, wie dem eindeutigen Identifikator und einem sprechenden Namen. 

Darauf folgt die Definition der zu rendernden Elemente, welche verschachtelt angegeben werden können. Sogenannte Container-Elemente können verwendet werden, um das Formular zu strukturieren. Die Container-Elemente enthalten dann die eigentlichen Formularfelder.

Das oberste "renderable" definiert die Seite des Formulars mit dem strukturgebenden Typ Neos.Form:Page. Die Seite hat wiederum einen eigenen Abschnitt "renderables" mit dem die nächste Ebene an Elementen – in unserem Fall direkt die Formularfelder – definiert werden.

Im Beispiel werden einfache Textfelder für Name und E-Mail verwendet, ein Mehrzeilenfeld für den Kommentar und ein Select-Feld zur Auswahl der Veranstaltung. Jedes Element benötigt einen eindeutigen Identifier, über den auch später auf die Benutzereingaben zugegriffen werden kann. Darüber hinaus stehen weitere Optionen zur Konfiguration der Felder zur Verfügung. 

Durch die Angaben von Validatoren können Pflichtfelder definiert sowie Benutzereingaben überprüft werden. Im Beispiel verwenden wir den Validator Neos.Flow:NotEmpty zur Festlegung von Pflichtfeldern. Der Neos.Flow:EmailAddress Validator prüft die Eingabe auf eine korrekte Adresse.

type: 'Neos.Form:Form'
identifier: 'registration-form'
label: 'Anmeldung zur Weinprobe'
renderingOptions:
  submitButtonLabel: 'Anmelden'
renderables:
  -
    type: 'Neos.Form:Page'
    identifier: 'registration'
    renderables:
      -
        type: 'Neos.Form:SingleSelectDropdown'
        identifier: 'date'
        label: 'Datum'
        properties:
          options:
            'September 2016': 'Weinprobe September 2016'
            'Oktober 2016': 'Weinprobe Oktober 2016'
            'November 2016': 'Weinprobe November 2016'
      -
        type: 'Neos.Form:SingleLineText'
        identifier: 'name'
        validators:
          - identifier: 'Neos.Flow:NotEmpty'
        properties:
          placeholder: 'Name'
      -
        type: 'Neos.Form:SingleLineText'
        identifier: 'email'
        validators:
          - identifier: 'Neos.Flow:NotEmpty'
          - identifier: 'Neos.Flow:EmailAddress'
        properties:
          placeholder: 'E-Mail'
      -
        type: 'Neos.Form:MultiLineText'
        identifier: 'comment'
        properties:
          placeholder: 'Kommentar'
          rows: '3'

Formular Definition in Resources/Private/Form/registration-form.yaml

Über die im Beispiel verwendeten Felder hinaus, sind im Form Framework aber noch viele weitere Elemente und Validatoren definiert und können direkt verwendet werden.

Liste der verfügbaren Feld- und Strukturtypen

Strukturelemente

TypBeschreibung
Neos.Form:PageEine Formularseite, ein mehrseitiges Formular ist möglich.
Neos.Form:SectionSection innerhalb einer Formularseite.

 

Spezielle Eingabefelder

TypBeschreibung
Neos.Form:DatePickerEine Formularseite, ein mehrseitiges Formular ist möglich.
Neos.Form:FileUploadSection innerhalb einer Formularseite.
Neos.Form:StaticTextAusgabe eines statischen Textes.

Standard Eingabefelder

TypBeschreibung
Neos.Form:SingleLineTextEinfaches Textfeld.

Neos.Form:Password

Neos.Form:PasswordWithConfirmation

Einfache Passworteingabe.

Passworteingabe mit Bestätigungsfeld.

Neos.Form:MultiLineTextMehrzeiliger Text. 
Neos.Form:CheckboxEinzelnes Checkbox Feld.
Neos.Form:SingleSelectDropdownDropdown Feld.
Neos.Form:SingleSelectRadiobuttonsRadio Button.
Neos.Form:MultipleSelectDropdownSelect-Liste für Mehrfachauswahl.

Liste der verfügbaren Validatoren

TypBeschreibung
Neos.Flow:NotEmptyFeld darf nicht leer sein. Damit wird ein Pflichtfeld definiert.
Neos.Flow:DateTimeRangeMit den options earliestDate und latestDate wird der valide Zeitraum festgelegt.
Neos.Flow:AlphanumericAlphanumerische Zeichen können verwendet werden.
Neos.Flow:TextText enthält keine XML Tags.
Neos.Flow:StringLengthMit den options minimum und maximum kann die nötige Längenbegrenzung angegeben werden.
Neos.Flow:EmailAddressValidiert auf eine korrekte E-Mail-Adresse .
Neos.Flow:IntegerPrüft auf Ganzzahl.
Neos.Flow:FloatPrüft auf eine valide Float-Zahl.
Neos.Flow:NumberRangePrüft auf eine Ganzzahl in einem Gültigkeitsbereich, welcher mit den options minimum und maximum angeben wird.
Neos.Flow:RegularExpressionPrüft gegen einen regulären Ausdruck aus der option regularExpression.

Formular einbinden

Mit der obigen Konfiguration kann das Formular bereits auf der Seite eingebunden werden. Dazu muss der Speicherpfad der Formulare geändert werden, so dass die Formular-Konfigurationen in unserem eigenen Site Packages gesucht werden. Unter Configuration in unserem Site Package legen wir dazu eine Settings.yaml an und fügen die folgende Konfiguration ein:

Neos:
  Form:
    yamlPersistenceManager:
      savePath: 'resource://WL.WeinLaden/Private/Form/'

Configuration/Settings.yaml

Zusätzlich muss unser Formular im Neos Formular NodeType als Option hinzugefügt werden, damit dieses im Inspektor ausgewählt werden kann. 

Screenshot des Online-Formulars für die Anmeldung zur Weinprobe
'Neos.NodeTypes:Form':
  properties:
    formIdentifier:
      ui:
        inspector:
          editorOptions:
            values:
              'registration-form':
                label: 'Anmeldung zur Weinprobe'

Configuration/NodeTypes.yaml

Finishers - was soll beim Absenden des Formulars passieren?

Was nach dem Absenden mit den Formulardaten passieren soll, wird mit Finisher definiert. Die beiden Finisher werden in der gleichen Datei wie auch alle anderen Angaben zum Formular definiert. 

Mit dem Neos.Form:Confirmation geben wir den Text an, welcher nach erfolgreichem Absenden des Formulars anstelle des Formulars angezeigt wird. Im Text, welchen wir mit der Option message definieren, können wir auch Angaben des Benutzers verwenden.

Der zweite Finisher vom Typ Neos.Form:Email versendet die Formulareingaben danach per E-Mail. Um diesen Finisher zu verwenden, muss zusätzlich das PHP Paket "SwiftMailer" installiert werden – dieser Schritt wird im nächsten Abschnitt erklärt.

Alle wichtigen Angaben der E-Mail, wie Ziel- und Absenderadresse und Betreff können dem Finisher direkt per Optionen übergeben werden. Der eigentliche E-Mail-Text wird in einer eigenen Datei gehalten, um die YAML Datei nicht unnötig aufzublähen. In diesem Beispiel senden wir eine Plaintext E-Mail, dessen Inhalt aus der Datei Resources/Private/Templates/Mail/Registration.txt gelesen wird.


finishers:
  -
    identifier: 'Neos.Form:Confirmation'
    options:
      message: >
        <h3>Vielen Dank für Ihre Anmeldung!</h3>
        <p>Wir freuen uns, Sie bei unserer Weinprobe im {formState.formValues.date} begrüßen zu dürfen.</p>
        <p>Ihr Weinladen Team</p>
  -
    identifier: 'Neos.Form:Email'
    options:
      templatePathAndFilename: 'resource://WL.Weinladen/Private/Templates/Mail/Registration.txt'
      subject: 'Neue Anmeldung zur Weinprobe'
      recipientAddress: 'anmeldung@weinladen'
      recipientName: 'Weinladen'
      senderAddress: 'no-reply@weinladen'
      senderName: '{name}'
      replyToAddress: 'no-reply@weinladen'
      format: 'plaintext'

Die konfigurierten Finisher in Resources/Private/Form/registration-form.yaml verarbeiten die Formulardaten.

Hallo liebes Weinladen Team,

eben ging eine neue Anmeldung für die Weinprobe im {form.formState.formValues.date} ein:

Name:     {form.formState.formValues.name}
E-Mail:   {form.formState.formValues.email}
Kommentar:{form.formState.formValues.comment}

Viele Grüße

Definition des Mailtextes in Resources/Private/Templates/Mail/Registration.txt

Neben den oben verwendeten Finishern bring das Form Framework noch weitere Möglichkeiten der Verarbeitung der Formdaten mit. Natürlich können auch eigene Klassen erstellt und an dieser Stelle zur Verarbeitung genutzt werden.

Liste der verfügbaren Finisher

TypBeschreibung
Neos.Form:ConfirmationZeigt nach dem Absenden einen konfigurierbaren Text an.
Neos.Form:EmailVersendet einen E-Mail mit dem Inhalt des abgesendeten Formulars.
Neos.Form:FlashMessageZeigt eine beliebige Flash-Message nach dem Absenden an.
Neos.Form:RedirectLeitet die Eingaben nach dem Absenden auf einen Controller aus einem beliebigen anderen Package um.

Formular als E-Mail versenden mit Swiftmailer

Der E-Mail-Finisher verwendet das PHP Paket SwiftMailer um E-Mails zu versenden. Dieses Package muss per composer installiert werden. In der Neos Box im Verzeichnis /var/www fügen fügen wir diese Package mit dem folgenden Befehl der bestehenden Installation hinzu:

composer require neos/swiftmailer:6.0.0

Während der Entwicklungsphase ist es aber recht unpraktisch, E-Mails wirklich zu versenden. Denn zur Prüfung des Inhalts muss so immer auf den Versand und den Abruf des Mailclients gewartet werden.
Einfacher ist es, die E-Mail lokal zu speichern. Dazu konfigurieren wir den Swiftmailer für die Ablage des Mailinhalts in einer lokalen Datei im MBox Format. Da dies nur im Development-Context, aber natürlich nicht im Live-Betrieb passieren soll, nehmen wir diese Einstellung in einer neuen Datei unter Configuration/Development/Settings.yaml vor:

Neos:
  SwiftMailer:
    transport:
      type: 'Neos\SwiftMailer\Transport\MboxTransport'
      options:
        mboxPathAndFilename: '%FLOW_PATH_DATA%/last-mail.mbox'

Configuration/Development/Settings.yaml

Die E-Mail kann nun direkt nach dem Absenden in der Datei /var/www/Data/last-mail.mbox ausgelesen werden. Beispielsweise mit dem Befehl "cat":

cat /var/www/Data/last-mail.mbox

Anzeigen der generierten E-Mail in der Entwicklerbox

Ich hoffe dieser Workshop Teil konnte vermitteln, wie mit dem Neos Form Framework einfach Formulare erstellt werden können. Den kompletten, dazu nötigen Code findest du wie immer auf unserem github Repository.  Eine momentan noch etwas rudimentäre, aber ständig erweiterte Dokumentation befindet sich auch auf ReadTheDocs. Für Fragen und Anmerkungen zu diesem Tutorial kann das Kommentarfeld unten gerne genutzt werden. 

Das war noch nicht genug Input? Du möchtest noch mehr über das Neos CMS lernen? Wir bieten auch Vor-Ort Schulungen an. 

zu den Neos-Workshops
Teilen:

Weitere Beiträge

Bekommen wir hin
Miran Cumurija, Product Owner bei punkt.de
Arbeiten bei punkt.de