第四回:その他のDrupal 8 のコンセプト

過去、数週間にわたったブログではDrupal8の構造および内部リクエスト処理について説明しました。Drupal8がどのようにビルドされるかについては、詳しく学んでいません。特定のコアモジュールコードを確認する前にDrupal8の新規・変更されたコンセプトについて知ることは重要です。今回の最後の記事でそれらを説明します。

構成

Drupal8では構成システムが面白い方法へと変わってきました。特記するべきことは、Drupal 8での構成の多くが「/sites/{name}/files/config_{HASH}/active」ディレクトリにYAMLファイルとして格納されていることです。ファイル名は、ファイル内に何が構成されるかを定義します。例えば、「node.settings.yml」はノードモジュールの設定を含み、「views.view.content.yml」は「content」というマシン名でビューの完全な定義を含みます。Drupalでは、config にプレフィックスを利用することができます。

構成ファイルは柔軟性のないファイルだと思われるかもしれません。しかし、実際には、YAML構文を使って、連想配列をビルドすることができます。しかも、DrupalのConfigオブジェクトは、構成ファイルをいつでも編集可能にし、手動で編集する必要はまったくありません。Drupalの設定画面で新規フィールド、ノード、ブロックやビューを作成したら、新規ファイルも作成されます。高速なクエリが作成できなくなるため、コンテンツ(ノード)とデータはデータベースに保存されます。

モジュールは、conf サブディレクトリで実行されることになります。モジュールが有効になると、ディレクトリ内の全構成ファイルがサイトの構成ディレクトリへコピーされます。ここにファイルを追加すると(そして、キャッシュをクリアすると)、自動的に検出・適用されます。このようにして、モジュールはDrupal 7の「hook_node_info」のようなhook関数を実装することなしに、追加の新しいノードタイプ、イメージスタイル、ビューなどを提供することができます。

構成ファイルは他のロケーションへ簡単にコピーすることができます。これは、あなたが構成変更を最後に決定できるという利点があります。

また、構成ファイルは関連したスキームがあって、これらは、ビュー・ブロック・イメージなどの外見に関する情報の詳細が書かれています。このため、構成はよりよく検証・翻訳できます。

エンティティ

Drupal 7によって、エンティティが紹介されました。それらは、同じ機能を提供する一般的なオブジェクトでした。例えば、フィールドの追加、アクセスメソッドの一般化、ビューにおいての参照などがあります。エンティティコンセプトは非常に強力なものとして認められました。Drupal 8では、エンティティのコンセプトはさらにCMSの中心機能となりました。コンテンツ(ノード、タクソノミー、ユーザ)だけではなく、ビュー・アクション・メニュー・イメージなどのようなフィールドではないデータもエンティティクラスとして扱われます。また、ノードタイプや語彙のようなバンドルもエンティティとして扱われます。これらの背景には、これらのオブジェクトタイプが fieldable でないにもかかわらず、設定ファイルの一般的な保存やエンティティ名に基づくルートパラメータの自動変換などの、他の一般的機能にたいしても便利になるからです。

属性を使ってエンティティのプロパティを定義します。例えば、エンティティは項目をもつことができるのかできないのか、または、他のエンティティのバンドルとして使うのかを指定します。コントローラによっては、エンティティは設定ファイルに保存されることもあります。コントローラが「ConfigStorageController」であるかどうかで、エンティティが設定ファイルに保存されるか決定されます。設定ファイルが便利だとしてもデータベースのクエリは利用できません。もし、エンティティを設定ファイルから検索したい場合は、全項目をロードしてPHPの「for loop」を使います。もし、データベースへ保存されるノードやユーザのような項目の場合は、「FieldableDatabaseStorageController」を使用できます。ノード、ユーザ、またはタクソノミーでも同様です。もちろん最終結果は、設定ファイルを利用してこのコンテンツを移行することは出来ません。(私には、それがfieldable 設定ストレージコントローラを持つことが出来るかはまだ不明です。)

エンティティの属性をよく理解するために、構成ベースエンティティのImageStyleクラス(のアノテーション)、fieldableでありデータベース格納式の(タクソノミー)TermやバンドルエンティティのVocabularyについて詳しく知ることをお勧めします。

プラグイン

プラグインは、フックのオブジェクト指向版と見ることができます。カスタムブロックやイメージ効果をモジュール構造で追加するためにプラグインが使われています。

BlockBase」クラスは、プラグインの良い例です。新規カスタムブロックを追加するには、このクラスをフォーラムモジュールの「ActiveTopicsBlock」で利用されるように、拡張しなければなりません。また、いくつかのメソッドは、アクセスチェックやビュー構成、ブロックの編集等のためにオーバーライドしなければなりません。

プラグインマネジャは、プラグインタイプを定義することに利用されます。名前空間とサブディレクトリの一覧は、どこにプラグインがあるかを定義するために用意されます。この方法で、いずれのモジュールでもプラグインを追加することができます。アノテーションクラスを設定して、プラグインを設定することができます。いくつかの構成プロパティは、プラグインのタイプに依存するのでアノテーションを指定しなければなりません。

Drupalクラス

Drupal 8コアのソースコードは大部分がオブジェクト指向のコードですが、モジュールフックのコードはまだ手続き型のままです。Symfonyは完全にオブジェクト指向に作られているので、この矛盾は大きなチャレンジです。Symfonyでは、他のサービスに依存する機能を作成したい時、新規サービスを作成して、サービスコンテナにサービスの依存性を定義します。その反面、Drupalフックをもちいて独自サービスを作成したい時、クラス構造ではないので、上記のような方法は適用できません。この場合、静的なDrupalクラスが作成されます。「Drupal::service('{service id}'), 」を使って手続き型の文脈の中でサービスを取得するか、または、「Drupal::request()」、 「Drupal::currentUser()」、「Drupal::entityManager()」のような特定のサービスaccessorを使用する必要があります。accessorを使用することで、プログラム時のエディタでより良いコード補完ができるようになります。また、サービスaccessorは、Drupal 7の「url()」と同様な「Drupal::url()」のような便利なヘルパー機能も提供します。

Drupalクラスを使ってnode.module 内のnode_access 機能の例を以下に示します。

function node_access($op, $node, $account = NULL, $langcode = NULL) {
  $access_controller = \Drupal::entityManager()->getAccessController('node');
  ...
  return $access_controller->access($node, $op, $langcode, $account);
}

まとめ

今回のブログでは、Drupal 8がどのように構成されているかを見てSymfony2との構成と比較を行いました。サービスコンテナは全サービスを管理および構成することができます。そして、Drupalカーネルによるルーティングとリクエスト処理についても説明しました。最後に、Drupal8の新しく重要なコンセプトである、Drupalクラスとプラグイン、Drupal 8での構成についても紹介しました。

この情報を利用することで、あなたがDrupal 8を勉強する際に少しでも手助けになること、そしてDrupal 8でのモジュール作成可能になり、プロジェクトへ貢献できるようになることを願っています。

Good luck!

翻訳元URL:https://cipix.nl/understanding-drupal-8-part-4-other-drupal-8-concepts