-   topic   - トピックス

baserCMSのテーマを自作する(Ver.3系統)

2014年11月25日 技術関係

今回はbaserCMSのテーマについて基本部分をまとめてみました。最近、当サイトに「basercms テーマ」というキーワードで入ってこられる方が多いようですので、そうした方のお役に立てればと思います。

20141125_title.png

(この記事は過去バージョンの為に書いた記事を、現行バージョン(ver.3系統)の為に加筆修正して書き直したものです。)

参考サイト

以下のサイトを参考にさせて頂きました。ありがとうございます。

テーマって何?

baserCMSに限らず、多くのCMSに「テーマ」と呼ばれる概念があります。 「テーマ」とは、CMSを使って構築したWEBサイト(ホームページ)のデザインを、簡単に切り替えられるようにするもので、画像ファイルやCSSファイル、JSファイル等の必要なものが全てセットになっているものです。 ユーザーはこの「テーマ」を取得し(個人のブログやGitHubなどで公開されている他、baserCMSの場合は公式マーケットサイト「baser Market」でも取り扱っています)、自分のWEBサイトに適用することができます。

また、テーマはCMSのコア部分とは切り離して作られるため、CMSを使ったホームページ制作においても、一般的に利用されています。CMSのコア部分がバージョンアップなどの際に書き換わっても、テーマだけ切り離されているので自作の部分が上書きされず安心して運用できることや、テスト環境で構築したWEBデザインを、本番環境へ移すのが簡単だからです(原則的には、テーマファイルをテスト環境から本番環境へコピーして、管理画面でそのテーマを「適用」すれば良い)。

テーマのカタチ

テーマフォルダの設置場所

baserCMSのテーマには構造上のルールがあり、役割の決まっているフォルダが幾つかありますが、何はともあれ、まずはテーマの設置場所からです。テーマはフォルダ単位で構成されていますので、テーマフォルダごと以下の場所に設置します。

/app/webroot/theme/

もしも、テーマフォルダ名が「sample」ならば、以下のようになるはずです。

/app/webroot/theme/sample/

テーマのフォルダ構造

テーマフォルダの中身は、おおむね以下の様な構造になっています(以下のフォルダ等しか入れてはいけない、という事ではありません)。

Blog
ブログプラグインのコンテンツテンプレートを入れるフォルダ
Config
テーマの初期データ等を入れるフォルダ
css
CSSファイルを入れるフォルダ
Elements
エレメントファイルを入れるフォルダ(ウィジェットのテンプレートもこの中)
Feed
フィードプラグインのコンテンツテンプレートを入れるフォルダ
Helpers
テーマで使用できるヘルパーを入れるフォルダ
img
画像ファイルを入れるフォルダ
js
javascriptファイルを入れるフォルダ
Layouts
レイアウトテンプレートを入れるフォルダ
Mail
メールフォームプラグインのコンテンツテンプレートを入れるフォルダ
Pages
固定ページのファイルが入るフォルダ(管理画面で登録したページも、ここに書きだされる)
VERSION.txt
テーマのバージョン情報が書かれたテキストファイル
config.php
テーマの制作者等の情報が入ったPHPファイル
screenshot.png
管理画面で使用されるスクリーンショット画像(PNG形式 300px×240px)

CSSやJSファイル、画像ファイルなどは、その種類に応じて規定の場所に入れておくことで、baserCMS関数で呼び出すことが出来るようになります。 また、少し紛らわしい名前で「レイアウトテンプレート」と「コンテンツテンプレート」というものがあります。詳細は公式Wikiなどを参考にして頂ければと思いますが、ざっとご説明しておくと、以下のように言えると思います。

レイアウトテンプレート
ページ全体に関わるような大枠のデザインテンプレート。
コンテンツテンプレート
コンテンツ毎(ブログ、メールフォーム、固定ページカテゴリ....etc)に適用されるデザインテンプレートで、上記「レイアウトテンプレート」の中で使用されるもの。

