Wir haben gerade mit Drupal 8 angefangen und sind sehr schnell auf unser erstes Problem gestoßen.
Wie soll ich ein bestehendes Formular in Drupal 8 ändern?
Wir müssen die Speichermethode für das Knotenformular ändern, um auf eine andere Seite umzuleiten. Wir möchten die Knotenform so ändern, dass sie einer mehrstufigen Form ähnelt. Nachdem der Benutzer neuen Inhalt erstellt hat, wird er in ein neues Formular umgeleitet (das wir erstellt haben), um weitere Informationen zu erhalten.
Wir haben unser Problem gelöst hook_entity_type_alter()
.
function mymodule_entity_type_alter(&$entity_info) {
$handlers = $entity_info['node']->get('handlers');
$handlers['form']['default'] = 'Drupal\mymodule\Form\MyExtendedNodeForm';
$handlers['form']['edit'] = 'Drupal\mymodule\Form\MyExtendedNodeForm';
$entity_info['node']->set('handlers', $handlers);
}
Anschließend haben wir eine neue Formularklasse erstellt, die das Knotenformular erweitert und die Speichermethode ändert.
class MyExtendedNodeForm extends NodeForm {
public function save(array $form, FormStateInterface $form_state) {
parent::save($form, $form_state);
$node = $this->entity;
$form_state->setRedirect('entity.regions.add_form', ['nid' => $node->id()]);
}
}
Das funktioniert einwandfrei, aber ist es gut? Wenn ein anderes Modul dasselbe tut, wird unser Code nicht mehr ausgeführt.
hook_form_alter()
. Wenn Sie das Formular nur umleiten müssen, ist es ausreichend, einen Formularübergabehandler hinzuzufügen, der die Umleitung ausführt.save()
Methode" tatsächlich bedeutet. Bedeutet das, die Art und Weise zu ändern, wie Daten gespeichert werden, oder einfach eine Umleitung durchzuführen? Im ersten Fall ist die Antwort komplexer.Antworten:
Ich musste gestern genau das Gleiche tun, und ich suche noch nach einem weiteren Drupal 8-Verfahren, habe es aber nicht gefunden. Am Ende habe ich es so gemacht:
Ich bin immer noch sehr daran interessiert, es anders zu machen, mein Modul sah ohne die .module-Datei so sauber aus :).
quelle
Ich verwende Drupal 8.1.1 und habe versucht, Benutzer umzuleiten, nachdem sie ihr Konto geändert haben, dh auf der Seite / user / edit auf die Schaltfläche Save (Speichern) geklickt. Ich habe es anfangs versucht:
Während das für die funktionierte
user_login_form
, würde es nicht für die funktionierenuser_form
. Dennuser_form
ich musste verwendenIch hoffe das hilft anderen, die über das gleiche Problem stolpern!
quelle
Nun, ich wollte das
site_information_settings
Formular ändern , um einige Felder hinzuzufügen.Als Sie hatte ich die Wahl zwischen
hook_form_alter
(oderhook_form_FORM_ID_alter
)Wollte etwas OOP machen, also fing ich an, einen Routenteilnehmerdienst zu schreiben, der
system.site_information_settings
das_form
Attribut der Route ändert .Dann habe ich in meiner neuen Klasse die Erweiterung
SiteInformationForm
, nachdem die Felder und deren Validatoren hinzugefügt und die Submit-Funktion erweitert wurden, genauso empfunden wie Sie ... Was nun, wenn ein anderes Modul auch die Route des Formulars umschreibt, um seine eigene Klasse zu verwenden?Zurück zum Anfang hatte ich die Wahl zwischen zwei Optionen ... es scheint, als hätte ich die falsche ausgewählt.
hook_form_alter
Ichhook_form_FORM_ID_alter
scheine der beste Weg zu sein, ein bestehendes Formular zu ändern.quelle
Es sieht aus wie das, was Sie tun möchten, es ist nicht wirklich, die Speichermethode zu ändern, sondern die Umleitung zu ändern, wenn ein Knoten gespeichert wird.
In dieser Situation ist
hook_form_alter
es eine gute Lösung , ähnlich wie bei Drupal 7 einen benutzerdefinierten Submit-Handler (auf dem Formular oder der Schaltfläche, je nach Formular und Anforderung) zu verwenden.Was Sie in der Frage beschreiben, funktioniert auch, aber ich würde es vermeiden, die Basisklasse zu überschreiben, es sei denn, ich möchte tatsächlich etwas in der Klasse ändern.
Die Speichermethode wird sowieso nur als Submit-Handler verwendet. Es macht also wenig Sinn, sie nur zu überschreiben, um eine Umleitung hinzuzufügen.
quelle
Ich denke, die bessere Methode ist es, immer noch einen der Hooks aus der form_alter-Familie zu verwenden, einen Submit-Handler anzuhängen und in diesem die Umleitung festzulegen.
Die Erweiterung der Basisklassen dazu beizutragen, ist meiner Meinung nach haarig. Zumal sich keine Funktion ändert, sondern nur umleitet.
quelle
Sie können einen neuen EventSubscriber erstellen, der das Ereignis KernelEvents :: REQUEST abhört, und dann reagieren, wenn Sie ein Knotenformular wie dieses senden
Wie auch immer, der hook_form_alter Weg funktioniert in Ordnung.
quelle
Was ich bisher gefunden habe: Einen Formularänderungs-Hook implementieren und versuchen, die Validate / Submit-Handler im Formularänderungs-Hook selbst zu ändern, funktioniert nur, wenn Sie die Handler $ form ['# validate] / $ form [#submit'] ändern. (Das Aufrufen von form_state-Funktionen funktioniert nicht im form alter hook selbst.)
Wenn Sie dies jedoch in einem Validierungs-Handler versuchen, funktioniert Folgendes:
Dies liegt daran, dass das Formular jetzt vollständig erstellt wurde und nicht mehr im Formularänderungs-Hook selbst.
Die Idee ist: Sie können einen Validierungs-Handler als letzten hinzufügen, andere Handler, die für die Übermittlung vorhanden sind, auswerten und direkt dort ändern.
Wenn Sie auch Validierungshandler ändern möchten, stellen Sie sicher, dass Ihre vor allen anderen ausgeführt werden, und ändern Sie, was Sie im Validierungshandler möchten.
Ich bin immer auf der Suche nach einem besseren Weg, aber ich muss immer nur die Validate / Submit-Handler für das Benutzerregistrierungsformular ersetzen. Es können jedoch auch andere Module vorhanden sein, die die Implementierung meiner Module beeinträchtigen. Also müsste mein Modul in der Lage sein, dies zu überprüfen, und das ist auf diese Weise möglich. Ich frage mich, ob es eine Entity-Form nach der Build-Funktion gibt, die dies ermöglicht. (etwas, das ausgeführt wird, wenn das Formular ausgefüllt wurde und zugestellt werden soll) (für diesen einfachen Fall ist das nicht allzu komplex)
Das Umgehen der Weiterleitung der save () -Methode ist nicht möglich, aber das Deaktivieren der save () -Methode erfolgt auf diese Weise (+ Implementieren Ihrer eigenen). Eine Klasse ist zwar besser und bietet einen einfacheren Zugriff auf Objekte / etc, aber das Überschreiben einer Kernklasse führt in der Tat zu Problemen, wenn andere Module diese verwenden möchten. Das ist nicht der Fall, wenn Sie diesen Code verwenden.
quelle
Nachdem ich dieses Problem überprüft habe, habe ich Folgendes gefunden, das zu Ihrem Fall passen sollte:
quelle