Dlaczego pliki routingu są wypełnione podkreśleniami?

24

Jaki jest układ wszystkich parametrów z prefiksem i bez znaku podkreślenia ?

Gdzie Drupal decyduje o sposobie przetwarzania tych parametrów?

Czy ta koncepcja została wprowadzona z Symfony, czy też jest nowa w Drupal?

Przykład ( node.routing.yml ):

node.overview_types:
  path: '/admin/structure/types'
  defaults:
    _controller: '\Drupal\Core\Entity\Controller\EntityListController::listing'
    entity_type: 'node_type'
    _title: 'Content types'
  requirements:
    _permission: 'administer content types'
Daniel
źródło
2
To konwencja Symfony . Jest to dobry artykuł tutaj , znaleźć kawałek, który mówi Ostateczną rzeczą, aby zwrócić uwagę na to szczególne znaczenie znaku podkreślenia w nazwach parametrów. Parametry rozpoczynające się od tego znaku mają specjalne znaczenie
Clive
1
Dzięki Clive. W tym artykule wspomniano o „szczególnym znaczeniu”, ale w ogóle go nie wyjaśniono. Dlaczego parametry nie podkreślone również są wyjątkowe?
Daniel
1
lol, dlaczego nie mogą być też parametry niebędące podkreśleniem? , to brzmi jak głęboko egzystencjalne pytanie! Zwykle (tylko zwykle) zmienne prefiksujące są wykonywane w celu wskazania zmiennej „prywatnej” (mało prawdopodobne tutaj) lub w celu uniknięcia nazewnictwa kolizji z innymi klasami / metodami / czymś innym w systemie. Dobrze byłoby zobaczyć oficjalne dokumenty, tak
Clive

Odpowiedzi:

41

Oto mam nadzieję, że jest to dobre wyjaśnienie idei systemu routingu, a także specyficznych dodatków do niego.

Przegląd ogólny

Komponenty Symfony mają tutaj dwie ważne koncepcje. Jądro http to system, który odbiera żądanie, w jakiś sposób prosi inne systemy o utworzenie fragmentu kodu, który generuje żądane wyjście (obiekt odpowiedzi) i odesłanie odpowiedzi do klienta. Ten fragment kodu nazywa się kontrolerem, więc może to być czysta funkcja podobna do php4, metoda obiektu lub nawet funkcja anonimowa.

Systemem, który wie, który kontroler jest odpowiedzialny za bieżące żądanie, jest system routingu.

wprowadź opis zdjęcia tutaj

Podstawowy plik routingu

Jako programista modułu definiujesz listę tras i odpowiadających im kontrolerów.

Oto przykład odpowiedzi JSON:

taxonomy.autocomplete_vid:
  path: '/taxonomy/autocomplete_vid/{taxonomy_vocabulary}'
  defaults:
    _controller: '\Drupal\taxonomy\Controller\TermAutocompleteController::autocompletePerVid'
  requirements:
    taxonomy_vocabulary: \d+

Większość dokumentacji symfony wspomina wzorzec, ale drupal zdecydował się po prostu zezwolić na nieaktualny klucz „path” w swoim pliku routingu.

Kluczową koncepcją jest sterownik, który pobiera niektóre parametry z systemu i konwertuje je na odpowiedź. W tym przykładzie masz parametr „taxonomy_vocabulary”. Więc wszystko bez podkreślenia jest uważane za parametr dla kontrolera. Jeśli chcesz określić wartość domyślną, umieść ją w tablicy wartości domyślnych. W tej samej tablicy yml określasz klasę i metodę związaną z '::', aby powiedzieć systemowi, gdzie ma szukać rzeczy. Każda inna właściwość nie ma nic wspólnego z parametrami kontrolera, a zatem są uważane za wewnętrzne i dlatego mają znak podkreślenia jako prefiks.

Sama Symfony pozwala również definiować wyrażenia regularne w celu sprawdzenia poprawności parametru przychodzącego (przy użyciu „wymagań”). Tutaj pasowałoby tylko do liczb.

Kontroler resolvera

Gdy symfony dowie się, który kontroler jest aktywny w bieżącym żądaniu, prosi tzw. Resolver kontrolera, aby utworzył instancję kontrolera, którą można wykonać poprzez call_user_func_array. Resolver kontrolera ma jedną metodę wywołania kontrolera (obiekt + metoda, funkcja anonimowa) i jedną metodę przekazania parametrów do kontrolera, patrz resolver kontrolera

Rozszerzenia Drupal

