¿Por qué los archivos de enrutamiento están llenos de guiones bajos?

24

¿Cuál es el trato con todos los parámetros con y sin un carácter de subrayado prefijado ?

¿Dónde decide Drupal cómo procesar estos parámetros?

¿Este concepto se introdujo desde Symfony o es nuevo en Drupal?

Ejemplo ( 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
fuente
2
Es una convención de Symfony . Hay un buen artículo aquí , encontrar la parte que dice La última cosa a prestar atención a es el significado especial del carácter de subrayado en los nombres de los parámetros. Los parámetros que comienzan con este personaje tienen un significado especial
Clive
1
Gracias Clive Este artículo menciona "significado especial", pero no explica esto en absoluto. ¿Por qué los parámetros que no son de subrayado no pueden ser especiales también?
Daniel
1
jajaja, ¿por qué los parámetros que no son de subrayado también pueden ser especiales? , eso suena como una pregunta profundamente existencial! Por lo general (solo generalmente), las variables de prefijo se realizan para indicar una var 'privada' (poco probable aquí) o para ayudar a evitar colisiones de nombres con otras clases / métodos / algo más en un sistema. Sería bueno ver los documentos oficiales, sí
Clive

Respuestas:

41

Aquí viene una buena explicación detrás de la idea del sistema de enrutamiento, así como las adiciones específicas de Drupal.

Visión general

Los componentes de Symfony tienen dos conceptos importantes aquí. El kernel http es un sistema que recibe la solicitud, de alguna manera le pide a otros sistemas que produzcan para definir el fragmento de código que produce la salida solicitada (un objeto de respuesta) y envía la respuesta al cliente. Este código se llama controlador, por lo que puede ser una función pura como php4, un método en un objeto o incluso una función anónima.

El sistema que sabe qué controlador es responsable de la solicitud actual es el sistema de enrutamiento.

ingrese la descripción de la imagen aquí

Archivo de enrutamiento básico

Como desarrollador de módulos, usted define la lista de rutas y los controladores correspondientes.

Aquí hay un ejemplo para una respuesta json:

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

La mayoría de la documentación de Symfony menciona el patrón, pero drupal decidió permitir la clave de "ruta" no obsoleta en su archivo de enrutamiento.

El concepto clave es el controlador que obtiene algunos parámetros del sistema y los convierte en la respuesta. En este ejemplo, tiene el parámetro 'taxonomy_vocabulary'. Por lo tanto, todo sin un guión bajo se considera un parámetro para el controlador. Si desea especificar un valor predeterminado, póngalo en la matriz predeterminada. En la misma matriz yml, especifica la clase y el método conectados con '::' para decirle al sistema dónde buscar cosas. Las demás propiedades no tienen nada que ver con los parámetros del controlador, por lo que se consideran internas y tienen un guión bajo como prefijo.

Symfony en sí también le permite definir expresiones regulares para validar que el parámetro entrante sea válido (usando 'requisitos'). Aquí solo coincidiría con los números.

Controlador de resolución

Una vez que Symfony descubre qué controlador está activo en la solicitud actual, le pide al llamado resolutor del controlador que cree una instancia del controlador, que se pueda ejecutar a través de call_user_func_array. La resolución del controlador tiene un método para hacer que el controlador sea invocable (objeto + método, función anónima) y un método para hacer que los parámetros pasen al controlador, consulte Resolución del controlador

Extensiones Drupal

Esto es básicamente lo que Symfony te ofrece.

Sin embargo, Drupal es un poco más complicado:

  • Puedes consultar el acceso a la ruta. Por ejemplo, llamar a user_access () era muy común en Drupal 7 y versiones posteriores.
  • No desea convertir el taxonomy_vocabulary en su objeto de entidad real
  • No desea generar la respuesta de página completa, sino solo el "contenido principal".

Comprobación de acceso

Drupal ha introducido un sistema en la parte superior de las partes de Symfony que verifica si el usuario tiene acceso a la ruta actual y la alternativa de lanzar una excepción 403 (acceso denegado). Administrador de acceso

En el archivo de enrutamiento, especifique esto en la parte de requisitos. Los bits más comunes se enumeran en el ejemplo:

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

_permission define una llamada a user_access (), _role asegura que el usuario tenga una determinada función (puede especificar varias a través de, para OR y + para lógica AND). _entity_access pregunta al sistema de la entidad si tiene acceso para ver la entidad del usuario. Por defecto, drupal asegura que agregue verificadores de acceso que le permitan continuar, pero puede cambiarlo en las opciones a través del _access_mode.

Upcasting

Como se menciona en la lista, no desea tener cuidado al cargar una entidad, vea / user / {user} como ejemplo. Para las entidades, básicamente solo usa el nombre del tipo de entidad y ejecutará una entidad_load con el ID pasado en la URL. Administrador de convertidor de parámetros

Respuesta de página

Como se escribió antes, el controlador es responsable de generar el objeto de respuesta. Esto sería horrible en Drupal ya que una página consiste en mucho más que todos los bloques que aparecen en sus regiones, las plantillas html y de página, etc. Por lo tanto, drupal especificó una clave diferente para especificar un controlador que devuelve el contenido de una página:

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

La cadena definida es el controlador utilizado para generar la matriz de representación para la región de contenido principal de su página.

Otra adición es también la forma de lidiar con los formularios, ya que devolver una página con un formulario es un poco más complejo que solo una matriz de representación, por lo que puede definir _form con el FormInterface responsable del formulario actual.

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

Nota: Esto cubre los puntos más importantes desde mi perspectiva, aunque seguramente hay muchos más puntos de los que hablar.

TL; DR

  • Los guiones bajos se especifican para todo lo que no son parámetros para el controlador. Esto viene como una especie de "estándar" de Symfony.
  • Estos parámetros se actualizan a través del convertidor param y se pasan al controlador utilizando el resolutor del controlador
  • Drupal tiene algunas adiciones para facilitar que las personas interactúen con el sistema de enrutamiento de Symfony.
Daniel Wehner
fuente
Guau. Impresionante respuesta. ¿Por qué ciertos parámetros tienen períodos opuestos al uso de un guión bajo? Por ejemplo user.pass(en el ejemplo anterior) vs. user_pass. ¿También es una convención de Symfony?
chrisjlee
2
Hay algún tipo de convención para usar $ module. $ Name como nombre de máquina de una ruta. Sin embargo, nada asume eso internamente.
Daniel Wehner el
Según el siguiente problema, _content ya no se usa en absoluto, pero _controller sí. Por lo tanto, el ejemplo en la parte Respuesta de la página no está actualizado. drupal.org/node/2378809 Si queremos mostrar datos en la región de contenido de nuestra página, entonces el controlador definirá una matriz de representación, de forma similar a cómo se hace en Drupal 7. Si queremos evitar eso y crear nuestra página desde cero, entonces podemos devolver un objeto de respuesta.
benelori
Seguro, no puedes esperar que no pasen 1.5 años
Daniel Wehner