Drupal 11 の最小カスタムモジュールを作る

結論

Drupal 11でモジュールとして認識させるために必須なのは、モジュール情報を定義する .info.yml です。hookは必須ではありません。独自ページを表示する場合は .routing.yml とControllerを追加し、Drupalの処理へ介入したい場合だけ必要なhookを実装します。

ここでは、公開ページ /pixie-hellohook_help() を持つ、コピーして試せる最小構成を作ります。

前提

  • Drupal 11がComposer構成でインストール済みであること
  • Drupalのドキュメントルートが web であること。構成が異なる場合は、そのドキュメントルートへ読み替えること
  • Drushを vendor/bin/drush から実行できること

完成するディレクトリ構成

web/modules/custom/pixie_hello を作り、次の4ファイルを配置します。

web/modules/custom/pixie_hello/
├── pixie_hello.info.yml
├── pixie_hello.module
├── pixie_hello.routing.yml
└── src/
    └── Controller/
        └── HelloController.php

ディレクトリ名、ファイル名、PHPのnamespaceで、機械名 pixie_hello を一致させるのが重要です。

1. モジュール情報を定義する

pixie_hello.info.yml:

name: Pixie Hello
type: module
description: 'Provides a minimal Drupal 11 custom page and help hook.'
package: Custom
core_version_requirement: ^11

nametypecore_version_requirement が基本となります。Drupal 10.3にも対応させる場合は、十分にテストしたうえで ^10.3 || ^11 のように指定できます。

2. URLとControllerを結び付ける

pixie_hello.routing.yml:

pixie_hello.page:
  path: '/pixie-hello'
  defaults:
    _controller: '\Drupal\pixie_hello\Controller\HelloController::content'
    _title: 'Pixie Hello'
  requirements:
    _permission: 'access content'

この例のページは access content 権限を持つ利用者へ公開されます。管理処理や機密情報を扱うページでは、専用権限を定義して使ってください。

3. ページを返すControllerを作る

src/Controller/HelloController.php:

<?php

declare(strict_types=1);

namespace Drupal\pixie_hello\Controller;

use Drupal\Core\Controller\ControllerBase;

/**
 * Returns the Pixie Hello example page.
 */
final class HelloController extends ControllerBase {

  /**
   * Builds the example page.
   */
  public function content(): array {
    return [
      '#markup' => $this->t('Hello from Drupal 11.'),
    ];
  }

}

ControllerはHTML全体ではなくrender arrayを返します。この例の文字列は翻訳可能で、Drupalのレンダリング処理を通ります。利用者が入力した値を未処理のまま #markup へ連結してはいけません。

4. hookを1つ実装する

pixie_hello.module:

<?php

declare(strict_types=1);

use Drupal\Core\Routing\RouteMatchInterface;

/**
 * Implements hook_help().
 */
function pixie_hello_help(string $route_name, RouteMatchInterface $route_match): array|null {
  if ($route_name !== 'help.page.pixie_hello') {
    return NULL;
  }

  return [
    '#type' => 'html_tag',
    '#tag' => 'p',
    '#value' => t('The Pixie Hello module provides a minimal Drupal 11 page.'),
  ];
}

hook名の hook 部分をモジュールの機械名へ置き換えるため、hook_help() の実装名は pixie_hello_help() になります。Helpモジュールが有効なら、モジュールのヘルプページに説明が表示されます。

Drupal 11では #[Hook] 属性を使うクラスベースの実装も利用できますが、手続き型のhookも引き続き利用できます。この例では最小構成を理解しやすくするため、.module ファイルへ実装しています。

5. 有効化して確認する

vendor/bin/drush pm:enable pixie_hello -y
vendor/bin/drush cache:rebuild
vendor/bin/drush pm:list --type=module --status=enabled --filter=pixie_hello

ブラウザーで https://example.com/pixie-hello を開き、次の文字列が表示されれば成功です。

Hello from Drupal 11.

Helpモジュールを使う場合は、次のように有効化して /admin/help/pixie_hello を確認します。

vendor/bin/drush pm:enable help -y
vendor/bin/drush cache:rebuild

変更が反映されない場合

  • モジュールが一覧に出ない場合は、ディレクトリ名と pixie_hello.info.yml の名前、YAMLのインデントを確認します。
  • ページが404になる場合は、pixie_hello.routing.yml のファイル名、routeのインデント、Controllerのnamespaceを確認してからキャッシュを再構築します。
  • Class not foundになる場合は、src/Controller/HelloController.php の大文字と小文字を含むパスを確認します。
  • アクセス拒否になる場合は、routeの _permission と現在のロール権限を確認します。

アンインストール

ファイルを先に削除せず、モジュールをアンインストールしてからディレクトリを削除します。

vendor/bin/drush pm:uninstall pixie_hello -y
vendor/bin/drush cache:rebuild
rm -r web/modules/custom/pixie_hello

古いDrupalとの違い

Drupal 7以前の hook_menu() を使ったページ定義は、Drupal 11では使いません。URLはrouting YAML、ページ処理はControllerへ分離します。また、モジュールに「最低限必要なhook」があるわけではなく、実現したい拡張点に対応するhook、イベント、プラグイン、サービスを選びます。

動作確認

この記事の4ファイルは、Drupal 11.4.5およびPHP 8.3.33の環境で、PHP構文、.info.yml、routing YAML、Controllerの戻り値、hook_help() の戻り値を確認しています。

参考資料

Comments