テーマ機能のソース読み

CakePHPには「テーマ」機能というものがあり、ビューテンプレートを変更することができます。
http://book.cakephp.org/ja/view/488/Themes

つまりこれで、「スキンチェンジャー機能」を実装できる(はず)。

でも情報が少ないので、CakePHPの関連ソースを読んでみることにしました。


テーマ機能は、それほど難しくありません。
読み込むテンプレートファイルを変更してるだけで、他は普通のビューと同じでよいようです。



CookBookによると、テーマ機能の改修は、コントローラに以下の2つの変数を設定するのみ。

class ExampleController extends AppController {
    var $view = 'Theme';
    var $theme = 'example';
}

あとは、/app/views/themed/以下の、テーマ名(example)に応じたテンプレートファイル(.ctp)を配置するだけ。


拍子抜けするほど、簡単です。


では、コントーラ単位ではなく、アクション単位でテーマを指定する場合、$viewと$themeのデフォルト値はどうするのが適しているのか。
$viewと$themeの取り扱いを、ソースを追って調べてみました。

cake/libs/controllers/controller.php

761行目以下

function render($action = null, $layout = null, $file = null) {
	$this->beforeRender();

	$viewClass = $this->view;
	if ($this->view != 'View') {
		if (strpos($viewClass, '.') !== false) {
			list($plugin, $viewClass) = explode('.', $viewClass);
		}
		$viewClass = $viewClass . 'View';
		App::import('View', $this->view);
	}

(中略)
	$View =& new $viewClass($this);

render()にて$view($this->view)からテーマ機能のインポートが行なわれるので、ここまでに$this->viewと$this->themeを設定する必要がある。

beforeFilter() → 各アクションの処理 → beforeRender() → render()
 の順番なので、アクションの中で$this->viewと$this->themeを設定してOK、と判りました。
http://book.cakephp.org/ja/view/60/Callbacks

cake/libs/view/theme.php

theme.phpはview.phpの拡張。
viewの__construct()と_paths()を上書きして、テーマビューを呼び出すようにしているようです。


読み込むテンプレートを変更するのみなので、他はelementなどviewの機能を普通に使えそうです。


また、controllerで$this->viewのデフォルト値は'View'なので、テーマ機能を使いたくないアクションでは$this->view='View'にしておくのがよさそうです。

/**
 * The name of the View class this controller sends output to.
 *
 * @var string
 * @access public
 */
	var $view = 'View';

$thie->themeのデフォルト値は、特にないので、nullでも入れておく、で良いかと思います。