Создание хлебных крошек в symfony 2.1 с использованием пакета knpmenu

Как лучше всего создать хлебные крошки с помощью пакета knpmenu в symfony 2.1.x? Помимо использования сторонних пакетов.

ОБНОВЛЕНИЕ:

Привет, theunraveler, извините за поздний ответ. Теперь я последовал вашему примеру, и я застрял в одном моменте. Здесь приведенный ниже код выдает исключение, которое

Missing argument 2 for Acme\DemoBundle\Menu\MenuBuilder::getBreadCrumbs()    

{% set item = knp_menu_get('main') %}
{{ knp_menu_render(item) }}
{% block breadcrumbs %}
    {% set breadcrumbs = knp_menu_get('breadcrumbs', [], {'request':    app.request, 'menu': item }) %}
    {{ dump(breadcrumbs) }}
{% endblock %}

Почему он не принимает переменную "item"?


person Mister Been    schedule 13.11.2012    source источник
comment
ну, KnpMenuBundle это сторонний комплект...   -  person Wouter J    schedule 13.11.2012
comment
Согласен, но я имел ввиду не добавлять больше бандлов, когда уже есть возможность создать хлебные крошки в существующем бандле knpmenu.   -  person Mister Been    schedule 13.11.2012


Ответы (3)


Класс Knp\Menu\MenuItem имеет метод getBreadcrumbsArray(). Он должен возвращать массив элементов в текущем активном меню. Если вы используете более раннюю версию KnpMenu (я думаю, ‹= 1.1.2), возвращаемый массив будет в форме label => uri. В противном случае это будет массив, в котором каждый элемент имеет ключи label, uri и item.

Чтобы найти текущий пункт меню, вы, вероятно, захотите создать метод в своем контроллере (или где-то еще, если это имеет смысл для вашего проекта), который выглядит примерно так:

public function getCurrentMenuItem($menu)
{
    foreach ($menu as $item) {
        if ($item->isCurrent()) {
            return $item;
        }

        if ($item->getChildren() && $current_child = $this->getCurrentMenuItem($item)) {
            return $current_child;
        }
    }

    return null;
}

Оттуда вы можете вызвать getBreadcrumbsArray() для возвращаемого значения:

$this->getCurrentMenuItem($your_menu)->getBreadcrumbsArray();

Я предполагаю, что в конечном итоге я бы сделал создал расширение Twig, которое регистрирует breadcrumbs global и поместите туда метод getCurrentMenuItem(). Таким образом, вы можете иметь переменную breadcrumb во всех своих шаблонах без необходимости вручную отображать ее в каждом контроллере.

Источник: https://github.com/KnpLabs/KnpMenu/blob/master/src/Knp/Menu/MenuItem.php#L544.

person theunraveler    schedule 13.11.2012
comment
не могли бы вы привести пример использования этого метода? Потому что проблема заключается в определении текущего пункта отображаемого меню. - person Mister Been; 13.11.2012
comment
Обновлен мой ответ с примером того, как найти текущий пункт меню. - person theunraveler; 13.11.2012
comment
getBreadcrumbsArray() больше не доступен. Вы знаете, что использовать вместо этого? - person Skid Kadda; 17.09.2014
comment
@Netbulae, этот метод был перемещен в Knp\Menu\Util\MenuManipulator, см. этот ответ: stackoverflow.com/a/28851780/1055200 - person b.b3rn4rd; 04.03.2015

Начиная с версии 2.0, getBreadcrumbsArray был перемещен в Knp\Menu\Util\MenuManipulator.

Возможное упражнение для этого решения заключается в создании расширения ветки:

<?php

namespace Kimwild\CommonBundle\Twig;
use Knp\Menu\Util\MenuManipulator;
use Knp\Menu\ItemInterface;

class MenuManipulatorExtension extends \Twig_Extension
{

    public function getFunctions()
    {
        return array(
            new \Twig_SimpleFunction('menu_manipulator', array($this, 'menuManipulator')),
        );
    }

    public function menuManipulator(ItemInterface $item)
    {
        $manipulator = new MenuManipulator();
        return $manipulator->getBreadcrumbsArray($item);
    }


    public function getName()
    {
        return 'menu_manipulator';
    }

}

Зарегистрируйте расширение ветки:

kimwild_common.menu_manipulator_extension:
    class: Kimwild\CommonBundle\Twig\MenuManipulatorExtension
    public: false
    tags:
        - { name: twig.extension }

В хлебных крошках.html.twig:

{% block root %}
    {%- for  link in menu_manipulator(item) %}
    /* whatever you want to do ... */
    {%- endfor %}
{% endblock %}
person b.b3rn4rd    schedule 04.03.2015
comment
С 2012 года по настоящее время (2015 год) это фактически стало правильным ответом на вопрос о том, как решить эту проблему дружественным для Symfony 2 способом, отказавшись от ранее принятого! - person pid; 19.06.2015

Начиная с KnpMenu 2.1, появилась новая функция ветки: knp_menu_get_breadcrumbs_array

Вы можете ознакомиться с моей сутью: https://gist.github.com/fsevestre/b378606c4fd23814278a

Я добавил новую функцию ветки knp_menu_get_current_item, которая извлекает текущий пункт меню и отлично работает с функцией knp_menu_get_breadcrumbs_array.

--

Редактировать:

С помощью KnpMenu 2.2 теперь вы можете:

<ol class="breadcrumb">
{% for breadcrumb_item in knp_menu_get_breadcrumbs_array(knp_menu_get_current_item('main')) %}
    {% if not loop.last %}
    <li><a href="{{ breadcrumb_item.uri }}">{{ breadcrumb_item.label }}</a></li>
    {% else %}
    <li class="active">{{ breadcrumb_item.label }}</li>
    {% endif %}
{% endfor %}
</ol>

https://github.com/KnpLabs/KnpMenu/blob/master/doc/02-Twig-Integration.markdown#functions

Функция knp_menu_get_current_item('main') Twig извлечет текущий пункт меню для меню main.

person fsevestre    schedule 29.10.2015