PHP
Drupal
Drupal8
RouteEnhancer
DrupalDay 21

Drupal 8 の Page Manager で作成したページのタイトルを RouteEnhancer で変更する

Drupal 8 の Page Manager モジュールでページを作成する際に、「〇〇リスト」といった“〇〇”を動的に出力しないといけない場合があります。その対応の際に、RouteEnhancer を使ったところ割と楽に変更する部分を作成できたのでそれを記載します。

TL;DR

RouteEnhancer を使うと、applies と enhance のメソッド定義と yaml の記述だけでタイトルを動的に設定できる。

RouteEnhancer の概要と設定方法

RouteEnhancer とは、作成された Route に条件を設定して後から変更することができるクラスです。 RouteEnhancer を使用するためには、module_name.service.yml に下記のような記述が必要になります。

module_name.service.yml
services:
  module_name.example_route_enhancer:
    class: Drupal\module_name\Routing\ExampleRouteEnhancer
    tags:
      - { name: route_enhancer }

もし、RouteEnhancer 内部で Drupal のサービスを使用したい場合は、下記のように arguments の設定を追加し、arguments に [@service_name1, @service_name2] の形式で記述します。

module_name.service.yml
services:
  module_name.example_route_enhancer2:
    class: Drupal\module_name\Routing\ExampleRouteEnhancer2
    arguments: [@current_user, @entity_type.manager]
    tags:
      - { name: route_enhancer }

RouteEnhancer クラスのメソッド

TL;DR でも記述した通り、クラスのメソッドは基本的には applies と enhance のみになります。

applies

enhance で変更を加える Route の条件を判断するメソッドです。引数に Route オブジェクトのみが来るので、下記のようにPage Manager で設定したパスを指定するのがベストだと思います。

public function applies(Route $route) {
  return $route->getPath() === '/hogehoge/{nid}/list';
}

enhance

enhance は Route オブジェクトに設定されたデフォルト値を変更するためのメソッドです。Page Manager で設定したパラメータに紐づく値は下記のコードのようになります。(前述の /hogehoge/{nid}/list なら $default['nid']
ページの内容を表示する variant は $defaults['page_manager_page_variant'] に代入されているので、この内容を変更するとページのタイトルを変更することができます。

public function enhance(array $defaults, Request $request) {
  // /hogehoge/{nid}/list ならパラメータ名が nid になる
  /** @var \Drupal\node\Entity\Node $node */
  $node = $defaults['nid'];

  // Page Manager の PageVariant Entity を取得してタイトルを動的に設定する
  /** @var \Drupal\page_manager\Entity\PageVariant $variant */
  $variant = $defaults['page_manager_page_variant'];
  $variant_settings = $variant->get('variant_settings');
  $variant_settings['page_title'] = $node->label() . '一覧';
  $variant->set('variant_settings', $variant_settings);
  return $defaults;
}

もし、Drupal のサービスを利用する場合は、下記のようにコンストラクタのメソッドを作成し、サービスをクラス内のプロパティとして設定する必要があります。

// 先述の ExampleRouteEnhancer2 なら下記のようになる
public function __construct(AccountProxy $current_user, EntityTypeManager $entity_type_manager) {
  $this->currentUser = $current_user;
  $this->entityTypeManager = $entity_type_manager;
}

まとめ

本記事では、Page Manager モジュールでパラメータが設定されたページのタイトルを RouteEnhancer を使用して動的に変更する方法を記載しました。RouteEnhancer では、既存の Route に対して変更を加えることができるため、未確認ですが Page Manager で設定した内容に限らず、routing.yml で設定した内容(_form など)を変えることも可能だと思います。