Drupal 8でテーマ開発をしよう(後編) ~いちからテーマを作ってみよう~

こんにちはスタジオ・ウミの大野です。

Drupal 8 が正式にリリースされてから早10ヶ月。利用したいモジュールもボチボチ揃ってきましたので、弊社でもようやく Drupal 8 を実案件に利用するようになってきました。

今回の記事はDrupal 8のテーマを一から作成するチュートリアルとなります。前回のブログの続きとなりますので、これから初めてDrupal 8のテーマを作られる場合は、本稿をご覧になる前にDrupal 8でテーマ開発をしよう(前編)~Drupal 7 からの変更点とテンプレートとテーマの違い~を見ていただいた方がより一層理解が深まると思います。

カスタムテーマを作る際にDrupal.orgに寄与されたテーマをカスタマイズして利用する方法もあると思いますが、今回はテーマの仕組みをちゃんと理解するために一からオリジナルのテーマを作成する方法を解説します。

本稿では以下の図のような、ヘッダー・サイドバー・コンテンツ・フッターを持った一般的なサイト構成となるテーマの作成を目指します。

目標のレイアウト

本稿ではumiexampleと言う名前でテーマを作成しますが、設定やディレクトリ名等は適宜変更してください。

開発中にDrupalのキャッシュ機能を無効化

Drupal 8ではに強力なキャッシュ機能が搭載され、テンプレートファイルもコンパイルされるようになりました。Drupal 7の時のようにテンプレートを変更しても即座に反映されません。変更の度に一々キャッシュをクリアをしなければなりませんので、開発中はキャッシュ機能が効かなくなるように設定します。(参考: Disable Drupal 8 caching during development)

/sitesディレクトリにあるexample.settings.local.php/sites/defaultディレクトリにsettings.local.phpという名前でコピーします。

cp sites/example.settings.local.php sites/default/settings.local.php

/sites/default/settings.phpにある以下の内容がコメントアウトされているので、コメントを解除し、ローカル用の設定ファイルを追加で読み込みます。

if (file_exists(__DIR__ . '/settings.local.php')) {
 include __DIR__ . '/settings.local.php';
}

次にコピーしたsites/default/settings.local.phpをテキストエディタで開き、以下の設定のコメントを解除し、キャッシュを無効化します。

67行目辺り:

$settings['cache']['bins']['render'] = 'cache.backend.null';

76行目あたり:

$settings['cache']['bins']['dynamic_page_cache'] = 'cache.backend.null';

sites/default/development.services.ymlのファイルを開き、以下の内容を記述してTwigのデバッグ機能を有効にします。

parameters:
 twig.config:
  debug: true
  auto_reload: true
  cache: false

上記でキャッシュ機能は無効になりましたが、他にも様々な設定がDrupalではキャッシュされます。基本的に.ymlを変更したりテンプレートが増減した場合はキャッシュのクリアが必要となります。環境設定 > パフォーマンスの管理画面で「すべてのキャッシュをクリアー」ボタンを押せばキャッシュがなくなるので、あれ?設定が反映されないなと言うことがあればまずはこのキャッシュを疑ってみてください。

 

テーマディレクトリの準備

Drupal 8ではインストールディレクトリ直下のthemesディレクトリに、新たなテーマ用ディレクトリを作って配置しますが、前回の記事でも触れたように独自のカスタムテーマはcustomというサブディレクトリを作って配置したほうが良いそうです。そこにumiexampleと言うディレクトリを作成してください。

/ (Drupalのインストールディレクトリ)
 └-- themes
    └-- custom
        └-- umiexample

.info.ymlファイルの作成

次にこれから作成するテーマの情報を書いた.info.ymlファイルを作成します。/themes/umiexampleディレクトリにumiexample.info.ymlという名前で、以下のようにYAMLフォーマットで書かれたテキストファイルを作成してください。

name: Umi example theme
type: theme
description: チュートリアル用のテーマです。
core: 8.x
base theme: classy
libraries:
  - umiexample/global-styling
regions:
  header: Header
  content: Content
  sidebar: Sidebar
  footer: Footer

Drupal.orgに投稿されているDefining a theme with an .info.yml fileの内容をもとに以下に設定項目を解説します。

