目次

まえがき
第1章 settings.php探訪
1.1 コードリーディングのすすめ
1.2 ローカル開発環境とエディターを用意しよう!
1.3 オススメの読み方
1.4 Drupalのディレクトリー構造
1.5 サイト固有の設定ファイル
1.6 まとめ
第2章 Webformをアンケート収集に活用しよう
2.1 この章でできること
2.2 Webformでアンケートの作成
2.3 Viewsでアンケートの結果表示
2.4 スパム対策
2.5 おわりに
第3章 Feedsモジュールの活用とDrupalから記事配信まで
3.1 Drupalマルチサイトの構築
3.2 ViewsからCSVを出力
3.3 FeedsモジュールでCSVをインポート
3.4 export_xmlモジュールの適用
3.5 おわりに
第4章 Geofieldモジュールで位置情報を可視化
4.1 Geofieldモジュールとは
4.2 オープンデータについて
4.3 おわりに
第5章 Drupalで理解するOAuth 2.0
5.1 Web APIの認証認可
5.2 OAuth 2.0とは
5.3 Simple OAuth (OAuth2) & OpenID Connectモジュールとは
5.4 Simple OAuthの設定方法
5.5 OAuth 2.0を使ってAPIリクエストを試そう
5.6 OAuth 2.0を使ってAPIリクエストを試そう(Postman編)
5.7 アクセストークンのデバッグ
5.8 おわりに
第6章 インストールプロファイルを作ってみよう
6.1 準備
6.2 既存サイトの構成をそのまま利用する
6.3 インストールプロファイルの作成
6.4 コンテンツを含める
6.5 まとめ
第7章 Drushの独自コマンドを作ってみよう
7.1 はじめに
7.2 モジュールの作成
7.3 Drushコマンドの追加
7.4 Xdebugでコードを追跡する
7.5 サービスの利用
7.6 サービスを利用したDrushコマンドの実装
7.7 おわりに
あとがき
著者紹介

まえがき

丸山 ひかる

 本書をお⼿に取ってくださり、ありがとうございます。Drupal Meetup 豊田のメンバーで、3冊目のDrupal書籍を発行することができました。最初のきっかけは「技術書典にDrupal本がないから、自分たちで作ろう!」から始まったことがここまで継続するとは、当初は考えられませんでした。これもひとえに、本を購入し、読んでくださる読者の皆様のおかげです。

 今回も、Drupal LOVEな7名のメンバーのとっておきのレシピを1冊にまとめ上げました。最後までごゆっくりとお楽しみいただけたら幸いです。

本書の流れ

 Drupalをインストールして簡単なサイトを作ったことがあるDrupalビギナーを想定として、

 ・settings.php探訪

 ・Webformをアンケート収集に活用しよう

 ・Feedsモジュールの活用とDrupalから記事配信まで

 ・Geofieldモジュールで位置情報を可視化

 ・Drupalで理解するOAuth 2.0

 ・インストールプロファイルを作ってみよう

 ・Drushの独自コマンドを作ってみよう

 といった、Drupalをもっと深く使っていくためのトピックスを取り上げています。

 各章の末尾には4コマ漫画も時折登場しますので、肩に力を入れず、ぜひ楽しみながら内容の理解を深めていただけたらと思います。

 本書のタイトルが「Drupal 9 おいしいレシピ集 2」となっているように、各章は今すぐ使える実践的なテクニックが、それぞれ独立した1章完結のオムニバス形式の構成となっています。すべての章を順番に読んでいただいても、お好きな章から読んでいただいても大丈夫です。著者それぞれに思い入れのあるトピックを選んで書き上げた渾身の一冊ですので、最終的にはぜひすべての章に目を通していただけたら幸いです。

