Drupalの紹介

DrupalGNU GPL ライセンスのもとで利用可能なコンテンツマネージメントシステム(CMS)です。商用・非商用を問わず、無料で利用することが出来ます。
日本では、XOOPS, Movable Typeを利用したサイト構築事例が増えておりますが、海外に目を向けると、Drupalの利用が急速に拡大してきており、今後日本で最も普及が見込まれるオープンソースCMSです。

Drupalの主な特徴

軽量
シンプルな構造のコアモジュールと必要に応じて追加する拡張モジュールによって構成され、サイト構築に必要な機能のみを選択する事によって、軽量でレスポンスの良いサイトを構築する事が出来ます。

SEO対策に最適
XHTMLとCSSでレイアウトされた検索エンジンと相性の良いコンテンツが出力されます。

RSS出力対応
これからのホームページには欠かせない機能となってきたRSS出力に対応しています。

高度なコンテンツ分類機能
コンテンツを階層的に構成したり、自由にタグ付けするなど多彩な分類・表示が可能です。

機能拡張/変更が容易
システムが統一的なAPIで構築されている為、わずかなカスタマイズでシステム横断的な機能変更を行う事が出来ます。

コンテンツフィールドの拡張が容易
拡張モジュールを追加する事により、商用CMSなみのフィールド拡張性を持たせる事が出来ます。

Drupalについてのコラム

こちらのページではDrupalについての雑多なお話をまとめたいと思います。

Drupal in one picture

2009年1月時点のDrupalの現状を1枚の画像で表してみました。
(画像をクリックすると拡大表示されます。)

Drupal in one picture: Drupalを1枚の画像でまとめ
Drupal in one picture:

尚、この画像は情報整理の為に個人的に作成したものであり、偏った内容、間違っている情報もあるかもしれないという点については、予めご了承ください。

コンテンツ管理の変遷

Drupalの今後を占う上で役に立つかも知れないので、コンテンツ管理の部分でDrupalがこれまでどのように進化してきたかをまとめておきたいと思います。(筆者は4.6からしか使用していない為、4.6以降についてのみ記述します。また筆者の経験を元に記述しているため、偏見も多く含まれている事をご了承下さい。)

コンテンツ定義方法と表示カスタマイズ手段の変遷

Drupalコア
バージョン
コンテンツ
定義
コンテンツ集約表示 備考
4.6 各モジュール,
Flexinode
各モジュール独自出力 -
4.7 各モジュール,
Flexinode, CCK
各モジュール独自出力,
Views
CCK登場
5.x CCK Views CCKの一部機能がコアに含まれ、自由にコンテンツタイプを定義出来るようになる
6.x CCK Views2 Views2でコンテンツを明示的に結合し出力可能になる
7.x CCK? Views? フィールド管理機能がコアに組み込まれる

Flexinode

Drupal4.6当時、独自のコンテンツタイプを使用する場合は、既存のモジュールをコピーして新たにモジュールを開発するか、またはFlexinodeというモジュールを使用していました。
このモジュールは、CCKの原型となったモジュールで、日付型やセレクトボックスなどのフィールドを追加し独自の入力フォームを作成出来る当時としては画期的なモジュールだったと思います。

CCKの登場

非常に便利だったFlexinodeですが、大きな欠点がありました。
それはデータベースのテーブル設計上の問題で

  • 多くのコンテンツを取得/表示する場合は、パフォーマンスが低下する。
  • より複雑なフィールド型を追加しずらい。

という点です。既に多くのサイトで使用されていたFlexinodeにおいて根本的な設計変更を行う事は困難だったため、それらの欠点を改善すべく、拡張性を持つ設計で、かつパフォーマンスの問題も改善した新たなモジュールCCKが開発されました。Drupal4.7当時は、使い慣れたFlexinodeがあるのにどうして同じようなモジュールが必要なのかという議論もありましたが、次第にその利点が認知されてゆきます。
flexinodecck.gif

CCKの一般化とフィールド定義モジュールの拡大

