Я ломал голову над этой проблемой в течение нескольких дней, и я думаю, что нашел самое чистое решение для решения этой проблемы, используя мою конфигурацию маршрутизации и собственный Voter. Поскольку речь идет о компоненте маршрутизации Symfony, я предполагаю, что вы используете фреймворк Symfony или имеете достаточно знаний о Symfony, чтобы заставить его работать на себя.
Создайте пользовательского избирателя
<?php
# src/AppBundle/Menu/RouteKeyVoter.php
namespace AppBundle\Menu;
use Knp\Menu\ItemInterface;
use Knp\Menu\Matcher\Voter\VoterInterface;
use Symfony\Component\HttpFoundation\Request;
/**
* Voter based on routing configuration
*/
class RouteKeyVoter implements VoterInterface
{
/**
* @var Request
*/
private $request;
public function __construct(Request $request = null)
{
$this->request = $request;
}
public function setRequest(Request $request)
{
$this->request = $request;
}
public function matchItem(ItemInterface $item)
{
if (null === $this->request) {
return null;
}
$routeKeys = explode('|', $this->request->attributes->get('_menu_key'));
foreach ($routeKeys as $key) {
if (!is_string($key) || $key == '') {
continue;
}
// Compare the key(s) defined in the routing configuration to the name of the menu item
if ($key == $item->getName()) {
return true;
}
}
return null;
}
}
Зарегистрировать избирателя в контейнере
# app/config/services.yml
services:
# your other services...
app.menu.route_key_voter:
class: AppBundle\Menu\RouteKeyVoter
scope: request
tags:
- { name: knp_menu.voter }
<!-- xml -->
<service id="app.menu.route_key_voter" class="AppBundle\Menu\RouteKeyVoter">
<tag name="knp_menu.voter" request="true"/>
</service>
Обратите внимание, что они не были полностью протестированы. Оставьте комментарий, если я должен улучшить ситуацию.
Настройка клавиш меню
После того, как вы создали собственный Voter и добавили его в настроенный Matcher, вы можете настроить текущие пункты меню, добавив _menu_key
default к маршруту. Ключи можно разделить с помощью |
.
/**
* @Route("/articles/{id}/comments",
* defaults={
* "_menu_key": "article|other_menu_item"
* }
* )
*/
public function commentsAction($id)
{
}
article_comments:
path: /articles/{id}/comments
defaults:
_controller: AppBundle:Default:comments
_menu_key: article|other_menu_item
<route id="article_comments" path="/articles/{id}/comments">
<default key="_controller">AppBundle:Default:comments</default>
<default key="_menu_key">article|other_menu_item</default>
</route>
Вышеупомянутые конфигурации будут соответствовать следующему пункту меню:
$menu->addChild('article', [ // <-- matched name of the menu item
'label' => 'Articles',
'route' => 'article_index',
]);
person
Coded Monkey
schedule
05.05.2017