在 Symfony2 中构建面包屑

问题描述 投票:0回答:1

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

A

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

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

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

编辑:

编辑2:

好吧,我已经快完成了。我成功地使用

$this->container->get('request')->getPathInfo();
Menu
的设置
url
来比较当前路径。

为此,我需要将菜单树结构展平为数组。当我使用 DoctrineExtensions 的树扩展时,我使用其存储库的

getChildren($node)
来执行此操作。所以现在迭代数组很容易并且可以比较 url 和路径。

在面包屑控制器中,我可以从菜单控制器传递

$current_item
,并再次使用树存储库及其
getPath()
方法,该方法递归地获取给定节点的父节点。

但是,仍然存在一个问题,因为网站上的某些页面没有菜单条目。例如,如果我访问

site.com/news/tags/stuff
,则没有菜单条目,因此会破坏网站。

到目前为止:

php symfony menu breadcrumbs
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
,网址
/news/tag/sports
将导致
/news/sports
成为选定的菜单。所需的选定菜单项将是
/news
,这就是为什么我不得不放弃
array_intersect

由于上面的菜单 #1 和 #2 的相交值为 1,因此只需找到其分解数组中项目最少的菜单即可给出所需的菜单。

最后,如果仍然没有匹配项:url 和任何菜单项之间没有相似之处,则必须创建一个临时菜单。我想创建一个

Menu
的实例来执行此操作,但在使用 MenuRepository 时遇到了问题(我假设它需要将菜单存储在数据库中),所以我只是创建了一个包含当前 url 和url 的
end()
作为名称。有点乱 - 可能在某些时候需要改进。

© www.soinside.com 2019 - 2024. All rights reserved.