跳到内容

创建作为服务的菜单

编辑此页

注意

将菜单注册为服务有一些限制

  • 它不允许使用构建器选项
  • 如果您多次渲染相同的菜单,它会多次重用相同的实例,这可能会产生奇怪的副作用。

建议仅注册 菜单构建器作为服务

此扩展包为您提供了一种非常便捷的方式,通过遵循约定来创建菜单。

但是,如果您愿意,您可以选择为您的菜单对象创建一个服务。此方法的优点是您可以注入菜单需要的确切依赖项。这可以使代码更具可测试性,并且可能更具可重用性。缺点是它需要稍微多一些的设置。

首先为您的菜单创建一个构建器。您可以在构建器中放入任意数量的菜单,因此您的应用程序中可能只有一个(或几个)这样的构建器类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// src/Menu/MenuBuilder.php

namespace App\Menu;

use Knp\Menu\FactoryInterface;
use Symfony\Component\HttpFoundation\RequestStack;

class MenuBuilder
{
    private $factory;

    public function __construct(FactoryInterface $factory)
    {
        $this->factory = $factory;
    }

    public function createMainMenu(RequestStack $requestStack)
    {
        $menu = $this->factory->createItem('root');

        $menu->addChild('Home', ['route' => 'homepage']);
        // ... add more children

        return $menu;
    }
}

接下来,注册两个服务:一个用于您的菜单构建器,另一个用于由 createMainMenu 方法创建的菜单对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# config/services.yaml
services:
    app.menu_builder:
        class: App\Menu\MenuBuilder
        arguments: ["@knp_menu.factory"]

    app.main_menu:
        class: Knp\Menu\MenuItem # the service definition requires setting the class
        factory: ["@app.menu_builder", createMainMenu]
        arguments: ["@request_stack"]
        tags:
            - { name: knp_menu.menu, alias: main } # The alias is what is used to retrieve the menu

    # ...

您现在可以通过上面 alias 键中给出的名称,直接在模板中渲染菜单

1
{{ knp_menu_render('main') }}

假设现在我们需要为侧边栏创建第二个菜单。过程很简单!首先向您的构建器添加一个新方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// src/Menu/MenuBuilder.php

// ...

class MenuBuilder
{
    // ...

    public function createSidebarMenu(RequestStack $requestStack)
    {
        $menu = $this->factory->createItem('sidebar');

        $menu->addChild('Home', ['route' => 'homepage']);
        // ... add more children

        return $menu;
    }
}

现在,为您的新菜单创建一个服务,为其指定一个新名称,例如 sidebar

1
2
3
4
5
6
7
8
9
10
# config/services.yaml
services:
    app.sidebar_menu:
        class: Knp\Menu\MenuItem
        factory: ["@app.menu_builder", createSidebarMenu]
        arguments: ["@request_stack"]
        tags:
            - { name: knp_menu.menu, alias: sidebar } # Named "sidebar" this time

    # ...

现在可以像其他菜单一样渲染它

1
{{ knp_menu_render('sidebar') }}
这项工作,包括代码示例,根据 Creative Commons BY-SA 3.0 许可协议获得许可。
目录
    版本