Zum Newsletter anmelden

TYPO3: Formulare mit Formhandler

  Christian Weiske     Feb 09, 2011

Das Erstellen von Formularen zur Erfassung von Daten ist eine immer wiederkehrende Aufgabe. Unter Typo3 war lange Zeit Mailformplus die erste Wahl um schnell ein Formular zu bauen. Wer allerdings einmal einen Blick auf den Quellcode der th_mailformplus-Extension gewagt hat, lief schreiend davon oder benutzte die Extension trotzdem, vergaß aber schnell, wie der Code aussieht.

Die Mailformplusentwickler haben das selbst bemerkt und einen Nachfolger für die in die Jahre gekommene Extension entwickelt: Formhandler.

Formhandler selbst kann mehr als nur Mails versenden:

  • Beliebig komplexe Formulare erstellen, auch mehrseitig
  • Prüfung der Feldwerte mit 40 Validatoren, u.a. mit Email-, Datums- und Dateitypvalidierung
  • Versenden von Emails (Plaintext und HTML), Speichern der Formulardaten in der Datenbank und Generierung von PDF und CSV-Dateien
  • CAPTCHA-Integration

Da die Konfiguration der Formulare über Typoscript erfolgt, ist man extrem flexibel. Wem das alles noch nicht flexibel genug ist, der kann problemlos eigenen PHP-Code in Form vom {Finisher|Interceptor|Logger|PreProcessor|Validator}-Klassen einbringen.

In diesem Artikel werde ich ein einfaches Kontaktformular bauen und schrittweise verfeinern.

Beispielformular

Anforderungen

Die Aufgabe des Formulars wird es sein, den Kundenfragen und -hinweise aufzunehmen und an den richtigen Ansprechpartner weiterzuleiten.

Formularelemente:

  • Dropdown zur Auswahl des Ansprechpartners. Die Ansprechpartner sind Frontendbenutzer, die zu einer bestimmten Gruppe gehören
  • Textfeld: Kundenname und -email
  • Nachricht des Kunden an den Ansprechpartner

Prüfung der Elemente:

  • Alle Felder müssen ausgefüllt werden
  • Die Nachricht muss eine Mindestlänge haben
  • Die Kundenemailadresse muss valid sein

Weiterverarbeitung

  • Verschicken der Nachricht an den gewählten Ansprechpartner
  • Verschicken einer Kopie der Anfrage an den Kunden
  • Anzeigen einer "Danke"-Nachricht mit Link auf die Startseite

Generelle Hinweise zum Formhandler

Die Dokumentation ist sehr ausführlich, aufgrund eines Fehlers in der manual.sxw allerdings nur als .pdf ordentlich anzuschauen. Die auf typo3.org gerenderte Version der Doku ist unbrauchbar.

Zum Debugging braucht man keine var_dump()-Statements in den Code zu packen; es reicht, wenn man debug=1 setzt und zusätzlich noch das Adminpanel zum TypoScript-Debuggen aktiviert:

config.admPanel=1
plugin.Tx_Formhandler.settings.debug=1

Formulare bestehen aus 2 oder 3 Dateien: Typoscript-Konfiguration, HTML-Template und Sprachdatei mit Fehlermeldungen und Labels. Diese legt man am Besten gesammelt in einem eigenen Ordner im fileadmin/ ab.

Einbindung des Formulars in TYPO3

  1. Formhandler über den Extensionmanager installieren
  2. Neue Seite im Seitenbaum anlegen
  3. Formhandlerplugin einbinden und keine Einstellungen setzen
  4. Links im Hauptmenü des Backends auf "Template" klicken und ein Extensiontemplate erstellen
    • Titel: +ext Kontaktformular
    • Setup: <INCLUDE_TYPOSCRIPT: source="FILE:fileadmin/contactform/1-contactform.ts">
  5. Die eben verlinkte TypoScriptdatei anlegen: fileadmin/contactform/1-contactform.ts
  6. HTML-Datei anlegen: fileadmin/contactform/1-contactform.html

Jetzt haben wir alle grundlegenden Dinge vorbereitet, um uns mit der Erstellung des Formulars beschäftigen zu können.

1. Version: einfaches Formular

Die erste Version soll nur ein einfaches mit Name, Email und Text sein. Beim Absenden wird eine Email an den einen festgelegten Administrator versendet.

TypoScript

plugin.Tx_Formhandler.settings {
debug = 1

templateFile = fileadmin/contactform/1-contactform.html
formValuesPrefix = formhandler

finishers {
1 {
class = Tx_Formhandler_Finisher_Mail
}
2 {
class = Tx_Formhandler_Finisher_SubmittedOK
config.returns = 1
}
}
}

HTML

<!-- ###TEMPLATE_FORM1### begin -->
<p>Wenn es ein Problem gibt, einfach schreiben:</p>
<form action="###REL_URL###" id="projektform" method="post" class="formhandler">
<dl>
<dt><label for="message">Problembeschreibung</label></dt>
<dd>
<textarea name="formhandler[message]" id="message">###value_message###</textarea>
</dd>