name: Umi example theme

必須項目。人間が読むためのテーマの名称です。テーマの管理画面にて使用されます。

type: theme

必須項目。このumiexample.info.ymlで定義するものがテーマまたはモジュールであるかをDrupalに伝えるためにthemeと宣言します。

description: チュートリアル用のテーマです。

このテーマの説明を記入します。開発者以外が管理画面にアクセスするようなサイトの場合は記入しておくと良いでしょう。

core: 8.x

必須項目。このテーマがサポートするDrupalのバージョンを記入します。今回はDrupal8のテーマを作成するので8.xと記入します。

base theme: classy

推薦設定。このテーマの元のなるテーマを指定します。Drupalはテンプレートのオーバーライドの仕組みにより、このテーマ内に無いテンプレートはここで設定したベーステーマから読み込まれます。

ここでベーステーマとして設定しているclassyは、これまでのDrupal 7と同等以上の、一般的にスタイルを表現するには十分なクラスを付与したHTMLを出力します。このベーステーマが無いと、Drupalで出力されるHTMLには何もクラス等が付加されない素っ気ないHTMLが出力されます。Drupalをバックエンドのみでしか使わないなど、特殊な用途を除き何かしらのテーマをベーステーマとして指定することを強くお勧めします。

ちなみにコアに含まれるSevenやBartikのテーマもClassyをベーステーマとして設定しています。

version: 8.x-1.0

このテーマのバージョンを示します。特にバージョン管理をする必要があるテーマでなければ省略して良いでしょう。

libraries:
 - example/global-styling

librariesではテーマで使用するライブラリを指定します。フォーマットは-システム名称(テーマのディレクトリ名)/ライブラリ名となります。ここで設定するライブラリ名は次に解説する.libraries.ymlファイルにて定義します。

regions:
  header: Header
  content: Content
  sidebar: Sidebar
  footer: Footer

リージョンの設定です。DrupalではHTMLの要素を機能ごとにまとめた単位を「ブロック」と言い、そのブロックを配置するための領域のことを「リージョン」と呼びます。
Drupal上で表示される要素の殆どはブロックとして扱われます。Drupal 8からはサイト名やページタイトルに至るまで、ほぼ全ての要素がブロックとして扱われるようになりました。
今回はヘッダー、コンテンツ、サイドバー、フッター全てにリージョンを設定します。
リージョンは、regions:の次の行からリージョンキー:人が判断するための管理用ラベルのフォーマットで記入します。リージョンキーは半角英数字とアンダースコア(_)しか使用することができません。
その他にも設定項目はありますが基本的なテーマを作るには上記だけで問題ありません。
その他のプロパティについてはDrupal.orgのDefining a theme with an .info.yml fileをご覧ください。

.libraries.ymlファイルの作り方

このファイルはテーマで使用する「ライブラリ」を定義するファイルで、ここで言うライブラリとはCSSやJSの集合体のことをいいます。一般的なサイトであれば最低でもCSSは使用すると思いますので作成する必要があります。
/themes/custom/umiexampleディレクトリにumiexample.libraries.ymlというファイル名で以下の内容のファイルを作成してください。

global-styling:
 version: 1.x
 css:
   theme:
     css/styles.css: {}

設定項目について以下に解説します。

global-styling:

既にお気づきかもしれませんが、前項で解説したライブラリの名称です。ここで設定する名称は.info.ymlファイルと一致していれば好きなものにできますが、サイト全体で使用するライブラリは習慣的にglobal-stylingの名前が使用されています。

version: 1.x

ライブラリのバージョンを示します。今回のように独自で作ったライブラリであれば適当な値で問題ありません。

css:
  theme:
    css/styles.css: {}

ライブラリ(テーマ全体)として読み込むスタイルシートのファイルを定義しています。

