Właśnie zaczynamy od Drupala 8 i bardzo szybko natrafiliśmy na nasz pierwszy problem.
Jak powinienem zmienić istniejący formularz w Drupal 8?
Musimy zmienić metodę zapisu formularza węzła, aby przekierować na inną stronę. Chcemy zmienić formę węzła, aby stała się czymś w rodzaju wieloetapowej. Gdy użytkownik utworzy nową treść, zostaje przekierowany do nowego formularza (utworzyliśmy), aby uzyskać więcej informacji.
Rozwiązaliśmy nasz problem z implementacją 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);
}
Następnie stworzyliśmy nową klasę formularzy, która rozszerza formę węzła i zmienia metodę zapisu.
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()]);
}
}
Działa to doskonale, ale czy jest dobre? Jeśli inny moduł zrobi to samo, nasz kod nie będzie już wykonywany.
hook_form_alter()
. Jeśli wystarczy przekierować formularz, wystarczy dodać moduł obsługi przesyłania formularzy, który przekierowuje.save()
tak naprawdę oznacza „zmiana metody”. Czy to oznacza zmianę sposobu zapisywania danych, czy po prostu przekierowanie? W pierwszym przypadku odpowiedź jest bardziej złożona.Odpowiedzi:
Wczoraj musiałem zrobić dokładnie to samo i wciąż szukam sposobu na Drupala 8, ale tego nie znalazłem. Skończyło się to tak:
Nadal jestem bardzo zainteresowany zrobieniem tego inaczej, mój moduł wyglądał tak czysto bez pliku .module :).
źródło
Korzystam z Drupal 8.1.1 i próbowałem przekierować użytkowników po zmodyfikowaniu konta, tj. Kliknięciu przycisku Zapisz na stronie / user / edit. Początkowo próbowałem tego:
Chociaż to działało w przypadku
user_login_form
, nie działałobyuser_form
. Bouser_form
musiałem użyćMam nadzieję, że to pomoże innym, którzy natkną się na ten sam problem!
źródło
Chciałem zmienić
site_information_settings
formularz, aby dodać pola.Jako ty miałem wybór między
hook_form_alter
(lubhook_form_FORM_ID_alter
)Chciałem zrobić trochę OOP, więc zacząłem pisać usługę subskrybenta trasy zmieniającą atrybut
system.site_information_settings
trasy_form
.Potem w mojej nowej klasie rozszerzającej
SiteInformationForm
, po dodaniu pól i ich walidatorów i rozszerzeniu funkcji wysyłania czułem się dokładnie tak samo jak ty ... A co, jeśli inny moduł przepisuje trasę formularza, aby użyć własnej klasy?Na początku miałem wybór między dwiema opcjami ... wygląda na to, że wybrałem niewłaściwy.
hook_form_alter
/hook_form_FORM_ID_alter
wydaje się być najlepszym sposobem na zmianę istniejącej formy.źródło
Wygląda na to, co chcesz zrobić, tak naprawdę nie zmienia metody zapisywania, ale zmienia przekierowanie po zapisaniu węzła.
W tej sytuacji
hook_form_alter
dobrym rozwiązaniem byłoby zrobienie czegoś podobnego do Drupala 7 wraz z niestandardowym modułem obsługi przesyłania (w formularzu lub przycisku, w zależności od formularza i wymagania).To, co opisujesz w pytaniu, również działa, ale unikałbym zastąpienia klasy podstawowej, chyba że rzeczywiście chcę coś zmienić w klasie.
W każdym razie metoda zapisu została użyta jako moduł obsługi przesyłania, więc nie ma sensu zastępować, aby dodać przekierowanie.
źródło
Myślę, że lepszym sposobem jest nadal użycie jednego z haczyków z rodziny form_alter, dołączenie procedury obsługi przesyłania i w ramach tego ustawienia przekierowanie.
Moim zdaniem udział w rozszerzaniu klas podstawowych w tym celu jest włochaty. Zwłaszcza, że żadna funkcja się nie zmienia, tylko przekierowanie.
źródło
Można utworzyć nowy EventSubscriber który nasłuchuje zdarzenia KernelEvents :: żądaniu, a następnie reagować podczas składania formularza węzła, coś jak to
W każdym razie sposób hook_form_alter działa dobrze.
źródło
To, co do tej pory znalazłem: Wdrażanie haka do zmiany formularza i próba zmiany procedur sprawdzania poprawności / przesłania w samym formularzu alter hak działa tylko, jeśli zmienisz procedury obsługi $ form ['# validate] / $ form [#submit']. (wywoływanie funkcji form_state dla tego nie będzie działać w samym haku zmiany formy)
Ale gdy wypróbujesz to w module obsługi sprawdzania poprawności, zwykle działa:
Wynika to z tego, że forma została już całkowicie zbudowana, a nie w przypadku samej modyfikacji haka.
Pomysł jest taki: możesz dodać moduł obsługi sprawdzania poprawności jako ostatni, ocenić inne programy obsługi, które istnieją dla przesyłania, i zmienić je w tym miejscu.
Jeśli chcesz również zmienić moduły sprawdzania poprawności, upewnij się, że działa ono wcześniej, i zmień to, co chcesz w module sprawdzania poprawności.
Wciąż szukam lepszego sposobu, po prostu zawsze muszę zastąpić procedury sprawdzania poprawności / przesyłania formularza rejestracji użytkownika. Ale mogą istnieć inne moduły, które psują wdrożenie moich modułów. Więc mój moduł musiałby być w stanie to sprawdzić, i jest to możliwe w ten sposób. Zastanawiam się, czy istnieje jakaś forma encji po funkcji kompilacji, aby to ściągnąć. (coś, co działa, gdy formularz jest wypełniony i ma zostać dostarczony) (to nie jest zbyt skomplikowane w tym prostym przypadku)
Ominięcie przekierowania metody save () nie jest możliwe, ale rozbrojenie save () odbywa się w ten sposób (+ zaimplementuj własne). To prawda, że klasa jest ładniejsza i oferuje łatwiejszy dostęp do obiektów / etc, ale przesłonięcie klasy podstawowej rzeczywiście prowadzi do problemów, gdy inne moduły chcą z nich korzystać. Nie jest tak w przypadku korzystania z tego kodu.
źródło
Po sprawdzeniu tego problemu znalazłem to, co powinno pasować do Twojego przypadku:
źródło