<dt><label for="sender_name">Ihr Name</label></dt>
<dd>
<input type="text" name="formhandler[sender_name]" id="sender_name"
value="###value_sender_name###" />
</dd>

<dt><label for="sender_email">Ihre E-Mailadresse</label></dt>
<dd>
<input type="text" name="formhandler[sender_email]" id="sender_email"
value="###value_sender_email###" />
</dd>
</dl>
<input type="submit" value="Absenden" ###submit_nextStep### />
</form>
<!-- ###TEMPLATE_FORM1### end -->

<!-- ###TEMPLATE_SUBMITTEDOK### begin -->
<p>Die Anfrage mit folgendem Text wurde gesendet:</p>
<p>###value_message###</p>
<!-- ###TEMPLATE_SUBMITTEDOK### end -->

<!-- ###TEMPLATE_EMAIL_ADMIN_PLAIN### begin -->
Das Kontakformular wurde an Sie geschickt:
Absender: ###value_sender_name### ###value_sender_email###
Text:
###value_message###
<!-- ###TEMPLATE_EMAIL_ADMIN_PLAIN### end -->

Jetzt muss man nur noch in den Plugineinstellungen bei "Admin E-Mail Settings" die Empfängeradresse und den Betreff eintragen, und alles man hat ein funktionierendes Formular.

2. Version: Validierung

Nachdem das Formular grundlegend funktioniert, sollen die Eingaben jetzt validiert und Fehlermeldungen angezeigt werden.

Im Formhandler wird die Datenprüfung über Validatoren geregelt. Der Standardvalidator Validator_Default bringt schon so ziemlich alles mit, was man im Normalfall benötigt:

  validators.1.class = Validator_Default
validators.1.disabled = 0
validators.1.config.fieldConf {
message.errorCheck.1 = required
message.errorCheck.2 = minLength
message.errorCheck.2.value = 5

sender_name.errorCheck.1 = required

sender_email.errorCheck.1 = required
sender_email.errorCheck.2 = email
}

Mit diesem TypoScript ist schon alles getan: Die Nachricht muss mindestens 5 Zeichen lang sein, der Name darf nicht leer sein, und im Emailadressfeld muss eine valide Emailadresse stehen.

Zur Anzeige der Fehlermeldungen im HTML muss man ein paar Marker im Template einfügen:

###ERROR###
Liste mit allen Fehlermeldungen
###error_$feldname###
Spezifische Fehlermeldung für das Feld mit Namen $feldname

Bindet man die Fehlermarker so ins Template ein, sehen die Fehler noch sehr unschön aus, da die Meldungen ohne jegliche Formatierung ausgegeben werden. Ein bisschen TypoScript ändert das:

  addErrorAnchors = 1
singleErrorTemplate {
totalWrap = |
singleWrap = <span style="color: red;">|</span>
}
errorListTemplate {
totalWrap = <div style="color: red;">Es sind folgende Fehler aufgetreten: <ul>|</ul></div>
singleWrap = <li>|</li>
}

Nun werden einzelne Fehlermeldungen rot dargestellt, und die gesammelte Liste aller Fehlermeldungen verwendet eine <li>ste zur Darstellung.

Wer das Formular jetzt ausprobiert wird feststellen, daß Debugmeldungen wie

Could not find error message with key "error_message_required"!

ausgegeben werden. Fehlermeldungen werden im Formhandler in einer Sprachdatei abgelegt, die im bekannten T3locallang-XMLdialekt geschrieben werden. Eingebunden wird die Sprachdatei folgendermaßen:

langFile = fileadmin/contactform/3-lang.xml

Die Datei selbst enthält nur Key-Value-Paare mit den Meldungen:

<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<T3locallang>
<data type="array">
<languageKey index="default" type="array">
<label index="error_message_required">Nachricht fehlt</label>
<label index="error_message_minLength">Die Nachricht ist zu kurz</label>

<label index="error_sender_name_required">Ihr Name fehlt</label>

<label index="error_sender_email_required">Ihre E-Mailadresse fehlt</label>
<label index="error_sender_email_email">Ihre E-Mailadresse ist ungültig</label>
</languageKey>
</data>
</T3locallang>

Nun haben wir ein Formular mit in alle Sprachen übersetzbaren Fehlermeldungen.

3. Version: Ansprechpartner

Bisher wurde der Empfänger der E-Mail ja der Einfachheit halber in den Plugineinstellungen festgelegt. Ein Feature des Formulars soll jedoch sein, daß der Kunde selbst auswählen kann, an wen die Email geht.

Um die Datenpflege möglichst einfach zu halten, sollen die potentiellen Empfänger nicht statisch im Kontaktformular gepflegt, sondern aus der Datenbank geholt werden. Die Frontendbenutzertabelle fe_users eignet sich dafür, da diese schon Name und Emailadresse enthält und Benutzer einfach einer bestimmten Gruppe zugeordnet werden können.

