Drupal は GNU GPL ライセンスのもとで利用可能なコンテンツマネージメントシステム(CMS)です。商用・非商用を問わず、無料で利用することが出来ます。
日本では、XOOPS, Movable Typeを利用したサイト構築事例が増えておりますが、海外に目を向けると、Drupalの利用が急速に拡大してきており、今後日本で最も普及が見込まれるオープンソースCMSです。
参考
GoogleトレンドによるCMSソフトウェア検索数比較
軽量
シンプルな構造のコアモジュールと必要に応じて追加する拡張モジュールによって構成され、サイト構築に必要な機能のみを選択する事によって、軽量でレスポンスの良いサイトを構築する事が出来ます。
SEO対策に最適
XHTMLとCSSでレイアウトされた検索エンジンと相性の良いコンテンツが出力されます。
RSS出力対応
これからのホームページには欠かせない機能となってきたRSS出力に対応しています。
高度なコンテンツ分類機能
コンテンツを階層的に構成したり、自由にタグ付けするなど多彩な分類・表示が可能です。
機能拡張/変更が容易
システムが統一的なAPIで構築されている為、わずかなカスタマイズでシステム横断的な機能変更を行う事が出来ます。
コンテンツフィールドの拡張が容易
拡張モジュールを追加する事により、商用CMSなみのフィールド拡張性を持たせる事が出来ます。
こちらのページではDrupalについての雑多なお話をまとめたいと思います。
2009年1月時点の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? | フィールド管理機能がコアに組み込まれる |
Drupal4.6当時、独自のコンテンツタイプを使用する場合は、既存のモジュールをコピーして新たにモジュールを開発するか、またはFlexinodeというモジュールを使用していました。
このモジュールは、CCKの原型となったモジュールで、日付型やセレクトボックスなどのフィールドを追加し独自の入力フォームを作成出来る当時としては画期的なモジュールだったと思います。
非常に便利だったFlexinodeですが、大きな欠点がありました。
それはデータベースのテーブル設計上の問題で
という点です。既に多くのサイトで使用されていたFlexinodeにおいて根本的な設計変更を行う事は困難だったため、それらの欠点を改善すべく、拡張性を持つ設計で、かつパフォーマンスの問題も改善した新たなモジュールCCKが開発されました。Drupal4.7当時は、使い慣れたFlexinodeがあるのにどうして同じようなモジュールが必要なのかという議論もありましたが、次第にその利点が認知されてゆきます。

Drupal5.xでCCKの一部の機能がコア機能として取り込まれた事により、CCKがより一般的に認知され、CCKで追加可能なフィールドを定義する拡張モジュールが急速に増加しました。その影響により、これ以前は
として新たな機能を追加していたワークフローが、この頃からは、
という流れに変わってきます。これにより、Viewsモジュールの重要性、利便性がより広く知られるようになりました。

Viewsの機能を発展させたViews2は、複数のコンテンツのリレーションを明示的に指定する事が可能になり、より複雑なデータ構造もプログラム開発なしで集約表示出来るようになりました。(開発者の方は、SQL文で複数テーブルのJOIN条件を指定出来るようになったと思えば理解しやすいと思います。)
Drupal7.xではフィールド管理機能がコア機能(API)として取り込まれる事が決まっています。その結果、ユーザアカウントのようなノード以外の情報も自由にフィールドを拡張する事が可能になります。1
またコア管理対象の最小単位がフィールドとなる為、CCKが一般化した時と同様にフィールド管理機能の拡張を目的とした拡張モジュールが多く開発される事になるかもしれません。
「すべてのコンテンツはノードである。」
という言い方をよくされるDrupalですが、7.x以降はノードだけが特別なオブジェクトではなくなりますので、
「すべてのDrupalオブジェクトはフィールドで構成される」
となるかも知れませんね。

