Introduction
In my personal project I am using:
XAMPP with PHP v7.1.6
Symfony v3.3.6
KnpMnenuBundle dev-master / 2.2.x-dev [link 1], [link 2], [link 3] in order to manage Menus.
Bootstrap v3.3.7
Bootstrap and KnpMenuBundle integration [link 4]
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
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>{{ 'layout.logged_in_as'|trans({'%username%': app.user.username}, 'FOSUserBundle') }}</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.
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 ! : )
A specific option extras.translation_params is available but not documented:
https://github.com/KnpLabs/KnpMenuBundle/blob/master/src/Resources/views/menu.html.twig#L7
You can use it in the same way you used the translation_domain option:
$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()]);
Simple answer to your question
Simply translate the label passed to addChild:
$label = $this->translator->trans('layout.logged_in_as', ['%user%' => $username ]);
$menu->addChild('Logged in as', array('label' => $label);
$this->translator is a \Symfony\Component\Translation\TranslatorInterface that is injected into the service creating the menu. I got it by passing "#translator" as an argument to the constructor in services.yml.
Add multiple child menus
For the sake of completeness, I'll also note that every child menu must have a different name. So, if you want to create multiple menus with different parameters, make sure you don't copy/paste the first line without also changing the menu name.
Or use something like this:
$idx = 0;
$menu->addChild("Language_".$idx++, array('label' => $label_lang1);
$menu->addChild("Language_".$idx++, array('label' => $label_lang2);
Or, if all the child menus are generated in one file:
$menu->addChild("Language_".__LINE__, array('label' => $label_lang1);
$menu->addChild("Language_".__LINE__, array('label' => $label_lang2);
If you don't use different names, only the last menu is displayed.
Avoid missing translation warnings
With the above solution, the symfony toolbar and the log both report warnings about missing messages. That's because the provided label can't be found in the translation domain (in messages.yml or whatever you use for your translations).
To avoid those false positive, add the following line after the addChild call:
$menu->addChild('Logged in as', array('label' => $label)
->setExtra('translation_domain', false);
Related
I'm developing a prestashop module and I'm trying to show a category tree in my backoffice configuration page.
I'm trying to follow this instructions below but I don't know exactly where to add this code.
It should be inside main module's php? or inside a separate .php file and call it from the main one (don't know how to do it either).
As much time I'm spending trying to figure out, how to implement the code in the link above, the more I think I'm losing my time.
I see that "use" files, and this JS, " /admin-dev/themes/new-theme/js/components/form/choice-tree.js " are not in any prestashop folders.
Well, you should invest some time and learn Symfony since this is what you need to build backend modules for Prestashop 1.7.
As a pointer, you need to create a form class extending the CommonAbstractType, add a build form method. e.g. :
public function buildForm(FormBuilderInterface $builder, array $options)
{
$this->context = Context::getContext();
$parents = [
['id_category' => 2, 'name' => 'Home', 'children' => $this->getSubCategories(1, true, 2)]
];
$builder->add('category', CategoryChoiceTreeType::class, [
'choices_tree' => $parents,
'choice_value' => 'id_category',
'choice_children' => 'children',
'choice_label' => 'name',
'disabled_values' => $disabledCategories,
'label' => 'Choose a category'
])
then add methods for retrieving the data to populate the form fields.
Then use this class in your controller and display the form:
$form = $this->createForm(YourFormForm::class);
Also add a processForm to process data.
As mentioned, this is not a copy/paste situation you need to understand the Symfony workflow.
The only way that I found to "paint" the categorytree in my configuration page is adding this code to the inputs form array:
Can anyone tell me how to retrieve users selection data to my database?
It does not work as any other form field.
array(
'type' => 'categories',
'label' => $this->l('Destination Category'),
'desc' => $this->l('Select ONE Category'),
'name' => 'CATEGORY_CATEGORY_TO',
'tree' => [
// 'selected_categories' => [],
'disabled_categories' => null,
'use_search' => false,
'use_checkbox' => false,
'id' => 'id_category_tree',
],
'required' => true
),
Well, it is SOLVED!!!! Finally it was very simple, but you must get the correct info for you particular case.
#Robertino's answer might be the best implementation, I don't know, but it became impossible to solve for me,
I uses this code below, and called $categoryTree from the form input. This input must be type=> categories_select
Thanks for your time, and for the help of another post from this forum.
$root = Category::getRootCategory();
//Generating the tree
$tree = new HelperTreeCategories('categories_1'); //The string in param is the ID used by the generated tree
$tree->setUseCheckBox(false)
->setAttribute('is_category_filter', $root->id)
->setRootCategory($root->id)
->setSelectedCategories(array((int)Configuration::get('CATEGORY_1'))) //if you wanted to be pre-carged
->setInputName('CATEGORY_1'); //Set the name of input. The option "name" of $fields_form doesn't seem to work with "categories_select" type
$categoryTree = $tree->render();
And the Form:
array(
'type' => 'categories_select',
'label' => $this->l('Category'),
'desc' => $this->l('Select Category '),
'name' => 'CATEGORY_1', //No ho podem treure si no, no passa la variable al configuration
'category_tree' => $categoryTree, //This is the category_tree called in form.tpl
'required' => true
I need to add an additional HTML attribute to each choice of an EntityType field in Symfony 2.7.
Following this guide, I assume that EntityType inherits this feature from ChoiceType. I tried something like the following, but without effect; no mytype attribute gets added to the rendered select options.
$builder->add('customer_email', 'email')
->add('Product', 'entity', array(
'class' => 'MyBundle:Product',
'property' => 'name',
'empty_value' => 'None',
'required' => false,
'choice_attr' => function ($val, $key, $index) {
return array('mytype' => $val->getType());
}))
This is not necessarily the best answer, but I can't post comments yet.
When implementing choice_attr, choice_labels etc... on ChoiceType and EntityType, it seems like choice_attr was left behind on the latter, there are a few comments about it on github, I personally need the same feature, hopefully it'll be implemented.
https://github.com/symfony/symfony/issues/4067
P.S.: Investigated further, it is indeed inherited from ChoiceType, and it only appears in the 2.7 documentation, if you write something like
'choice_attr' => function (Product $product, $key, $index) {
return ['class' => $product->getType() ];
}
You should get the class attribute set correctly, for custom attributes I am not sure, you might need to use 'attr' => 'foo'.
P.P.S.: Tested 'foo' =>'bar' and it works, no need to nest inside 'attr'.
In CakePHP2 we use FormHelper's inputDefault options to set default values for all input within form
For Example :
echo $this->Form->create('User', array(
'inputDefaults' => array(
'required' => false,
'error' => false,
'div' => 'form-group',
'label' => false
)
));
But i am not finding any option in CakePHP3 helper like this, they haven't mentioned removed it or not?
Is anybody there, who know about this....
Thanks
According to migration guide inputDefaults option was removed.
The inputDefaults option has been removed from create().
FormHelper::inputDefaults() has been removed. You can use templates() to define/augment the templates FormHelper uses.
templates() method of FormHelper documentation you can find here.
I find the Breadcrumbs widget quite useful. However, on the right side within the widget there is enough space for something else. If I'd like to put a link ('a' tag, but could be actually any other small thing) right aligned into the Breadcrumbs, how could I do that? What is a simple and proper solution? Should I extend the class, develop my own, use begin and end of the widget somehow?
If you look at yii\widgets\Breadcrumbs you see that there is a third parameter in the breadcrumbs items
From the Yii2 file
[
'label' => 'Post Category',
'url' => ['post-category/view', 'id' => 10],
'template' => "<li><b>{link}</b></li>\n", // template for this link only
],
So by adding something like this in your main layout file
$this->params['breadcrumbs'][] = [
'label' => 'Your Label',
'url' => ['controller/action'],
'template' => "<li style="float: right;">{link}</li>\n"
];
you will get a link at the right side. This link will come with a / prefixed, but you can bind it to a .class instead and configure it the way you want.
'template' => "<li class=\"yourClass\">{link}</li>\n"
I am converting a ZF2 "filename.phtml" view to a "filename.twig" view. I am needing help knowing how to pass a variable to a partial. The nature of the partial provides a variety of "social network" share type buttons. What I am giving the partial is the URL of the web page being accessed to "share".
The code I am trying to convert:
echo $this->partial('partial/socialnetworkshare', array('web_page' => $this->url('main-prayersfortoday', array('prayer_reference' => $this->prayer_reference ))));
I haven't correctly figured out how to pass the value of "$this->prayer_reference". This is what I have tried:
{{ partial('partial/socialnetworkshare', {'web_page' : url('main-prayersfortoday') , 'prayer_reference' : prayer_reference }) }}
prayer_ministry is to match this route:
'main-prayersfortoday' => array(
'type' => 'segment',
'options' => array(
'route' => '/prayers-for-today[/:prayer_reference]',
'constraints' => array(
'prayer_reference' => '[0-9]*'
),
'defaults' => array(
'controller' => 'Main\Controller\Main',
'action' => 'prayersfortoday'
)
)
),
The value of "prayer_ministry" is passing through this controller:
$viewModel
->setTemplate('main/main/prayersfortodaydocument')
->setVariable('prayer_reference', $this->params()->fromRoute('prayer_reference'))
->setVariable('document', $document);
I very much appreciate your help. Thank you.
I think what you're after is something like this, using the include tag:
{% include 'partial/socialnetworkshare' with {
'web_page': path('main-prayersfortoday'),
'prayer_reference': prayer_reference
} %}
In Symfony, we have Twig extensions which provide the Twig path() function similar to $this->url() in Zend. You may need to register you own Twig extension to provide this in Zend.