前提とする知識

 本書を読むにあたり、次のような知識があるとより理解が深まります。

 ・Drupalの基礎知識

 ・Linux コマンドの基礎知識

 ・WordPress、concrete5、Joomlaなどの他CMSの利用経験

 ・Web開発の基礎知識

 まだDrupalを触ったことがないという場合には、ぜひ既刊の商業誌「Drupal 9 Web開発ことはじめ」(株式会社インプレスR&D)1と併せて、お手に取っていただけましたら幸いです。Drupalの概要から基本まで丁寧に解説していますので、一緒に読んでいただけると、理解がより一層深まることと思います。

 また、所々、既刊の「Drupal 9 おいしいレシピ集」(株式会社インプレスR&D)2で取り上げた内容を参照する部分もあります。まだお読みになっていない方は、こちらもぜひご一読いただけると幸いです。

ソフトウェアバージョンおよび動作環境

 本書は執筆時点の最新版Drupal 9.3.xにて動作確認を行っています。各章のトピックに固有なソフトウェアおよびハードウェアの要件については、章内の本文にてご確認ください。

謝辞

 同人誌・商業誌を手に取ってくださり、SNSやMeetupをはじめとして、各所でお寄せてくださったご意見・ご感想が執筆の原動力となっています。今回も執筆を応援してくださった方々に、この場を借りて心より感謝を申し上げます。

 そして、これまでDrupalをよりよくするために様々な形で貢献してくださった世界中の方々に、心より感謝を申し上げます。こうして私たちがDrupalと出会い、同人誌を執筆できているのも、今までに貢献してくださった方々の足跡があってこそです。本当にどうもありがとうございます。

 本書は、Drupal Meetupに集まっているコミュニティーメンバーで執筆し、相互に原稿のレビューを行いました。普段のお仕事がある中で、貴重な時間を捻出しながら執筆活動にコミットしてくださったことは、きっと今後のDrupalの発展に寄与するものと思います。末筆ではありますが、各執筆メンバーのDrupalに対する貢献という不断の努力に感謝いたします。

底本について

 本書籍は、技術系同人誌即売会「技術書典12」で頒布されたものを底本としています。

1. https://www.amazon.co.jp/dp/B0922326NR

2. https://www.amazon.co.jp/dp/B09NBN6934

第1章 settings.php探訪

本章では、サイト固有の設定ファイルであるsettings.phpを読み進めながら、一緒にコードリーディングを擬似体験します。

小松 高廣

