在Symfony2中构建面包屑

时间:2013-04-09 13:41:24

标签: symfony menu breadcrumbs

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

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

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

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

编辑:

编辑2:

好的,我差不多完成了。我已设法使用$this->container->get('request')->getPathInfo();Menu的集合url比较当前路径。

为此,我需要将菜单树结构展平为数组。当我使用DoctrineExtensions的树扩展时,我使用其存储库的getChildren($node)来执行此操作。所以现在迭代数组很容易,可以比较网址和路径。

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

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

到目前为止:

1 个答案:

答案 0 :(得分:3)

我终于管理了它,虽然代码比我想象的要多得多。

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

简单的部分是通过比较网址和菜单网址来找到完全匹配(此时我选择不处理多个完全匹配)。

如果未找到完全匹配,即网址与任何菜单都不匹配,则需要猜测要设置为当前项目的内容。首先,当前的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的问题在于,无论数值的顺序如何,它都会比较数组。例如,假设当前网址为/news/tag/sports,这会给出交集值:

菜单项网址:

  1. / news 相交:1
  2. / news / general 相交:1
  3. / news / sports 相交:2
  4. 因此,使用array_intersect,网址/news/tag/sports会导致/news/sports成为所选菜单。所需的选定菜单项为/news,这就是我不得不放弃array_intersect的原因。

    由于上面的菜单#1和#2的交叉值均为1,因此只需找到包含最少项目的菜单,其分解数组就会显示所需的菜单。

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