2014-10-17 92 views
2

我剛開始研究Zend框架2。我似乎無法弄清楚的一件事是如何在決定使用哪個視圖模板時更改框架的行爲當我沒有通過視圖模型。更改Zend Framework 2的默認模板解析器行爲

在尋找自己的答案我發現下面的,其中指出,Zend的使用下面的尋路解決視圖模板:

{normalized-module-name}/{normalized-controller-name}/{normalized-action-name}

(來源:http://zend-framework-community.634137.n4.nabble.com/Question-regarding-template-path-stack-tp4660952p4660959.html

現在我期待編輯或刪除標準化的模塊名稱段。所有的視圖文件保留在我的模塊/視圖文件夾。我想改變這個的原因是因爲我使用子命名空間作爲我的模塊名稱,導致命名空間的第一部分作爲標準化模塊名稱(這對我來說不夠具體)。

/modules/Foo/Bar/view/foo/test/index.phtml

給你舉一個例子,模塊Foo\Bar將導致一個例子視圖被渲染。

我想改變這種默認行爲:

/modules/Foo/Bar/view/bar/test/index.phtml

+0

不知道我得到你,但我這是怎麼設置我的模板$視圖 - > setTemplate(「路徑」); – dixromos98 2014-10-17 14:28:43

+0

嘿@ dixromos98,你的建議的答覆是確實是正確的,如果你想手動告訴ZF2,它需要使用特定的視圖。我只是好奇,如果有什麼方法可以在不設置模板時改變ZF2的行爲。 – nstapelbroek 2014-10-17 14:53:39

+0

謝謝大家回答我的問題!我在辦公室留下了關於此問題的代碼,因此我會盡快在星期一回復您,以標記正確的答案。 – nstapelbroek 2014-10-18 13:25:10

回答

3

我也有類似問題,這是我的解決方案。

默認模板注射器附連到優先-90電流控制器的事件管理器,它解決了僅當一個視圖模型不具有一個模板名稱。 知道了這一點,你可以用一個邏輯需要創建自己的模板注射器,它具有較高的優先級附加到事件管理器。

請參閱下面的代碼:

public function onBootstrap(EventInterface $event) 
{ 
    $eventManager = $event->getApplication()->getEventManager(); 

    $eventManager->getSharedManager() 
     ->attach(
      'Zend\Stdlib\DispatchableInterface', 
      MvcEvent::EVENT_DISPATCH, 
      new TemplateInjector(), 
      -80 // you can put here any negative number higher -90 
     ); 
} 

你的模板噴射器,它解決模板路徑而不是默認的。

class TemplateInjector 
{ 
    public function __invoke(MvcEvent $event) 
    { 
     $model = $event->getResult(); 

     if (!$model instanceof ViewModel) 
     { 
      return; 
     } 

     $controller = $event->getTarget(); 


     if ($model->getTemplate()) 
     { 
      return ; 
     } 

     if (!is_object($controller)) 
     { 
      return; 
     } 

     $namespace = explode('\\', ltrim(get_class($controller), '\\')); 

     $controllerClass = array_pop($namespace); 
     array_pop($namespace); //taking out the folder with controllers 
     array_shift($namespace); //taking out the company namespace 

     $moduleName = implode('/', $namespace); 

     $controller = substr($controllerClass, 0, strlen($controllerClass) - strlen('Controller')); 
     $action = $event->getRouteMatch()->getParam('action'); 
     $model->setTemplate(strtolower($moduleName.'/'.$controller.'/'.$action)); 
    } 
} 

下面是從我的博客,我更詳細地寫了一篇關於它的鏈接:http://blog.igorvorobiov.com/2014/10/18/creating-a-custom-template-injector-to-deal-with-sub-namespaces-in-zend-framework-2/

+1

下一頁開發商的答覆是最適合我,在這一刻,因爲提供的代碼示例。 Iku幾乎是這樣說的,但是因爲我對Zend來說很新,所以有點難以理解。通過告訴我Iku和Exlord都有效,我應該手動定義模板,優化性能。而且我也喜歡Xerkus的答案,因爲它是完成任務的最「乾淨」的解決方案。由於我沒有足夠的聲望來支持所有人,所以我將Next Developer的答案標記爲已解決的問題。不過謝謝大家的參與。 – nstapelbroek 2014-10-20 08:06:03

4

與ZF 2.3開始,你可以使用額外的配置參數view_manager['controller_map'],使不同的模板名稱解析。

看看這個PR的詳細信息:

  1. 條\控制器\命名空間:https://github.com/zendframework/zf2/pull/5670

    'view_manager' => array(
        'controller_map' => array(
         'Foo\Bar' => true, 
        ), 
    ); 
    

    會導致控制器FQCN以 '富\酒吧' 到以下這些規則來解決

  2. 帶狀拖尾控制器類名
  3. inflect駝峯撞向
  4. 用斜槓替換命名空間分隔符

如:Foo\Bar\Controller\Baz\TestController - >foo/bar/baz/test/actionname

更新:

與Zend-MVC V3.0開始,這是默認的行爲

+0

我等待着這一切我的生活:d謝謝 – MonkeyMonkey 2016-07-06 13:55:35

+0

這應該是公認的答案@nstapelbroek – thexpand 2018-01-23 14:40:34

0

模板名稱解析是一個沉重的過程(系統資源),以及所有關於ZF2性能的文章說,你應手動提供模板名稱以提高性能。

所以不要浪費時間尋找一種方法做一些事情,你最終會做手工:在TemplateInjector.php d

0

爲了提高下一步開發的答案,我寫了下面的代碼:

class TemplateInjector 
{ 

    public function __invoke(MvcEvent $event) 
    { 
     $model = $event->getResult(); 

     if (!$model instanceof ViewModel) { 
      return; 
     } 

     if ($model->getTemplate()) { 
      return; 
     } 

     $controller = $event->getTarget(); 

     if (!is_object($controller)) { 
      return; 
     } 

     $splitNamespace = preg_split('/[\\\]+/', ltrim(get_class($controller), '\\')); 
     $moduleName = $splitNamespace[1]; 
     $controller = $splitNamespace[0]; 
     $action = $event->getRouteMatch()->getParam('action'); 
     $model->setTemplate(strtolower($moduleName . '/' . $controller . '/' . $action)); 
    } 
} 

我已經改變了建模板路徑的方式。使用正則表達式比使用數組方法更快。