Właśnie to daje ci symfony.

Drupal jest jednak nieco bardziej skomplikowany:

  • Możesz sprawdzić dostęp do trasy. Na przykład wywołanie user_access () było bardzo powszechne w Drupal 7 i poniżej.
  • Nie chcesz konwertować słownika taksonomii na jego faktyczny obiekt encji
  • Nie chcesz generować pełnej odpowiedzi strony, a jedynie „główną treść”.

Kontrola dostępu

Drupal wprowadził system na częściach symfony, który sprawdza, czy użytkownik ma dostęp do bieżącej trasy i alternatywnie zgłasza wyjątek 403 (odmowa dostępu). Menedżer dostępu

W pliku routingu określasz to w części wymagań. Najczęstsze bity są wymienione w przykładzie:

  path: '/user/{user}'
  options:
    _access_mode: 'ANY'
  requirements:
    _permission: 'access user profiles'
    _entity_access: 'user.view'
    _role: 'administrator'

_permission definiuje wywołanie user_access (), _role zapewnia, że ​​użytkownik ma określoną rolę (możesz określić wiele z nich za pomocą, dla OR i + dla logiki AND). _entity_access pyta system encji, czy masz dostęp do przeglądania encji użytkownika. Domyślnie drupal zapewnia, że ​​dodanie kontrolerów dostępu pozwala ci kontynuować, ale możesz przełączyć go w opcjach za pomocą trybu _access_mode.

Upcasting

Jak wspomniano w wykazie, że nie chcesz dbać o ładowanie encji, patrz przykład / użytkownik / {użytkownik}. W przypadku encji po prostu używasz nazwy typu encji, a ona wykona encję _load z identyfikatorem przekazanym w adresie URL. Menedżer konwertera Param

Odpowiedź strony

Jak napisano wcześniej, kontroler jest odpowiedzialny za wygenerowanie obiektu odpowiedzi. Byłoby to okropne w Drupal, ponieważ strona składa się o wiele bardziej z wszystkich bloków pojawiających się w jej regionach, html i szablonów stron itp. Dlatego drupal określił inny klucz, aby określić kontroler, który zwraca zawartość strony:

user.page:
  path: '/user'
  defaults:
    _content: '\Drupal\user\Controller\UserController::userPage'
  requirements:
    _access: 'TRUE'

Zdefiniowany ciąg to kontroler używany do generowania tablicy renderowania dla głównego obszaru zawartości strony.

Kolejnym dodatkiem jest również sposób radzenia sobie z formularzami, ponieważ zwracanie strony z formularzem jest nieco bardziej złożone niż tylko tablica renderująca, dzięki czemu można zdefiniować _form z interfejsem FormInterface odpowiedzialnym za bieżący formularz.

user.pass:
  path: '/user/password'
  defaults:
    _form: '\Drupal\user\Form\UserPasswordForm'
  requirements:
    _access: 'TRUE'

Uwaga: Obejmuje to najważniejsze punkty z mojej perspektywy, choć na pewno jest o wiele więcej punktów do omówienia.

TL; DR

  • Podkreślenia są określone dla wszystkiego, co nie jest parametrem dla kontrolera. To nadchodzi jako rodzaj „standardu” z symfony.
  • Parametry te są przesyłane w górę przez konwerter parametrów i przekazywane do kontrolera za pomocą resolvera kontrolera
  • Drupal ma kilka dodatków, które ułatwiają interakcję z systemem routingu symfony.
Daniel Wehner
źródło
Łał. Imponująca odpowiedź. Dlaczego niektóre parametry zawierają kropki, a nie podkreślenie? Przykładowo user.pass(na przykład powyżej) w porównaniu user_pass. Czy to także konwencja symfony?
chrisjlee
2
Istnieje pewna konwencja, aby używać $ module. $ Name jako nazwy maszyny dla trasy. Nic jednak nie zakłada tego wewnętrznie.
Daniel Wehner
Zgodnie z poniższym problemem, _content nie jest już w ogóle używany, ale _controller jest. Przykład w odpowiedzi strony części strony jest nieaktualny. drupal.org/node/2378809 Jeśli chcemy wyświetlać dane w obszarze zawartości naszej strony, wówczas kontroler zdefiniuje tablicę renderowania, podobnie jak w Drupal 7. Jeśli chcemy to obejść i stworzyć naszą stronę od zera możemy zwrócić obiekt Response.
benelori
Na pewno nie można oczekiwać, że 1,5 roku się nie wydarzy
Daniel Wehner