Zur Vorbereitung für diesen Schritt wird eine Frontendbenutzergruppe ("Kontaktformularempfänger", hier im Beispiel mit uid 3) und einige Benutzer mit Name, Email und dieser Gruppe erstellt. Weiterhin muss der Emailempfänger im Plugin entfernt werden, da die Einstellung im Formhandlerplugin die TypoScriptkonfiguration überschreibt.

Hier ist es extrem hilfreich, das Typo3-Adminpanel im Frontend zu aktivieren.

#typoscript debugging
config.admPanel = 1

Damit kann man unter TypoScript -> "Display messages" und "Explain SELECT queries" Fehler in der SQL-Konfiguration im TypoScript relativ einfach aufspüren.

Das Auslesen der Benutzer  per SQL erfolgt - wie auch sonst - über TypoScript, und zwar über ein CONTENT-Objekt. Der Formhandler stellt in Templates frei verwendbare Marker bereit; einen davon benutzen wir, um die <option>-Tags mit den Namen und E-Mailadressen ins Template zu bekommen:

  markers.options_recipient = CONTENT
markers.options_recipient {
table = fe_users
select {
#pid where feusers are stored
pidInList = 29
orderBy = name
selectFields = email, name
#contact form user group
where = FIND_IN_SET(3, fe_users.usergroup)
max = 10
}
renderObj = COA
renderObj {
#value
10.wrap = <option value="|"
10 = TEXT
10.field = email

#selected
12.noTrimWrap = | ###selected_recipient_|###>|
12 = TEXT
12.field = email

#label
13 = TEXT
13.value = {field:name} ({field:email})</option>
13.insertData = 1
}
}

Mit table und select spezifizieren wir, was genau wir aus der Datenbank möchten. Das renderObj generiert ein <option value="e@ma.il">-Tag, das automatisch das selected="selected" bekommt, wenn die entsprechende E-Mailadresse ausgewählt ist.

Nun brauchen wir nur noch den Marker mit umschließenden <select>-Tag ins HTML zu packen:

<dt><label for="recipient">Empfänger</label></dt>
<dd>
###error_recipient###
<select name="formhandler[recipient]" id="recipient" size="1">
<option value="">- kein Empfänger gewählt -</option>
###options_recipient###
</select>
</dd>

.. und den Empfänger zu validieren:

    recipient.errorCheck.1 = required
recipient.errorCheck.2 = email

Jetzt muss man dem Mail-Finisher nur noch sagen, daß die Email an die gewählte Adresse gehen soll:

      class = Tx_Formhandler_Finisher_Mail
config.admin {
to_email = TEXT
to_email.data = GPvar:formhandler|recipient
subject = TEXT
subject.data = LLL:fileadmin/contactform/4-lang.xml:mail_subject_admin
}

Damit ist alles getan, und die Emails gehen an den richtigen Empfänger.

4. Version: Schönmachen

Die Hauptfunktionalität des Formulars ist umgesetzt; jetzt wird es noch "schön" gemacht:

  • Kopie der E-Mail an Kunden versenden
  • Texte und Labels aus der Übersetzungsdatei nehmen, damit man das Formular problemlos auf mehrsprachigen Seiten einsetzen kann
  • Link zurück auf die Startseite

Die Verwendung der Übersetzungen ist mit Formhandlerextrem einfach: Ins HTML-Template an Stelle des Textes einfach ###LLL:name_meines_labels### eintragen, und schon wird der Text mit diesem Index aus der in Version 2 konfigurierten lang.xml geholt.

Das Versenden der Email an den Kunden ist auch recht schnell konfiguriert:

      config.user {
to_email = TEXT
to_email.data = GPvar:formhandler|sender_email
subject = TEXT
subject.data = LLL:fileadmin/contactform/4-lang.xml:mail_subject_user
}

Für den Link zurück auf die Startseite konfigurieren wir einfach einen weiteren Marker und statten ihn mit einem typolink aus:

  markers.backlink = TEXT
markers.backlink {
value = Startseite
typolink.parameter = 6
}

Diesen Marker verwenden wir jetzt innerhalb des SUBMITTEDOK-Blocks des HTML-Templates:

Zurück zur ###backlink###

Abschlußbemerkungen

Der Beispielcode mit allen vier Schritten kann ist verfübar als contactform.tar.gz und muss einfach nur ins fileadmin/ entpackt werden.

Mit ein bisschen TypoScript, einem HTML-Template und der Sprachdatei war es möglich, für TYPO3 innerhalb kurzer Zeit ein mehrsprachiges Kontaktformular mit Datenbankanbindung zu bauen. Die Dokumentation zum Formhandler enthält noch massig Features, die bei eigenen Formularen nützlich sein werden. Es gibt kaum einen Grund, für ein Formular noch selbst eine TYPO3-Extension zu bauen - der Formhandler hat auf jeden Fall mehr Features, ist bereits getestet und sicherer.

Tags  Development Lab PHP Tutorial TYPO3 TypoScript

Kategorien:

alle ansehen

Zum Newsletter anmelden