WEBサービス創造記

WEBサービスを作ったり保守したりしてる人のメモブログです。

SmartyをZendFrameworkのビューとして利用する

      2012/12/17

この記事について

SmartyをZendFrameworkのビューとして採用する手順をメモしたものです。
過去に同様の記事として下記の記事を書きましたが、古い技術書を参考に書いたため手法が古く、この記事の手法のほうが簡単に設定できるため参考程度に残しておきます。

Smarty を ZendFramework の View として利用する
SmartyをZendFrameworkのビューとして利用する(モジュール化対応版)

また、この記事の手法を実践するには以下の条件を満たしている必要があります。

  • WEBサーバが構築されていること
  • PHPがインストールされていること
  • ZendFrameworkがインストール済みでパスが通っていること
  • Smartyがインストール済みでパスが通っていること
  • zfコマンドを利用してワンライナーのコマンドでフレームワークのプロジェクトやコントローラの雛形が生成できる

まだ上記の環境が整っていない場合は、以下の記事を参考にしていただければと思います。

Apacheのインストール
PHPのインストール
ZendFrameworkのインストール

Smartyのインストール
ZFコマンドの使い方

この記事は下記のページの内容を参考に書きました。
Smartyを利用する方法 – [Zend Framework] ぺんたん info

設定の手順

1. ディレクトリの一括生成

zf create projectコマンドを利用すれば、ZendFrameworkの推奨ディレクトリ構成を一括で生成いてくれます。
また、この記事ではSmartyのコンパイルファイルとキャッシュはdata/smarty/ディレクトリ以下に設置しますので、そのディレクトリも作っておきます。

$ zf create project /path/to/project
$ cd /path/to/project
$ mkdir -p data/smarty/templates_c
$ mkdir data/smarty/cache
$ chmod 0777 data/smarty/templates_c
$ chmod 0777 data/smarty/cache

2. Smartyラッパークラスの準備

ZendFrameworkの公式ドキュメントにあるSmartyラッパークラスをそのまま利用しますが、メンバ変数$_smartyの修飾子がpublicとなっていますので、ご注意ください。

library/Zend_View_Smarty.class.php
<?php echo '<?php'; ?>

class Zend_View_Smarty implements Zend_View_Interface
{
  /**
   * Smarty object
   * @var Smarty
   */
  public $_smarty;

  /**
   * コンストラクタ
   *
   * @param string $tmplPath
   * @param array $extraParams
   * @return void
   */
  public function __construct($tmplPath = null, $extraParams = array())
  {
      $this->_smarty = new Smarty;

      if (null !== $tmplPath) {
          $this->setScriptPath($tmplPath);
      }

      foreach ($extraParams as $key => $value) {
          $this->_smarty->$key = $value;
      }
  }

  /**
   * テンプレートエンジンオブジェクトを返します
   *
   * @return Smarty
   */
  public function getEngine()
  {
      return $this->_smarty;
  }

  /**
   * テンプレートへのパスを設定します
   *
   * @param string $path パスとして設定するディレクトリ
   * @return void
   */
  public function setScriptPath($path)
  {
      if (is_readable($path)) {
          $this->_smarty->template_dir = $path;
          return;
      }

      throw new Exception('無効なパスが指定されました');
  }

  /**
   * 現在のテンプレートディレクトリを取得します
   *
   * @return string
   */
  public function getScriptPaths()
  {
      return array($this->_smarty->template_dir);
  }

  /**
   * setScriptPath へのエイリアス
   *
   * @param string $path
   * @param string $prefix Unused
   * @return void
   */
  public function setBasePath($path, $prefix = 'Zend_View')
  {
      return $this->setScriptPath($path);
  }

  /**
   * setScriptPath へのエイリアス
   *
   * @param string $path
   * @param string $prefix Unused
   * @return void
   */
  public function addBasePath($path, $prefix = 'Zend_View')
  {
      return $this->setScriptPath($path);
  }

  /**
   * 変数をテンプレートに代入します
   *
   * @param string $key 変数名
   * @param mixed $val 変数の値
   * @return void
   */
  public function __set($key, $val)
  {
      $this->_smarty->assign($key, $val);
  }

