zoukankan      html  css  js  c++  java
  • yaf(5) smarty

    2013年4月6日 13:41:37

    参考:

    http://www.oschina.net/question/812776_71817

    http://yaf.laruence.com/manual/yaf.class.dispatcher.setView.html

    这两者都是在bootstrap.php中写_initSmarty()函数来重新实现yaf的视图接口

    这中方案默认的是存放模版文件的上级文件夹名字必须是views

    根据项目要求,要求可以自定义存放模版文件的文件夹名字,过程及注意事项记录如下:

    1.没有在bootstrap.php中写_initSmarty()函数来重新实现yaf的视图接口,而是在路由结束时的hook代码中来重写视图接口

    hook 
     1 <?php
     2 class LayoutPlugin extends Yaf_Plugin_Abstract {
     3 
     4     public function routerStartup(Yaf_Request_Abstract $request, Yaf_Response_Abstract $response) {
     5         echo "Plugin routerStartup called <br/>\n";
     6     }
     7 
     8     public function routerShutdown(Yaf_Request_Abstract $request, Yaf_Response_Abstract $response) {
     9         echo "Plugin routerShutdown called <br/>\n";
    10         //整合smarty
    11         $dispatcher = Yaf_Dispatcher::getInstance();
    12 //         $dispatcher->disableView();
    13         $dispatcher->autoRender(false);
    14         $objSmarty = new Smarty_Adapter;
    15         $dispatcher->setView($objSmarty);
    16         
    17     }
    18 
    19     public function dispatchLoopStartup(Yaf_Request_Abstract $request, Yaf_Response_Abstract $response) {
    20         echo "Plugin DispatchLoopStartup called <br/>\n";
    21     }
    22 
    23     public function preDispatch(Yaf_Request_Abstract $request, Yaf_Response_Abstract $response) {
    24         echo "Plugin PreDispatch called <br/>\n";
    25     }
    26 
    27     public function postDispatch(Yaf_Request_Abstract $request, Yaf_Response_Abstract $response) {
    28         echo "Plugin postDispatch called <br/>\n";
    29     }
    30 
    31     public function dispatchLoopShutdown(Yaf_Request_Abstract $request, Yaf_Response_Abstract $response) {
    32         echo "Plugin DispatchLoopShutdown called <br/>\n";
    33     }
    34 }

    此时可以确保yaf已经分析URL完毕,确定了moduleName,controllerName,ActionName,

    此时重写yaf视图接口就可以根据不同的moduleName去设定不同的smarty模版目录

    注意几点:

    ①在bootstrap.php中写_initSmarty()函数来重新实现yaf的视图接口:

    1 //smarty
    2     public function _initSmarty(Yaf_Dispatcher $dispatcher)
    3     {
    4         var_dump('@@@@@@@@@');
    5     }

    结果:

    1 string '@@@@@@@@@' (length=9)
    2 
    3 Plugin routerStartup called
    4 Plugin routerShutdown called
    5 Plugin DispatchLoopStartup called
    6 Plugin PreDispatch called
    7 Plugin postDispatch called
    8 Plugin DispatchLoopShutdown called 

    说明:在分析URL得到 moduleName,controllerName,ActionName 之前已经执行了_initSmarty();如果在这里边重写接口,灵活性就不是很大


    ② 关闭yaf自动默认的display动作(hook代码的第13行:$dispatcher->autoRender(false);)

    否则yaf在执行完action内的代码后会根据当前的controllerName和actionName去尝试加载controllerName/actionName.html,如果加载不到就会抛出异常:

    e.g. 访问本地:www.yaftwo.com/test/index/aaa时,打开自动默认的display动作

    1 Plugin routerStartup called
    2 Plugin routerShutdown called
    3 Plugin DispatchLoopStartup called
    4 Plugin PreDispatch called
    5 -------smarty say hello to you !-------
    6 
    7 object(SmartyException)[24]
    8   protected 'message' => string 'Unable to load template file 'F:/zzbserv/apache/htdocs/yaftwo/code/application/modules/test/templates/index\aaa.html'' (length=117)
    9 ...

    说明:第5行的输出说明已经成功display,但是紧接着就抛出了异常,内容很明显是因为找不到默认的disply路径

    2.重写yaf视图接口

    View Code
     1 <?php
     2 /*
     3  * 自定义视图类接口,用来封装smarty共yaf全局使用
     4  * 必须实现接口定义的5个函数
     5  */
     6 class Smarty_Adapter implements Yaf_View_Interface
     7 {
     8     public $_smarty;
     9     private $_script_path;
    10     
    11     public function __construct()
    12     {
    13         require 'Smarty.class.php';
    14         $this->_smarty = new Smarty;
    15         $this->_smarty->left_delimiter = "<{";
    16         $this->_smarty->right_delimiter = "}>";
    17         $this->_smarty->setCompileDir(ROOT.'/templates_c');//编译目录
    18         $this->_smarty->setCacheDir(ROOT.'/cache');//缓存目录
    19         //根据不同的模块设置不同的模版路径
    20         $dispatcher = Yaf_Dispatcher::getInstance();
    21         $arrRequest = $dispatcher->getRequest();
    22         if (empty($arrRequest->module)) {
    23             $this->_script_path = APP.'/templates';
    24             $this->setScriptPath(APP.'/templates');
    25         } else {
    26             $strModuleName = strtolower($arrRequest->module);
    27             $this->_script_path = APP.'/modules/'.$strModuleName.'/templates';
    28             $this->setScriptPath(APP.'/modules/'.$strModuleName.'/templates');
    29         }
    30     }
    31     
    32     //返回要显示的内容
    33     public function render( $view_name ,  $tpl_vars = NULL )//string
    34     {
    35         $view_path = $this->_script_path.'/'.$view_name;
    36         $cache_id     = empty($tpl_vars['cache_id']) ? '' : $tpl_vars['cache_id'];
    37         $compile_id = empty($tpl_vars['compile_id']) ? '' : $tpl_vars['compile_id'];
    38         return $this->_smarty->fetch($view_path, $cache_id, $compile_id, false);//返回应该输出的内容,而不是显示
    39     }
    40     
    41     //显示模版
    42     public function display( $view_name, $tpl_vars = NULL )//boolean
    43     {
    44         $view_path = $this->_script_path.'/'.$view_name;
    45         $cache_id     = empty($tpl_vars['cache_id']) ? '' : $tpl_vars['cache_id'];
    46         $compile_id = empty($tpl_vars['compile_id']) ? '' : $tpl_vars['compile_id'];
    47         return $this->_smarty->display($view_path, $cache_id, $compile_id);
    48     }
    49     
    50     //模版赋值
    51     public function assign( $name, $value = NULL )//boolean
    52     {
    53         return $this->_smarty->assign($name, $value);
    54     }
    55     
    56     //设定脚本路径
    57     public function setScriptPath( $view_directory )//boolean
    58     {
    59         return $this->_smarty->setTemplateDir($view_directory);
    60     }
    61     
    62     //得到脚本路径
    63     public function getScriptPath()//string
    64     {
    65         return $this->_script_path;
    66     }
    67     
    68 }

    注意几点:
    ① setScriptPath()接口函数内不要写判断模版路径是否存在的代码,因为除了在重写视图接口时会执行这行代码外,yaf还会在"分发请求前"默默的执行这个函数,并且传递给它的实参是yaf默认的视图存放路径:views/actionName,此时如果你的layout中没有这个路径的话,你的程序就会报错

    帖代码看看这个成员函数什么时候会被执行:

    1 //设定脚本路径
    2     public function setScriptPath( $view_directory )//boolean
    3     {
    4         var_dump('setScriptPath called with param '.$view_directory);
    5         return $this->_smarty->setTemplateDir($view_directory);
    6     }
     1 Plugin routerStartup called
     2 Plugin routerShutdown called
     3 
     4 string 'setScriptPath called with param F:/zzbserv/apache/htdocs/yaftwo/code/application/modules/test/templates' (length=103)
     5 
     6 Plugin DispatchLoopStartup called
     7 Plugin PreDispatch called
     8 
     9 string 'setScriptPath called with param F:/zzbserv/apache/htdocs/yaftwo/code/application/modules/Test/views' (length=99)
    10 
    11 -------smarty say hello to you !-------
    12 Plugin postDispatch called
    13 Plugin DispatchLoopShutdown called 

    说明:下边代码块第4行的输出是因为那里我们重写了视图接口,在构造函数中调用了此函数;

    但是第9行的输出则是在执行action时的自动调用输出,根据传入的实参可以知道这是yaf自己调用的(现在我还不知道如何去阻止这个调用)

    ②注意重写接口的diaplay();函数时,要手动拼接上模版文件的绝对路径,这里再贴一遍代码:

    1 //显示模版
    2     public function display( $view_name, $tpl_vars = NULL )//boolean
    3     {
    4         $view_path = $this->_script_path.'/'.$view_name;
    5         $cache_id     = empty($tpl_vars['cache_id']) ? '' : $tpl_vars['cache_id'];
    6         $compile_id = empty($tpl_vars['compile_id']) ? '' : $tpl_vars['compile_id'];
    7         return $this->_smarty->display($view_path, $cache_id, $compile_id);
    8     }

    说明:注意第4行手动拼接上模版文件的绝对路径(不用管第5,6行代码),这样yaf就可以找到自己定义的模版目录下的模版了,否则:

    1 Plugin routerStartup called
    2 Plugin routerShutdown called
    3 Plugin DispatchLoopStartup called
    4 Plugin PreDispatch called
    5 
    6 object(SmartyException)[21]
    7   protected 'message' => string 'Unable to load template file 'test.html'' (length=40)
    8 ...

    最后贴出重写后的用法:

    1 <?php
    2 class IndexController extends Yaf_Controller_Abstract 
    3 {
    4     public function aaaAction()
    5     {
    6         $this->getView()->assign('var', 'smarty say hello to you !');
    7         $this->getView()->display('test.html');
    8     }
    9 }


    另外:

    ①我在刚接触zend framework的时候,也整合过smarty当时用的是它的全局变量注册功能,我看到yaf的在线手册里也有此类(Yaf_Registry),有用到的可以试试

    ②Yaf_Controller_Abstract中有个默认执行的init()函数,也可以打打它的注意(*^__^*)

    完.

  • 相关阅读:
    nio的学习
    并发编程学习(二)
    并发编程学习(一)
    linux基础知识-常用命令
    linux基础知识-目录结构
    springcloud的config
    zuul学习
    hystrix学习
    feign学习
    ribbon学习
  • 原文地址:https://www.cnblogs.com/iLoveMyD/p/3002417.html
Copyright © 2011-2022 走看看