1.1 コードリーディングのすすめ

 みなさんはコードを読むことが好きですか?

 「はい、好きです。」と胸を張って言える人には、この章はあまり役に立たないかもしれませんが、「うーん...」と少しでも考えてしまった人にとっては、本章が何かのきっかけになるかもしれません。

 世の中には様々なプログラミング言語で書かれた、非常に膨大な量のソフトウェアが存在しています。Drupalは、GPLv2以降のライセンス1で配布されているOSS(オープンソース・ソフトウェア)で、その一番のメリットは何といっても「ソースコードを読もうと思ったら読めること」だと筆者は思っています。2

 どんな作品であろうと「できあがった完成作品を五感で堪能して、その機能や美しさに感動する」という楽しみ方があります。一方で、人(あるいは機械)が作品を作っている過程を見る、アイデアや思考プロセスが映し出された設計図を見る、作る行為や思考を自分で再現(トレース)してみる、といった楽しみ方もあります。

 料理でたとえるならば、お店へ行ってシェフが作るおいしい料理に舌鼓を打つ、という楽しみ方だけでなく、料理番組やレシピを見てみる、自分でレシピに沿って作ってみる、というのも料理の楽しみ方のひとつです。

 ふと、本から目を上げて自分の周りを見渡してみると、目に映るありとあらゆる人工物は、ひとつひとつすべて誰かが設計し、作り上げたものであることに気づきます。世の中の誰かが作りたいものを発想し、作り方を考え、原材料を採掘し、加工して作り上げる。そして、いろんな流通経路をたどる、というプロセスを経て、最終的にやっと自分の目の前にやってくる。そこに至るまでの膨大な時間や労力に思いを馳せると、人類の叡智による営みにただただ圧倒されます。

 ソフトウェアであれ、ハードウェアであれ、それらの人工物を作るための背後には、ソースコードやレシピ、回路図、楽譜、原稿、原画、型紙、原型、金型など、作り手が時間とお金を費やして作り上げた努力の結晶とも言うべき設計図3が存在しています。

 普段使っているデバイスのソフトウェア(たとえば、パソコンやスマホのOSや電子機器のファームウェアなど)は、必ずしもすべてのソースコードが公開されているわけではなく、残念ながら読むことができないものも多いです。そして、そういったソフトウェアにもし何らかのバグがあった場合、ユーザーとしては製造メーカーが直してくれるまで待ち続ける必要があります。

 でもOSSの場合、直そうと思えば、自分でソースコードを読み、そのバグを直すことができます。そして、必要があれば、自分でコードを書いて機能を追加し、それを使う自由が与えられているのも、OSSの魅力です。

 OSSのソースコードを読んでいると、コメントや変数名のスペリングミスにもよく出会います。そういったところを見かけると、筆者はコードを書いた人にとても人間味を感じてしまいます。

 OSSは世界中のコントリビュータが作り上げ、寛大な心で利用を許してくれている人類共通の財産です。そんな人類の叡智が詰まったソースコードがオープンになっているにもかかわらず、それを読まないことはすごくもったいないです。ソースコードを読むことは、何も「よーし、これからがんばって読むぞ!」と気合いを入れて行うのではなく、本を読んだり、テレビを見たり、SNSを確認するのと同じぐらいの軽い気持ちで行うと長続きします。まずはコーヒーを入れて、気軽にブラウザーやテキストエディターを開き、ソースコードを読むことから始めてみましょう。

 息を吸うようにソースコードを読むコツ、それは「自分が読もうと思った瞬間に、すぐ読める環境を整えること」です。

 DrupalのソースコードはGitリポジトリーhttps://git.drupalcode.org/project/drupalで管理されています。まずはこのURLをブラウザーで開いてみましょう。

 どうでしょう?開いてみましたか?

 では、このサイトをブラウザーにブックマークして、いつでも読めるようにおきましょう。ついでにSNSにURLも投稿しておけば、ふと次に気が向いたときにコードを読む自分へのリマインダにもなります。

1.2 ローカル開発環境とエディターを用意しよう!

 単にDrupalのソースコードを読むだけであれば、ブラウザーからでも十分可能です。しかし、ソフトウェアなので、やっぱりコードを動かしてみたくなります。料理の場合、レシピを読むだけではなく、レシピ通りに自分でも作ってみると、レシピに書かれている内容や意図をより深く理解できます。同じように、コードも読みながら実際に動かしてみると、コードを書いた人の気持ちや意図が少しずつわかってきます。それがコードリーディングをもっともっと楽しくするための秘訣です。

 本章執筆時での筆者オススメのDrupal向けローカル開発環境は、Lando4またはDDEV-Local5です。

 どちらもDrupalが動作するために必要なLAMP(Linux/Apache/MySQL/PHP)環境を手元のPC内に簡単に構築できるソフトウェアです。今回は、Landoを使ってみます。6

 Landoの導入については、公式ドキュメント7を参考にしながら、ご自身のCPUおよびOSに適したインストーラーをダウンロードして導入してみてください。

 また、macOSを利用している人は、以下のコマンドでHomebrewおよびComposerをインストールしておきましょう。

% cd ~/

% /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

% brew install composer

それでは、Landoを使ってDrupalが動作するプロジェクトを作成してみます。

% cd ~/

% composer create-project drupal/recommended-project drupal

% cd drupal


% lando init --source cwd --recipe drupal9 --webroot web --name my-lando-app


? From where should we get your app's codebase? current working directory

? What recipe do you want to use? drupal9

? Where is your webroot relative to the init destination? web

? What do you want to call this app? my-lando-app


