[Codeigniter-users] テンプレートの扱いをCakePHPみたいにする

Back to archive index

decoy youtu****@gmail*****
2008年 6月 17日 (火) 00:51:10 JST


decoyです。

CakePHPでSmartyを使用する際にtplがあればSmartyを使用し、なければ使用しない
というものがありましたがそれを自分なりにCIでアレンジしてみました。
長いですが最後までお読み頂けますと幸いです。


手順は以下のとおりです。
もっと良い方法があれば是非、教えて下さい。

1. ここに書かれているとおりにSmartyを導入する
http://codeigniter.jp/wiki/index.php/Smarty%E3%81%A8%E9%80%A3%E6%90%BA%E3%81%99%E3%82%8B%EF%BC%88UTF-8%E7%B7%A8%EF%BC%89

2. application/config/autoload.phpの$autoload['libraries']にSmarty_parserを入れる

3. 以下の定数をどっかに記入する(application/config/config.php辺りが望ましい?)

// DIRECTORY_SEPARATORへのエイリアス
define('DS', DIRECTORY_SEPARATOR);

// ビューファイルへのパス
define('APP_VIEW_PATH', APPPATH . 'views' . DS);

// レイアウトファイルへのパス
define('APP_LAYOUT_PATH', APP_VIEW_PATH . 'layouts' . DS);


4. application/libraries/MY_Controller.phpを追加する(ない場合)
(config.phpで設定した$config['subclass_prefix']がMY_以外の場合は下記、適当に置き換えて下さい。)


5. 以下のコードを追加する(すでにMY_Controller.phpを使用されている場合はrenderメソッドの部分とvar $aryViewExtの部分のみ追加)

<?php
class MY_Controller extends Controller
{

    // 使用するテンプレートの拡張子を宣言
    // 優先度が高い順に記述
    var $aryViewExt = array(
        'tpl',
        'php',
    );


    function MY_Controller()
    {

        parent::Controller();
    }


    function render($ascContents = NULL, $mixConAct = array(), 
$strLayoutName = 'default')
    {

        // コントローラとアクションのキーを宣言する
        $aryConActKey = array(
            'controller',
            'action',
        );

        // __METHOD__で指定されている場合
        if (is_string($mixConAct)) {

            // ::で分割
            $mixConAct = explode('::', $mixConAct);
        }

        // 配列の数だけループ
        foreach ($aryConActKey as $i => $strConActName) {

            // コントローラ名とアクション名を小文字に変換して取得する
            $ascConActData[$strConActName] = strtolower($mixConAct[$i]);
        }

        // 初期化
        $i = 0;
        $ascAssign['content_for_layout'] = NULL;
        $bolLayoutUse = TRUE;

        // レイアウトを使用しない場合
        if (is_null($strLayoutName)) {

            // レイアウト使用フラグをFALSEにする
            $bolLayoutUse = FALSE;
        }

        do {

            // テンプレートが存在するかどうか調べる
            $bolViewFile = file_exists(APP_VIEW_PATH . 
$ascConActData['controller'] . DS . $ascConActData['action'] . '.' . 
$this->aryViewExt[$i]);

            // テンプレートが存在する場合
            if ($bolViewFile) {

                // Smarty用テンプレートが存在する場合
                if ($this->aryViewExt[$i] == 'tpl') {

                    // Smarty用テンプレートのデータを取得
                    $ascAssign['content_for_layout'] = 
$this->smarty_parser->parse(
                        'ci:' . $ascConActData['controller'] . DS . 
$ascConActData['action'] . '.' . $this->aryViewExt[$i],
                        $ascContents,
                        $bolLayoutUse
                    );
                }

                // 通常のテンプレートが存在する場合
                elseif ($this->aryViewExt[$i] == 'php') {

                    // 通常のテンプレートのデータを取得
                    $ascAssign['content_for_layout'] = $this->load->view(
                        $ascConActData['controller'] . DS . 
$ascConActData['action'],
                        $ascContents,
                        $bolLayoutUse
                    );
                }
            }

            // インクリメント
            $i++;

        } while($bolViewFile === FALSE && $i < count($this->aryViewExt));

        // 初期化
        $i = 0;

        // レイアウトを使用する場合
        if (!is_null($strLayoutName)) {

            do {

                // レイアウトファイルが存在するかどうか調べる
                $bolLayoutFile = file_exists(APP_LAYOUT_PATH . 
$strLayoutName . '.' . $this->aryViewExt[$i]);

                // レイアウトファイルが存在する場合
                if ($bolLayoutFile) {

                    // Smarty用レイアウトが存在する場合
                    if ($this->aryViewExt[$i] == 'tpl') {

                        // Smartyで出力
                        $this->smarty_parser->parse(
                            'ci:' . basename(APP_LAYOUT_PATH) . DS . 
$strLayoutName . '.' . $this->aryViewExt[$i],
                            $ascAssign
                        );
                    }

                    // 通常のレイアウトが存在する場合
                    elseif ($this->aryViewExt[$i] == 'php') {

                        // 通常出力
                        $this->load->view(
                            basename(APP_LAYOUT_PATH) . DS . $strLayoutName,
                            $ascAssign
                        );
                    }
                }

                // インクリメント
                $i++;

            } while($bolLayoutFile === FALSE && $i < 
count($this->aryViewExt));
        }
    }
}
?>


