Настройте KnpMenuBundle

Как настроить KNPMenuBundle?

Я не могу понять, как добавить изображение или тег span с помощью KnpMenuBundle.

Я просто хочу это:

<ul>
    <li>
         <img src="{{asset('bundles/mybundle/images/my_image.png')}} /">
         <span>My Title</span>        
     </li>
</ul>

В MenuBuilder это начнется с:

$menu->addChild('My Title');

Как я могу добавить изображение в оператор <li>?


РЕДАКТИРОВАТЬ: ЛЕГКИЙ СПОСОБ

На самом деле в пакете есть простой способ сделать это:

1 Скопируйте шаблон vendor\KnpMenu\src\Knp\Menu\Resources\views\knp_menu.html.twig в свой Acme\AcmeBundle\Resources\views\Menu\knp_menu.html.twig и расширьте его следующим образом:

{% extends 'knp_menu.html.twig' %}


2 Измените шаблон в соответствии с вашими потребностями. Например, если вы решите добавлять тег span каждый раз, когда используете $menu->addChild('Your Title');, просто добавьте тег span между <a></a>:

{% block linkElement %}
    <a href="{{ item.uri }}"{{ _self.attributes(item.linkAttributes) }}>
        <span>{{ block('label') }}</span>
    </a>
{% endblock %}


3 Теперь вы можете выбрать свой собственный макет, используя меню:

{{ knp_menu_render('main', {'template': 'AcmeBundle:Menu:knp_menu.html.twig'}) }}

person Mick    schedule 27.06.2012    source источник
comment
Почему бы не определить атрибут элемента <li> или <span> и не добавить изображение в css?   -  person j0k    schedule 27.06.2012
comment
Перечисленный выше Easy Way потрясающий. Спасибо.   -  person Kevin    schedule 09.02.2013
comment
Я хотел поместить файл knp_menu.html.twig в каталог app / Resouces / views. Это не работает. В чем может быть ошибка?   -  person Slowwie    schedule 18.02.2014
comment
Как сказал @ DARSC0D3 в своем ответе, вам необходимо импортировать родительский шаблон, чтобы атрибуты работали.   -  person PutzKipa    schedule 04.05.2014
comment
В дополнение к копированию шаблона, как указано выше, необходимо также изменить config.yml так, чтобы строка template: в блоке knp_menu: читалась как YourBundle:Menu:knp_menu.html.twig.   -  person geoB    schedule 27.06.2014
comment
Следуя вашим инструкциям, вы получите Unable to find template "AppBundle:Menu:knp_menu.html.twig". Кстати, я проголосовал за ваш ответ за то время, которое вы потратили на подготовку этого руководства.   -  person Pmpr    schedule 06.03.2017


Ответы (5)


CSS работает в этом случае, но иногда вам может потребоваться добавить или изменить разметку более существенно. Для этого вы можете использовать настраиваемое средство визуализации, как определено здесь: https://github.com/KnpLabs/KnpMenuBundle/blob/master/Resources/doc/custom_renderer.md

Примером пакета, который делает это, является MopaBoostrapBundle, здесь я выделил важные части.

Определение службы, в которое добавлен тег knp_menu.renderer:

services:
    mopa_bootstrap.navbar_renderer:
        class: Mopa\Bundle\BootstrapBundle\Navbar\Renderer\NavbarRenderer
        arguments: [ @service_container, [] ]
        tags:
            # The alias is what is used to retrieve the menu
            - { name: knp_menu.renderer, alias: navbar }

и шаблон веточки можно написать, например, так.

