ルーティングファイルにアンダースコアが入力されるのはなぜですか?


24

接頭辞付きアンダースコア文字の有無にかかわらず、すべてのパラメーターはどうなりますか?

Drupalはこれらのパラメーターの処理方法をどこで決定しますか?

この概念はSymfonyから導入されたのですか、それともDrupalにとって新しいのですか?

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
これはSymfonyのコンベンションです。ここに良い記事があります。最後に注意すべきことは、パラメーター名のアンダースコア文字の特別な意味です。この文字で始まるパラメータは、特別な意味を持っている
クライヴ

1
ありがとう、クライヴ。この記事では「特別な意味」に言及していますが、これについてはまったく説明していません。アンダースコア以外のパラメーターも特別なものにできないのはなぜですか?
ダニエル

1
笑、なぜアンダースコア以外のパラメータも特別ではないのですか?、それは深く実存的な質問のように聞こえます!通常(ちょうど通常)変数のプレフィックスは、「ここではない」「プライベート」変数を示すため、またはシステム内の他のクラス/メソッド/何かとの名前の衝突を避けるために行われます。公式ドキュメントを見るといいでしょう、はい
クライブ

回答:


41

ここで、ルーティングシステムのアイデアの背後にあるうまくいけば良い説明と、それへのdrupal固有の追加があります。

総括

Symfonyコンポーネントには、ここで2つの重要な概念があります。httpカーネルはリクエストを取得するシステムであり、何らかの方法で他のシステムに生成を依頼して、リクエストされた出力(応答オブジェクト)を生成するコードを定義し、クライアントに応答を送り返します。このコードはコントローラーと呼ばれるため、これは純粋なphp4のような関数、オブジェクトのメソッド、または匿名関数のいずれかです。

どのコントローラーが現在の要求に責任があるかを知っているシステムは、ルーティングシステムです。

ここに画像の説明を入力してください

基本ルーティングファイル

モジュール開発者として、ルートのリストと対応するコントローラーを定義します。

JSON応答の例を次に示します。

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

symfonyのドキュメントのほとんどはパターンに言及していますが、drupalはルーティングファイルで非推奨の「パス」キーのみを許可することを決定しました。

重要な概念は、システムからいくつかのパラメーターを取得し、それらを応答に変換するコントローラーです。この例では、パラメーター「taxonomy_vocabulary」があります。したがって、アンダースコアのないものはすべて、コントローラーのパラメーターと見なされます。デフォルト値を指定する場合は、デフォルト配列に入れます。同じyml配列で、「::」で接続されたクラスとメソッドを指定して、システムにどこを検索するかを伝えます。他のすべてのプロパティは、コントローラパラメータとは関係がないため、内部と見なされるため、プレフィックスとしてアンダースコアを使用します。

symfony自体では、正規表現を定義して、着信パラメーターが有効であることを検証することもできます(「要件」を使用)。ここでは、数字のみに一致します。

コントローラーリゾルバー

symfonyは現在のリクエストでどのコントローラーがアクティブであるかを見つけると、いわゆるコントローラーリゾルバーに、call_user_func_arrayを介して実行できるコントローラーのインスタンスを作成するように要求します。コントローラーリゾルバーには、コントローラー呼び出し可能オブジェクト(オブジェクト+メソッド、匿名関数)を取得する1つのメソッドと、コントローラーに渡されるパラメーターを取得する1つのメソッドがあります。コントローラーリゾルバーを参照してください。

Drupal拡張機能

これは基本的にsymfonyが提供するものです。

Drupalは少し複雑ですが:

  • ルートへのアクセスを確認できます。たとえば、user_access()の呼び出しは、Drupal 7以降では非常に一般的でした。
  • taxonomy_vocabularyを実際のエンティティオブジェクトに変換したくない
  • ページ全体の応答を生成するのではなく、「メインコンテンツ」のみを生成します。

アクセス確認

Drupalはユーザーが現在のルートにアクセスできるかどうかをチェックするシステムをsymfonyパーツの上に導入し、代わりに403(アクセス拒否)例外をスローします。アクセスマネージャー

ルーティングファイルでは、要件部分でこれを指定します。最も一般的なビットを例にリストします。

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

_permissionはuser_access()の呼び出しを定義し、_roleはユーザーが特定の役割を持つことを保証します(ORには、AND論理には+を介して複数の役割を指定できます)。_entity_accessは、ユーザーシステムを表示するアクセス権があるかどうかをエンティティシステムに問い合わせます。デフォルトでは、drupalはアクセスチェッカーを追加することを保証しますが、_access_modeを介してオプションで切り替えることができます。

アップキャスティング

リストで述べたように、エンティティの読み込みを気にしたくない場合は、例として/ user / {user}を参照してください。エンティティの場合、基本的にはエンティティタイプの名前を使用するだけで、URLで渡されたIDでentity_loadを実行します。パラメータ変換マネージャー

ページ応答

コントローラーが応答オブジェクトを生成する責任がある前に書かれています。これは、ページがその領域に表示されるすべてのブロック、html、ページテンプレートなどに非常に似ているため、Drupalでは恐ろしいことです。したがって、drupalはページのコンテンツを返すコントローラーを指定するために異なるキーを指定しました。

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

定義された文字列は、ページのメインコンテンツ領域のレンダー配列を生成するために使用されるコントローラーです。

もう1つの追加は、フォームを処理する方法です。フォームを含むページを返すことは、単なるレンダリング配列よりも少し複雑なので、現在のフォームを担当するFormInterfaceで_formを定義できます。

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

注:これは私の観点から最も重要なポイントをカバーしていますが、さらに多くのポイントがあります。

TL; DR

  • アンダースコアは、コントローラーのパラメーターではないすべてのものに対して指定されます。これはsymfonyの一種の「標準」として提供されています。
  • これらのパラメーターは、パラメーターコンバーターを介してアップキャストされコントローラーリゾルバーを使用してコントローラーに渡されます。
  • Drupalには、symfonyルーティングシステムとの対話を簡単にするための追加機能がいくつかあります。

ワオ。印象的な答え。特定のパラメーターにアンダースコアを使用するのではなく、ピリオドがあるのはなぜですか?たとえばuser.pass(上記の例では)vs user_pass. それもsymfonyの慣習ですか?
chrisjlee

2
ルートのマシン名として$ module。$ nameを使用する何らかの規則があります。ただし、内部的には何も想定していません。
ダニエルウェナー

以下の問題によると、_contentはもう使用されていませんが、_controllerは使用されています。そのため、ページ応答部分の例は最新ではありません。drupal.org/node/2378809ページのコンテンツ領域にデータを表示したい場合、コントローラーはDrupal 7で行われた方法と同様にレンダー配列を定義します。それをバイパスしてページを作成したい場合最初から、Responseオブジェクトを返すことができます。
ベネロリ

まあ確かに、あなたは1.5年が起こらないことを期待することはできません
ダニエルWehner
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.