6. application/controllersの中でコントローラを作成する際にMY_Controllerを継承する


application/controllers/welcome.php

<?php
// Welcomeクラス
class Welcome extends MY_Controller
{

    function Welcome()
    {
        parent::MY_Controller();
    }

    function index()
    {

        $data['title'] = "タイトルです。";
        $data['body'] = "中身です。";

        // renderする
        $this->render(
            $data,
            array(
                __CLASS__,
                __FUNCTION__
            )
        );

    }
}
?>
※PHP5であればarray(__CLASS__, __FUNCTION__)の部分を__METHOD__と書くこともできます。
 レイアウトを使用しない場合はrenderの第三引数にNULLを入れて下さい。


7. application/views/layouts/の中にSmartyを使用する場合はdefault.tplを置き、CIのviewを使う場合はdefault.phpを置く
   (両方置いた場合はvar $aryViewExtで書いた順にファイルを探して先に見つかったほうを使用します。)
   そして以下のようなコードを書いてみる

application/views/layouts/default.tpl

<html>
<body>
Smarty使用のレイアウト<br>
{$content_for_layout}
</body>
</html>


application/views/layouts/default.php

<html>
<body>
CI使用のレイアウト<br>
<?php echo $content_for_layout; ?>
</body>
</html>


8. application/views/welcome/の中にSmartyを使用する場合はindex.tplを置き、CIのviewを使う場合はindex.phpを置く
   そして以下のようなコードを書いてみる

application/views/welcome/index.tpl

{$title}<br>
{$body}<br>
このページは{$CI->benchmark->elapsed_time()}秒でレンダリングされました。<br>

application/views/welcome/index.php

<?php echo $title; ?><br>
<?php echo $body; ?><br>
このページは{elapsed_time}秒でレンダリングされました。<br>


9. http://example.jp/welcome/ にアクセス
tplがある場合はSmartyを使用し、ない場合はCIのviewを使うようになっているのがわかるかと思います。


備考
・views以下のフォルダ及びファイルの配置方法はCakePHPでのやり方をパクってますw 


・本当は$this->render()なんかを書かずに自動的にそのコントローラのメソッドに対応するテンプレートが呼ばれるようにし、
 そのテンプレート以外のテンプレートを使用したい場合のみ$this->render();を記述して
 明示的に宣言する(CakePHPみたいなやり方)というようにしたかったんですがやり方がわかりませんでした。OTL

・renderというメソッド名もCakePHPからパクってますが渡す引数の内容は全く違うものです。

・renderメソッドの中の処理はノリで書いただけですので無駄があるかもしれません。 

 同じ事をやるならこう書くべき、というものがあればこのMLに投稿して頂けますと幸いです。



以上です。 




Codeigniter-users メーリングリストの案内
Back to archive index