Drupal 8 でテーマ開発をしよう(前編) ~Drupal 7 からの変更点とテンプレートとテーマの違い~

はじめまして、スタジオ・ウミの大野と申します。さくナレには最初の投稿となりますので、まずは簡単な自己紹介をさせていただきます。

スタジオ・ウミは滋賀県の琵琶湖の畔で Drupal を専門としたウェブ制作会社です。これまでは関西や地元企業のお客様を主体に制作のお仕事をさせていただいておりましたが、今年の4月に東京にもオフィスを開設し、関東圏内でも活動させていただくようになりました。

私が Drupal を初めて触ったのがバージョン 4.7 の頃で、Drupal が好きで好きで他の CMS には目もくれず、今年で開発歴が10年目になってしまいました。私自身はまだエンジニアを自負していますが、社内ではデザイン以外の業務であればディレクションから開発まで、ケースに応じて殆どのことをしています。

本稿では Drupal.org の Theme folder structure の記事を参考に、テーマ開発をするにあたって前提知識として必要なテーマのディレクトリ・ファイルの構造と Drupal 7 開発者の視点で何が変わったのかを交えて解説します。

「テーマ」と「テンプレート」の違い

CMS によって「テーマ」や「テンプレート」の意味が同じだったりとゴッチャになってしまうことがありますが、Drupal で言うテーマとはテンプレートや JavaScript、CSS、テーマの設定、テーマ用の関数群全てをまとめたものをテーマと言います。フロントエンドに関わる全ての要素をまとめたものとも言えますね。一方でテンプレートファイルとはHTML に動的な要素を埋め込んで出力するための雛形となるファイルのことを指します。

Drupal ではテンプレートファイルが各種コンポーネントと言われるコンテンツの塊ごとに細分化されていますので、通常は変更したいコンポーネントのテンプレートファイルだけを上書きして開発します。以下の図は Drupal 8 をインストールした初期状態で、ページ内にどのようなテンプレートが使用されているかを表した図です。実際はもっと細かくテンプレートが分けられていいますが、代表的なものだけ抽出しています。

ページ内で使用されているテンプレート

ページ内で使用されているテンプレート

余談ですが、日本語だと Theme を「テーマ」と発音しますが、英語だと「シーム」と発音します。過去に弊社で働いていた外国人のスタッフに「テーマ」と言っても、全く通じなかったのでもし国外の方と喋る機会があればご注意ください(笑)

Drupal 7 との違い

Drupal 7 での開発に慣れ親しんだ方のために、テーマを開発する上で Drupal 7 と Drupal 8 で何が変わったのか、Drupal.org に投稿されている Theming differences between Drupal 6, 7 & 8 から抜粋して紹介します。

  • Drupal 6, 7 では XHTML が出力されていましたが、Drupal 8 ではデフォルトで HTML5 が出力されるようになりました。
  • Drupal 8 では jQuery 2.x が採用され、Modernizr や Underscore.js、Backbone.js などもコアに含まれ、標準で利用できるようになりました。
  • Drupal 8 ではデフォルトのテンプレートエンジンが、PHPTemplate から Twig に切り替わり、(初学者にとっては)よりシンプルかつ安全になりました。テンプレート内の記述方法は PHPTemplate とは大きく変わっています。
  • Drupal 8 ではパフォーマンスを重視するため、デフォルトで CSS と JavasScript の最適化オプションが有効になりました。テーマ開発をする場合は真っ先にこれらのオプションを管理画面から無効にする必要があります。
  • Drupal 8 ではテーマやツールバー、画像、テーブルがレスポンシブ対応になりました。ただし、これはコアに含まれているテーマや機能が対応していると言うことなので、新たにテーマを作る場合は個別に対応が必要です。
  • Drupal 6 や 7 では CSS または JavaScript を特定のページに適用する場合は drupal_add_css()drupal_add_js() を使用していましたが、これらの関数は廃止され利用できなくなりました。テーマで使用する CSS や JS は後述する .libraries.yml に全て「ライブラリ」として定義し、レンダー配列の #atttached プロパティに使用するライブラリを宣言したり、Twig のテンプレート内でライブラリを指定する必要があります。
  • Drupal 8 では HTML 5 / CSS 3 を前提とした jQuery 2.0 などを使用するため、 IE 6 から8 をサポートしなくなりました。
  • Drupal 8 では CSS の構造が SMACSS と BEM に基いて構成されるようになりました。
  • Drupal 8 では CSS 3 の擬似クラスが使用されるようになりました。Drupal 7 まではリストタグなどに li.evenli.odd などのクラスが追加されていましたが、それらが li:nth-of-type(even) の様な CSS の擬似クラスでスタイルされるようになりました。
  • コアのベーステーマとして Classy が用意されました。Classy は Drupal の標準的なクラスを各 HTML に追加するベーステーマです。Drupal 標準のクラスを使いたくないと言うケースを除き、この Classy をベーステーマとして開発することになります。
  • Druapl 8 では preprocess 関数で追加されていた CSS クラスが Twig のテンプレート内でコントロールされるようになりました。