WEBデザインを切り分けてみる

さて、テーマそのものについては上のような説明になりますが、実際のHTMLをテーマに落とし込んでいくには、どうすれば良いでしょうか。 簡単な事例を元に、切り分けの考え方についてご紹介します。

20141125_blog01.png

上図のようなページがあった場合、大きく4つに切り分けて考える事ができると思います。ページ全体の「レイアウト部分」、全ページで共通して必要な「ヘッダー部分」、カテゴリ毎に内容が変わる「メニュー部分」、ページ毎に内容が異なる「コンテンツ部分」の4つです。

今回はこれらのパーツを以下のように考えていきたいと思います。まずページ全体のレイアウトについて記述された「レイアウト部分」。 これはそのまま「レイアウトテンプレート」として考えたいと思います。

次に全ページで共通して表示させたい「ヘッダー部分」は、エレメントファイルとして持っておきたいと思います(全ページで共通するので、レイアウトテンプレート内に入れてしまっても良さそうですが、切り分けることで保守性が高くなり、かつ、ヘッダーやフッターに関しては、切り分けてエレメント化することでフックが利用できるようになります)。エレメントファイルとは、ページを構成する各部位を細分化したもので、レイアウトテンプレートから呼び出して使います。

続いて「メニュー部分」は、コンテンツテンプレートとして保持したいと思います。このサイドメニュー部分は、カテゴリによって内容を変えたいと思っています。そこで、カテゴリ毎に設定できる「固定ページのコンテンツテンプレート」として制作します。

最後に「コンテンツ部分」です。この部分はページごとに異なる内容が表示されます。固定ページを例にして考えると、管理画面の固定ページ管理で登録・編集した文章が表示される部分です。

以上のように各パーツを捉えた場合、後述するHTMLファイルの分解後に、それぞれを以下のフォルダ&ファイル名でテーマフォルダに設置することになります。

レイアウト部分
Layoutsフォルダ内に「default.php」として設置します(他のファイル名でも構いませんが、defaultという名前にしておくと、標準レイアウトテンプレートとして自動的に読み込まれます)。
メニュー部分
Pagesフォルダ内に「templates」フォルダを作成し、その中に「category01.php」として設置します(ファイル名は好きなもので構いません)。
ヘッダー部分
Elementsフォルダ内に「header.php」という名前で設置します(ファイル名は他の名前でも構いませんが、headerという名前にしておけば、ヘッダーエレメントを呼び出す専用関数で呼び出せるようになります)。

HTMLを分解する

上述のように、デザインを切り分ける事ができたら、実際のHTMLを分解していきます。分解したパーツは、それぞれテーマフォルダ内の規定の場所(前述)に設置していきます。まず、分解前のファイルとして、以下の様なHTMLファイルがあったとします。

<!DOCTYPE html>
<html lang="ja">
<head>
<link rel="stylesheet" type="text/css" href="style.css" />
<script type="text/javascript" src="sample.js"></script>
</head>
<body>

<header>
ヘッダー部分
</header>

<div id="sideMenu">
メニュー部分
</div>

<div id="contents">
コンテンツ部分
</div>

</body>
</html>

まずは分解しやすい所から始めましょう。最初はヘッダー部分を切り離すことにします。headerタグで囲われている部分をファイル化し、以下の場所に設置します。

/app/webroot/theme/sample/Elements/header.php
<header>
ヘッダー部分
</header>

そして、分解したヘッダー部分を呼び出すため、HTML部分を編集します。これはレイアウトテンプレートとして、以下の場所に保存します。

/app/webroot/theme/sample/Layouts/default.php
<!DOCTYPE html>
<html lang="ja">
<head>
<link rel="stylesheet" type="text/css" href="style.css" />
<script type="text/javascript" src="sample.js"></script>
</head>
<body>

<?php
//ヘッダー部分の呼び出し
$this->BcBaser->header();
?>

<div id="sideMenu">
メニュー部分
</div>

<div id="contents">
コンテンツ部分
</div>

