欢迎到我的博客讨论交流
在一些开源的系统中模板机制很常见,如discuz、ecshop、wordpress等等。所谓模板机制,就是将所有表现层的html代码和相关静态文件放置到一个主题文件夹下面,用户可以在后台随意切换主题外观。在zend framework中默认是不支持模板的,通常html文件都是放置在application或者module的views文件夹下面。但是我们可以通过简单的修改来实现这一功能。
创建一个 frontController 插件
主题都是在view中体现的,view根据web请求来决定,因此我们需要创建一个front controller的插件。当然你也可以放置在bootstrap的_initView中,但是在bootstrap中并不知道请求的控制器,因此无法根据modlue、controller和action设置相应的主题。 bootstrap实现方法
1 protected function _initView()
2 {
3 $view = new Zend_View();
4 $view->setScriptPath(APPLICATION_PATH.DS.'views'.DS.'scripts');
5 $view->addScriptPath(APPLICATION_PATH.DS.'themes'.DS.'default'.DS.'views');
6
7 $viewRenderer = Zend_Controller_Action_HelperBroker::getStaticHelper(
8 'ViewRenderer'
9 );
10 $viewRenderer->setView($view);
11 return $view;
12 }
首先在bootstrap中注册插件 application/bootstrap.php
1 class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
2 {
3 protected function _initFrontControllerPlugin()
4 {
5 $front = $this->bootstrap('frontcontroller')->getresource('frontcontroller');
6 $front->registerPlugin(new Application_Plugin_Theme());
7 }
8 }
application/plugins/Theme.php
1 class Application_Plugin_Theme extends Zend_Controller_Plugin_Abstract
2 {
3 public function routeShutdown($request)
4 {
5 $theme = new stdClass;
6 $theme->foldername = 'simple';
7 Zend_Registry::set('theme', $theme);
8
9
10 $bootstrap = Zend_Controller_Front::getInstance()->getParam('bootstrap');
11 $view = $bootstrap->bootstrap('View')->getResource('View');
12 $view->setBasePath(APPLICATION_PATH . '/views/' . $theme->foldername);
13
14 $layout = $bootstrap->bootstrap('Layout')->getResrouce('Layout');
15 $layout->setLayoutPath(APPLICATION_PATH . '/layouts/' . $theme->foldername);
16 }
17 }
那么对于下面的url,view的文件结构如下
url: /blog/viewAll
controller/action: BlogController::viewAllAction()
layout: application/layouts/simple/layout.phtml
view: application/views/simple/scripts/blog/viewAll.phtml
创建视图助手
我们还需要在模板中使用到很多静态文件,比如css、js、图片等等,这些图片我们通常储存在public文件夹下面,为了在视图中根据主题名字加载相应的文件,我们需要做一个视图助手
Application_View_Helper_Theme
1 class Application_View_Helper_Theme
2 {
3 public function theme($url)
4 {
5 $theme = Zend_Registry::get('theme');
6 $baseURL = "/themes/{$theme->foldername}";
7 return $baseURL . $url;
8 }
9 }
也可以将theme名字放入到session中
1 $session = Zend_Registry::get('Zend_Session');
2 if (!isset($session->theme))
3 $session->theme = 'simple';
4
5 //需要时获取,viewHelper中
6 $session = Zend_Registry::get('Zend_Session');
7 $url = $baseUrl . $session->theme . $content;
视图中使用此助手
echo '<img src='" . $this->theme('/images/smiley.gif') . '" alt="smiley">';