theme:はDrupal 8から採用されたCSSのスタイルガイドSMACSSで定義されているルールの一つで、CSSをどのレイヤーに配置するかの指定となります。SMACSSの解説は長くなりますのでここでは省略しますが、とりあえずtheme:としておけば問題ありません。詳しく知りたい場合はDrupal.orgのCSS architecture(for Drupal 8)をご覧くだ
さい。
css/styles.css: {}の部分で、今回作成するテーマディレクトリ配下のcss/styles.cssのスタイルシートを読み込む定義です。ファイル名の横の{}は、スタイルシートの読み込む方法を指定する時に使用し、例えば外部のスタイルシートを読み込む場合は{type: external}と記述します。今回は特別な設定は不要なので中身を空のままにします。また、複数のスタイルシートを読み込みたい場合は、同じインデント量で追記していきます。

Drupalにテーマが認識されるか確認

.info.ymlファイルの用意ができたので、ここまでの工程でDrupalが新たに作ったテーマを認識するようになったはずです。テーマの管理画面へ行って確認してみましょう。

Drupal 8 テーマの管理画面

上記のスクリーンショットのように今回作成したテーマが表示されていれば成功です。早速ですが「インストールしてデフォルトに設定」のリンクを押して今回のテーマを適用してみましょう。この状態でフロントページへ戻るとレイアウトが崩れたような感じになると思いますが、新たに作成したテーマにCSSやテンプレートが適用されていないだけですので一先ずは問題ありません。

テンプレートファイルの作成

次にテンプレートファイルを作成しましょう。/themes/custom/umiexampleにテンプレートファイルを入れるためのディレクトリtemplatesを作成し、そこにpage.html.twigという名前で以下の内容のファイルを作成してください。

/themes/custom/umiexample/templates/page.html.twig:

<header class="header">
  {{ page.header }}
</header>

<section class="main">
  <div class="main-content">
    {{ page.content }}
  </div>
  <aside class="sidebar">
    {{ page.sidebar }}
  </aside>
</section>

<footer class="footer">
  {{ page.footer }}
</footer>

見慣れない{{ page.* }}と言うタグが出てきましたね。これはDrupal 8で採用されたTwigと言うテンプレートエンジン独自のタグです。タグ内の*の部分にumiexample.info.ymlファイルで定義したリージョンのキーを記述することで、その場所にリージョンが描画されるようになります。このリージョンに描画するブロックは後ほどDrupalの管理画面から行ないます。

CSSファイルを作成

umiexample.libraries.ymlで定義したCSSファイルを作成します。まずは/themes/custom/umiexampleにCSSファイルを入れるためのディレクトリcssを作成し、以下の内容のファイルを作成します。

/themes/custom/umiexample/css/styles.css:

.header,
.main-content,
.sidebar,
.footer {
  padding: 20px;
  position: relative;
}
.header {
  background-color: #efe;
}
.main {
  display: flex;
}
.main-content {
  background-color: #fee;
  width: 75%;
}
.sidebar {
  background-color: #eef;
  width: 25%;
}
.footer {
  background-color: #fff;
}

※今時のdisplay: flexを使用していますので古いブラウザでは崩れてしまいます。

ブロックの配置

初期状態だと以下のスクリーンショットのようにDrupalがブロックを適当に配置するためゴチャゴチャの状態になってしまっているかと思います。

Drupal 8 テーマ構築 ブロック整理前のレイアウト

一般的なサイト構成に近づけるため、以下のスクリーンショットを参考にブロックを再配置し、ブロックの保存ボタンを押してください。なお、使用しないブロックは後で復活させることができるので邪魔であれば削除しても大丈夫です。

Drupal 8 ブロック整理の画面

トップページへ戻り、以下の画面のように指定したリージョンにブロックが正しく表示されていれば完了です。

Drupal 8 ブロックを再配置した後の画面

いかがでしたでしょうか。開発の前準備が必要だったり、テンプレートエンジンにTwigを採用、ライブラリ、ブレイクポイントの設定などDrupal 7の時よりも開発の敷居が少し高くなってしまった感はありますね。一方でDrupal 8からはブロックの多重配置ができるようになり、ページタイトルやシステムメッセージまでもがブロック化されたので、より柔軟なレイアウトができるようになって便利になりました。みなさんも是非新しいDrupal 8にチャレンジしてみてください。

最後までご覧いただきありがとうございました。弊社スタジオ・ウミのブログでは様々な Drupal 関連の記事を掲載しています。Drupal 7 の記事の割合が多めですが、これから Drupal 8 関連の情報も随時公開していきますので、是非お越しください!