【问题标题】:Zend Framework - cms page routingZend Framework - cms 页面路由
【发布时间】:2011-02-14 21:06:37
【问题描述】:

我有一个 CMS,管理员可以在其中构建自己的递归页面结构。每个页面都有自己的“url-key”。接下来将 url-key 与页面结构结合使用,构建 URL 结构,得到如下结构:

{rootpage url-key}/{subpage url-key}

多语言支持(可选)已开启,您还可以获得语言前缀:

{language code}/{rootpage url-key}/{subpage url-key}

通过为每个页面提供自己的静态路由,然后将它们链接在一起,我几乎完成了上述工作。

/**
 * Initializes the sites navigation.
 *
 * @param array $pages  An array with the cms pages to initialize
 */
protected function _initNavigation(array $pages = null)
{
    $root = true;

    if ($pages === null) {
        $pages = Sjr_App::get()->getModel('page')->getTree();
        $root = true;
    }

    $front = Zend_Controller_Front::getInstance();
    $router = $front->getRouter();

    foreach ($pages as $page) {

        $router->addRoute($page->getRouteName(), $page->getRoute());

        if ($page->children) {
            $this->_initNavigation($page->children);
        }
    }
}

$page->getRoute():

/**
 * Gets the routing for the page.
 * 
 * @return Zend_Controller_Router_Route_Abstract
 */
public function getRoute()
{
    if ($this->_route === null) {

        $this->_route = new Zend_Controller_Router_Route_Static($this->url_key,
            $this->getNavigationData()
        );

        if ($this->parent) {
            $parentRoute = $this->parent->getRoute();
            $this->_route = $parentRoute->chain($this->_route);
        }
    }
    return $this->_route;
}

接下来,如果支持多语言,我会在所有路由前加上语言路由:

foreach ($front->getRouter()->getRoutes() as $routeName => $route) {
    if ($routeName != 'lang') {
        $front->getRouter()->addRoute($routeName, $this->_languageRoute->chain($route));
    }
}

所有路线都正确组装。但是,一旦页面具有和/或是子页面,则路由不匹配。

但除了它还没有工作之外,我还想知道这是否是最好的方法。页面结构可能会变得非常大,这意味着它还会创建很多路由对象。我不确定这对性能有什么影响。

另外,我正在考虑编写一个自定义路由器/路由来处理 1 条路由中的所有 cms 路由。这也将更容易组装 cms-url。

希望有人能就这个问题给我一些建议。

【问题讨论】:

    标签: zend-framework zend-route


    【解决方案1】:

    我认为您的方法应该有效(原则上)。当我在做类似的事情时,让我感到痛苦的一件事是,你不能将路由链用作“树”,在其中你有一个顶级路由,其下有多个路由选项。

    如果你有:

    /something
    /something/foo
    /something/bar
    

    这些需要是三个完全独立的路线。您不能通过添加 /foo 和 /bar 来重用 /something 的一个路由对象,期望路由器能够确定使用哪一个。如果您的 $this->parent 方法正在重用页面,这可能就是您的问题所在。

    但是,我认为您想知道这是否是最好的方法是正确的。它应该适用于小型站点,但是由于在循环中检查路由直到找到匹配项,如果一个站点有 10,000 个页面,那么这将是一个非常缓慢的路由过程,并且路由器将执行大量重复性任务。

    另一种方法是使用自定义路由类,该类能够根据数据库中的键检查相关路由部分。这样一来,您应该只需一条路线即可完成所有操作,这将大大加快速度。

    我不久前发布了一个blog post,其中包含一些关于如何以这种方式处理虚 URL 的代码示例,所以虽然这是一个不同的问题,但解决方案是相同的(自定义路由类),所以它可能会指向你正确的方向。

    【讨论】:

    • 谢谢!这似乎是我所希望的所有答案。生病去阅读你的博客,然后可能会写我自己的路线。
    猜你喜欢
    • 1970-01-01
    • 2015-06-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-09
    • 2011-04-01
    • 2014-05-02
    相关资源
    最近更新 更多