Your app has been initialized!


Go to the directory where your app was initialized and run lando start to get rolling.

Check the LOCATION printed below if you are unsure where to go.


Oh... and here are some vitals:


 NAME      my-lando-app

 LOCATION  /Users/takahiro/drupal

 RECIPE    drupal9

 DOCS      https://docs.lando.dev/config/drupal9.html

ここでDrupal 9.3.0から正式対応したPHP 8.1を使うように、Landoの設定ファイルに追記します。

% vi .lando.yml

name: my-lando-app

recipe: drupal9

config:

  php: 8.1

  webroot: web

Drupalのインストール時に必要なデータベースの情報は、以下のように確認できます。

% lando info

[ { service: 'appserver',

    urls: [ 'http://my-lando-app.lndo.site/', 'https://my-lando-app.lndo.site/' ],

    type: 'php',

    healthy: true,

    via: 'apache',

    webroot: 'web',

    config: { php: '/Users/takahiro/.lando/config/drupal9/php.ini' },

    version: '8.1',

    meUser: 'www-data',

    hasCerts: true,

    hostnames: [ 'appserver.mylandoapp.internal' ] },

  { service: 'database',

    urls: [],

    type: 'mysql',

    healthy: true,

    internal_connection: { host: 'database', port: '3306' },

    external_connection: { host: '127.0.0.1', port: true },

    healthcheck: 'bash -c "[ -f /bitnami/mysql/.mysql_initialized ]"',

    creds: { database: 'drupal9', password: 'drupal9', user: 'drupal9' },

    config: { database: '/Users/takahiro/.lando/config/drupal9/mysql.cnf' },

    version: '5.7',

    meUser: 'www-data',

    hasCerts: false,

    hostnames: [ 'database.mylandoapp.internal' ] } ]

service: 'database' 以降がデータベース接続に関する項目で、internal_connectionおよびcredsの情報を後ほど使用します。それでは、Drupalを動作させるための各サーバーを起動してみましょう。8

% lando start

Let's get this party started! Starting app my-lando-app...

Starting landoproxyhyperion5000gandalfedition_proxy_1 ... done

Starting mylandoapp_appserver_1 ... done

Starting mylandoapp_database_1  ... done

Scanning to determine which services are ready... Please standby...


Your app has started up correctly.

Here are some vitals:


 NAME            my-lando-app

 LOCATION        /Users/takahiro/drupal

 SERVICES        appserver, database

 APPSERVER URLS  https://localhost:63403

                 http://localhost:63404

                 http://my-lando-app.lndo.site/

                 https://my-lando-app.lndo.site/

次に、手元にあるテキストエディター(またはIDE)で、Drupalのソースコードを開いてみましょう。テキストエディターも、世の中には本当に多種多様なものがあります。最近は Visual Studio CodeAtomPhpStormなどが人気ですが、ご自身が好きなものを使ってください。9

 PHPに対してシンタックスハイライトが効くと、構文や変数が見やすくなるので、もっとコードを読むのが楽しくなります。もしシンタックスハイライトが有効化されていないテキストエディターであれば、設定や拡張機能を確認してみてください。

1.3 オススメの読み方

 では、試しにブラウザーがサイトへアクセスした際に、最初に実行されるdrupal/web/index.phpを見てみましょう。

リスト1.1: index.php

% cat ~/drupal/web/index.php
<?php

/**
 * @file
 * The PHP page that serves all page requests on a Drupal installation.
 *
 * All Drupal code is released under the GNU General Public License.
 * See COPYRIGHT.txt and LICENSE.txt files in the "core" directory.
 */

use Drupal\Core\DrupalKernel;
use Symfony\Component\HttpFoundation\Request;

$autoloader = require_once 'autoload.php';

$kernel = new DrupalKernel('prod', $autoloader);

$request = Request::createFromGlobals();
$response = $kernel->handle($request);
$response->send();

$kernel->terminate($request, $response);

