Por que os arquivos de roteamento são preenchidos com sublinhados?

24

Qual é o problema de todos os parâmetros com e sem um caractere de sublinhado prefixado ?

Onde o Drupal decide como processar esses parâmetros?

Este conceito foi introduzido no Symfony ou é novo no Drupal?

Exemplo ( 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
fonte
2
É uma convenção Symfony . Há um bom artigo aqui , encontre o trecho que diz A última coisa a se prestar atenção é o significado especial do caractere sublinhado nos nomes dos parâmetros. Parâmetros que começam com esse personagem têm um significado especial
Clive
11
Obrigado Clive. Este artigo menciona "significado especial", mas não explica nada disso. Por que os parâmetros não sublinhados também não podem ser especiais?
Daniel
11
lol, Por que os parâmetros não sublinhados também não podem ser especiais? , isso soa como uma questão profundamente existencial! Geralmente (apenas normalmente) as variáveis ​​de prefixo são feitas para indicar uma var 'privada' (improvável aqui) ou para ajudar a evitar colisões de nomes com outras classes / métodos / outra coisa em um sistema. Seria bom ver os documentos oficiais, sim
Clive

Respostas:

41

Aí vem uma explicação esperançosamente boa por trás da idéia do sistema de roteamento, bem como das adições específicas drupais a ele.

Visao geral

Os componentes do Symfony têm dois conceitos importantes aqui. O kernel http é um sistema que recebe a solicitação, de alguma forma solicita que outros sistemas produzam para definir a parte do código que produz a saída solicitada (um objeto de resposta) e envia a resposta de volta ao cliente. Esse trecho de código é chamado controller, portanto, pode ser uma função pura do php4, um método em um objeto ou até uma função anônima.

O sistema que sabe qual controlador é responsável pela solicitação atual é o sistema de roteamento.

insira a descrição da imagem aqui

Arquivo de roteamento básico

Como desenvolvedor de módulos, você define a lista de rotas e os controladores correspondentes.

Aqui está um exemplo para uma resposta json:

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

A maioria das documentações do symfony menciona padrão, mas o drupal decidiu apenas permitir a chave "path" não obsoleta em seu arquivo de roteamento.

O conceito-chave é o controlador que obtém alguns parâmetros do sistema e os converte na resposta. Neste exemplo, você tem o parâmetro 'taxonomy_vocabulary'. Portanto, tudo sem um sublinhado é considerado um parâmetro para o controlador. Se você deseja especificar um valor padrão, coloque-o na matriz de padrões. Na mesma matriz yml, você especifica a classe e o método conectados com '::' para informar ao sistema onde procurar as coisas. Todas as outras propriedades não têm nada a ver com os parâmetros do controlador e, portanto, são consideradas internas e, portanto, têm um sublinhado como prefixo.

O próprio Symfony também permite definir expressões regulares para validar que o parâmetro recebido é válido (usando 'requisitos'). Aqui corresponderia apenas a números.

Resolvedor de controlador

Depois que o symfony descobre qual controlador está ativo na solicitação atual, ele solicita que o chamado resolvedor do controlador crie uma instância do controlador, que pode ser executada via call_user_func_array. O resolvedor do controlador possui um método para obter a chamada do controlador (objeto + método, função anônima) e um método para obter os parâmetros passados ​​ao controlador, consulte Resolvedor do controlador

Extensões Drupal

Isso é basicamente o que o symfony oferece a você.

Drupal é um pouco mais complicado:

  • Você pode verificar o acesso à rota. Por exemplo, chamar user_access () era muito comum no Drupal 7 e abaixo.
  • Você não deseja converter o taxonomy_vocabulary em seu objeto de entidade real
  • Você não deseja gerar a resposta da página inteira, mas apenas o "conteúdo principal".

Verificação de acesso

O Drupal introduziu um sistema no topo das partes do symfony que verifica se o usuário tem acesso à rota atual e, em alternativa, lança uma exceção 403 (acesso negado). Gerenciador de acesso

No arquivo de roteamento, você especifica isso na parte de requisitos. Os bits mais comuns estão listados no exemplo:

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

_permission define uma chamada para user_access (), _role garante que o usuário tenha uma determinada função (você pode especificar várias via, para OR e + para AND). _entity_access pergunta ao sistema da entidade se você tem acesso para visualizar a entidade do usuário. Por padrão, o drupal garante que você adicione verificadores de acesso, permitindo que você continue, mas você pode alterná-lo nas opções através do _access_mode.

Upcasting

Conforme mencionado na listagem, você não deseja cuidar de carregar uma entidade, consulte / user / {user} como exemplo. Para entidades, você basicamente usa o nome do tipo de entidade e ele executará um entity_load com o ID passado na URL. Gerenciador de conversores de parâmetros

Resposta da página

Conforme escrito antes, o controlador é responsável por gerar o objeto de resposta. Isso seria horrível no Drupal, pois uma página consiste muito mais em todos os blocos que aparecem em suas regiões, nos modelos html e de página etc. Portanto, o drupal especificou uma chave diferente para especificar um controlador que retorna o conteúdo de uma página:

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

A cadeia definida é o controlador usado para gerar a matriz de renderização para a principal região de conteúdo da sua página.

Outra adição é também a maneira de lidar com formulários, pois retornar uma página com um formulário é um pouco mais complexo do que apenas uma matriz de renderização, para que você possa definir _form com o FormInterface responsável pelo formulário atual.

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

Nota: Isso abrange os pontos mais importantes da minha perspectiva, embora haja com certeza muitos outros pontos a serem discutidos.

TL; DR

  • Sublinhados são especificados para tudo que não são parâmetros para o controlador. Isso está vindo como uma espécie de "padrão" do symfony.
  • Esses parâmetros são aumentados através do conversor de parâmetros e transmitidos ao controlador usando o resolvedor do controlador
  • O Drupal possui algumas adições para facilitar a interação das pessoas com o sistema de roteamento symfony.
Daniel Wehner
fonte
Uau. Resposta impressionante. Por que certos parâmetros têm períodos neles, ao contrário de usar um sublinhado? Por exemplo, user.pass(no exemplo acima) vs user_pass. Isso também é uma convenção do symfony?
Chrisjlee #
2
Existe algum tipo de convenção para usar $ module. $ Name como nome da máquina de uma rota. Nada, porém, assume isso internamente.
Daniel Wehner
Conforme o problema abaixo, _content não é mais usado, mas _controller. Portanto, o exemplo na parte Resposta da página não está atualizado. drupal.org/node/2378809 Se quisermos exibir dados na região de conteúdo da nossa página, o controlador definirá uma matriz de renderização, da mesma forma que é feita no Drupal 7. Se quisermos ignorar isso, e criar nossa página do zero, podemos retornar um objeto de resposta.
precisa saber é
Bem certeza, você não pode esperar que 1,5 anos não acontecem
Daniel Wehner