Drupal5.xでCCKの一部の機能がコア機能として取り込まれた事により、CCKがより一般的に認知され、CCKで追加可能なフィールドを定義する拡張モジュールが急速に増加しました。その影響により、これ以前は

  1. 拡張モジュールを追加
  2. 拡張モジュールの設定変更
  3. 拡張モジュールの表示をカスタマイズ

として新たな機能を追加していたワークフローが、この頃からは、

  1. CCKのフィールド定義モジュールを追加
  2. CCKで新たなコンテンツタイプを定義
  3. Viewsモジュールでコンテンツ表示またはブロック表示のビューを作成

という流れに変わってきます。これにより、Viewsモジュールの重要性、利便性がより広く知られるようになりました。
cckviews.gif

Views2の登場

Viewsの機能を発展させたViews2は、複数のコンテンツのリレーションを明示的に指定する事が可能になり、より複雑なデータ構造もプログラム開発なしで集約表示出来るようになりました。(開発者の方は、SQL文で複数テーブルのJOIN条件を指定出来るようになったと思えば理解しやすいと思います。)

フィールド管理機能がコアに

Drupal7.xではフィールド管理機能がコア機能(API)として取り込まれる事が決まっています。その結果、ユーザアカウントのようなノード以外の情報も自由にフィールドを拡張する事が可能になります。1
またコア管理対象の最小単位がフィールドとなる為、CCKが一般化した時と同様にフィールド管理機能の拡張を目的とした拡張モジュールが多く開発される事になるかもしれません。
「すべてのコンテンツはノードである。」
という言い方をよくされるDrupalですが、7.x以降はノードだけが特別なオブジェクトではなくなりますので、
「すべてのDrupalオブジェクトはフィールドで構成される」
となるかも知れませんね。
corefield2.gif

16.x以前でもprofileモジュールによってユーザアカウントフィールドを拡張する事は可能ですが、profileモジュールもFlexinodeモジュール同様にDB設計上の問題を抱えています。

参考にしたサイト一覧

Drupalコーディング規約

こちらの情報は、 Drupal日本語プロジェクト の以下のページに移しましたので、そちらをご参照下さい。

Drupalコーディング規約

テーマ作成ガイド

Drupalテーマ作成方法の一例をご紹介致します。
特に断りがある場合を除き、コアシステムは Drupal5.x 、テンプレートエンジンは PHPTemplate を前提とします。またDrupalの基本操作についてある程度習熟している方を読者として想定していますので、基本操作の詳細については割愛させて頂きます。

尚、筆者も未だ学習中の身である為、誤りや偏った記述などの不備が多々あると思いますが、その点については予めご了承の上、お気づきの点がございましたら お問い合わせページ からお知らせ頂けましたら幸いです。

テーマファイルの準備

テーマを作成する方法として、自分で製作したXHTMLファイルにDrupalで使用可能な変数を埋め込んでゆく方法と、既存の公開されているテーマをカスタマイズしてゆく方法が考えられますが、ここではより簡単な後者の方法を説明します。

作業手順

  1. http://drupal.org/project/Themes から変更元とするテーマをダウンロードします。例として癖が少なくカスタマイズに適している Zenテーマ を使用します。
  2. ダウンロードしたファイルを解凍し、ご自身の1テーマファイル保存ディレクトリにディレクトリごとアップロードします。
  3. 管理者IDでログインし、zenテーマを有効にします。
  4. テーマ確認用のテストユーザを新規に作成し、アカウント情報変更でそのユーザの初期テーマをzenテーマに設定します。
  5. 作成したテストユーザでサイトにログインし、zenテーマが表示される事を確認します2

ZENテーマに含まれるファイル

ファイル名 役割
page.tpl.php ページ全体を定義する
style.css テーマが使用するスタイルシート
template.php テーマエンジンの機能を置換する
forum-node.tpl.php フォーラムノードの表示定義
node.tpl.php デフォルトノードの表示定義
comment.tpl.php コメントの表示定義
box.tpl.php メイン表示部のボックス表示定義
block.tpl.php サイドバーブロックの表示定義
screenshot.png テーマの画面イメージ
favicon.ico テーマのFaviconファイル

