fuelphp のLayout View クラス。独自拡張案
<?php
/**
* Layoutクラス
*
* Viewのサブクラスではない!!←ここ重要
*
* グローバルなLayout変数の格納庫と、
* LayoutViewクラスのファクトリー、という位置づけ
*
* 用語的にはレイアウト->テンプレート的な感じでコメント書いてます。
*
* 単純なViewのファクトリークラスにしようとも思ったけど
* FuelのViewの構造上どうしてもレイアウト側をfactoryしないと行けない。
* やっぱり使う側の事情的にはテンプレート側をfactoryしたいよね…ってことで。
*
* @author mikakane
*/
class Layout
{
/**
* レイアウトファイルのパス
* デフォルトはlayout、で。
* 面倒だからセッタとかゲッタは用意しない。
*/
static public $layout = "layout";
static public $viewModel = "LayoutView";
//レイアウト向け変数
static protected $_vars = [];
//ゲッター
static public function get($key = null, $default = null)
{
if (is_null($key))
{
return static::$_vars;
}
if (array_key_exists($key, static::$_vars))
{
return static::$_vars[$key];
} else
{
return $default;
}
}
//セッター
static public function set($key, $value)
{
static::$_vars[$key] = $value;
}
//配列向けセッター
static public function add($key, $value)
{
if (array_key_exists($key, static::$_vars) && is_array(static::$_vars[$key]))
{
static::$_vars[$key][] = $value;
} else
{//空っぽの時は配列作成してvalue埋め込む。配列以外で存在するとき?そんなん知らんわ
static::$_vars[$key] = [$value];
}
}
static public function forge($file,$data=[]){
$viewModel = static::$viewModel;
return $viewModel::forge($file,$data);
}
}
/**
* Layout とココらへんの処理を混ぜると(というか、LayoutをView継承にすると)
* 確実にメソド名関連でもろかぶりして怒られるので,分ける。
* 基本Layout使ってからの、LayoutViewだから、
* 直接コールされることもないし,fuelの命名規則むしでもOK
* (というか直接呼ばれたくはない。)
*/
class LayoutView extends View
{
static protected $_file_name = "";
static protected $_data=[];
/*
* View Model 向けにシンプルなファクトリーを実装
*/
static public function forge($file=null,$data=[],$auto_filter = NULL){
$file = ($file)?: static::$_file_name;
$data = ($data)?: static::$_data;
return parent::forge($file,$data);
}
//遅延レンダがあるので,
//普通にテンプレート側のファイルはLayoutクラスからforgeできるはず。
//なので必要な処理は、
//オブジェクトコンテキストでrenderされるときに、レイアウトを考慮する、という事だけ。
//
//Viewクラスのrenderを上書き:
//基本これは直でコールされることはない、と認識してるが、
//一応引数の$fileは、テンプレート側のファイルパスと認識してみる(好みの別れる所)。
//
//処理としては,レイアウト側のViewをforgeして$thisをプロパティに埋め込む、みたいな方法もアリかな、って思ったけど
//ソレをやるとテンプレートのプロパティのrenderで多重ループになりそうな気がしたのでやめ(面倒だから検証してない)
//
//テンプレートの埋め込み場所はcontent_for_layoutで。あえてcakeっぽく
public function render($file=null)
{
$this->initialize();
$template = parent::render($file);
$view = View::forge(Layout::$layout,Layout::get());
$view->set("content_for_layout",$template,false);
return $view->render();
}
public function initialize(){
}
}