Zend Layout - “智能”布局选择器

时间:2009-12-09 04:23:16

标签: zend-framework layout zend-layout zend-application

我目前有Zend设置在每个模块的view / scripts / layout.phtml文件中查找布局脚本(即:/application/modules/moduleName/scripts/layout.phtml)。这是通过在application.ini文件(resources.layout[] =

中将layout []设置为空(空白)

问题是许多模块可能共享相同的布局。我不想将相同的布局复制到使用它的每个模块中。我知道我可以通过设置像resources.layout.layoutpath = /layoutPath这样的特定路径来设置所有内容以使用一个布局脚本,并且一切都会使用/layoutpath/layout.phtml,我知道我可以在init中设置单个页面(或整个控制器)使用$this->_helper->layout->setLayout('foobaz');

问题是某些模块将具有不同的布局,而不是“标准”模块,我不想在控制器或操作的基础上设置它。我想为整个模块设置它,设置在一个地方(或直接通过代码/ Zend自动计算)。理想情况下,它将如何设置它当前,但如果一个模块没有自己的layout.phtml,它将使用默认模块的布局。

那么......我该怎么做?

3 个答案:

答案 0 :(得分:2)

有几种解决方案,选择自己的策略

1扩展动作控制器

class App_Controller_Action extends Zend_Controller_Action 
{

    public function init()
    {
        parent::init();

        $moduleName = $this->getRequest()->getModuleName();
        $layoutPath = APPLICATION_PATH . '/modules/' . $moduleName . '/layouts';
        if (is_dir($layoutPath)) {
            $this->view->addScriptPath($layoutPath);
        }    
    }
 }

然后像往常一样IndexController extends App_Controller_Action ...
如果布局文件存在于APPLICATION_PATH . '/modules/' . $moduleName . '/layouts'目录中 - 它将被用来代替默认布局

2你可以编写frontcontroller插件

class App_Controller_Plugin_ModuleSwitcher extends Zend_Controller_Plugin_Abstract
 {
     protected $_view = null;

     public function routeShutdown(Zend_Controller_Request_Abstract $request)
     {
         $moduleName = $request->getModuleName();

         Zend_Layout::startMvc();
         $layout = Zend_Layout::getMvcInstance();
         $layout->setLayoutPath(APPLICATION_PATH . '/modules/' . $moduleName . '/layouts')->setLayout($moduleName);

         return $request;
     }
 }

并且不要忘记谷歌寻求其他解决方案;)

答案 1 :(得分:1)

您可以通过几个步骤设置自己的布局选择器

第1步: make module admin和default。

第2步: 在每个模块中创建布局文件夹作为admin / layouts / scripts 和默认/布局/脚本 放入layout.phtml

第3步: 从Application / layouts / scripts中删除layout.phtml文件。

第4步: 在库中创建Plugin文件夹并制作Plugin.php 如

class Plugin_Layout extends Zend_Controller_Plugin_Abstract 
{

   public function preDispatch(Zend_Controller_Request_Abstract $request)

    {
        $layoutPath = APPLICATION_PATH . '/modules/' . $request->getModuleName() . '/layouts/scripts/';
        Zend_Layout::getMvcInstance()->setLayoutPath($layoutPath);
    }
}   

第5步:

打开Application / configs / Appication.ini文件 并编辑它 如

;resources.layout.layoutPath = APPLICATION_PATH "/layouts/scripts/"
resources.layout.layout = "layout"
;register your plugin

autoloaderNamespaces[] = "Plugin"
resources.frontController.plugins[] = "Plugin_Layout"

第6步:

打开bootstrap文件Application / Bootstrap 将代码放在

protected function _initAutoload()

 {

        $loader = new Zend_Application_Module_Autoloader(array(
                    'namespace' => '',
                    'basePath' => APPLICATION_PATH . '/modules/'
                ));

        return $loader;
    }

    protected function _initPlugins()

{

        $this->bootstrap('frontcontroller');
        $fc = $this->getResource('frontcontroller');
        $fc->registerPlugin(new Plugin_Layout());
}

答案 2 :(得分:0)

最快的解决方案可能是创建符号链接以将模块布局文件指向默认布局。这不适用于Windows,并且难以维护。

更好的是,在Bootstrap中创建一个方法来设置布局。

class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
{

    public function _initLayoutScript(){
        //ensure layout is setup
        $this->bootstrap(array('layout', 'FrontController'));

        $layout= $this->getResource('layout');

        $front = $this->getResource('FrontController');

        //do something with $layout and $front - set layout script/path etc based on request 
        //You could use file_exists to detect module layout scripts 

    }

}

有关详细信息,请参阅http://framework.zend.com/manual/en/zend.application.quick-start.html#zend.application.quick-start.resources

最后,您可以write your own application resource与Zend_Application一起使用。