Perché i file di routing sono pieni di caratteri di sottolineatura?


24

Qual è il problema con tutti i parametri con e senza un carattere di sottolineatura con prefisso ?

Dove Drupal decide come elaborare questi parametri?

Questo concetto è stato introdotto da Symfony o è nuovo in Drupal?

Esempio ( 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'

2
È una convenzione di Symfony . C'è un buon articolo qui , trova quello che dice L'ultima cosa a cui prestare attenzione è il significato speciale del carattere di sottolineatura nei nomi dei parametri. I parametri che iniziano con questo personaggio hanno un significato speciale
Clive

1
Grazie Clive. Questo articolo menziona "significato speciale", ma non lo spiega affatto. Perché anche i parametri non di sottolineatura possono essere speciali?
Daniel,

1
lol, Perché anche i parametri non di sottolineatura possono essere speciali? , sembra una domanda profondamente esistenziale! Di solito (solo di solito) le variabili di prefisso vengono fatte per indicare una var 'privata' (improbabile qui), o per aiutare a evitare di nominare le collisioni con altre classi / metodi / qualcos'altro in un sistema. Sarebbe bello vedere i documenti ufficiali, sì
Clive

Risposte:


41

Ecco, si spera, una buona spiegazione dietro l'idea del sistema di routing e le aggiunte specifiche drupal ad esso.

Panoramica generale

I componenti di Symfony hanno due concetti importanti qui. Il kernel http è un sistema che ottiene la richiesta, in qualche modo chiede ad altri sistemi di produrre per definire il pezzo di codice che produce l'output richiesto (un oggetto di risposta) e rispedire la risposta al client. Questo pezzo di codice è chiamato controller, quindi può essere una pura funzione simile a php4, un metodo su un oggetto o persino una funzione anonima.

Il sistema che sa quale controller è responsabile della richiesta corrente è il sistema di routing.

inserisci qui la descrizione dell'immagine

File di routing di base

Come sviluppatore del modulo definisci l'elenco di route e i controller corrispondenti.

Ecco un esempio per una risposta json:

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

La maggior parte della documentazione di symfony menziona lo schema, ma drupal ha deciso di consentire solo la chiave "percorso" non deprecata nel suo file di routing.

Il concetto chiave è il controller che ottiene alcuni parametri dal sistema e li converte in risposta. In questo esempio hai il parametro 'taxonomy_vocabulary'. Pertanto, tutto senza un carattere di sottolineatura è considerato un parametro per il controller. Se si desidera specificare un valore predefinito, lo si inserisce nella matrice dei valori predefiniti. Nello stesso array yml si specifica la classe e il metodo connessi con '::' per dire al sistema dove cercare gli oggetti. Ogni altra proprietà non ha nulla a che fare con i parametri del controller e quindi sono considerati interni e quindi hanno un trattino basso come prefisso.

Symfony stesso consente anche di definire espressioni regolari per convalidare la validità del parametro in entrata (usando 'requisiti'). Qui corrisponderebbe solo ai numeri.

Controller resolver

Una volta che symfony ha scoperto quale controller è attivo sulla richiesta corrente, chiede al risolutore del controller di creare un'istanza del controller, che può essere eseguita tramite call_user_func_array. Il resolver del controller ha un metodo per richiamare il controller (oggetto + metodo, funzione anonima) e un metodo per ottenere i parametri passati al controller, vedere Controller resolver

Estensioni di Drupal

Questo è fondamentalmente ciò che ti dà symfony.

Drupal è leggermente più complicato:

  • Puoi controllare l'accesso al percorso. Ad esempio, chiamare user_access () era molto comune in Drupal 7 e versioni successive.
  • Non vuoi convertire il taxonomy_vocabulary nel suo oggetto entità reale
  • Non vuoi generare la risposta a pagina intera, ma solo il "contenuto principale".

Verifica d'accesso

Drupal ha introdotto un sistema in cima alle parti di symfony che controlla se l'utente ha accesso al percorso corrente e in alternativa lancia un'eccezione 403 (accesso negato). Manager degli accessi

Nel file di routing si specifica questo nella parte dei requisiti. I bit più comuni sono elencati nell'esempio:

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

_permission definisce una chiamata a user_access (), _role assicura che l'utente abbia un determinato ruolo (puoi specificare più ruoli tramite, per OR e + per la logica AND). _entity_access chiede al sistema entità se hai accesso per visualizzare l'entità utente. Per impostazione predefinita, drupal ti assicura di aggiungere checker di accesso che ti consentono di procedere, ma puoi cambiarlo nelle opzioni tramite la modalità _access_.

upcasting

Come menzionato nell'elenco, non ti devi preoccupare di caricare un'entità, vedi / user / {user} come esempio. Per le entità in pratica usi semplicemente il nome del tipo di entità ed eseguirà un entity_load con l'ID passato nell'URL. Gestore del convertitore di parametri

Risposta alla pagina

Come scritto prima, il controller è responsabile della generazione dell'oggetto response. Questo sarebbe orribile in Drupal poiché una pagina è molto più simile a tutti i blocchi che compaiono nelle sue regioni, i modelli html e di pagina ecc. Pertanto drupal ha specificato una chiave diversa per specificare un controller che restituisce il contenuto di una pagina:

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

La stringa definita è il controller utilizzato per generare l'array di rendering per l'area di contenuto principale della pagina.

Un'altra aggiunta è anche il modo in cui gestire i moduli, poiché la restituzione di una pagina con un modulo è leggermente più complessa di un semplice array di rendering, quindi è possibile definire _form con FormInterface responsabile del modulo corrente.

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

Nota: questo copre i punti più importanti dal mio punto di vista, anche se ci sono sicuramente molti più punti di cui parlare.

TL; DR

  • I caratteri di sottolineatura sono specificati per tutto ciò che non è un parametro per il controller. Questo sta arrivando come una sorta di "standard" di symfony.
  • Questi parametri vengono aggiornati tramite il convertitore di parametri e passati al controller utilizzando il resolver del controller
  • Drupal ha alcune aggiunte per facilitare l'interazione delle persone con il sistema di routing di symfony.

Wow. Risposta impressionante. Perché alcuni parametri contengono punti in contrapposizione all'utilizzo di un trattino basso? Es user.pass(nell'esempio sopra) vs. user_pass. È anche una convenzione di symfony?
chrisjlee,

2
Esiste un tipo di convenzione per utilizzare $ module. $ Name come nome macchina di una route. Nulla però lo presuppone internamente.
Daniel Wehner,

Come da problema di seguito, _content non viene più utilizzato, ma lo è _controller. Quindi l'esempio nella parte Risposta pagina non è aggiornato. drupal.org/node/2378809 Se vogliamo visualizzare i dati nell'area di contenuto della nostra pagina, il controller definirà un array di rendering, analogamente a come è stato fatto in Drupal 7. Se vogliamo bypassarlo e creare la nostra pagina da zero, quindi possiamo restituire un oggetto Response.
benelori,

Beh, certo, non puoi aspettarti che non succedano 1,5 anni
Daniel Wehner,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.