跳到内容

创建作为服务的菜单构建器

编辑此页

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

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

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

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
27
28
29
// src/Menu/MenuBuilder.php

namespace App\Menu;

use Knp\Menu\FactoryInterface;
use Knp\Menu\ItemInterface;

class MenuBuilder
{
    private $factory;

    /**
     * Add any other dependency you need...
     */
    public function __construct(FactoryInterface $factory)
    {
        $this->factory = $factory;
    }

    public function createMainMenu(array $options): ItemInterface
    {
        $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
# config/services.yaml
services:
    app.menu_builder:
        class: App\Menu\MenuBuilder
        arguments: ["@knp_menu.factory"]
        tags:
            - { name: knp_menu.menu_builder, method: createMainMenu, 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
19
20
21
// src/Menu/MenuBuilder.php

// ...

class MenuBuilder
{
    // ...

    public function createSidebarMenu(array $options): ItemInterface
    {
        $menu = $this->factory->createItem('sidebar');

        if (isset($options['include_homepage']) && $options['include_homepage']) {
            $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.menu_builder:
        class: App\Menu\MenuBuilder
        arguments: ["@knp_menu.factory"]
        tags:
            - { name: knp_menu.menu_builder, method: createMainMenu, alias: main } # the previous menu
            - { name: knp_menu.menu_builder, method: createSidebarMenu, alias: sidebar } # Named "sidebar" this time

    # ...

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

1
2
{% set menu = knp_menu_get('sidebar', [], {include_homepage: false}) %}
{{ knp_menu_render(menu) }}
这项工作,包括代码示例,根据 Creative Commons BY-SA 3.0 许可协议获得许可。
目录
    版本