いかがでしょうか。これまでの Drupal と比べると「お作法は似てるけど、より進化して殆ど別ものになった」と思った方がいいでしょう。Drupal 7 までは CSS / JS を追加したい場合は .info に書いておけば良い程度の感覚だったのですが、Drupal 8 ではそれらをライブラリとして認識して読み込まなければいけなくなったので、少し難しくなった感じがしますね。

テーマのディレクトリ

Drupal 7 まではテーマを sites/all/themes のディレクトリに入れることが推薦されていましたが、Drupal 8 ではディレクトリ構成が大幅に見直され、Drupal のルートディレクトリ直下の themes に入れることになりました。ちなみにコアのテーマファイルは core/themes に格納されています。

また、Drupal 開発者のあいだではダウンロードしてきたコントリビュートテーマを themes/contrib に、自分で作ったカスタムテーマは themes/custom ディレクトリに入れることがベストプラクティスのようです。

|-core
|  |-modules
|  |-themes
|  |  |-bartik
|  |  |-seven
..
|-modules
|-themes
|  |-contrib
|  |  |-zen
|  |  |-basic
|  |  |-bluemarine
|  |-custom
|  |  |-作成したカスタムテーマ

Theme folder structure より引用

テーマディレクトリの構造

以下の例は fluffiness と言う名前でテーマを作った場合の、一般的なディレクトリとファイルの構造です。

|-fluffiness.breakpoints.yml
|-fluffiness.info.yml
|-fluffiness.libraries.yml
|-fluffiness.theme
|-config
|  |-install
|  |  |-fluffiness.settings.yml
|  |-schema
|  |  |-fluffiness.schema.yml
|-css
|  |-style.css
|-js
|  |-fluffiness.js
|-images
|  |-buttons.png
|-logo.png
|-screenshot.png
|-templates
|  |-maintenance-page.html.twig
|  |-node.html.twig

Theme folder structure より引用

.yml ファイルとは?

Drupal 7 までの開発者にとってはあまり見慣れない .yml 形式のファイルが多くありますね。このファイルはテキスト形式で構造化されたデータを表現するためのフォーマットです。Drupal 7 までの .info 内で使われていた形式や XML、JSON に較べると読みやすく、書きやすいことが特徴です。

*.info.yml

テーマには テーマ名.info.yml と言う名前のファイルを必ず設置する必要があります。このファイルにテーマの基本情報やライブラリ、ブロックのリージョン情報などを定義します。

*.libraries.yml

テーマで使用する CSS や JavaScript を定義するファイルです。

*.breakpoints.yml

異なるデバイス同士でどのような条件で切り替えるか判断するためのブレークポイントを定義するファイルです。ここで定義されたブレークポイントは Responsive image style モジュールなどで利用されます。

*.theme

Drupal 7 までの template.php に該当するファイルです。このファイルは PHP で書かれており、フロントエンド側へ出力するデータを変更したい場合に、このファイルへ Drupal のフックを書いて書き換えます。

css/

CSS ファイルを置くための推薦サブディレクトリです。使用する CSS ファイルは前述の .libraries.yml で定義する必要があります。

js/

JavaScript ファイルを置くための推薦サブディレクトリ。CSS と同様に .libraries.yml への記述が必要です。

images/

画像ファイルを置くための推薦ディレクトリです。

screenshot.png

テーマディレクトリ内に screensho.png のファイルが在ると、Drupal のテーマ管理画面でこの画像が表示されます。.info.yml ファイルで別のものを指定することも可能です。

logo.svg

テンプレートファイルの作り方にもよりますが、logo.svg がテーマディレクトリ内にあるとウェブサイトのヘッダー部分に表示されます。なお、ロゴは テーマ > 設定 からアップロードすることが可能です。

templates/

テンプレートファイル *.html.twig を入れるためのディレクトリです。Drupal 7 まではテーマディレクトリ以下であれば自由にテンプレートファイルを配置することができましたが、Drupal 8 では この templates ディレクトリに入れることが必須となりました。

後編では今回解説した内容をもとに、実際に一からテンプレートを作成してみたいと思います。

後編はこちら >