  /**
   * empty() や isset() のテストが動作するようにします
   *
   * @param string $key
   * @return boolean
   */
  public function __isset($key)
  {
      return (null !== $this->_smarty->get_template_vars($key));
  }

  /**
   * オブジェクトのプロパティに対して unset() が動作するようにします
   *
   * @param string $key
   * @return void
   */
  public function __unset($key)
  {
      $this->_smarty->clear_assign($key);
  }

  /**
   * 変数をテンプレートに代入します
   *
   * 指定したキーを指定した値に設定します。あるいは、
   * キー => 値 形式の配列で一括設定します
   *
   * @see __set()
   * @param string|array $spec 使用する代入方式 (キー、あるいは キー => 値 の配列)
   * @param mixed $value (オプション) 名前を指定して代入する場合は、ここで値を指定します
   * @return void
   */
  public function assign($spec, $value = null)
  {
      if (is_array($spec)) {
          $this->_smarty->assign($spec);
          return;
      }

      $this->_smarty->assign($spec, $value);
  }

  /**
   * 代入済みのすべての変数を削除します
   *
   * Zend_View に {@link assign()} やプロパティ
   * ({@link __get()}/{@link __set()}) で代入された変数をすべて削除します
   *
   * @return void
   */
  public function clearVars()
  {
      $this->_smarty->clear_all_assign();
  }

  /**
   * テンプレートを処理し、結果を出力します
   *
   * @param string $name 処理するテンプレート
   * @return string 出力結果
   */
  public function render($name)
  {
      return $this->_smarty->fetch($name);
  }
}

Zend Framework: Documentation: ビュースクリプト – Zend Framework Manual

Zend_View互換クラスを定義する場合は、Zend_View_Interfaceを実装する必要があり、上記ラッパークラスもこれを実装しています。
Zend_View_Interface実装クラスで定義すべきメソッドに関しては以下の旧ページで解説しておりますので、必要に応じて参考にしていただければと思います。
Smarty を ZendFramework の View として利用する

3. 設定ファイルへ編集

手順1で実行したzfコマンドによって、アクションコントローラやビュースクリプトはもちろん、これから編集するブートストラップや設定ファイルもすべて自動的に生成されているはずです。

アプリケーションの設定ファイル application/configs/application.ini にSmartyに関する下記の数行を追記します。

view.smarty.cache_dir = APPLICATION_PATH "/../data/smarty/cache/"
view.smarty.compile_dir = APPLICATION_PATH "/../data/smarty/templates_c/"
view.scriptPath = APPLICATION_PATH "/views/scripts"

4. ブートストラップの編集

ブートストラップでビュー部分の初期化、つまりSmartyの設定行っています。

library/Zend_View_Smarty.class.php
<?php echo '<?php'; ?>

class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
{
    protected function _initView()
    {
        $options = new Zend_Config($this->getOptions());
        $view_config = $options->view->toArray();
        $smarty_config = $options->view->smarty->toArray();

        require_once 'libs/Smarty.class.php';
        require_once 'Zend_View_Smarty.class.php';
        $view = new Zend_View_Smarty($view_config['scriptPath'],$smarty_config);
        $viewRenderer =
            Zend_Controller_Action_HelperBroker::getStaticHelper("ViewRenderer");
        $viewRenderer->setView($view)
                     ->setViewBasePathSpec($view->_smarty->template_dir)
                     ->setViewScriptPathSpec(':controller/:action.:suffix')
                     ->setViewScriptPathNoControllerSpec(':action.:suffix')
                     ->setViewSuffix('tpl');
    }
}

Smarty本体の読み込みもラッパークラスの読み込みも両方ここで行っていますが、適当な場所へ変更していただいても構いません。

ラッパークラスもアプリケーションの設定ファイルの以下の1行でパスが通っています。

includePaths.library = APPLICATION_PATH "/../library"

5. 動作確認

ここまで完了したら、ビュースクリプトを用意してブラウザからアクセスしてみましょう。
このページでの設定だと、アクションコントローラIndexに対応するビュースクリプトは application/views/scripts/index/index.tpl になります。ここで適当なhtmlを書いてブラウザから出力が確認できれば成功です。

 - ZendFramework , , , , , ,