<div class="navbar {{ (navbar.hasOption('fixedTop') and  navbar.getOption('fixedTop')) ? 'navbar-fixed-top' : '' }}">
    <div class="navbar-inner">
        <div class="container{{ (navbar.hasOption('isFluid') and navbar.getOption('isFluid')) ? '-fluid' : '' }}">
            <a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
            </a>
            {% if navbar.hasOption('title') %}<a class="brand" href="{{ path(navbar.getOption('titleRoute')) }}">{{ navbar.getOption('title') }}</a>{% endif %}
            <div class="nav-collapse">
                {{ navbar.hasMenu('leftmenu') ? knp_menu_render(navbar.getMenu('leftmenu'), {'currentClass': 'active', 'ancestorClass': 'active', 'allow_safe_labels': 'true'}) : '' }}
                {% if navbar.hasFormView('searchform') %}
                    {%- set form_view = navbar.getFormView('searchform') -%}
                    {%- set form_type = navbar.getFormType('searchform') -%}
                    {%- set form_attrs = form_view.vars.attr -%}
                    {% form_theme form_view _self %}
                    <form class="navbar-search pull-{{ form_attrs.pull|default('left') }}" method="{{ form_attrs.method|default('post') }}" action="{{ path(navbar.getFormRoute('searchform')) }}">
                    {{ form_widget(form_view) }}
                    </form>
                {% endif %}
                {{ navbar.hasMenu('rightmenu') ? knp_menu_render(navbar.getMenu('rightmenu'), {'currentClass': 'active', 'ancestorClass': 'active', 'allow_safe_labels': 'true'}) : '' }}
            </div>

        </div>
    </div>
</div>
person MDrollette    schedule 27.06.2012
comment
Спасибо, MDrolette, этот ответ мне ОЧЕНЬ помог! Ваше руководство было действительно полезным! Я сделал что-то очень похожее на то, что вы рекомендовали, за исключением того, что в этом случае я расширил только шаблон knp_menu.html.twig. Я отредактировал свой вопрос, если вам интересно. И снова отличный ответ. Ваше здоровье :-) - person Mick; 27.06.2012
comment
Есть ли полный пример того, как иметь работающий пользовательский рендерер? symfony.com/doc/master/bundles/KnpMenuBundle/ У меня есть последовал за этим, но все еще не помогает. - person Chris; 11.04.2018

Я потратил некоторое время на то, чтобы понять это.

Существует параметр, который вы можете применить при определении пункта меню под названием «safe_label». Установив для него значение true, оно выводит изображение на панели навигации вместо HTML.

    $image = "<img src='/path/to/image' />";
    $menu->addChild( $image , 
      array(
        'route' => 'url_route_name',
        'extras' => array(
          'safe_label' => true
        )
      )
    );

надеюсь, это поможет

person onnyjay    schedule 23.12.2012
comment
Правильно, но вы также должны использовать необработанный формат при рендеринге пакета, например: {{knp_menu_render ('main', {'template': 'AcmeBundle: Menu: knp_menu.html.twig', {'allow_safe_labels': true}) | сырой }} - person repincln; 14.11.2013
comment
Небольшая поправка к предложению @repincln по спасению жизни: правильный синтаксис с symfony 2.8 - {{ knp_menu_render('main', {'template': 'AcmeBundle:Menu:knp_menu.html.twig', 'allow_safe_labels': true})|raw }} - person Attila Fulop; 11.05.2016

Вам необходимо импортировать макросы из родительского шаблона, прежде чем вы сможете их использовать.

{% block linkElement %}
    {% import 'knp_menu.html.twig' as knp_menu %}
    <a href="{{ item.uri }}"{{ knp_menu.attributes(item.linkAttributes) }}>
        <span>{{ block('label') }}</span>
    </a>
{% endblock %}


person D4R5C0D3    schedule 19.02.2014

Чтобы просто добавить классы и другие атрибуты HTML (например, чтобы интегрировать menù с Twitter Bootstrap, добавить его классы и идентификаторы), вы можете использовать методы, предусмотренные для такого рода настройки.

Вот несколько полезных ресурсов:

KnpMenuBundles предоставляет некоторые документированные методы, такие как setAttributes, selLinkAttirbute или setLabelAttribute (а также другие методы), которые полезны для настройки отображения меню.

person Aerendir    schedule 18.02.2015

Почему бы не определить атрибут элемента <li> или <span> и не добавить изображение в css?

person j0k    schedule 27.06.2012