0

管理者が独自の再帰的なページ構造を構築する 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-routes を処理するカスタム ルーター/ルートを作成することを考えていました。これにより、cms-url の組み立ても容易になります。

誰かがこの問題についてアドバイスをくれることを願っています。

4

1 に答える 1

1

あなたのアプローチは(原則として)うまくいくはずだと思います。私が似たようなものに取り組んでいたときに私を苦しめたことの 1 つは、ルート チェーンを「ツリー」として使用できないことでした。これは、複数のルート オプションを持つ 1 つのトップ レベル ルートを持つ場合です。

あなたが持っている場合:

/something
/something/foo
/something/bar

これらは 3 つの完全に別個のルートである必要があります。/foo と /bar を追加して再利用する /something のルート オブジェクトを 1 つ持つことはできません。ルーターがどれを使用するかを判断できることを期待してください。$this->parent メソッドがページを再利用している場合、ここに問題がある可能性があります。

ただし、これが最善のアプローチであるかどうかを疑問に思うのは正しいと思います。小規模なサイトでは機能するはずですが、一致が見つかるまでルートがループでチェックされるため、サイトに 10,000 ページがある場合、これはルーティング プロセスがかなり遅くなり、ルーターは多くの反復タスクを実行することになります。

別の方法は、データベース内のキーに対して関連するルート部分をチェックできるカスタム ルート クラスを使用することです。こうすれば、たった 1 つのルートですべてを実行できるはずです。これにより、かなり高速になります。

バニティ URL をこのように処理する方法のいくつかのコード例を掲載したブログ記事をしばらく前に投稿しました。これは別の問題ですが、解決策は同じ (カスタム ルート クラス) であるため、正しい方向を示している可能性があります。

于 2011-02-15T14:34:24.047 に答える