【问题标题】:Translation parameters for menu items using KnpMenuBundle and Symfony3使用 KnpMenuBundle 和 Symfony3 的菜单项的翻译参数
【发布时间】:2017-08-22 18:20:34
【问题描述】:

简介

在我正在使用的个人项目中:

  • XAMPP 与 PHP v7.1.6
  • Symfony v3.3.6
  • KnpMnenuBundle dev-master / 2.2.x-dev [link 1], [link 2], [link 3] 用于管理菜单。
  • 引导程序v3.3.7
  • Bootstrap 和 KnpMenuBundle 集成 [link 4]

设置

为了设置,我使用了 [2]、[3] 中的文档和代码示例 [4]。我的菜单正常工作,BootstrapKnpMenuBundle 之间的集成也可以工作。

目前

菜单包工作正常,简单翻译工作和集成工作。

我的ProfileMenu 代码示例:

public function profileMenu(array $options)
{
    $menu = $this->factory->createItem('root');
    $menu->setChildrenAttribute('class', 'nav navbar-nav navbar-right');

    $menu->addChild('Profile', array('label' => 'menu.profile'))
        ->setExtras(array('dropdown' => true, 'icon' => 'fa fa-user'))
        ->setLinkAttribute('class', "dropdown-toggle")
        ->setLinkAttribute('data-toggle', "dropdown")
        ->setExtra('translation_domain', 'menu');

    $menu['Profile']->setChildrenAttribute("class", "dropdown-menu")
        ->addChild('Logged in as', array('label' => 'layout.logged_in_as'))
        ->setExtra('divider_append', true)
        ->setExtra('translation_domain', 'FOSUserBundle');

    $menu['Profile']->setChildrenAttribute("class", "dropdown-menu")
        ->addChild('My data', array('label' => 'menu.profile.myData', 'route' => 'fos_user_profile_show'))
        ->setExtra('translation_domain', 'menu');
    $menu['Profile']->setChildrenAttribute("class", "dropdown-menu")
        ->addChild('Edit data', array('label' => 'menu.profile.editMyData', 'route' => 'fos_user_profile_edit'))
        ->setExtra('translation_domain', 'menu');
    $menu['Profile']->setChildrenAttribute("class", "dropdown-menu")
        ->addChild('Change password', array('label' => 'menu.profile.changePassword', 'route' => 'fos_user_change_password'))
        ->setExtra('translation_domain', 'menu');

    $menu['Profile']->setChildrenAttribute("class", "dropdown-menu")
        ->addChild('Exit', array('label' => 'menu.profile.logout', 'route' => 'fos_user_security_logout'))
        ->setExtra('divider_prepend', true)
        ->setExtra('translation_domain', 'menu');

    return $menu;
}

菜单渲染如下图所示

问题

如何将翻译参数(即%username%)传递给菜单(由 KnpMenuBundle 提供支持)并使其按预期呈现?

如何提供论据:

|trans({'%username%': app.user.username}

MenuBuilder?

我的密码

有问题的代码块是

$menu['Profile']->setChildrenAttribute("class", "dropdown-menu")
    ->addChild('Logged in as', array('label' => 'layout.logged_in_as'))
    ->setExtra('divider_append', true)
    ->setExtra('translation_domain', 'FOSUserBundle');

label字符串

翻译带参数的字符串通常会提供如下参数:

<li><a href="#">{{ 'layout.logged_in_as'|trans({'%username%': app.user.username}, 'FOSUserBundle') }}</a></li>

然而,在使用KnpMenuBundleBootstrap 集成的情况下,我似乎无法弄清楚如何传递它们。

结论

请指教。

感谢您的时间和知识。

【问题讨论】:

标签: php twitter-bootstrap symfony knpmenubundle knpmenu


【解决方案1】:

您可以将您的 MenuBuilder 声明为这样的服务

#services.yml
app.menu_builder:
        class: AppBundle\Menu\MenuBuilder
        arguments:
            - @knp_menu.factory
            - @security.token_storage
            - @translator.default

根据上面定义的依赖更新MenuBuilder的构造函数

有了这个,您可以访问执行翻译所需的所有内容

$user = $this->tokenStorage->getToken()->getUser(); // If you are under a path protect by security.yml access_constrol
$yourLoggedInTraduction = $this->translator->trans(
    'layout.logged_in_as', [
        '%username%' => $user->getUsername()
    ], 
    'FOSUserBundle', 
    'yourlocale'
); 
dump($yourLoggedInTraduction);

你应该有你的翻译,然后将它映射到你的profileMenu(...)函数逻辑

我没有使用与你相同的 symfony/knpMenu 版本,所以也许这段代码不能直接工作,但你只需要适应你的需要

如果不清楚,请提出问题

希望对您有所帮助,如果可以,请将帖子标记为已解决! :)

【讨论】:

    【解决方案2】:

    特定选项extras.translation_params 可用但未记录: https://github.com/KnpLabs/KnpMenuBundle/blob/master/src/Resources/views/menu.html.twig#L7

    您可以像使用 translation_domain 选项一样使用它:

    $menu['Profile']->setChildrenAttribute("class", "dropdown-menu")
        ->addChild('Logged in as', array('label' => 'layout.logged_in_as'))
        ->setExtra('divider_append', true)
        ->setExtra('translation_domain', 'FOSUserBundle')
        ->setExtra('translation_params', ['%username%' => $user->getUsername()]);
    

    【讨论】:

      【解决方案3】:

      简单回答您的问题

      只需翻译传递给addChild的标签:

      $label = $this->translator->trans('layout.logged_in_as', ['%user%' => $username ]);
      $menu->addChild('Logged in as', array('label' => $label);
      

      $this-&gt;translator 是一个\Symfony\Component\Translation\TranslatorInterface,它被注入到创建菜单的服务中。我通过将"@translator" 作为参数传递给services.yml 中的构造函数来得到它。

      添加多个子菜单

      为了完整起见,我还要注意每个子菜单必须有不同的名称。因此,如果您想创建具有不同参数的多个菜单,请确保不要在不更改菜单名称的情况下复制/粘贴第一行。

      或者使用这样的东西:

      $idx = 0;
      $menu->addChild("Language_".$idx++, array('label' => $label_lang1);
      $menu->addChild("Language_".$idx++, array('label' => $label_lang2);
      

      或者,如果所有子菜单都生成在一个文件中:

      $menu->addChild("Language_".__LINE__, array('label' => $label_lang1);
      $menu->addChild("Language_".__LINE__, array('label' => $label_lang2);
      

      如果不使用不同的名称,则只显示最后一个菜单。

      避免丢失翻译警告

      使用上述解决方案,symfony 工具栏和日志都会报告有关丢失消息的警告。这是因为在翻译域(messages.yml 或您用于翻译的任何内容中)找不到提供的标签。

      为避免这些误报,请在 addChild 调用之后添加以下行:

      $menu->addChild('Logged in as', array('label' => $label)
           ->setExtra('translation_domain', false);
      

      【讨论】:

        猜你喜欢
        • 2018-02-10
        • 1970-01-01
        • 1970-01-01
        • 2016-07-22
        • 2013-01-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多