mikakane
4/27/2013 - 5:57 PM

fuelphp のLayout View クラス。独自拡張案

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(){
        
    }
    
    
}