Pourquoi les fichiers de routage sont-ils remplis de traits de soulignement?

24

Quel est le problème avec tous les paramètres avec et sans caractère de soulignement préfixé ?

Où Drupal décide-t-il comment traiter ces paramètres?

Ce concept a-t-il été introduit par Symfony, ou est-il nouveau pour Drupal?

Exemple ( 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
la source
2
C'est une convention Symfony . Il y a un bon article ici , trouvez le bit qui dit La dernière chose à faire attention est la signification spéciale du caractère de soulignement dans les noms de paramètres. Les paramètres commençant par ce caractère ont une signification particulière
Clive
1
Merci Clive. Cet article mentionne une «signification spéciale», mais ne l'explique pas du tout. Pourquoi les paramètres non soulignés ne peuvent-ils pas être spéciaux aussi?
Daniel
1
lol, Pourquoi les paramètres non soulignés ne peuvent-ils pas être spéciaux aussi? , cela ressemble à une question profondément existentielle! Habituellement (juste généralement), le préfixage des variables est effectué soit pour indiquer un var 'privé' (peu probable ici), soit pour éviter de nommer les collisions avec d'autres classes / méthodes / autre chose dans un système. Ce serait bien de voir les documents officiels, oui
Clive

Réponses:

41

Voici, espérons-le, une bonne explication derrière l'idée du système de routage ainsi que les ajouts spécifiques à Drupal.

Aperçu général

Les composants Symfony ont ici deux concepts importants. Le noyau http est un système qui obtient la demande, demande en quelque sorte à d'autres systèmes de produire pour définir le morceau de code qui produit la sortie demandée (un objet de réponse) et renvoyer la réponse au client. Ce morceau de code est appelé contrôleur, il peut donc s'agir d'une fonction purement php4, d'une méthode sur un objet ou même d'une fonction anonyme.

Le système qui sait quel contrôleur est responsable de la demande en cours est le système de routage.

entrez la description de l'image ici

Fichier de routage de base

En tant que développeur de module, vous définissez la liste des routes et les contrôleurs correspondants.

Voici un exemple de réponse json:

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

La plupart des documentations symfony mentionnent le modèle, mais drupal a décidé d'autoriser simplement la clé "path" non déconseillée dans son fichier de routage.

Le concept clé est le contrôleur qui obtient certains paramètres du système et les convertit en réponse. Dans cet exemple, vous avez le paramètre 'taxonomy_vocabulary'. Ainsi, tout ce qui n'est pas souligné est considéré comme un paramètre pour le contrôleur. Si vous souhaitez spécifier une valeur par défaut, vous la placez dans le tableau par défaut. Dans le même tableau yml, vous spécifiez la classe et la méthode connectées avec '::' pour indiquer au système où rechercher les éléments. Toutes les autres propriétés n'ont rien à voir avec les paramètres du contrôleur et sont donc considérées comme internes et ont donc un trait de soulignement comme préfixe.

Symfony lui-même vous permet également de définir des expressions régulières pour valider que le paramètre entrant est valide (en utilisant des «exigences»). Ici, cela correspondrait uniquement aux nombres.

Résolveur de contrôleur

Une fois que symfony a découvert quel contrôleur est actif sur la requête en cours, il demande au soi-disant résolveur de contrôleur de créer une instance du contrôleur, qui peut être exécutée via call_user_func_array. Le résolveur de contrôleur a une méthode pour obtenir le contrôleur appelable (objet + méthode, fonction anonyme) et une méthode pour obtenir les paramètres passés au contrôleur, voir Résolveur de contrôleur

Extensions Drupal

C'est essentiellement ce que vous offre symfony.

Drupal est cependant un peu plus compliqué:

  • Vous pouvez vérifier l'accès à l'itinéraire. Par exemple, appeler user_access () était très courant dans Drupal 7 et versions antérieures.
  • Vous ne voulez pas convertir le vocabulaire taxonomique en son objet entité réel
  • Vous ne voulez pas générer la réponse de la page complète, mais juste le "contenu principal".

Contrôle d'accès

Drupal a introduit un système au-dessus des parties symfony qui vérifie si l'utilisateur a accès à la route actuelle et lève une exception 403 (accès refusé). Gestionnaire d'accès

Dans le fichier de routage, vous le spécifiez dans la partie exigences. Les bits les plus courants sont répertoriés dans l'exemple:

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

_permission définit un appel à user_access (), _role garantit que l'utilisateur a un certain rôle (vous pouvez en spécifier plusieurs via, pour OR et + pour la logique AND). _entity_access demande au système d'entités si vous avez accès pour voir l'entité utilisateur. Par défaut, Drupal garantit que vous ajoutez des vérificateurs d'accès vous permettant de continuer, mais vous pouvez le basculer dans les options via le mode _access_.

Upcasting

Comme mentionné dans la liste, vous ne voulez pas vous soucier du chargement d'une entité, voir / user / {user} comme exemple. Pour les entités, vous utilisez simplement le nom du type d'entité et il exécutera un entity_load avec l'ID passé dans l'URL. Gestionnaire de convertisseur de paramètres

Réponse de la page

Comme écrit auparavant, le contrôleur est responsable de générer l'objet de réponse. Ce serait horrible dans Drupal car une page se compose de beaucoup plus comme tous les blocs apparaissant dans ses régions, les modèles html et page etc. Par conséquent, drupal a spécifié une clé différente pour spécifier un contrôleur qui retourne le contenu d'une page:

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

La chaîne définie est le contrôleur utilisé pour générer le tableau de rendu pour la région de contenu principale de votre page.

Un autre ajout est également la manière de traiter les formulaires, car le retour d'une page avec un formulaire est légèrement plus complexe qu'un simple tableau de rendu, vous pouvez donc définir _form avec le FormInterface responsable du formulaire actuel.

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

Remarque: Cela couvre les points les plus importants de mon point de vue, bien qu'il y ait certainement beaucoup plus de points à discuter.

TL; DR

  • Les traits de soulignement sont spécifiés pour tout ce qui n'est pas un paramètre du contrôleur. Cela vient comme une sorte de "standard" de symfony.
  • Ces paramètres sont transférés via le convertisseur de paramètres et transmis au contrôleur à l'aide du résolveur du contrôleur
  • Drupal a quelques ajouts pour faciliter l'interaction des gens avec le système de routage symfony.
Daniel Wehner
la source
Sensationnel. Réponse impressionnante. Pourquoi certains paramètres comportent-ils des périodes opposées à l'utilisation d'un trait de soulignement? Par exemple user.pass(dans l'exemple ci - dessus) par rapport à user_pass. Est-ce aussi une convention symfony?
chrisjlee
2
Il existe une sorte de convention pour utiliser $ module. $ Name comme nom de machine d'une route. Rien ne le suppose cependant en interne.
Daniel Wehner
Selon le problème ci-dessous, _content n'est plus du tout utilisé, mais _controller l'est. Par conséquent, l'exemple de la partie Réponse de page n'est pas à jour. drupal.org/node/2378809 Si nous voulons afficher des données dans la zone de contenu de notre page, le contrôleur définira un tableau de rendu, de la même manière que dans Drupal 7. Si nous voulons contourner cela, et créer notre page à partir de zéro, nous pouvons alors renvoyer un objet Response.
benelori
Bien sûr, vous ne pouvez pas vous attendre à ce que 1,5 an ne se produise pas
Daniel Wehner