...あまりに抽象化されたコードで、そしてコメントもほとんどないため、正直なところ読んでいても全く親近感が湧かないのではないかと思います。

 Drupalは多くのエンジニアによって書かれた非常に膨大なコードの集積により作られている10ため、メリハリをつけて読まないと、時間がいくらあっても足りなくなりそう11というのは容易に想像がつきます。

 DrupalはSymfonyフレームワークをベースに開発されているので、そのコードは抽象化されている部分も多いです。ですので、Drupalのコードリーディングに関していえば、index.phpから順に読み進めるよりも、もっと身近な設定ファイルなどから読み始めるのがいいと思います。

 筆者がコードリーディングをするときのオススメの読み方は、「まず全体を見て、どんな区画に分かれていて、そこに何が書かれているかを意識して読み始める」というアプローチです。12

 本でいえば「まず本の章構成を意識しながら目次を読む」ということに該当するでしょう。まずは大枠を掴むことができる地図を自分で作ることから始め、それから少しずつ自分の興味が持てるところを読み進めると、徐々に「ここ、前に見たことがある!」と安心できる空間を広げていくことができます。

 もちろん本当に重要なコードであれば、2周目、3周目と読む機会は必ずやってきます。そして、そのときになって、さらにじっくりと時間をかけて深く読み進めればよいです。いずれ理解としての点と点がつながって、線となる瞬間がやってきます。

 最初はあまり気負って精読するのではなく、まずは少し俯瞰してから、森の探索に向かいましょう。

1.4 Drupalのディレクトリー構造

 それではコードリーディングのはじめの一歩として、まずはDrupalにおけるサイト固有の設定ファイルsettings.phpを一緒に探訪してみたいと思います。

 さっそくsettings.phpの中身を見ていきましょう!...といいたいところですが、そもそもsettings.phpは一体どこにあるのでしょうか?まずは、テキストエディターでsettings.phpの在りかを探してみましょう。どうでしょう?見つかりましたか?

 前節のように、composerコマンドでdrupal/recommended-projectパッケージを利用してプロジェクトを作成した場合、drupalプロジェクトのディレクトリーおよびファイル構造はリスト1.2のようになっています。13

リスト1.2: drupal/recommended-projectパッケージのディレクトリーおよびファイル構造

drupal/
|-- composer.json
|-- composer.lock
|-- example.gitignore
|-- vendor
|   |-- autoload.php
|   `-- composer
`-- web
    |-- index.php
    |-- autoload.php
    |-- update.php
    |-- core
    |   |-- profiles
    |   |-- themes
    |   `-- modules
    |-- profiles
    |-- themes
    |-- modules
    `-- sites
        |-- default
        |   `-- default.settings.php
        |-- example.settings.local.php
        `-- example.sites.php

実は、Drupalをダウンロードした段階では、settings.phpはそもそも存在していません。でも、なんだか似た名前のファイル drupal/web/sites/default/default.settings.php という名前のファイルがありますね。実はDrupalをインストールすると、このファイルを雛形にしたsettings.phpが同じ階層に生成されます。

 なので、まずは先に、Drupalをインストールしてみましょう。もう一度

% lando info

を実行してみてください。そして、service: 'appserver' のurlsに書かれたURLに対して、どれか好きなものにブラウザーでアクセスしてみてください。ブラウザーによってはTLS証明書のエラーが出てしまうかもしれませんが、今回はテストなので、そのまま進めてアクセスして大丈夫です。

 インストール時に唯一注意が必要なのは、先ほど確認したデータベース接続情報を入力する画面です。「データベース名」「データベースのユーザー名」「データベースのパスワード」に対しては、すべて共通のdrupal9を入力します。「高度なオプション」の「ホスト」項目に対して、先ほどコマンドlando infoで確認した際にservice: 'database'のinternal_connectionに書かれていたホスト名databaseを入力します。

 ここで、ソースコードや付随するドキュメントを読んでいく上で、押さえておきたいDrupalの用語・概念をいくつかご紹介します。

