わかった。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);