各テンプレートファイルの表示範囲

各テンプレートファイルで定義される領域を識別表示すると、以下のようになります。

下記の図からもわかるようにpage.tpl.phpで全体の構成を定義し、その中にnode.tpl.php3、block.tpl.php、comment.tpl.php、box.tpl.phpが含まれる構成となります。
ブロックやノードが複数表示される場合はテンプレートで記述された内容が複数回表示される事にご注意下さい。
テンプレートファイルによる画面定義範囲
テンプレートファイルによる画面定義範囲

コメント表示時は、comment.tpl.phpがテンプレートとして使用される。
コメント表示テンプレート
コメント表示テンプレート

box.tpl.phpはメイン表示領域を識別表示する際に使用される。
box.tpl.php
box.tpl.php

Drupalテーマシステム

テーマのカスタマイズに先立ち、Drupalテーマシステムについて簡単に説明しておきます。(開発者以外は関心の薄い話題かもしれないので、興味のない方はこのページは読み飛ばして下さい。)

テーマシステムの概要
テーマシステムの概要

Drupalテーマシステムの主な特徴

  1. テーマシステムサービスはAPIによって実装されています。(以降、テーマAPIと呼びます)。
  2. テーマAPIの処理内容は、各テーマごとにオーパーライド(置換)可能です。1
  3. *.tpl.phpファイルにxhtmlページやxhtmlタグなどのデザイン要素を定義し、プログラムとデザイン要素を分離しています。(MVC構造)

Drupalでは、基本的にどんなモジュールであってもテーマAPIを利用してデータ出力を実装している為、その処理内容を変更する事によりサイト全体のデザイン変更を行う事ができ、またテーマAPIの処理を各テーマごとに変更する事によって、テーマごとにまったく異なったページ構成・表示にする事が出来ます。

使用可能な変数

まず最初にサイト構築の中心となるページテンプレート(page.tpl.php)の編集を行います。
page.tpl.phpでは、初期状態で以下の変数1を使用する事が出来ます2

変数名 内容 備考
$breadcrumb パンくずリスト ページナビゲーションに使用
$closure ページの最後に出力するJavascriptなど ページの最下部で出力する
$content HTMLコンテンツ  
$feed_icons フィード出力用リンク  
$footer_message フッタメッセージ 管理画面で設定
$head HTMLヘッダ HTMLヘッダ領域に出力する
$head_title ページタイトル HTMLヘッダ領域のタイトル部分に出力する
$help ヘルプメッセージ 主に管理用ページで出力される
$language サイトの言語  
$layout ページレイアウト変数 サイドブロック表示の有無で画面定義を変更する際に使用
$logo ロゴ画像パス ロゴ画像はテーマ設定画面で設定
$messages HTMLメッセージ 状態表示やエラー情報が含まれる
$mission サイトミッション 管理画面のサイト情報で設定
$primary_links プライマリリンク配列 管理画面のメニューで設定
$search_box 検索ボックスHTML テーマ設定で有効にされた場合のみ表示
$secondary_links セカンダリリンク 管理画面のメニューで設定
$sidebar_left 左サイドバーに表示するHTML  
$sidebar_right 右サイドバーに表示するHTML  
$site_name サイト名 管理画面のサイト情報で設定
$site_slogan サイトスローガン 管理画面のサイト情報で設定
$styles スタイルシート 使用するスタイルシートが全て含まれる
$scripts Javascript 使用するJavascriptが全て含まれる
$tabs タブナビゲーションHTML  
$title ノードのタイトル  

page.tpl.php はphpファイルですので、phpコードを記述する事が出来ます。
以下テーマファイルのphpコードでよく使用する変数をご紹介します。

変数 内容
$is_front トップページ表示の場合はtrueがセットされる3
$base_path Drupalベースパス
$directory テーマファイル保存ディレクトリ