16.x以前でもprofileモジュールによってユーザアカウントフィールドを拡張する事は可能ですが、profileモジュールもFlexinodeモジュール同様にDB設計上の問題を抱えています。
■参考にしたサイト一覧
Drupalテーマ作成方法の一例をご紹介致します。
特に断りがある場合を除き、コアシステムは Drupal5.x 、テンプレートエンジンは PHPTemplate を前提とします。またDrupalの基本操作についてある程度習熟している方を読者として想定していますので、基本操作の詳細については割愛させて頂きます。
尚、筆者も未だ学習中の身である為、誤りや偏った記述などの不備が多々あると思いますが、その点については予めご了承の上、お気づきの点がございましたら お問い合わせページ からお知らせ頂けましたら幸いです。
テーマを作成する方法として、自分で製作したXHTMLファイルにDrupalで使用可能な変数を埋め込んでゆく方法と、既存の公開されているテーマをカスタマイズしてゆく方法が考えられますが、ここではより簡単な後者の方法を説明します。
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
1 通常は、“drupalインストールディレクトリ/sites/all/themes/“または、“drupalインストールディレクトリ/themes/“になります。
2 もしご自身のパソコンに複数のブラウザがインストールされている場合は、別のブラウザを起動してテストユーザーでログインした方が後々の作業を考えると便利です。
3 forumノードを表示する場合は、forum-node.tpl.phpが使用されます。
テーマのカスタマイズに先立ち、Drupalテーマシステムについて簡単に説明しておきます。(開発者以外は関心の薄い話題かもしれないので、興味のない方はこのページは読み飛ばして下さい。)
Drupalでは、基本的にどんなモジュールであってもテーマAPIを利用してデータ出力を実装している為、その処理内容を変更する事によりサイト全体のデザイン変更を行う事ができ、またテーマAPIの処理を各テーマごとに変更する事によって、テーマごとにまったく異なったページ構成・表示にする事が出来ます。
1 オーバーライド可能なコアモジュールのテーマ関数は、公式サイトの Themeable functions に記述されています。また各モジュール内に定義されている theme_xxxx という関数がtemplate.phpによって置換可能な関数になります。
まず最初にサイト構築の中心となるページテンプレート(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 | テーマファイル保存ディレクトリ |
1 公式サイトの http://drupal.org/node/11812 でこれらの変数を参照出来ます。(公式サイトの情報が一部古かった為、上記の変数はphptemplate.engineのファイルから抽出しました。)
2 後述するテーマ関数のオーバーライドによってこれらの変数の内容を変更したり、新規の変数を定義する事が出来ます。
3 Drupal5.xからはこの変数を使用しなくてもトップページだけを別のテンプレート(page-front.tpl.php)で定義する事が可能です。
テーマシステムの仕組みを理解する為に、トップページ上部に、アクセスする度に異なる画像を表示するような簡単なカスタマイズを行ってみます。ここで変更するファイルは、page.tpl.php、template.phpになります。
1.表示する画像(ship1.jpg、ship2.jpg、ship3.jpg、ship4.jpg)を作成し、zen/imagesディレクトリ以下にアップロードします。
2.template.phpの編集[1]
$topimage = array(
"/images/ship1.jpg",
"/images/ship2.jpg",
"/images/ship3.jpg",
"/images/ship4.jpg",
);
$variables['topimage'] = $topimage[rand(0, count($topimage)-1)];<?php if ($is_front){ ?>
<img src="<?php print check_url($base_path . $directory . $topimage) ?>" alt="" />
<?php } ?>DrupalのテーマAPIコール時には、下記のように、
1.<テーマ名>_<機能名>
2.<テーマエンジン名>_<機能名>
3.theme_<機能名>
の順で関数が存在するかを確認し、もし関数が存在した場合は、その関数を実行する仕様になっています。
テーマ関数のオーバーライド
したがって、もしzenテーマのtemplate.phpに zen_page 関数が定義されていた場合、 phptemplate_page [2] の替わりに zen_page 関数が実行される事になります [3] 。
template.phpによるオーバーライド
上記の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;
}1 実際にはpage.tpl.phpやブロックに直接phpコードを記述した方が簡単なのですが、オーバーライドの説明の為に意図的に遠回りな方法を紹介しています。
2 theme_pageはページ全体を表示するテーマ関数です。詳細は、公式サイトの theme_page をご参照下さい。
3 オーバーライド可能なコアモジュールのテーマ関数は、公式サイトの Themeable functions に記述されています。また各モジュール内に定義されている theme_xxxx という関数がtemplate.phpによって置換可能な関数になります。
4 zenテーマでは既に_phptemplate_variables関数が定義されていますので、実際には“case ‘page’ :“以下の必要なコードをコピーする作業になります。
ブロック表示領域(リージョン)を追加するカスタマイズを行います。
1.template.phpの編集
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')
);
}<?php if ($content_ad):?><div id="content-middle"><?php print $content_ad; ?></div><?php endif; ?>
作成した領域にブロックを表示
1 この例では$content_top領域の下に表示するようにしました
これまでページのデザインを変更する為に、page.tpl.phpファイルを変更してきましたが、より複雑なサイトを構築する際には、特定のページだけデザインを変更したい場合があります。そのような目的の為にpage.tpl.phpの替わりに別のテンプレートを使用する事が出来ます。
ページテンプレートファイル命名規則
各テンプレート選択の優先順位は、以下のようになっています。
特定ページのデザイン変更
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
fn1. クリーンURLをオンにした場合で記述していますが、オフの場合でも同様に入力パラメータでテンプレートの優先順位が決まります
前ページではページ全体について異なるデザインテンプレートを使用出来る事を説明しましたが、同様にページ内の各ブロックについても表示箇所によってデザインを変更する事が出来ます。
表示の際にどのテンプレートを使用するかは、以下の命名規則のブロックテンプレートファイルが存在するかどうかで判断されます。(上位のテンプレートファイルがより優先されます。)
ブロックテンプレートファイル命名規則
1.block-[モジュール名]-[識別子].tpl.php1
2.block-[モジュール名].tpl.php
3.block-[リージョン名].tpl.php
4.block.tpl.php
下記のブロックテンプレートファイルを作成し、各ブロックの背景色を変更すると以下のような画面となります。ここでは、背景色のみを変更しましたが、実際には各ブロックごとにまったく異なったデザインに変更する事が出来ます。[2]
ブロックテンプレート
1 識別子は同一モジュールで生成される複数のブロックを識別する為のID。0,1,2のように連続した数値で作成される事が多い。
2 テンプレート内で使用可能な変数は、公式サイトの Block.tpl.php に記載されています。
コンテンツ表示領域の中心となるノードテンプレート(node.tpl.php)についても、ブロックテンプレートと同様にノードタイプごとに表示内容を変更する事が出来ます。
表示の際にどのテンプレートを使用するかは、ノードタイプのテンプレートファイルが存在するかどうかで判断され、もし存在しない場合は、デフォルトのnode.tpl.phpが使用されます。
ノードテンプレートファイル命名規則
下記のノードテンプレートファイルを作成し、各ブロックの背景色を変更すると以下のような画面となります。ここでは、背景色のみを変更しましたが、実際には各ノードタイプごとにまったく異なったデザインに変更する事が出来ます。[1]
ノードテンプレート
1 ノードテンプレート内で使用可能な変数は、公式サイトの Node.tpl.php に記載されています。