肉とビールとパンケーキ by @sotarok

少し大人になった「肉とご飯と甘いもの」

Ethna-2.3.2用レイアウトテンプレートの作り方(続:xoopsみたいなテンプレートの使い方をする)

前の2つのエントリ(Ethnaでxoopsみたいなテンプレートの使い方をする:ビュー内でテーマ変更Ethnaでxoopsみたいなテンプレートの使い方をする)で、レイアウトテンプレートを使って、ヘッダやフッタなど、各ページで常に読み込まれるものを外枠としたテンプレートを作ろうって話をしました。

そして、Ethna-2.3.2で変更されたEthna_Renderer_Smartyについて で書いた、変更点。


これを組み合わせると、もうちょい素敵にレイアウトレンプレートができます。


というわけで、一度前のエントリ2つは忘れてもらって、仕切りなおし。

Rendererから、fetchを返してもらえるようになったので、それを利用して、{APPID}_ViewClass::perform をオーバーライドして、ちょいちょいカスタマイズします。

app/{APPID}_ViewClass.php

<?php

class {APPID}_ViewClass extends Ethna_ViewClass
{
    // レイアウトファイルを指定るすプロパティ
    var $layout = 'layout.tpl';
    
    function _setDefault(&$renderer)
    {
        ...
    }
    
    /**
     *  これ。
     */
    function forward()
    {
        $renderer =& $this->_getRenderer();
        $this->_setDefault($renderer);
        
        // performの第二引数にtrueを指定すれば、fetchした結果が返ってくる。
        $renderer->assign('content', $renderer->perform($this->forward_path, true));
        $renderer->display($this->layout);
    }
}

前のときとテンプレート名とか変えてありますが、デフォルトで指定されるのは、layout.tpl です。これがないとダメです(存在判定とかしてません)。(エラー処理とかした内容は↓に追記してあります)
これが、Viewで指定できるようになったことは、すごくデカい。その理由は、

  1. {APPID}_ViewClassがすべてのViewファイルで継承されているため、プロパティの $layout に、{APPID}_View_{VIEWNAME} からアクセスできるようになったこと(後述)
  2. レンダラファイルをいじらずにすむようになった(コントローラの設定なども必要ない)
  3. {APPID}_ViewClass をいじるだけなので、ラクチン。*1


1.は、何がいいたいかというと、外枠のレイアウトを変更したい場合、以前は


前の設定

<?php
...
    function preforward()
    {
        ...
        $renderer =& $this->backend->ctl->getRenderer();
        $renderer->theme = 'theme_wide.tpl';
    }

というように、レンダラを呼び出して、それからプロパティセットしなければならなかったのが、


Ethna-2.3.2用の素敵な設定

<?php
...
    function preforward()
    {
        ...
        $this->layout = 'layout_wide.tpl';
    }
...

などと、1行で、しかも継承してるからそのままアクセス可能。

layout.tpl

こちらは前回と変更ありません。この、{$content} 部分に、内容が表示されます。

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
...
</head>
<body>

<div id="header">
    <h1>Ethnabbs Theme</h1>
</div>
<div id="content">

<{$content}>

</div>
<div id="footer">
    Theme Powered By <a href="http://ethna.jp">Ethna</a>-<{$smarty.const.ETHNA_VERSION}>.
</div>
</body>
</html>

というわけで、こんなカンジで利用してます。



(8/11 追記)

エラー処理とか色々加えたバージョンはこちらです。

{APPID}_ViewClass.php

<?php

class {APPID}_ViewClass extends Ethna_ViewClass
{
    /**
     *  @var    string  $layout      レイアウトテンプレートファイル名
     */
    var $layout = 'layout.tpl';
    
    /**
     *  @var    bool  $is_layout    レイアウトテンプレートを使うかどうかのフラグ
     */
    var $is_layout = true;
    
    ...
    
    //{{{forward
    /**
     *  遷移処理:レイアウトテンプレートに関する処理を追加
     *  
     *  @access public
     */
    function forward()
    {
        $renderer =& $this->_getRenderer();
        $this->_setDefault($renderer);
        
        
        // using layout.tpl flag
        if ($this->is_layout) {
            // check : layout file existance
            if ((is_absolute_path($this->layout) && is_readable($this->layout))
                ||is_readable($renderer->template_dir . $this->layout)) {
                $renderer->assign('content', $renderer->perform($this->forward_path, true));
                $renderer->display($this->layout);
            } else {
                return Ethna::raiseWarning('file "'.$this->layout.'" not found');
            }
        } else {
            $renderer->perform($this->forward_path);
        }
    }
    //}}}
}


見てのとおりですが、$this->is_layout = false を指定すれば、レイアウトファイルを使わずにそのまま出力できるようになります。AJAXから呼び出したりなどなどのときはこうするカンジで。

*1:なにこの理由。。笑