ランダム画像を表示する

テーマシステムの仕組みを理解する為に、トップページ上部に、アクセスする度に異なる画像を表示するような簡単なカスタマイズを行ってみます。ここで変更するファイルは、page.tpl.php、template.phpになります。

手順

1.表示する画像(ship1.jpg、ship2.jpg、ship3.jpg、ship4.jpg)を作成し、zen/imagesディレクトリ以下にアップロードします。
2.template.phpの編集1

  • /themes/engines/phptemplate/phptemplate.engine ファイルの中から phptemplate_page の関数定義をまるごとtemplate.php内にコピーします。
  • template.php内のphptemplate_pageの関数名を zen_page に変更します。
  • zen_page 関数の最終行直前(_phptemplate_callbackの前)に以下のコードを追加します。
    $topimage = array(
      "/images/ship1.jpg",
      "/images/ship2.jpg",
      "/images/ship3.jpg",
      "/images/ship4.jpg",
    );
    $variables['topimage'] = $topimage[rand(0, count($topimage)-1)];

    3.page.tpl.phpの編集
  • 画像を表示する位置($mission表示の下辺り)に以下の記述を追加します。
    <?php if ($is_front){ ?>
      <img src="<?php print check_url($base_path . $directory . $topimage) ?>" alt="" />
    <?php } ?>

    4.template.php、page.tpl.php をzenディレクトリ以下にアップロードします。
    5.テストユーザでログインしてトップページを確認します。正しく編集できた場合は、表示する度に画像がランダムに変更されます。

上記変更内容の解説

DrupalのテーマAPIコール時には、下記のように、
1.<テーマ名>_<機能名>
2.<テーマエンジン名>_<機能名>
3.theme_<機能名>
の順で関数が存在するかを確認し、もし関数が存在した場合は、その関数を実行する仕様になっています。
テーマ関数のオーバーライドテーマ関数のオーバーライド
したがって、もしzenテーマのtemplate.phpに zen_page 関数が定義されていた場合、 phptemplate_page 2 の替わりに zen_page 関数が実行される事になります 3

template.phpによるオーバーライドtemplate.phpによるオーバーライド

  • 上記の変更では、phptemplate.engine内の関数をzenテーマのtemplate.phpにコピーした後で、 toppage という変数を新たに定義し、その変数にランダムに表示する画像ファイル名を設定しています。
  • page.tpl.php には、 $is_front 変数でトップページ表示かを判断し、もしトップページであった場合は、画像を表示するような編集を加えています。

別の実装方法

上記のtemplate.phpの編集部分では、phptemplate.engineから関数をまるごとコピーして変更する方法を紹介しましたが、単純にテンプレートに変数を追加する目的であれば、以下のコードをtemplate.phpに追加する方が簡単です4

function _phptemplate_variables($hook, $vars) {
  switch($hook) {
    case 'page' :
      $topimage = array(
      "/images/ship1.jpg",
      "/images/ship2.jpg",
      "/images/ship3.jpg",
      "/images/ship4.jpg",
      );
      $vars['topimage'] = $topimage[rand(0, count($topimage)-1)];
      break;
  }
  return $vars;
}

_phptemplate_variables 関数は、テンプレートに変数を追加する場合に使用する関数で、$hook 部分には<機能名>が設定されてコールされます。

表示領域を追加する

ブロック表示領域(リージョン)を追加するカスタマイズを行います。

手順

1.template.phpの編集

  • zen_regions 関数に広告表示用の領域 content_add を追加します。
    function zen_regions() {
      return array(
           'left' => t('left sidebar'),
           'right' => t('right sidebar'),
           'content_top' => t('content top'),
           'content_ad' => t('content ad'),
           'content_bottom' => t('content bottom'),
           'header' => t('header'),
           'footer' => t('footer')
      );
    }

    2.page.tpl.phpの編集
  • 広告を表示したい場所1に以下のコードを追加します。
    <?php if ($content_ad):?><div id="content-middle"><?php print $content_ad; ?></div><?php endif; ?>

    3.管理者IDでログインし、ブロック管理画面で広告ブロックを新規に作成します。
    4.作成した広告ブロックの表示領域を content ad に設定します。

