knpMenu 无法添加动态路由
knpMenu can't add dynamique route
我正在使用 symfony 3.3 和 knpMenu 2.2
我已将菜单生成器注册为服务
lilworks_store.menu_builder:
class: LilWorks\StoreBundle\Menu\MenuBuilder
arguments: ["@knp_menu.factory","@request_stack"]
tags:
- { name: knp_menu.menu_builder, method: createMainMenu, alias: main } # The alias is what is used to retrieve the menu
我可以毫无问题地呈现一个简单的菜单。但是当我尝试使用带参数的路由时出现错误
An exception has been thrown during the rendering of a template ("Parameter "customer_id" for route "customer_show" must match "[^/]++" ("" given) to generate a corresponding URL.").
我可以在 $this->requestStack->getCurrentRequest()->get('customer_id') 条件下避免这种情况,仅当路由参数可用时才创建子对象。
class MenuBuilder
{
private $factory;
private $requestStack;
/**
* @param FactoryInterface $factory
*
* Add any other dependency you need
*/
public function __construct(FactoryInterface $factory,RequestStack $requestStack)
{
$this->factory = $factory;
$this->requestStack = $requestStack;
}
public function createMainMenu(array $options)
{
$menu = $this->factory->createItem('root');
$menu->addChild('storebundle.menu.storehome', array('route' => 'site_homepage'));
$menu->addChild('storebundle.menu.adminhome', array('route' => 'lilworks_store_homepage'));
$userMenuCat = $menu->addChild('storebundle.menu.cat.user');
$customerMenu = $userMenuCat->addChild('storebundle.menu.customer', array('route' => 'customer_index'));
$customerMenu->addChild('storebundle.menu.customer.new', array('route' => 'customer_new'));
if($this->requestStack->getCurrentRequest()->get('customer_id')){
$customerMenu->addChild('storebundle.menu.customer.show', array('route' => 'customer_show', 'routeParameters' => array('customer_id' => $this->requestStack->getCurrentRequest()->get('customer_id'))));
$customerMenu->addChild('storebundle.menu.customer.edit', array('route' => 'customer_edit', 'routeParameters' => array('customer_id' => $this->requestStack->getCurrentRequest()->get('customer_id'))));
}
$userMenu = $userMenuCat->addChild('storebundle.menu.user', array('route' => 'user_index'));
$userMenu->addChild('storebundle.menu.user.new', array('route' => 'user_new'));
if($this->requestStack->getCurrentRequest()->get('user_id')){
#$userMenu->addChild('storebundle.menu.user.show', array('route' => 'user_show', 'routeParameters' => array('user_id' => $this->requestStack->getCurrentRequest()->get('user_id'))));
#$userMenu->addChild('storebundle.menu.user.edit', array('route' => 'user_edit', 'routeParameters' => array('user_id' => $this->requestStack->getCurrentRequest()->get('user_id'))));
}
$sessionMenu = $userMenuCat->addChild('storebundle.menu.session', array('route' => 'session_index'));
if($this->requestStack->getCurrentRequest()->get('session_id')){
#$sessionMenu->addChild('storebundle.menu.session.show', array('route' => 'session_show', 'routeParameters' => array('session_id' => $this->requestStack->getCurrentRequest()->get('session_id'))));
#$sessionMenu->addChild('storebundle.menu.session.edit', array('route' => 'session_edit', 'routeParameters' => array('session_id' => $this->requestStack->getCurrentRequest()->get('session_id'))));
}
$orderMenuCat = $menu->addChild('storebundle.menu.cat.order');
$orderMenu = $orderMenuCat->addChild('storebundle.menu.order', array('route' => 'order_index'));
$orderMenu->addChild('storebundle.menu.order.new', array('route' => 'order_new'));
if($this->requestStack->getCurrentRequest()->get('order_id')){
#$orderMenu->addChild('storebundle.menu.order.show', array('route' => 'order_show', 'routeParameters' => array('order_id' => $this->requestStack->getCurrentRequest()->get('order_id'))));
#$orderMenu->addChild('storebundle.menu.order.edit', array('route' => 'order_edit', 'routeParameters' => array('order_id' => $this->requestStack->getCurrentRequest()->get('order_id'))));
}
$couponMenu = $orderMenuCat->addChild('storebundle.menu.coupon', array('route' => 'coupon_index'));
$couponMenu->addChild('storebundle.menu.coupon.new', array('route' => 'coupon_new'));
if($this->requestStack->getCurrentRequest()->get('coupon_id')){
#$couponMenu->addChild('storebundle.menu.coupon.show', array('route' => 'coupon_show', 'routeParameters' => array('coupon_id' => $this->requestStack->getCurrentRequest()->get('coupon_id'))));
#$couponMenu->addChild('storebundle.menu.coupon.edit', array('route' => 'coupon_edit', 'routeParameters' => array('coupon_id' => $this->requestStack->getCurrentRequest()->get('coupon_id'))));
}
$depositSaleMenu = $orderMenuCat->addChild('storebundle.menu.depositsale', array('route' => 'coupon_index'));
$depositSaleMenu->addChild('storebundle.menu.depositsale.new', array('route' => 'depositSale_new'));
if($this->requestStack->getCurrentRequest()->get('depositsale_id')){
#$depositSaleMenu->addChild('storebundle.menu.coupon.show', array('route' => 'depositSale_show', 'routeParameters' => array('depositsale_id' => $this->requestStack->getCurrentRequest()->get('depositsale_id'))));
#$depositSaleMenu->addChild('storebundle.menu.coupon.edit', array('route' => 'depositSale_edit', 'routeParameters' => array('depositsale_id' => $this->requestStack->getCurrentRequest()->get('depositsale_id'))));
}
return $menu;
}
在所有示例中,我都没有看到有人使用此条件来构建带参数路由的菜单。
我做错了什么?
你没有做错任何事。如果您需要请求中的信息,例如 URL 中的参数或服务中的用户名(如 $this->tokenStorage->getToken()->getUser();
),请安排获取并使用它。
在我自己的代码中,我获取了用户(如上所述 - 假设它存在)并使用它来制作 link:
$menu->addChild('menu.edit_settings', [
'route' => 'ca_profile_update',
'routeParameters' => array('username' => $user->getUsernameCanonical()),
]);
对你来说,我唯一特别想做的就是将各种参数('user_id' 等等)一次放入一个变量中然后使用它,而不是不断地重新获取它(那是在我看来有点太冗长了)。那只是将菜单服务拆分成更小的功能,使其也更容易理解 - 但这比原始问题更具风格和代码标准。
$this->addCustomerMenu(
$userMenuCat,
$this->requestStack->getCurrentRequest()->getInt('customer_id', 0)
);
public function addCustomerMenu(MenuItem $userMenuCat, int $customer_id): void
{
$customerMenu = $userMenuCat->addChild('storebundle.menu.customer', array('route' => 'customer_index'));
$customerMenu->addChild('storebundle.menu.customer.new', array('route' => 'customer_new'));
if ($customer_id){
$customerMenu->addChild('storebundle.menu.customer.show', array('route' => 'customer_show', 'routeParameters' => array('customer_id' => $customer_id)));
$customerMenu->addChild('storebundle.menu.customer.edit', array('route' => 'customer_edit', 'routeParameters' => array('customer_id' => $customer_id)));
}
}
我正在使用 symfony 3.3 和 knpMenu 2.2 我已将菜单生成器注册为服务
lilworks_store.menu_builder:
class: LilWorks\StoreBundle\Menu\MenuBuilder
arguments: ["@knp_menu.factory","@request_stack"]
tags:
- { name: knp_menu.menu_builder, method: createMainMenu, alias: main } # The alias is what is used to retrieve the menu
我可以毫无问题地呈现一个简单的菜单。但是当我尝试使用带参数的路由时出现错误
An exception has been thrown during the rendering of a template ("Parameter "customer_id" for route "customer_show" must match "[^/]++" ("" given) to generate a corresponding URL.").
我可以在 $this->requestStack->getCurrentRequest()->get('customer_id') 条件下避免这种情况,仅当路由参数可用时才创建子对象。
class MenuBuilder
{
private $factory;
private $requestStack;
/**
* @param FactoryInterface $factory
*
* Add any other dependency you need
*/
public function __construct(FactoryInterface $factory,RequestStack $requestStack)
{
$this->factory = $factory;
$this->requestStack = $requestStack;
}
public function createMainMenu(array $options)
{
$menu = $this->factory->createItem('root');
$menu->addChild('storebundle.menu.storehome', array('route' => 'site_homepage'));
$menu->addChild('storebundle.menu.adminhome', array('route' => 'lilworks_store_homepage'));
$userMenuCat = $menu->addChild('storebundle.menu.cat.user');
$customerMenu = $userMenuCat->addChild('storebundle.menu.customer', array('route' => 'customer_index'));
$customerMenu->addChild('storebundle.menu.customer.new', array('route' => 'customer_new'));
if($this->requestStack->getCurrentRequest()->get('customer_id')){
$customerMenu->addChild('storebundle.menu.customer.show', array('route' => 'customer_show', 'routeParameters' => array('customer_id' => $this->requestStack->getCurrentRequest()->get('customer_id'))));
$customerMenu->addChild('storebundle.menu.customer.edit', array('route' => 'customer_edit', 'routeParameters' => array('customer_id' => $this->requestStack->getCurrentRequest()->get('customer_id'))));
}
$userMenu = $userMenuCat->addChild('storebundle.menu.user', array('route' => 'user_index'));
$userMenu->addChild('storebundle.menu.user.new', array('route' => 'user_new'));
if($this->requestStack->getCurrentRequest()->get('user_id')){
#$userMenu->addChild('storebundle.menu.user.show', array('route' => 'user_show', 'routeParameters' => array('user_id' => $this->requestStack->getCurrentRequest()->get('user_id'))));
#$userMenu->addChild('storebundle.menu.user.edit', array('route' => 'user_edit', 'routeParameters' => array('user_id' => $this->requestStack->getCurrentRequest()->get('user_id'))));
}
$sessionMenu = $userMenuCat->addChild('storebundle.menu.session', array('route' => 'session_index'));
if($this->requestStack->getCurrentRequest()->get('session_id')){
#$sessionMenu->addChild('storebundle.menu.session.show', array('route' => 'session_show', 'routeParameters' => array('session_id' => $this->requestStack->getCurrentRequest()->get('session_id'))));
#$sessionMenu->addChild('storebundle.menu.session.edit', array('route' => 'session_edit', 'routeParameters' => array('session_id' => $this->requestStack->getCurrentRequest()->get('session_id'))));
}
$orderMenuCat = $menu->addChild('storebundle.menu.cat.order');
$orderMenu = $orderMenuCat->addChild('storebundle.menu.order', array('route' => 'order_index'));
$orderMenu->addChild('storebundle.menu.order.new', array('route' => 'order_new'));
if($this->requestStack->getCurrentRequest()->get('order_id')){
#$orderMenu->addChild('storebundle.menu.order.show', array('route' => 'order_show', 'routeParameters' => array('order_id' => $this->requestStack->getCurrentRequest()->get('order_id'))));
#$orderMenu->addChild('storebundle.menu.order.edit', array('route' => 'order_edit', 'routeParameters' => array('order_id' => $this->requestStack->getCurrentRequest()->get('order_id'))));
}
$couponMenu = $orderMenuCat->addChild('storebundle.menu.coupon', array('route' => 'coupon_index'));
$couponMenu->addChild('storebundle.menu.coupon.new', array('route' => 'coupon_new'));
if($this->requestStack->getCurrentRequest()->get('coupon_id')){
#$couponMenu->addChild('storebundle.menu.coupon.show', array('route' => 'coupon_show', 'routeParameters' => array('coupon_id' => $this->requestStack->getCurrentRequest()->get('coupon_id'))));
#$couponMenu->addChild('storebundle.menu.coupon.edit', array('route' => 'coupon_edit', 'routeParameters' => array('coupon_id' => $this->requestStack->getCurrentRequest()->get('coupon_id'))));
}
$depositSaleMenu = $orderMenuCat->addChild('storebundle.menu.depositsale', array('route' => 'coupon_index'));
$depositSaleMenu->addChild('storebundle.menu.depositsale.new', array('route' => 'depositSale_new'));
if($this->requestStack->getCurrentRequest()->get('depositsale_id')){
#$depositSaleMenu->addChild('storebundle.menu.coupon.show', array('route' => 'depositSale_show', 'routeParameters' => array('depositsale_id' => $this->requestStack->getCurrentRequest()->get('depositsale_id'))));
#$depositSaleMenu->addChild('storebundle.menu.coupon.edit', array('route' => 'depositSale_edit', 'routeParameters' => array('depositsale_id' => $this->requestStack->getCurrentRequest()->get('depositsale_id'))));
}
return $menu;
}
在所有示例中,我都没有看到有人使用此条件来构建带参数路由的菜单。 我做错了什么?
你没有做错任何事。如果您需要请求中的信息,例如 URL 中的参数或服务中的用户名(如 $this->tokenStorage->getToken()->getUser();
),请安排获取并使用它。
在我自己的代码中,我获取了用户(如上所述 - 假设它存在)并使用它来制作 link:
$menu->addChild('menu.edit_settings', [
'route' => 'ca_profile_update',
'routeParameters' => array('username' => $user->getUsernameCanonical()),
]);
对你来说,我唯一特别想做的就是将各种参数('user_id' 等等)一次放入一个变量中然后使用它,而不是不断地重新获取它(那是在我看来有点太冗长了)。那只是将菜单服务拆分成更小的功能,使其也更容易理解 - 但这比原始问题更具风格和代码标准。
$this->addCustomerMenu(
$userMenuCat,
$this->requestStack->getCurrentRequest()->getInt('customer_id', 0)
);
public function addCustomerMenu(MenuItem $userMenuCat, int $customer_id): void
{
$customerMenu = $userMenuCat->addChild('storebundle.menu.customer', array('route' => 'customer_index'));
$customerMenu->addChild('storebundle.menu.customer.new', array('route' => 'customer_new'));
if ($customer_id){
$customerMenu->addChild('storebundle.menu.customer.show', array('route' => 'customer_show', 'routeParameters' => array('customer_id' => $customer_id)));
$customerMenu->addChild('storebundle.menu.customer.edit', array('route' => 'customer_edit', 'routeParameters' => array('customer_id' => $customer_id)));
}
}