分享

在zend Framework 中使用Smarty,并使用zend的助手功能

 sumi2005 2012-05-18

这两天对项目用zf 1.7进行重构。基于种种原因,项目的视图需要用smarty来完成。关于zf结合smarty,网上有很多资料。换用smarty和发现一个问题,就是 zf的各种视图助手无法使用了。在网上的了好久,也没有见到任何资料。狠下心来,把zf的源码看了一遍终于找到解决方案。在这里记录一下:

一、集成smarty

1.首先需要根据Zend_View_Interface接口编写ZF的Smarty视图类,假设你在library创建在
library/View/这样的文件目录结构,同时假设你下载的Smarty类库也在library目录中。在library/View/下新建 Smarty.php,然后按照手册中的说明,编写Zend_View_Smarty类实现Zend_View_Interface接口,代码如下:

<?php
/**
* 实现一个Zend View 的一个接口
* author:xydream@gmail.com
*/
require_once 'Zend/View/Interface.php';
require_once 'Smarty/Smarty.class.php';

class Zend_View_Smarty extends Zend_View_Abstract implements Zend_View_Interface
{
    /**
     * Smarty 对象
     * @var Smarty
     */
    protected $_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('Invalid path provided');
    }

    /**
     * 返回当前存放模板文件的路径
     * @return string
     */
    public function getScriptPaths ()
    {
        return array(
            $this->_smarty->template_dir);
    }

    /**
     * 配置Smarty引擎
     *
     * @param unknown_type $var
     * @param unknown_type $value
     */
    public function setupSmarty ($var, $value = '')
    {
        if (is_array($var)) {
            foreach ($var as $k => $v) {
                $this->setupSmarty($k, $v);
            }
        } else {
            if (in_array($var, array(
                'template_dir' ,
                'compile_dir' ,
                'cache_dir' ,
                'caching' ,
                'cache_lifetime' ,
                'left_delimiter' ,
                'right_delimiter'))) {
                $this->_smarty->$var = $value;
            }
        }
        return;
    }

    /**
     * 获取Smarty配置
     *
     * @param unknown_type $var
     * @return unknown
     */
    public function getSmartySet ($var)
    {
        if (in_array($var, array(
            'template_dir' ,
            'compile_dir' ,
            'cache_dir' ,
            'caching' ,
            'cache_lifetime' ,
            'left_delimiter' ,
            'right_delimiter'))) {
            return $this->_smarty->$var;
        }
    }

    /**
     * 设置存放模板编译文件的路径
     * @param string $path 要作为路径的目录.
     * @return void
     */
    public function setCompilePath ($path)
    {
        if (is_readable($path)) {
            $this->_smarty->compile_dir = $path;
            return;
        }
        throw new Exception('Invalid path provided');
    }

    /**
     * 返回当前存放模板编译文件的路径
     * @return string
     */
    public function getCompilePaths ()
    {
        return array(
            $this->_smarty->compile_dir);
    }

    /**
     * 设置存放模板缓存文件的路径
     * @param string $path 要作为路径的目录.
     * @return void
     */
    public function setCachePath ($path)
    {
        if (is_readable($path)) {
            $this->_smarty->cache_dir = $path;
            return;
        }
        throw new Exception('Invalid path provided');
    }

    /**
     * 返回当前存放模板缓存文件的路径
     * @return string
     */
    public function getCachePaths ()
    {
        return array(
            $this->_smarty->cache_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);
    }

    /**
     * 返回一个已设置的模板变量值
     * @param string $key 变量名
     * @return mixed 变量值
     */
    public function __get ($key)
    {
        return $this->_smarty->get_template_vars($key);
    }

    /**
     * 允许用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);
    }

    /**
     * 为模板设置一个变量
     * 允许设置一个具体的值给一个具体的变量,或者传递一个数组,用key => value键值对的形式批量赋值。()
     * @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);
    }

    /**
     * 清除所有已设置变量
     * @return void
     */
    public function clearVars ()
    {
        $this->_smarty->clear_all_assign();
    }

    /**
     * 处理一个模板,并返回其输出。.
     * @param string $name 要处理的模板.
     * @return string 输出的内容.
     */
    public function render ($name)
    {
        return $this->_smarty->fetch($name);
    }

    protected function _run ()
    {
        include func_get_arg(0);
    }
}
2.接下来我们需要编写一个动作助手,把Smarty注册到控制器全局属性中,编写类Zend_Controller_Action_Helper_View,对应的目录结构为library目录中
Zend/Controller/Action/Helper/View.php,代码如下:

<?php

class Zend_Controller_Action_Helper_View extends Zend_Controller_Action_Helper_Abstract
{
    protected $_smartyConfig;
    protected $_tmpPath;

    public function __construct($tmpPath,array $config){
        $this->_smartyConfig=$config;
        $this->_tmpPath=$tmpPath;
    }

    public function preDispatch ()
    {
        $smarty = new Zend_View_Smarty($this->_tmpPath, $this->_smartyConfig);
        $this->getActionController()->view = $smarty;
    }
}

3.然后在入口文件中前端控制器分发前添加动作助手,并进行smarty的配置。这里我将配置放一了配置文件中,具体代码:

//配置模板
$style = empty($_COOKIE['style'])?$config->smarty->template_dir:$_COOKIE['style'];
$viewBasePath = $config->smarty->template_base_dir;
$templates_dir = $viewBasePath . DIRECTORY_SEPARATOR . ltrim($style, '///');
if (! is_readable($templates_dir)) {
    setcookie('style', false, 315554400, // strtotime('1980-01-01'),
              $config->cookie->path,
              $config->cookie->domain,
              $config->cookie->secure
             );
    echo '你选择的风格不存在!调用默认风格进行显示';
    exit();
}
$smartySetup = array(
    'compile_dir' => $viewBasePath . $config->smarty->compile_dir ,
    'cache_dir' => $viewBasePath . $config->smarty->cache_dir ,
    'caching' => $config->smarty->caching ,
    'cache_lifetime' => $config->smarty->cache_lifetime ,
    'left_delimiter' => $config->smarty->left_delimiter ,
    'right_delimiter' => $config->smarty->right_delimiter);
Zend_Controller_Action_HelperBroker::addHelper(new Zend_Controller_Action_Helper_View($templates_dir,$smartySetup));

这样就完成了zf和Smarty的集成。

二、让smarty使用Zend_View的助手功能(需修改smarty源文件)

1.在smarty.class.php中为类添加一个属性:var $_zend_view=null;

2.找到这个函数 function Smarty()然后改为 function Smarty($zend_view=NULL)

并在内部增加这样一个语句: $this->_zend_view=$zend_view;

3.增加一个函数

    /**
     * 为了使用zend_view而增加,使smarty内部可以自动调用助手类
     *
     */
    public function __call($name, $args)
    {
        return $this->_zend_view->__call($name,$args);
    }

4.在Zend_View_Interface的实现类 smarty.php中将 $this->_smarty = new Smarty();改为: $this->_smarty = new Smarty(new Zend_View());

这样就可以在模板中以<{php}> echo $this->url(array('page' => $page)); <{/php}> 这种形式来使用助手类了

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多