リージョンの追加

上記変更内容の解説

  • template.phpに <テーマ名>_regions 関数を定義し、その中で上記のように領域を追加定義する事で必要なだけブロック表示領域を作成する事が出来ます。初期状態の領域定義は、/themes/engines/phptemplate/phptemplate.engine ファイル内の phptemplate_regions 関数に定義されていますので、そちらからコピーしてくるとよいでしょう。

特定ページデザイン変更

これまでページのデザインを変更する為に、page.tpl.phpファイルを変更してきましたが、より複雑なサイトを構築する際には、特定のページだけデザインを変更したい場合があります。そのような目的の為にpage.tpl.phpの替わりに別のテンプレートを使用する事が出来ます。

ページテンプレートファイル命名規則

  • page-front.tpl.php
    • トップページ表示の場合だけデザインを変更したい時に使用
  • page-<入力パラメータ1> – <入力パラメータ2> – <…>.tpl.php
    • 特定ページアクセスの場合だけデザインを変更したい時に使用

各テンプレート選択の優先順位は、以下のようになっています。

特定ページのデザイン変更特定ページのデザイン変更

具体例1

http://xxxxxx/node/1 にアクセスがあった場合
(1)page-node-1.tpl.php
(2)page-node.tpl.php
(3)page.tpl.php
の順でテンプレートファイルの存在を確認し、ファイルが存在した場合は、そのページテンプレートを使用します。以下の例についても同様です。

トップページ(http://xxxxxx/) の場合
(1)page-front.tpl.php
(2)page.tpl.php

http://xxxxxx/taxonomy/term/1 の場合
(1)page-taxonomy-term-1.tpl.php
(2)page-taxonomy-term.tpl.php
(3)page-taxonomy.tpl.php
(4)page.tpl.php

http://xxxxxx/admin の場合
(1)page-admin.tpl.php
(2)page.tpl.php

ブロックテンプレート

前ページではページ全体について異なるデザインテンプレートを使用出来る事を説明しましたが、同様にページ内の各ブロックについても表示箇所によってデザインを変更する事が出来ます。

表示の際にどのテンプレートを使用するかは、以下の命名規則のブロックテンプレートファイルが存在するかどうかで判断されます。(上位のテンプレートファイルがより優先されます。)

ブロックテンプレートファイル命名規則

1.block-[モジュール名]-[識別子].tpl.php1
2.block-[モジュール名].tpl.php
3.block-[リージョン名].tpl.php
4.block.tpl.php

具体例

下記のブロックテンプレートファイルを作成し、各ブロックの背景色を変更すると以下のような画面となります。ここでは、背景色のみを変更しましたが、実際には各ブロックごとにまったく異なったデザインに変更する事が出来ます。2

  • block-user-2.tpl.php
  • block-user-3.tpl.php
  • block-search.tpl.php
  • block-left.tpl.php
  • block.tpl.php

ブロックテンプレート

ノードテンプレート

コンテンツ表示領域の中心となるノードテンプレート(node.tpl.php)についても、ブロックテンプレートと同様にノードタイプごとに表示内容を変更する事が出来ます。

表示の際にどのテンプレートを使用するかは、ノードタイプのテンプレートファイルが存在するかどうかで判断され、もし存在しない場合は、デフォルトのnode.tpl.phpが使用されます。

ノードテンプレートファイル命名規則

  1. node-[ノードタイプ].tpl.php
  2. node.tpl.php

具体例

下記のノードテンプレートファイルを作成し、各ブロックの背景色を変更すると以下のような画面となります。ここでは、背景色のみを変更しましたが、実際には各ノードタイプごとにまったく異なったデザインに変更する事が出来ます。1

  • node-forum.tpl.php
  • node-blog.tpl.php
  • node.tpl.php

ノードテンプレート