</body>
</html>

これでレイアウトテンプレート「default.php」から、エレメントファイル「header.php」を呼び出す仕組みが出来ました。なお、ヘッダーエレメントの実態は他のエレメントファイルと変わりませんので、以下のようにしても呼び出せます(ただし、これではプラグイン等で利用されるフック機能のうち、ヘッダー部分に割り当てられた処理が機能しません。今回の記事では出てきませんが、フッターエレメントも同様です)。

<?php
//ヘッダーエレメントの呼び出し
$this->BcBaser->element('header');
?>

次にメニュー部分とコンテンツ部分です。今回、メニュー部分は「コンテンツテンプレート」として作成します。少しややこしくなりますが、コンテンツテンプレートは、その名の通り「コンテンツ」のテンプレートであり、コンテンツ内部で使われるものです(言葉よりもソースを見て頂いたほうが、お分かり頂けると思いますが、以下、もう少し言葉を足しておきます)。

そのため、大きな流れとしては「1.レイアウトテンプレートからコンテンツを呼び出す」「2.呼び出されたコンテンツ部分に、コンテンツテンプレートが設定されている場合、それが表示される。」「3.コンテンツテンプレートの中に記述された、「出力部分」に最終的なコンテンツが出力される。」

まずは、レイアウトテンプレートからコンテンツを呼び出します(メニュー部分が消えたように見えますが、これは後ほど再び登場します)。以下のようになると思います。

<!DOCTYPE html>
<html lang="ja">
<head>
<link rel="stylesheet" type="text/css" href="style.css" />
<script type="text/javascript" src="sample.js"></script>
</head>
<body>

<?php
//ヘッダー部分の呼び出し
$this->BcBaser->header();
?>

<?php
//コンテンツ呼び出し(今回は結果的にコンテンツテンプレートが呼ばれる)
$this->BcBaser->content();
?>

</body>
</html>

続いて固定ページのコンテンツテンプレートを用意します。以下の場所に下のような内容で作成します。コンテンツの呼び出し部分がBcPageとなることに注意してください。

/app/webroot/theme/sample/Pages/templates/category01.php
<div id="sideMenu">
メニュー部分
</div>
<?php
//コンテンツ部分の呼び出し
$this->BcPage->content();
?>

この固定ページのコンテンツテンプレートを使用するには、管理画面での設定が必要です。固定ページカテゴリ管理で、適用したいカテゴリを選択してください。「コンテンツテンプレート」という項目の中で、先ほど作った「category01」が選択できるようになっているはずです。

20141125_blog02.png

これでパーツの切り分けは終わりです。最後にCSSとJSファイルの呼び出しをbaserCMS関数にしておきましょう。それぞれ専用の関数(ヘルパー)があり、テーマの規定フォルダ内にあるものが、優先的に呼び出されます。呼び出す際は、ファイルの拡張子を省いても構いません(CSSとJSは拡張子が1つと決まっているため、専用ヘルパーで呼ぶ際に分かりきった部分だからです。なお、.jpg .gif .png .jpegなど拡張子が複数ある画像ファイルは、専用ヘルパーで呼び出す際にも拡張子が必要です)。

<!DOCTYPE html>
<html lang="ja">
<head>
<?php $this->BcBaser->css('style') ?>
<?php $this->BcBaser->js('sample') ?>
</head>
<body>

<?php
//ヘッダー部分の呼び出し
$this->BcBaser->header();
?>

<?php
//コンテンツ呼び出し(今回は結果的にコンテンツテンプレートが呼ばれる)
$this->BcBaser->content();
?>

</body>
</html>

いかがでしたでしょうか? ここに書いたのは本当に基本の部分です。baserCMSのテーマでは、他にも様々な関数や機能を利用することが出来ます。 興味のある方は公式サイトや公式Wikiをご覧ください。また、テーマだけの話ではなくなりますが、他のCMSでの開発経験をお持ちの方はAPIドキュメントもおすすめです。