2

我正在创建一个网站,并使用存储在数据库中的树结构成功地让我的导航菜单正常工作。

Menu作为属性的对象active,但我不知道如何将其设置为活动!如果我能做到这一点,那么我可以获取当前活动Menu的路径并使用 WhiteOctober 的 BreadcrumbsBundle 或类似的东西渲染面包屑。

我已经阅读了大量关于 SO 的问题,并且还查看了可用的不同捆绑包,但我仍然坚持如何做到这一点。

我将如何找出要设置为活动的菜单项?

编辑:

编辑2:

好的,我几乎做到了。我已经设法比较了当前路径,使用$this->container->get('request')->getPathInfo();to aMenu的 set url

为此,我需要将菜单树结构展平为一个数组。当我使用 DoctrineExtensions 的 Tree 扩展时,我使用它的存储库getChildren($node)来执行此操作。所以现在遍历数组很容易,可以比较 url 和 path。

在面包屑控制器中,我可以$current_item从菜单控制器传递 ,然后再次使用 Tree 存储库及其getPath()递归获取给定节点的父节点的方法。

但是,仍然存在一个问题,因为网站上的某些页面没有菜单条目。因此,例如,如果我访问site.com/news/tags/stuff,则没有菜单条目,因此会破坏该站点。

至今:

4

1 回答 1

3

我终于用了比我想象的要多得多的代码来管理它。

在我的标题模板中,我调用了一些自定义 Twig 扩展来呈现主菜单。在 MenuController 中,setCurrentMenuItemAction在渲染菜单期间调用以找出当前菜单项。需要知道当前菜单项,以便可以创建面包屑。本质上,此方法尝试匹配当前 url 路径(使用 getPathInfo()到主菜单中的菜单 url。

简单的部分是通过比较 url 和菜单 url 来找到精确匹配(我现在选择不处理多个精确匹配)。

如果没有找到完全匹配,即 url 不匹配任何菜单,那么它有点需要猜测要设置为当前项目的内容。首先将当前的url路径和菜单路径展开,然后我使用for循环比较每个数组的值:

$count = count($url_parts);
//echo $count;
$intersects = 0;
for($i = 0; $i < $count; $i++){
        if(array_key_exists($i, $child_parts)){
        if($child_parts[$i] == $url_parts[$i]){
            //echo $child_parts[$i];
            $intersects++;
        }
    }
}
return $intersects;

返回值用于计算应选择哪个菜单项。这给出了与 类似的结果array_intersect。问题array_intersect在于它会比较数组,而不管值的顺序如何。例如,假设当前 url 是/news/tag/sports,这给出了以下的交集值:

菜单项网址:

  1. /新闻相交:1
  2. /新闻/一般相交:1
  3. /新闻/体育相交:2

因此array_intersect,使用 url/news/tag/sports将导致/news/sports成为选定的菜单。所需的选定菜单项将是/news,这就是我不得不放弃的原因array_intersect

由于上面的菜单 #1 和 #2 的相交值都是 1,因此只需找到具有最少项目的菜单,其爆炸数组就会给出所需的菜单。

最后,如果仍然没有匹配项:在 url 和任何菜单项之间没有相似之处,则必须创建一个临时菜单。我想创建一个实例Menu来执行此操作,但是在使用 MenuRepository 时遇到了问题(我假设它需要一个菜单​​需要存储在数据库中),所以我只是创建了一个包含当前 url 和 url 的end()数组作为名字。有点凌乱 - 在某些时候可能需要改进。

于 2013-04-12T09:18:21.057 回答