【问题标题】:Nested menu with parameters in Symfony and KNPmenuSymfony 和 KNPmenu 中带有参数的嵌套菜单
【发布时间】:2014-07-01 12:41:17
【问题描述】:

我正在努力使用 Symfony2 和 Knpmenu 来构建一个菜单来处理:

  • 面包屑
  • 使用动态参数路由
  • 从不同的孩子开始呈现单独的菜单

我的Menu/Builder.php 文件看起来像这样(navbar、pull-nav 等额外位是 mopa_bootstrap 扩展的一部分,它使用引导类处理渲染):

namespace My\AppBundle\Menu;

use Knp\Menu\FactoryInterface;

class Builder
{
    public function mainMenu(FactoryInterface $factory, array $options)
    {
        $menu = $factory->createItem(
            'root', array(
                'navbar' => true,
                'pull-right' => true,
            )
        );

        // Main Menu -> Config
        // no link here, it's just a placeholder
        $dropdown = $menu->addChild(
            'Config', array(
                'dropdown' => true,
                'caret' => true,
            )
        );

        // Menu -> Config -> User
        $dropdown2 = $dropdown ->addChild(
            'User', array(
                'route' => 'user',
            )
        );

        // Secondary Menu -> Edit (but child of Menu -> Config -> User)
        $dropdown2->addChild(
            'Edit',
            array(
                'route' => 'user_edit',
                'routeParameters' => array('name' => $options['id']),
            )
        );

我们的想法是有一个仅打印前两个级别的主菜单,以及一个在其他地方呈现的单独菜单,以允许用户在正在查看的特定元素的编辑/删除/任何视图之间移动。

我想要实现的是拥有一个单一的结构,从而处理育儿结构,不仅让标志父母在菜单中处于活动状态,而且能够处理有效的面包屑结构。

Resources/views/base.html.twig 我这样调用主菜单:

{{ mopa_bootstrap_menu('MyAppBundle:Builder:mainMenu', {depth: 2}) }}

理想情况下是这样的子菜单:

{% set id = app.request.attributes.get('id') %}
{% if app.request.attributes.get('_route') starts with 'user_' %}
    {% set menu = knp_menu_get('MyAppBundle:Builder:mainMenu', ['User'], {'id': id }) %}
    {{ knp_menu_render(menu) }}
{% endif %}

但是:

  1. knpmenu 在渲染主菜单时返回错误,因为 $options['id'] 未定义
  2. 我仍然无法呈现二级菜单(因此通过传递参数“用户”) - 页面只是在该块中返回黑色输出

这种方法正确吗? 我正在使用"knplabs/knp-menu": "2.0.*@dev""symfony/symfony": "2.5.*"

【问题讨论】:

    标签: symfony knpmenu


    【解决方案1】:

    事实证明,使用this method可以有效访问$request,并在MenuBuilder.php文件中添加条件,仅在特定条件下才提示子子项。

    最终代码如下所示:

    // Menu/MenuBuilder.php
    
    namespace My\AppBundle\Menu;
    
    use Knp\Menu\FactoryInterface;
    use Symfony\Component\HttpFoundation\Request;
    
    class MenuBuilder
    {
        private $factory;
    
        /**
         * @param FactoryInterface $factory
         */
        public function __construct(FactoryInterface $factory)
        {
            $this->factory = $factory;
        }
    
        public function createMainMenu(Request $request)
        {
            $menu = $this->factory->createItem(
                'root', array(
                    'navbar' => true,
                    'pull-right' => true,
                )
            );
    
        // Main Menu -> Config
        // no link here, it's just a placeholder
        $dropdown = $menu->addChild(
            'Config', array(
                'dropdown' => true,
                'caret' => true,
            )
        );
    
        // Menu -> Config -> User
        $dropdown2 = $dropdown ->addChild(
            'User', array(
                'route' => 'user',
            )
        );
    
        // Secondary Menu -> Edit (but child of Menu -> Config -> User)
        // Skip this part if we are not in the relevant page, thus to avoid errors
        if (false !== strpos($request->get('_route'), 'user_') && $request->get('id')):
        $dropdown2->addChild(
            'Edit',
            array(
                'route' => 'user_edit',
                'routeParameters' => array('id' => $request->get('id')),
            )
        );
        endif;
    

    以及服务配置文件:

    // Resources/config/services.yml
    
    services:
        my_app.menu_builder:
            class: My\AppBundle\Menu\MenuBuilder
            arguments: ["@knp_menu.factory"]
    
        my_app.menu.main:
            class: Knp\Menu\MenuItem
            factory_service: my_app.menu_builder
            factory_method: createMainMenu
            arguments: ["@request"]
            scope: request
            tags:
                - { name: knp_menu.menu, alias: main }
    

    然后是Resources/views/base.html.twig 模板:

    // Main menu
    {% set menu = knp_menu_get('main', ['Config', 'Users'], {'id': id }) %}
    {{ knp_menu_render(menu) }}
    
    // Secondary menu
    {% if app.request.attributes.get('_route') starts with 'user_' %}
        {% set menu = knp_menu_get('main', ['Config', 'Users'], {'id': id }) %}
        {{ mopa_bootstrap_menu(menu, {'automenu': 'navbar'}) }}
    {% endif %}
    

    该解决方案似乎有效,但如果您有更好的方法,请告诉我!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-08-24
      • 1970-01-01
      • 2023-04-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多