在 Zend Framework 应用中使用 Smarty 做模版引擎

Zend Framework 是 PHP 官方出的开发框架,随着 PHP5 的推广,越来越多的人开始学习、使用 Zend Framework。 Smarty 是一个非常强大的模版引擎,由于其完善的语法、内置的缓存功能,已经被众多开发人员应用在自己的开发项目中。

正因为二者的强大,因此有越来越多的人开始考虑将 Smarty 集成到 Zend Framework ,以便充分的发挥各自的优点。本文翻译自 Zend Developer Zone 。翻译为意译,由于水平有限,纰漏在所难免,欢迎指出翻译中出现的问题。本文为 CodeBit.cn ( http://www.codebit.cn ) 组织翻译,转载请注明出处。

原文作者首先指明了整合的目的:(1)保留 Zend_View 提供的 API;(2)利用 Smarty 提供的缓存功能。

目录结构:

文件名是按照作者的公司(Travello)命名:

 
  /Zend
    /View
  /Travello
    /View
      Smarty.php

定义类和构造函数:
首先是定义类和构造函数, Travello_View_Smarty 是继承自 Zend_View_Abstract,在构造函数中首先调用了父类的构造函数,然后将初始化好的 Smarty 对象存储在 private 属性中。

注意:这里使用了 configuration 对象存取 Smarty 的配置信息。

 
<?php
 
class Travello_View_Smarty extends Zend_View_Abstract
{
    private $_smarty = false;
    
    public function __construct($data = array())
    {
        parent::__construct($data);
        
        $config = Zend::registry('config');
        
        $this->_smarty = new Smarty();
        
        $this->_smarty->caching = $config->getSetting('smarty', 'caching');
        $this->_smarty->cache_lifetime = $config->getSetting('smarty', 'cache_lifetime');
        $this->_smarty->template_dir = $config->getSetting('smarty', 'template_dir');
        $this->_smarty->compile_dir = $config->getSetting('smarty', 'compile_dir');
        $this->_smarty->config_dir = $config->getSetting('smarty', 'config_dir');
        $this->_smarty->cache_dir = $config->getSetting('smarty', 'cache_dir');
    }

实现 _run() 方法:
_run() 是唯一的需要在 Zend_View_Abstract 子类中实现的方法,他会自动在 render() 方法中被调用,这里使用了 Smarty 的 display() 方法来输出模版。

 
<?php
 
    protected function _run($template)
    {
        $this->_smarty->display($template);
    }

重写 assign() 方法:
下面是要重写 Zend_View_Abstract 下面的 assign() 方法,我们直接将参数值赋到 Smarty 对象,而不是默认的 Zend_View_Abstract 的 $this->_vars 数组。

 
<?php
 
    public function assign($var)
    {
        if (is_string($var))
        {
            $value = @func_get_arg(1);
            
            $this->_smarty->assign($var, $value);
        }
        elseif (is_array($var))
        {
            foreach ($var as $key => $value)
            {
                $this->_smarty->assign($key, $value);
            }
        }
        else
        {
            throw new Zend_View_Exception('assign() expects a string or array, got '.gettype($var));
        }
    }

重写 escape() 方法:
下面是要重写 Zend_View_Abstract 下面的 escape() 方法,使用的是 Zend_View_Abstract 内置的 escape() 方法,但是能够根据传入的字符串或者数组作出相应处理。

 
<?php
 
    public function escape($var)
    {
        if (is_string($var))
        {
            return parent::escape($var);
        }
        elseif (is_array($var))
        {
            foreach ($var as $key => $val)
            {
                $var[$key] = $this->escape($val);
            }
 
            return $var;
        }
        else
        {
            return $var;
        }
    }

打印输出:
output() 是对 Zend_View_Abstract 中 render() 方法的封装,增加了一些 header 设置:

 
<?php
 
    public function output($name)
    {
        header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
        header("Cache-Control: no-cache");
        header("Pragma: no-cache");
        header("Cache-Control: post-check=0, pre-check=0", FALSE);
 
        print parent::render($name);
    }

使用 Smarty 的缓存:
最后的2个方法是为了在 View 类中整合 Smarty 的缓存机制,第一个方法是检查是否已经缓存,第二个是设置是否打开缓存功能。

 
<?php
 
    public function isCached($template)
    {
        if ($this->_smarty->is_cached($template))
        {
            return true;
        }
        
        return false;
    }
 
    public function setCaching($caching)
    {
        $this->_smarty->caching = $caching;
    }
} // end Travello_View_Smarty
 
?>

上面是完整的 Travello_View_Smarty 代码。

使用说明:
使用非常简单,在你的导入文件(通常是 index.php ,译注)中,可以用下面的方法初始化, $viewConfig 是设置 Zend_View 的路径,一旦创建好对象后,就将他存在对象中,方便后面调用。

 
<?php
 
$viewConfig = array();
$viewConfig['scriptPath'] = $config->getSetting('framework', 'view_dir');
 
$view = new Travello_View_Smarty($viewConfig);
Zend::register('view', $view);
 
?>

在你的 controller 和 action 方法中可以这样使用:

 
<?php
 
    public function indexAction()
    {
        $temp_file = 'homepage.htm';
        
        $view = Zend::registry('view');
        
        if (false === $view->isCached($temp_file))
        {
            $vars = array();
            $vars['title'  ] = 'Page <title>';
            $vars['text'   ] = 'A text is a text & a text is a text.';
            $vars['numbers'][0] = 12.9;
            $vars['numbers'][1] = 29;
            $vars['numbers'][2] = 78;
            
            $vars = $view->escape($vars);
            
            $view->assign($vars);
        }
        
        $view->output($temp_file);
    }
 
?>

原文地址:
http://devzone.zend.com/node/view/id/120

Smarty 在表格(table)里输出多列多行数据的方法

Smarty 是一个非常流行的 PHP 模板引擎,她支持缓存,能在实现 MVC 构架的同时,提高程序执行效率,深受众多 PHPer 的喜爱。Smarty 提供功能全面的模板语法,如果使用得当,你能很方便的实现你想要的显示方式。

本文讨论的是一个对初学者来说非常头痛的问题:将数据分成多列显示在表格中。单条数据循环对大多数模板引擎来说,实现都非常简单,但是要每行显示多条记录就需要一些额外的设置了。本文详细说明了解决这一问题的方法,相信对初学者非常有用。

模板文件:

 
<table border="1">
	<tr>
 
<?section name=site loop=$siteList?>
 
	<td><?$siteList[site].url?></td>
 
	<?if $siteListColumn > 1 ?>
 
	<?if $smarty.section.site.index != 0 && ($smarty.section.site.index + 1) % $siteListColumn == 0 ?>
	</tr>
	<tr>
	<?/if?>
 
	<?else?>
	</tr>
	<tr>
	<?/if?>
 
<?/section?>
 
	</tr>
</table>

注:示例中的模板定界符为 <??>

PHP 代码:

 
<?php
 
// 说明:Smarty 在表格(table)里输出多列多行数据的方法
// 站点:http://www.codebit.cn
 
// 设置列表内容
$siteList = array(
	array('url'=>'http://www.codebit.cn'),
	array('url'=>'http://YITU.org'),
	array('url'=>'http://www.google.com'),
	array('url'=>'http://www.baidu.com'),
	array('url'=>'http://www.yahoo.com.cn'),
	array('url'=>'http://www.163.com'),
	array('url'=>'http://www.sohu.com'),
	array('url'=>'http://www.sina.com.cn'),
);
 
// 列表数据统计
$siteListCount = count($siteList);
 
// 显示列数
$siteListColumn = 3;
 
// 如果列表数据不能将最后一行填满,
// 如:共 8 条记录,每列 3 条记录,最后一行还差 1 条
if($siteListColumn > 1 && $siteListCount % $siteListColumn != 0)
{
	// 计算最后一行还差几列
	$emptyColumn = $siteListColumn - ($siteListCount % $siteListColumn);
 
	for($i=0; $i<$emptyColumn; $i++)
	{
		// 用空值填充,保证最后一行正确显示
		$siteList[$siteListCount + $i] = array('url'=>'&nbsp;');
	}
}
 
// 将显示列数赋值到模板
$smarty->assign('siteListColumn', $siteListColumn);
 
// 将显示数据赋值到模板
$smarty->assign('siteList', $siteList);
 
?>

此代码可以将指定数据显示在一个任意列(通过 $siteListColumn 设置)的表格中。

除了将数据显示在表格中,我们还有另外一个选择,那就是将数据显示在一个 UL 列表中,然后通过 CSS 控制 LI 的宽度,同样也能实现多列数据显示。这种方法在前台页面中也实现了数据和结构的分离,页面上只有数据,具体显示由 CSS 控制,这样,就实现了前台页面的 MVC 构架,好处多多。