gpt4 book ai didi

zend-framework - 想法讨论: dynamic view script switching in zend MVC implementation

转载 作者:行者123 更新时间:2023-12-02 04:10:59 25 4
gpt4 key购买 nike

这个问题不太可能帮助任何 future 的访客;它只与一个小地理区域、一个特定时刻或一个非常狭窄的情况相关,而这些情况通常不适用于互联网的全局受众。如需帮助使这个问题更广泛地适用,visit the help center .




10年前关闭。




这基本上是“我做对了吗?”问题。

我知道如何在运行时透明地切换默认/移动版本/管理区域的 View 。我想知道您在这种方法中看到的利弊。

主要要求是:

  • 切换整个应用程序
    几乎没有编码
  • 集成到 zend MVC 工作流中,
    不要覆盖它
  • 回退到默认
  • 保留标准功能
  • Controller 不应该知道
    变化

  • 这是我的伪助手
    class Xrks_Controller_Action_Helper_VrExtension extends Zend_Controller_Action_Helper_Abstract
    {
    public function postDispatch()
    {
    if(!$this->_shouldRender()) {
    return; //just skip
    }
    try {
    $vr = $this->_getViewRenderer();
    $backupView = clone $vr->view;
    $this->_setBasePaths(); //set base path(s) through ViewRenderer::initView($path)
    $oldSpecArray = $this->_setVrPathSpecs(); //set VR view script path specs
    $vr->render();
    $vr->setNoRender(true); //disable renderer

    } catch(Zend_View_Exception $e) { //fallback to default viewscripts if view script file not found
    $vr->setView($backupView); //restore view on error

    } catch(Exception $e) {
    $vr->setView($backupView); //restore view on error
    $this->_setVrPathSpecs($oldSpecArray); //restore script path spec
    throw $e;
    }
    $this->_setVrPathSpecs($oldSpecArray);//restore script path spec
    }

    /**
    * Same functionality as ViewRenderer helper _shouldRender method
    * @return boolean
    */
    protected function _shouldRender();

    /**
    * @return Zend_Controller_Action_Helper_ViewRenderer
    */
    protected function _getViewRenderer();

    /**
    * Sets viewRenderer path specifications
    *
    * @param array $spec if NULL uses $this->_viewRendererPathSpecs
    * @return array old path spec (0 => pathSpec, 1 => pathNoControllerSpec)
    */
    protected function _setVrPathSpecs(array $spec = NULL);
    }

    应该如何配置助手并不重要,并且跳过了该部分

    这是它应该如何工作的示例:
    $this->_setBasePaths();将 View 基本路径设置为 应用程序/ View /默认/应用程序/ View /管理员/
    $this->_setVrPathSpecs();将路径规范设置为 ' :module/:controller/:action.:suffix '

    所以对于 foo-baz-bar 它将搜索
    1. 应用程序/views/admin/scripts/foo/baz/bar.phtml
    2. 应用程序/ View /默认/脚本/foo/baz/bar.phtml
    如果未找到 View 脚本回退到默认 ViewRenderer:
    3. 应用程序/模块/foo/views/scripts/baz/bar.phtml

    如果我错过了什么,请提出问题

    更新:经过一些研究,我决定使用 Action 助手根据变形器和指定变量的规范自动注册 View 脚本路径。如果来自其他模块的部分请求,我还修改了部分帮助程序以注册 scriptPaths。

    这是 Action 助手的粗略但有效的版本:
    class Xrks_Controller_Action_Helper_ViewRendererPathstack extends Zend_Controller_Action_Helper_Abstract
    {
    const PATH_APPEND = 'append';
    const PATH_PREPEND = 'prepend';

    protected $_enabled = FALSE;
    protected $_viewScriptPaths = array();
    /**
    * By default following vars available: baseDir, area, theme, module
    * @var string
    */
    protected $_viewScriptPathSpec = ':baseDir/:area/:module';
    protected $_defaults = array(
    'area' => 'frontend',
    'theme' => 'default',
    );
    protected $_vars = array();
    protected $_inflector;
    protected $_viewRenderer;

    public function __construct($baseDir = NULL)
    {
    if($baseDir == NULL) {
    $baseDir = APPLICATION_PATH . DS . 'views';
    }
    $this->setDefaultVar('baseDir', $baseDir);
    $this->addPath(array());
    }

    /**
    * Enter description here ...
    * @return Zend_Controller_Action_Helper_ViewRenderer
    */
    protected function _getViewRenderer()
    {
    if(!$this->_viewRenderer) {
    $this->_viewRenderer = Zend_Controller_Action_HelperBroker::getStaticHelper('viewRenderer');
    }
    return $this->_viewRenderer;
    }

    /**
    * Should the ViewRenderer render a view script?
    *
    * @return boolean
    */
    protected function _shouldRender()
    {
    $vR = $this->_getViewRenderer();
    return (!$this->getFrontController()->getParam('noViewRenderer')
    && !$vR->getNeverRender()
    && !$vR->getNoRender()
    && (null !== $vR->getActionController())
    && $vR->getRequest()->isDispatched()
    && !$vR->getResponse()->isRedirect()
    );
    }

    public function generatePaths(array $vars = array())
    {
    $this->_registerVarsWithInflector();
    $vars = array_merge($this->_defaults, $this->_vars, $vars);
    $inflector = $this->getInflector();
    $generatedPaths = array();
    foreach($this->_viewScriptPaths as $path) {
    $pathVars = array_merge($vars, $path);
    $generatedPaths[] = $inflector->filter($pathVars);
    }
    return array_reverse(array_unique(array_reverse($generatedPaths)));//last occurence more important than first
    // array('test', 'test2', 'test') => array('test2', 'test')
    // @todo rethink this code piece later. must be better solution
    }

    protected function _registerVarsWithInflector()
    {
    $vars = array_merge($this->_defaults, $this->_vars);
    $inflector = $this->getInflector();
    $unregistered = array_keys(array_diff_key($vars, $inflector->getRules()));
    sort($unregistered, SORT_DESC);//more specific first (moduleDir prior to module key)
    foreach($unregistered as $var) {
    $inflector->addFilterRule($var, array('Word_CamelCaseToDash', 'StringToLower'));
    }
    }

    protected function _viewAddScriptPaths(Zend_View_Abstract $view, $paths)
    {
    foreach ($paths as $path) {
    $view->addScriptPath($path);
    }
    }

    /**
    * Get inflector
    *
    * @return Zend_Filter_Inflector
    */
    public function getInflector()
    {
    if (null === $this->_inflector) {
    $this->_inflector = new Zend_Filter_Inflector();
    $this->_inflector->setThrowTargetExceptionsOn(true);
    //setup default rules
    $this->_inflector->addRules(array(
    ':baseDir' => array(),
    ))
    ->setTargetReference($this->_viewScriptPathSpec);
    }
    return $this->_inflector;
    }

    /**
    *
    * @return array
    */
    public function getPaths()
    {
    return $this->_basePaths;
    }

    public function getEnabled()
    {
    return $this->_enabled;
    }

    public function setEnabled($flag = TRUE)
    {
    $this->_enabled = (bool)$flag;
    return $this;
    }

    /**
    *
    * @todo add check for $pathVars keys and values validity
    * @param array $pathVars associative array
    * @param string $placement either append or prepend
    * @return Xrks_Controller_Action_Helper_ViewRendererPathstack
    */
    public function addPath(array $pathVars, $placement = self::PATH_APPEND)
    {
    if($placement == self::PATH_PREPEND) {
    array_unshift($this->_viewScriptPaths, $pathVars);
    } else {
    $this->_viewScriptPaths[] = $pathVars;
    }
    return $this;
    }

    /**
    *
    * @param array|Zend_Config $paths
    * @param string $placement either append or prepend
    * @return Xrks_Controller_Action_Helper_ViewRendererPathstack
    * @throws Xrks_Exception
    */
    public function addPaths($paths, $placement = self::PATH_APPEND)
    {
    if($paths instanceof Zend_Config) {
    $paths = $paths->toArray();
    } elseif (!is_array($paths)) {
    throw new Xrks_Exception('$paths should be either array or instance of Zend_Config');
    }

    if($placement == self::PATH_PREPEND) {
    $paths = array_reverse($paths);
    }
    foreach($paths as $path) {
    $this->addPath((array)$path, $placement);
    }
    return $this;
    }

    /**
    *
    * @param array $pathVars associative array
    * @return Xrks_Controller_Action_Helper_ViewRendererPathstack
    */
    public function setPath(array $pathVars)
    {
    $this->_basePaths = array();
    $this->addPath($pathVars);
    return $this;
    }

    /**
    *
    * @param array|Zend_Config $paths
    * @return Xrks_Controller_Action_Helper_ViewRendererPathstack
    * @throws Xrks_Exception
    */
    public function setPaths($paths)
    {
    $this->_basePaths = array();
    $this->addPaths($paths);
    return $this;
    }

    /**
    *
    * @param string $varName
    * @return string |NULL
    */
    public function getDefaultVar($varName)
    {
    if(key_exists($varName, $this->_defaults)) {
    return $this->_defaults[$varName];
    }
    return NULL;
    }

    /**
    * @param string $varName
    * @param string $value
    * @return Xrks_Controller_Action_Helper_ViewRendererPathstack Provides fluent interface
    */
    public function setDefaultVar($varName, $value)
    {
    $this->_defaults[$varName] = (string)$value;
    return $this;
    }

    /**
    *
    * @param string $name
    * @return string |NULL
    */
    public function getVar($name, $defaults = false)
    {
    if(key_exists($name, $this->_vars)) {
    return $this->_vars[$name];
    }
    return $defaults ? $this->getDefaultVar($name) : NULL;
    }

    /**
    * @param string $varName
    * @param string $value
    * @return Xrks_Controller_Action_Helper_ViewRendererPathstack Provides fluent interface
    */
    public function setVar($varName, $value)
    {
    $this->_vars[$varName] = $value;
    return $this;
    }

    public function unsetVar($name)
    {
    if(key_exists($name, $this->_vars)) {
    unset($this->_vars[$name]);
    }
    return $this;
    }


    public function postDispatch()
    {
    if(!$this->getEnabled() || !$this->_shouldRender()) {
    return; //just skip
    }
    try {
    $vr = $this->_getViewRenderer();
    $this->setVar('module', $vr->getModule());
    $paths = $this->generatePaths();
    $this->_viewAddScriptPaths($vr->view, $paths);
    if(Zend_Registry::isRegistered('Zend_Log')) {
    Zend_Registry::get('Zend_Log')
    ->log($paths, Zend_Log::DEBUG);
    }
    } catch(Exception $e) {
    if(Zend_Registry::isRegistered('Zend_Log')) {
    Zend_Registry::get('Zend_Log')
    ->log($e, Zend_Log::WARN);
    }
    throw $e;
    }
    }
    }

    最佳答案

    我通常处理这个的方式:

  • 我注册了一个布局插件,扩展 Zend_Layout_Controller_Plugin_Layout
  • 我使用 preDispatch Hook 来确定我在
  • 中的模块、 Controller 、操作
  • 我根据上下文在布局和 View 之间切换

  • 对我来说,这是迄今为止最简单的方法。

    GJ

    关于zend-framework - 想法讨论: dynamic view script switching in zend MVC implementation,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5210475/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com