Durch das Hinzufügen eines Top- bzw. eines Second-Level-Menüs erstellt WordPress automatisch eine Unterseite die Sie mit Inhalt füllen können. In der Regel dient diese Seite zur Darstellung von Formularfeldern. Gleiches gilt, wenn Sie eine neue Metabox hinzufügen.
Die Settings-API wurde entwickelt um solche Formulare halbautomatisch zu bearbeiten und abzuspeichern.
Halbautomatisch deswegen, weil WordPress Ihnen nicht die gesamte Arbeit abnimmt.
Das kann die Settings API:
- Einstellungen (Settings) registrieren.
- Formulare in Bereiche (Sections) unterteilen.
- Fehlermeldungen erfassen.
- Fehlermeldungen ausgeben.
- Formularfelder validieren.
- Formularfelder in die Datenbank speichern.
- Formulare in einer Tabelle ausgeben (rendern).
Die Settins-API erspart Ihnen das Design einer Benutzeroberfläche, da die WordPress-Internen CSS-Styles benutzt werden. Darüber hinaus kümmert es sich (fast) automatisch um alle nötigen Security-Checks (Sie erfahren im nächsten Kapitel mehr über die Plugin-Sicherheit).
Das kann die Settings API nicht
Lediglich um die Darstellung der einzelnen Formular-Felder (Input, Select, Checkbox, etc.) müssen Sie sich selbst kümmern. Das heißt, es gibt keine vorgefertigten Funktionen für Input-Felder.
Voraussetzung
Layout vorbereiten
Damit die globalen WordPress Styles auch auf das zu erstellende Formular angewandt wird, bauen wir uns zuerst den Rumpf nach der Vorgabe im Kapitel Konsequenz im Layout.
Anzeige des Formulars
WordPress benötigt zur richtigen Funktionsweise zwei interne Funktionen. Zum einen settings_fields()
und zum Zweiten do_settings_sections()
.
Die Funktion sieht demnach so aus:
Einfügen der Pflichtfelder
settings_fields()
erzeugt mehrere Hidden-Input Felder, die nötig sind, damit WordPress beim Absenden des Formulars und der anschließenden Verarbeitung weiß, welche Formularfelder abgespeichert werden müssen. Die Funktion erwartet nur einen Parameter. Und das ist eine Gruppenbezeichnung. Hier also mm_settings_group
.
Die Ausgabe sieht in etwa so aus:
Rendern der Einstellungsbereiche (Sections)
Die do_settings_sections()
Funktion übernimmt letztlich noch das Rendern (also das Darstellen) der einzelnen Felder und Bereiche (Sections). Da wir allerdings noch keine Felder hinzugefügt haben, sehen wir erst einmal nichts:
Als einzigen Parameter erwartet die Funktion den so genannten Page-Hook. In der Regel wird hier der Rückgabewert angegeben, der von der Funktion add_submenu_page()
oder add_menu_page()
erzeugt wird.
Einfügen eines Absende-Buttons
Die Funktion submit_button()
nimmt Ihnen ebenfalls Arbeit ab. Sie erzeugt einen Absende-Button im WordPress-Stil und wurde wie folgt definiert:
Einstellungsbereiche (Sections) registrieren
Zu aller erst möchte WordPress, dass ein Einstellungsbereich (Section) registriert wird, dem dann später die einzelnen Einstellungsfelder (Settings) hinzugefügt werden. Zur Registrierung benutzen Sie:
Eine Einstellung (Setting) zur Section hinzufügen
Nachdem die erste Section erstellt wurde, lassen sich endlos viele Formularfelder (Settings) anhängen. Dazu benutzen wir folgende von WordPress bereits definierte Funktion:
Eine Einstellung registrieren
Bis jetzt haben Sie:
- Einen Menüpunkt (bzw. dadurch eine Einstellungsseite) erstellt.
- Das Formular-Grundgerüst mit Absende-Button zur Einstellungsseite angefügt.
- Einen Einstellungsbereich (Section) generiert.
- Und schließlich ein Einstellungsfeld (HTML-Input) zur Section hinzufügt.
Klicken Sie jetzt auf “Änderungen speichern” passiert folgendes: WordPress erzeugt eine Fehlermeldung die besagt: “FEHLER: Die Einstellungsseite wurde nicht gefunden.
Das liegt daran, dass das Einstellungsfeld aus dem Beispiel oben noch nicht registriert wurde. In der Laufzeitumgebung existiert das Feld daher noch nicht und kann nicht gefunden werden. Ergo müssen wir eine letzte Funktion nutzen:
Settings-API Flussdiagramme
Beim Abrufen der Einstellungsseite passiert dann folgendes:
- Der Action-Hook
admin_init
mit der Funktionmm_register_settings()
wird aufgerufen. - Eine neue Section wird mittels
add_settings_section()
registriert. - Ein neues Feld wird mittels
add_settings_field()
zur Section hinzugefügt. - Das Settings-Feld wird durch
register_setting()
registriert. - Nun stehen alle Felder, die bis dahin registriert wurde, bereit und können mittels
do_settings_sections()
gerendert werden.
Beim Speichern der Seite passiert fast das gleiche. Nur, dass die Felder nicht angezeigt sondern abgespeichert werden. Danach erfolgt eine Weiterleitung auf die Einstellungsseite, die dann die Erfolgs- oder Fehlermeldung ausgibt.
Einen Einstellungswert auslesen
Was schließlich noch fehlt ist das Auslesen der Felder, da der jetzige Code lediglich immer den selben Inhalt im input
-Feld anzeigt. Was aber, wenn sich dieser verändert? Also wenn der Benutzer etwas anderes eingibt als vorgegeben wurde?
wenn man Optionsfelder setzt, sollten dann diese auch beim deaktivieren des Plugins entfernt werden?
Reicht dann die Funktion unregister_setting()? Oder gibt es auch für die Felder eine delete function? In der Referece bin ich nicht fündig geworden.
lg
Andreas
PS: hast du meine eMail bekommen?
Ja richtig. Optionen sollten immer beim Deinstallieren entfernt werden. Sonst bleiben sie in der Datenbank als Leichen gespeichert.
unregister_setting() hilft an der Stelle nicht. Denn es würde nur das Einstellungsfeld von der Settings-Page entfernen falls dort bereits hinzugefügt wurde.
Es kommt darauf an, wo man seine Einstellungen gespeichert hat. In der Regel nutzt man die Options API. Ein
delete_option()
wäre dann richtig um die Einstellung aus der Datenbank zu entfernen.Wenn ich ein inputfeld hinzufüge, das ich nur zur überprüfung benötige und nicht gespeichert werden soll, wie filtere ich das zb. $_POST[‘beispiel’] nach dem klicken auf den submit button heraus?
Ich glaube, die Antwort darauf hast du dir selbst schon gegeben. Oder was meinst du genau?
Mein Problem daran ist, dass ich auf das einzelne Input Feld keinen Einfluss habe. Ich habe in meinem Form eine checkbox, das gesetzt wird, wenn zb die Tabellen in Datenbank neu erstellt werden sollen. Mit dem $_POST kann ich zwar das Feld abfragen, aber nicht verhindern, das dieses Feld nicht mit der setting_api in der wp_option mitgespeichert wird. Die checkbox erstelle ich genau so wie in diesem Beispiel beschrieben. Daher meine Frage wie kann ich verhindern, das die Einstellung dieser Checkbox nicht in die wp_options gespeichert wird
Wenn du nicht möchtest, dass ein Feld überhaupt gespeichert wird, kannst du den Filter whitelist_options nutzen und das Feld entfernen bevor es gespeichert wird. Im Beispiel von oben würde das z.B. so funktionieren:
Ich habe ein Problem mit den register_setting. folgenden code habe ich geschrieben:
jedoch schein es so als würde mir der Validate nicht aufgerufen. Denn die var $this->_renew_table wird in dieser Funktion nie gesetzt auch kann ich $input nicht abfragen. Irgend etwas ist in meiner Überlegung falsch und im Internet komme ich auch nicht weiter. Hast du einen Tipp wo ich meinen Fehler habe?
Servus Andreas,
seit WordPress 4.7.0 benötigt
register_setting()
als letzten Parameter ein Array mit Argumenten. Dort kannst du dann den Callback angeben. Richtig wäre also in deinem Fall:Bitte versuch es doch einmal so.
Darüber hinaus: Bist du dir sicher, dass zweimal
$this->plugin_name
richtig ist?Ja so wie du beschrieben hast funktioniert jetzt der Aufruf von fsct_validate. Ich setze in dieser Funktion die Variable $this->_renew_table = $valid[‘renew_tables’]; diese Private Var kann ich aber in der klassen funktion nach dem register_setting aufruf nicht abfragen. Innerhalb der fsct_validate wird der Wert nicht der Klassen Var zugewiesen.
Auch dieser Filter for dem register_setting funktioniert nicht.
ich bekomme immer einen Array ausgegeben (mit print_r mache ich das damit ich sehe ob daten drinnen stehen) mit dem error ERROR: options page not found.
Bei deiner zweiten Anmerkung, bin ich mir nicht sicher. Ich habe im Internet gestöbert und es ein paarmal so vorgefunden, wenn ich alle options in einem speichern möchte und nicht jeden Wert einzeln.
A) Wie stellst du fest, dass der Wert an
$this->_renew_table
nicht zugewiesen wird?B) Beachte bitte, dass ein Filter immer einen Rückgabewert haben muss. Bei dir fehlt
return $whitelist_options
. Wahrscheinlich führt das zu einem genannten Fehler.