这是我的做法(按照对 OP 问题的评论中的要求)
在我的布局中,我将以下代码放在我希望顶部菜单出现的位置:
<?php echo $this->element('Menu.top_navigation'); ?>
这非常简单,并且允许我团队中的 HTML 设计人员将菜单放在他们想要的任何位置。
当然,幕后还有更多事情发生。以下是完成这项工作所需的其他文件:
插件/菜单/视图/元素/top_navigation.ctp:
$thisMenu = ClassRegistry::init('Menu.Menu');
$menus = $thisMenu->display_menu_widget(array('position'=> 'top'));
echo $this->element('Menu.display_ul', array('menus' => $menus));
请注意,这只是一个包装器——您可以为页脚导航制作更多这些内容,甚至可以制作一个允许您将位置作为参数传递的元素。
插件/菜单/视图/元素/display_ul.ctp:
<?php
if(empty($depth)){
$depth = 0;
}
switch($depth){
case 0:
$classes = "dropdown";
break;
default:
$classes = "";
break;
}
?>
<ul class="<?php echo $classes ?> depth_<?php echo $depth ?>">
<?php foreach ($menus as $menu): ?>
<li>
<a href="<?php echo $menu['MenuItem']['url']; ?>">
<?php echo $menu['MenuItem']['title']; ?>
</a>
<?php
if(count($menu['children']) > 0){
echo $this->element(
'Menu.display_ul',
array(
'menus' => $menu['children'],
'depth' => $depth + 1
)
);
}
?>
</li>
<?php endforeach; ?>
</ul>
插件/菜单/模型/Menu.php:
/**
* display_menu_widget method
*
* @param array $options
* @return void
*/
public function display_menu_widget($options = array()) {
$defaults = array(
'position' => 'top'
);
$settings = array_merge($defaults, $options);
$this->recursive = 0;
$menuItems = array();
$conditions = array(
'Menu.position' => $settings['position']
);
$menuDetails = $this->find('first', array('recursive' => -1, 'conditions' => $conditions));
$menuPosition = $menuDetails[$this->alias]['position'];
$parentId = $menuDetails[$this->alias][$this->primaryKey];
$conditions = array(
$this->MenuItem->alias . '.menu_id' => $parentId
);
$this->MenuItem->recursive = 0;
$cacheName = 'default' . 'ModelMenuItem';
$cacheKey = $this->generateCacheName(array('type' => 'threaded', 'conditions' => $conditions));
$menuItems = Cache::read($cacheKey, $cacheName);
if(empty($menuItems) || PWFunctions::forceCacheFlush()){
$menuItems = $this->MenuItem->find('threaded', array('conditions' => $conditions));
Cache::write($cacheKey, $menuItems, $cacheName);
}
return $menuItems;
}
该菜单功能可能比您需要的更多,我正在使用一些积极的缓存例程来减少数据库负载,我建议在担心缓存之前只使用该功能的基本功能。
这个解决方案对我来说效果很好,我认为它是最不违反 MVC 概念的解决方案——当你作为设计师处于 HTML 模式并认为“嘿,我需要显示顶部菜单”时,它只是一个线在您的视图中,您不必担心修改控制器或模型。
我在我当前的 CakePHP 项目中一直使用这种模式,而且它似乎工作得很好。