ドキュメントルート(document root/docroot)

 ブラウザーがアクセス可能なHTTPサーバーの公開ディレクトリーで、index.phpが存在している場所です。HTTPサーバーの設定ファイル内で、ドキュメントルートとして指定する14ディレクトリーです。リスト1.2では、ディレクトリー drupal/web/ になります。

コードベース

 開発時にGitリポジトリーで管理するコードの一式です。リスト1.2では、ディレクトリー drupal/ 以下にあるすべてになります。必ずしもすべてのディレクトリーやファイルをGitリポジトリーにコミットする必要はないため、drupal/web/example.gitignoreを参考にして

% cp example.gitignore .gitignore

のようにファイルをコピーして、必要なものだけをGitの管理対象としてください。15

サイト

 Drupalでサイトを作るときに必要な要素として、以下のものがあります。

 ・コードベース(codebase)

 ・データベース(database)

 ・構成(configuration)

 ・ファイル(files)

 ・URL

コードベースには、Drupalコア、テーマ、モジュールが含まれます。基本的にひとつのサイトには、上記に挙げた要素をサイトごとにそれぞれひとつずつ用意して、独立したサイトとして作ることが多いです。

 一方、Drupalにはマルチサイトという機能もあります。マルチサイトはさきほど挙げた要素のうち、「各サイトのコードベースを可能な限り共有して、複数のサイトを効率よく管理する」というものです。16

 テーマおよびモジュールは、マルチサイトの各サイトで個別のものを利用することが可能ですが、マルチサイトの趣旨を考えると、モジュールを共通化できる性質のサイト群をマルチサイトとしてまとめ、構築・運用するのがいいプラクティスだと思います。

1. https://www.drupal.org/about/licensing

2. もちろんソースコードを読めるからこそ、自分でソフトウェアを改変したり、それを他者へ再配布するなど、ライセンスで許されている範囲内で、本当にいろんなことが自由にできます。

3. ハンドメイドの一品物やアドリブでの演奏など、その場でのみ作られる一回性のものは、他者へ伝達して再現することを意図していないので、何らかの記録を残すことはあっても、設計図を作るという行為自体がそもそも存在しないでしょう。

4. https://lando.dev

5. https://ddev.com/ddev-local/

6. DDEV-Localの導入方法は「Drupal 9 Web開発ことはじめ」の第2章「Drupalのローカル開発環境構築」も参考にしてください。

7. https://docs.lando.dev/basics/installation.html

8. もしLandoの操作が一通り終わり、各サーバーを終了させる場合にはコマンドlando destroy -yを入力してください。

9. ちなみに筆者は Vim が好きです。

10. Drupal 9.3.12のソースコードを cloc で簡易的に計測してみたところ、総コード行数(空行やコメント行を除く)は約98万行もありました。

11. 1行を読むのに10秒かかると仮定して、1日8時間のペースで読み続けたとしても、約340日かかります。

12. 筆者は回路図や分解した電子機器の基板も同様の視点で眺めるのが大好きです。

13. ソースコードの展開方法によってディレクトリーおよびファイル構造には若干の差異があります。また、本章の焦点ではないディレクトリーやファイルは記載を省いています。

14. たとえば、Apache httpdの場合にはDocumentRootディレクティブ、NGINXの場合にはrootディレクティブで指定します。

15. くれぐれも重要な設定情報や秘匿情報を誤ってGitリポジトリーにコミットしないように注意してください。

16. データベース内のテーブルをうまく切り分けることで、ひとつのデータベースを各サイトで共有することも技術的には可能です。しかし、障害発生時の影響範囲が広くなること、パフォーマンスのチューニングやマイグレーション時の煩雑さ、などを考慮すると、素直にデータベースは各サイト間では分離しておくのがいいプラクティスだと思います。

試し読みはここまでです。
この続きは、製品版でお楽しみください。