Zend_View 定義了 Zend_View_Interface,只要實作此介面即可替換預設的 PHP 腳本引擎。以下為介面定義:
interface Zend_View_Interface {
public function getEngine();
public function setScriptPath($path);
public function getScriptPaths();
public function setBasePath($path, $classPrefix = 'Zend_View');
public function addBasePath($path, $classPrefix = 'Zend_View');
public function __set($key, $val);
public function __isset($key);
public function __unset($key);
public function assign($spec, $value = null);
public function clearVars();
public function render($name);
}
將 Smarty 類別包裝為 Zend_View 相容介面:
class Lq_View_Smarty implements Zend_View_Interface {
protected $_smarty;
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;
}
public function getEngine() { return $this->_smarty; }
public function setScriptPath($path) {
if (is_readable($path)) { $this->_smarty->template_dir = $path; return; }
throw new Exception('Invalid path provided');
}
public function getScriptPaths() { return array($this->_smarty->template_dir); }
public function setBasePath($path, $prefix = 'Zend_View') { return $this->setScriptPath($path); }
public function addBasePath($path, $prefix = 'Zend_View') { return $this->setScriptPath($path); }
public function __set($key, $val) { $this->_smarty->assign($key, $val); }
public function __get($key) { return $this->_smarty->get_template_vars($key); }
public function __isset($key) { return null !== $this->_smarty->get_template_vars($key); }
public function __unset($key) { $this->_smarty->clear_assign($key); }
public function assign($spec, $value = null) {
if (is_array($spec)) { $this->_smarty->assign($spec); return; }
$this->_smarty->assign($spec, $value);
}
public function clearVars() { $this->_smarty->clear_all_assign(); }
public function render($name) {
ob_start();
echo $this->_smarty->fetch($name);
unset($name);
}
}
/www/zf_demo1 ├── application │ ├── Bootstrap.php │ ├── configs/application.ini │ ├── controllers/IndexController.php │ └── views/scripts/index/index.tpl ├── library │ ├── Lq/View/Smarty.php │ └── smartylib/ (Smarty 核心檔案) ├── public/index.php └── temp/smarty/templates_c/
[production] includePaths.library = APPLICATION_PATH "/../library" bootstrap.path = APPLICATION_PATH "/Bootstrap.php" bootstrap.class = "Bootstrap" appnamespace = "Application" autoloadernamespaces.lq = "Lq_" pluginpaths.Lq_View_Smarty = "Lq/View/Smarty" resources.frontController.controllerDirectory = APPLICATION_PATH "/controllers" resources.frontController.params.displayExceptions = 1 phpSettings.display_startup_errors = 1 phpSettings.display_errors = 1
class Bootstrap extends Zend_Application_Bootstrap_Bootstrap {
protected function _initSmarty() {
$smarty = new Lq_View_Smarty();
$smarty->setScriptPath('/www/zf_demo1/application/views/scripts');
return $smarty;
}
}
class IndexController extends Zend_Controller_Action {
public function indexAction() {
$this->_helper->getHelper('viewRenderer')->setNoRender();
$this->view = $this->getInvokeArg('bootstrap')->getResource('smarty');
$this->view->book = 'Hello World! ';
$this->view->author = 'by smarty';
$this->view->render('index/index.tpl');
}
}
<!DOCTYPE html>
<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Smarty 整合範例</title></head>
<body>
{$book} {$author}
</body></html>
可修改 library/smartylib/Smarty.class.php 建構子:
public function __construct() {
// ...
$this->setTemplateDir('/www/zf_demo1/temp/smarty/templates/')
->setCompileDir('/www/zf_demo1/temp/smarty/templates_c/')
->setPluginsDir(SMARTY_PLUGINS_DIR)
->setCacheDir('/www/zf_demo1/temp/smarty/cache/')
->setConfigDir('/www/zf_demo1/temp/smarty/configs/');
$this->debug_tpl = 'file:' . dirname(__FILE__) . '/debug.tpl';
if (isset($_SERVER['SCRIPT_NAME'])) $this->assignGlobal('SCRIPT_NAME', $_SERVER['SCRIPT_NAME']);
}
透過實作 Zend_View_Interface,Zend Framework 可無縫整合 Smarty 等第三方模板引擎。關鍵在於正確對應路徑管理、變數指派、渲染流程,並透過 Bootstrap 註冊為 View 資源,在 Controller 中取代預設 ViewRenderer 即可使用。