Drupalでカスタムモジュールを作ってみよう

この記事ではDrupalでカスタムモジュールを作成するやり方をご紹介します。

この記事の内容

  • カスタムモジュールを使う場面とは?
  • カスタムモジュールの作成方法
  • カスタムモジュールの活用例

Drupalを使ってWEBサイトを作る基本的な流れは次のとおりです。

STEP
コアモジュールで機能を実現する

Drupalインストール時に用意されているモジュールで実現できないか検討します。

STEP
コアモジュールでできないことをコントリビュートモジュールで実現する

Drupal.orgで公開されているコントリビュートモジュールで実現できないか検討します。

STEP
コントリビュートモジュールで実現できない機能をカスタムモジュールで実現する

ここまで検討して実現できていない場合は独自の機能である可能性が高いです。
そのためルーティングやテンプレートを活用してカスタムモジュールで機能を実現します。

まずはコアモジュールやコントリビュートモジュールで実現できないか?という観点で検討します。
なぜならばコアモジュールやコントリビュートモジュールで実現できれば、
インストールと設定で作業が済むため圧倒的にコストを抑えることができるからです。

ですがそのサイト独自の機能であれば出回っている可能性が非常に高いです。
そのような場合はカスタムモジュールを作成して機能を実現します。

今回はサンプルのモジュールを用いてカスタムモジュールの作成方法をご紹介していきます。

目次

今回作成するモジュール

画面にアクセスすると文字列を表示するページを作ってみます。
文字列はプログラムで指定した値を表示します。

カスタムモジュールを作成する

モジュール用のフォルダを作成する

web/moudles配下にcustomフォルダを作ります。

mkdir custom

さらにその配下にカスタムモジュール用のフォルダを作ります。
このフォルダはカスタムモジュール1つに対して作成し、フォルダ名はカスタムモジュールのマシン名にします。
今回はhello_moduleというマシン名で作成します。

mkdir hello_module

設定ファイルを作成する

設定ファイルはそのモジュールの名前や説明、対応するコアバージョンを定義するファイルです。
先ほど作成したweb/modules/custom/hello_moduleにhello_module.info.ymlを作成します。

touch hello_module.info.yml

ファイル名のhello_moduleの部分は作成するモジュールのマシン名に置き換えてください。

今回は設定ファイルは以下のように設定します。

name: HelloWorld
type: module
description: '画面に「Hello, World!」を表示します。'
package: Custom
core_version_requirement: ^9 || ^10

今回設定ファイルに定義した項目はそれぞれ以下の通りです。

name : モジュールの名前です。管理画面に表示されます。
type : モジュールの場合はmoduleで固定です。
description : モジュールの説明です。管理画面に表示されます。
package : Customというパッケージで管理することを表しています。無くても問題ないです。
core version requirement : どのコアバージョンで動作するかを指定します。

これでモジュールとして必要最低限作成できました。
この状態でインストールは可能ですがまだ何も機能がないのでここからカスタマイズしていきます。

ルーティングを作成する

ルーティングとはURLとそのURLにアクセスしたときに動作するプログラムを紐づけることです。
hello_moduleでは/hello_worldというURLにアクセスしたら文字列を表示することにします。

hello_module.info.ymlと同階層にhello_module.routing.ymlを作成します。
以下の内容を記載します。

hello_module.content:
  path: '/helloworld'
  defaults:
    _controller: '\Drupal\hello_module\Controller\HelloWorldController::display'
    _title: 'Hello, World!'
  requirements:
    _permission: 'access content'

今回定義した項目はそれぞれ以下の通りです。

path : ルーティングのURL
controller : ルーティングで使用するプログラム(コントローラー)
title : ページのタイトル
permission : どの権限を持つユーザーにアクセスできるようにするか
 ※’access content’を指定しておけばどのユーザーもアクセスできます。

次にルーティングで指定したプログラムを作成します(controllerに指定したプログラム)。
hello_module.info.ymlと同階層にsrcフォルダを、
さらに配下にControllerフォルダを、
そしてその配下にHelloWorldController.phpを作成します。

mkdir src
mkdir Controller
touch HelloWorldController.php

HelloWorldController.phpは以下のソースコードです。

<?php
namespace Drupal\hello_module\Controller;

use Drupal\Core\Controller\ControllerBase;

class HelloWorldController extends ControllerBase {

    public function display() {

        $arr = [
            '#theme' => 'custom_template',
            '#text' => 'Test',
        ];

        return $arr;

    }

}

