phptwitter-bootstrapsymfonyknpmenubundleknpmenu

Translation parameters for menu items using KnpMenuBundle and Symfony3


Introduction

In my personal project I am using:

Setting up

To setup i used documentation in [2], [3] and code samples [4]. My menu is working, integration between Bootstrap and KnpMenuBundle also works.

At the moment

Menu bundle works fine, simple translating works and integration works too.

My ProfileMenu code sample:

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;
}

menu rendering is shown in following image

menu rendering

Question

How can i pass translation parameters (namely %username%) to menu (powered by KnpMenuBundle) and get it to render as intended?

How can one supply arguments:

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

in the MenuBuilder?

MY CODE

The code block in question is

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

namely label string

Translating strings with parameters ordinarily, one would supply arguments like so:

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

Yet, i can not seem to figure out how to pass them in case of using KnpMenuBundle and Bootstrap integration.

Conclusion

Please advise.

Thank you for your time and knowledge.


Solution

  • You could declare your MenuBuilder as a service like this

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

    Update MenuBuilder's constructor according to the dependencies on the above definition

    With this you have access to all the things you need to perform your traduction

    $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);
    

    You should have your traduction and then map it to your profileMenu(...) function logic

    I don't use sames version of symfony/knpMenu than you so maybe this code won't work directly but you just have to adapt to your needs

    Ask for question if you want if it isn't clear

    I hope I have helped you, if yes please mark the post as resolved ! : )