めも帖

「めも帖」代わりにダラダラと書いていったり、めもしたりしているだけです。

CakePHPでテンプレートをDBに保存して使う

CakePHP(1.2)でテンプレートをDBに保存して使うということをしてみました。
正直、Smartyを利用してデーターベースに保存してあるテンプレートデータを利用する方法から、Smarty部分を取り除きました。具体的には、「CakePHPでテンプレートにDBを使用する方法 - kaz_29@はてな」で紹介されている事から、Smarty部分を取り除いたようなものです。

今回、やってみてわかったのは、CakePHPのViewは、なんだか随分と豪快な方法で実装されている?とちょっと疑問に思いました。あと、Controllerから、Viewオブジェクトを差し替えできるんですね。これも知りませんでした。

DBの用意

これは「CakePHPでテンプレートにDBを使用する方法 - kaz_29@はてな」で書かれている方法と同じ。

DBの用意2

templateテーブルに、

  • nameがmylayout
  • nameがtestpage

のカラムを用意します。また、それぞれのカラムのdataには、テンプレート(.ctp)で書かれている内容をそのまま入れます

testtemplates_controller.php

コントローラーは、以下のようになります。$viewがポイント

<?php
class TesttemplatesController extends AppController {
    var $name    = 'Testtemplates';
    var $uses    = array();
    var $helpers = array('Html', 'Form');
    var $layout  = 'mylayout';
    var $view    = 'dbtemplate';
		
    function index()
    {
		$this->pageTitle = 'DBからのテンプレートテスト';
		$this->set('content', 'DBからのテンプレートテスト');
		$this->render('testpage') ;
    }
}
?>

dbtemplate.php

dbtemplate.phpという名前のファイルをapp/view以下に置きます

<?php
class DbtemplateView extends View
{   
      function __construct(&$controller)
     {
          parent::__construct($controller);
          $this->subDir    = null;
          $this->ext       = null;    // 拡張子は使わない
          $this->_template = ClassRegistry::init('Template');    
          $this->template  = array();
     }


     function _getViewFileName($name=NULL)
     {
          if($name === NULL){
               $name = $this->action;
          }
          $name = str_replace('/', DS, $name);
          $template = $this->__read_template($name);

          if($template !== false){
               return $name;
          }

          return $this->_missingView($name, 'missingView');
     }


     function _getLayoutFileName($name=NULL)
     {
          if($name === NULL){
               $name = $this->layout;
          }
          $name = str_replace('/', DS, $name);
          $template = $this->__read_template($name);

          if($template !== false){
               return $name;
          }

          return $this->_missingView($name, 'missingView');
     }

     function __read_template($name)
     {
          if(!array_key_exists($name, $this->template)){
               $template = $this->_template->findByName($name);
               if(!$template){
                    return false;
               }else{
                    $this->template[$name] = $template;
               }
          }

          return $this->template[$name];
     }

     function _render($___viewFn, $___dataForView, $loadHelpers = true, $cached = false) {
          $loadedHelpers = array();

          if ($this->helpers != false && $loadHelpers === true) {
               $loadedHelpers = $this->_loadHelpers($loadedHelpers, $this->helpers);

               foreach (array_keys($loadedHelpers) as $helper) {
                    $camelBackedHelper = Inflector::variable($helper);
                    ${$camelBackedHelper} =& $loadedHelpers[$helper];
                    $this->loaded[$camelBackedHelper] =& ${$camelBackedHelper};
               }

               $this->_triggerHelpers('beforeRender');
          }


          $__dbtemplate = $this->__read_template($___viewFn);
          extract($___dataForView, EXTR_SKIP);

          ob_start();
          eval('?>' . $__dbtemplate['Template']['data'] . '<?');

          if ($loadHelpers === true) {
               $this->_triggerHelpers('afterRender');
          }

          $out = ob_get_clean();
          $caching = (
               isset($this->loaded['cache']) &&
               (($this->cacheAction != false)) && (Configure::read('Cache.check') === true)
          );

          if ($caching) {
               if (is_a($this->loaded['cache'], 'CacheHelper')) {
                    $cache =& $this->loaded['cache'];
                    $cache->base = $this->base;
                    $cache->here = $this->here;
                    $cache->helpers = $this->helpers;
                    $cache->action = $this->action;
                    $cache->controllerName = $this->name;
                    $cache->layout     = $this->layout;
                    $cache->cacheAction = $this->cacheAction;
                    $cache->cache($___viewFn, $out, $cached);
               }
          }
          return $out;
     }
}
?>