ここではcustom_templateと呼ばれるレンダリングファイル(テンプレート)を使用し、
textという変数に「Text」という文字列を格納してテンプレートに渡しています。

次にルーティングファイルのテンプレートを作成します。
hello_module.info.ymlと同階層にtemplateフォルダを、
その配下にcustom-template.html.twigを作成します。

mkdir template
touch custom-template.html.twig

custom-template.html.twigは以下のソースコードです。

<p>Hello, World!</p>
<p> Welcome to our {{ text }} site</p>

ロジックはコントローラーで作り、ビューはテンプレートで作りました。
このように役割を分けると後々の保守もしやすくなります。

モジュールフックを作成する

最後にモジュール用のフックを作成するためのファイルを作ります。
hello_module.info.ymlと同階層でhello_module.moduleを作成します。

touch hello_module.module

hello_module.moduleの内容は以下の通りです。

<?php

/**
* Implementation of hook_theme()
*/

function hello_module_theme($existing, $type, $theme, $path) {
    
    $arr = [
        'custom_template' => [
            'variables' => ['text' => ""],
        ],
    ];

    return $arr;
}

hook_themeをオーバーライドし、
custom_templateでtextという変数を使えるように設定しています。

ここまででモジュールが作成できました。
最後にモジュールをインストールします。

モジュールをインストールする

管理画面の機能拡張にアクセスします。
フィルターでhello_moduleを検索し、チェックを入れてインストールを実行します。

以下のようなメッセージが出ればインストール成功です。

確認のため/helloworldにアクセスしてみます。

無事文字列を表示することができました!
テンプレート上でtestという変数に入っていた文字列も表示できています。

以上がカスタムモジュールを作成するまでの流れです。

カスタムモジュールの使用事例

冒頭で「カスタムモジュールはコアモジュールやコントリビュートモジュールでも実現できない場合に作成する」
と説明しました。

では実際にどういうケースでカスタムモジュールを作成するのでしょうか?
私の経験を踏まえてご紹介します(一部フィクションを交えながら)

Drupal外のシステムとの連携機能

とある案件にて、
Drupalを使って構築していたサイトと外部システムのユーザー情報を連携したいという要件がありました。

Drupal上のユーザー情報と外部システムのユーザー情報を共有して同じメールアドレス・パスワードでログインしたい(≒SSO)
とのことでしたのでカスタムモジュールを作って連携機能を作成しました。

SSOを実現するためのコントリビュートモジュール(Ex. simpleSAMLphp Authモジュール)はありますが、
これだけだと要件が不足していたため、足りない部分を補う形でカスタムモジュールを実現しました。

Drupal外部のDBと連携する機能

ある案件ではDrupal上のデータとDrupal外にあるシステムが持つDBのデータを合わせた帳票を作成したいという要件がありました。

Drupal外のDBを参照するにはPHPプログラムを作成する必要があります。
そこでDrupal上のDBとDrupal外のDBをSQLを用いて結合したビューを作成し、
作成したビューをもとに帳票を作成するという機能をカスタムモジュールで実現しました。

コンテンツとして管理するほどでもないが機能があるページ

通常DrupalでWEBサイトのページに相当するものを作る場合はコンテンツを作成しますが、
コンテンツタイプやコンテンツを作成するほど量産しないページもWEBサイトには存在する場合があります。

ある案件ではユーザーに応じて表示する内容を切り替えるページを作成したいという要件がありました。
ページ数としては1ページのみで今後も増える見込みはないため、
ルーティングとテンプレートを用いたページをカスタムモジュールとして実現しました。

さいごに

今回はDrupalでカスタムモジュールを作成する方法をご紹介しました。

もしコアモジュールでもコントリビュートモジュールでも実現できない機能があれば
今回ご紹介した内容を参考にぜひモジュールを作ってみてください。

この記事ではページとして機能を提供するモジュールを作成しましたが、
実際にはブロックやAPIとして作成することもできます。
カスタムモジュールについてもっと知りたいという方は以下の記事が参考になるかと思います。
ぜひ目を通してみてください。

Acquia
Drupalでカスタムモジュールを作るときはExamplesモジュールを参考にしよう 開発者がモジュール開発を行う際どのようなコードを書けば良いのかの例を示すDrupalのコントリビュートモジュールとして、Examples for Developersモジュールというのもが...

このブログでは今後もDrupalをはじめとしたWEB開発に関する記事を掲載していきますので、
ぜひお気に入り登録お願いします!!

目次