3

わかった。Zendを使用してCMSを構築しています。見た目ほど単純ではありませんが、それでも私にとって最良の解決策です。IDとPARENTのツリーシステムがあります。PARENTマークは、子が存在するページの下にあります。ともかく。シンプルなもの。

ページが作成またはソートされるたびに、ナビゲーションとルートが再生成されます。

ナビゲーションとルートを作成するためのAdmin_Pages_Modelコード全体をここにコピーします。

ナビゲーションはここで作成されます:(ルーターからロードされるため、モジュール/コントローラー/アクション情報は必要ないと思います)

    public function createNavigation($locale = false){  
    $root = $this->getRoot($locale);

    $navigation = array();
    $router = array();

    foreach($root as $row){

        $navigation[$row["id"]] = array(
            "label" => $row["name"],
            "module" => "frontend",
            "controller" => "page",
            "action" => "show",
            "route" => "route_".$row["id"],
            "visible" => (boolean) $row["active"],
            "lastmod" => ($row["modified"] ? $row["modified"] : $row["created"])
        );

        $children = $this->getChildren($row["id"]);

        if(count($children)){
            foreach($children as $child){

                $navigation[$row["id"]]["pages"][$child["id"]] = $this->_createNavigation($child["id"]);

            }
        }

    }

    $nav = new Zend_Navigation(new Zend_Config($navigation));

    $this->createRoutes();

    if(!$locale){
        Crcms_Config::setConfig("navigation_sitemap", $nav->toArray());
    } else {
        Crcms_Config::setConfig("navigation_".$locale, $nav->toArray());
    }
}
private function _createNavigation($id){
    $page = $this->getPage($id);

    $navigation = array(
        "label" => $page["name"],
        "module" => "frontend",
        "controller" => "page",
        "action" => "show",
        "route" => "route_".$page["id"],
        "visible" => (boolean) $page["active"],
        "lastmod" => ($page["modified"] ? $page["modified"] : $page["created"])
    );

    $children = $this->getChildren($page["id"]);

    if(count($children)){
        foreach($children as $child){

            $navigation["pages"][$child["id"]] = $this->_createNavigation($child["id"]);

        }
    }

    return $navigation;
}

最後に、ナビゲーションをデータベースに保存する前に、$ this-> createRoutes();を呼び出します。だからここにコードがあります:

    public function createRoutes(){
    $root = $this->getRoot($locale);

    foreach($root as $row){

        $slugPath = "/".$row["slug"]."";

        $router["route_".$row["id"]] = array(
            "route" => $slugPath.".html",
            "defaults" => array(
                "pageId" => $row["id"],
                "locale" => $row["locale"],
                "module" => "frontend",
                "controller" => "page",
                "action" => "show"
            )
        );

        $children = $this->getChildren($row["id"]);

        if(count($children)){
            foreach($children as $child){

                $router = array_merge($router, $this->_createRoutes($child["id"], $slugPath."/".$child["slug"].""));

            }
        }
    }

    $routerConfig = new Zend_Config($router);

    Crcms_Config::setConfig("frontend_router", $routerConfig->toArray());

}
private function _createRoutes($id, $slugPath){
    $page = $this->getPage($id);

    $router["route_".$page["id"]] = array(
        "route" => $slugPath.".html",
        "defaults" => array(
            "pageId" => $page["id"],
            "locale" => $page["locale"],
            "module" => "frontend",
            "controller" => "page",
            "action" => "show"
        )
    );

    $children = $this->getChildren($page["id"]);

    if(count($children)){
        foreach($children as $child){
            $router = array_merge($router, $this->_createRoutes($child["id"], $slugPath."/".$child["slug"].""));
        }
    }

    return $router;
}

これで、すべてがデータベースになりました。私のブーストラップで私はロードします:

    protected function _initPostFrontController(){
    $this->bootstrap('frontController');

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

    $frontendRouterConfig = new Zend_Config(Crcms_Config::getConfig("frontend_router"));

    $router = $front->getRouter();
    $router->addConfig($frontendRouterConfig);

    $front
        ->setParam("prefixDefaultModule", true)
        ->registerPlugin(new Global_Setup())
        ->registerPlugin(new Global_Auth())
        ->registerPlugin(new Global_Translation())
        ->registerPlugin(new Global_LayoutLoader());
}

これは私のGlobal_Setupです:

class Global_Setup extends Zend_Controller_Plugin_Abstract {
public function preDispatch (Zend_Controller_Request_Abstract $request){

    $front = Zend_Controller_Front::getInstance();

    $errorHandler = $front->getPlugin("Zend_Controller_Plugin_ErrorHandler");
    $errorHandler->setErrorHandlerModule("frontend");

    $layout = Zend_Layout::getMvcInstance();
    $view = $layout->getView();

    switch($request->getModuleName()){
        case "admin":
            $session = new Zend_Session_Namespace("Crcms_Admin");

            $locale = Zend_Registry::get("Zend_Locale");
            $view->doctype("HTML5");        
            $view->headTitle(Zend_Registry::get("Zend_Config")->system->about->software);
            $view->headTitle()->setSeparator(" | ");
            $view->headTitle(Crcms_Config::getConfig("site_name"));
            $view->headLink()->headLink(array(
                "rel" => "shortcut icon",
                "href" => Zend_Registry::get("Zend_Config")->system->paths->http->publib."/images/favicon.ico"), "PREPEND");    
        break;
        default:
            $session = new Zend_Session_Namespace("Crcms_Frontend");

            if(!$session->locale){
                $session->locale = Crcms_Config::getConfig("locale_default");
            }

            $navigation = new Zend_Navigation(new Zend_Config(Crcms_Config::getConfig("navigation_".$session->locale)));
            $view->navigation()->setContainer($navigation);

        break;
    }

}

}

つまり、基本的にすべてが大丈夫です。LayoutLoaderは、管理者/フロントエンドに基づいてデフォルトのレイアウトパスとレイアウトを選択します。

ともかく。私のフロントエンドレイアウトにはこれがあります:

<div id="menu"><?= $this->navigation()->menu(); ?></div>
<div id="breadcrumb"><?= $this->navigation()->breadcrumbs(); ?></div>
<div id="content"><?= $this->layout()->content; ?></div>

メニューはうまく作成されます。すべてのレベルはスーパー(Y)です。しかし、すべてがclass="active"です!!! そしてreadcrumbは常に最も深い要素を表示します。

ページ選択は正常に機能します。param pageIdが正しく渡され、ルーターが機能します。ナビゲーションがめちゃくちゃになっているだけです。

あなたにアイデアを与えるためのいくつかの写真:

管理者側: -http: //grab.by/6d67

フロントエンド側:

写真からわかるように、URLが変更されます-コンテンツも変更されます。したがって、ルーターは機能する必要があります。

すべてが「アクティブ」です:http://grab.by/6d6j

ここにたくさんの情報を貼り付けたことは知っていますが、助けてください。私はこの問題に20時間以上取り組んできましたが、解決策はありません。

ちょっと修正しました。私はそれが「正しい方法」だとは思いませんが、それでも-今は機能しています。ナビゲーションからコントローラー/アクション/モジュールをコメントアウトしました(ルートでは何も変更されていません)。"id"=>"page-"。$page["id"]を追加しました。

今私のGlobal_Setupで私はこのようなことをしました->

$navigation = new Zend_Navigation(new Zend_Config(Crcms_Config::getConfig("navigation_".$session->locale)));
$navigation->findBy("id", "page-".$request->getParam("pageId"))
->setActive(true);
4

1 に答える 1

4

コードを見ただけではこれを解決するのは難しいため、これは推測にすぎません。

ルートを構築しているときは、pageId を設定しています。

$router["route_".$row["id"]] = array(
    "route" => $slugPath.".html",
    "defaults" => array(
        "pageId" => $row["id"],
        "locale" => $row["locale"],
        "module" => "frontend",
        "controller" => "page",
        "action" => "show"
    )
);

おそらくこれは、リクエストされたページを特定するためにコントローラーで使用する一意の識別子ですか?

Zend Navigation は、各ページで isActive() メソッドを呼び出して、どのページを強調表示するかを決定します。Mvc ページの場合、指定したルート パラメーター (コントローラー、モジュール、アクション、およびその他のパラメーター) を要求オブジェクトのパラメーターと比較します。あなたの場合、すべてのページが同じアクションを指しており、Zend Navigation に pageId を指定していないため、モジュール/コントローラー/アクションをリクエスト内のモジュール/コントローラー/アクションと比較するだけで、常に一致します。 .

私が正しければ、作成するナビゲーション オブジェクトに pageId を追加するだけでよいので、最初のコード サンプルのループでは次のようになります。

$navigation[$row["id"]] = array(
    "label" => $row["name"],
    "module" => "frontend",
    "controller" => "page",
    "action" => "show",
    "route" => "route_".$row["id"],
    "params" => array("pageId" => $row["id"]), // this line is new!
    "visible" => (boolean) $row["active"],
    "lastmod" => ($row["modified"] ? $row["modified"] : $row["created"])
);

これがうまくいかない場合は、少なくとも正しい方向に向けられることを願っています。問題は isActive() メソッドにあると思います。そのため、Zend Framework コードを (一時的に) デバッグしてもかまわない場合は、Zend/Navigation/Page/Mvc.php でそのメソッドを見つけて、それが呼び出されていることを確認してください。 、どこが間違っているのかを理解できるかどうかを確認してください。

于 2010-09-02T23:15:47.387 に答える