symfony - Personaliza el KnpMenuBundle
(5)
¿Por qué no definir un atributo del elemento <li>
o <span>
y agregar la imagen en css?
¿Cómo personalizar KNPMenuBundle?
No puedo encontrar la manera de agregar una imagen o una etiqueta span usando el KnpMenuBundle.
Simplemente quiero esto:
<ul>
<li>
<img src="{{asset(''bundles/mybundle/images/my_image.png'')}} /">
<span>My Title</span>
</li>
</ul>
En el MenuBuilder, esto comenzaría con:
$menu->addChild(''My Title'');
¿Cómo podría agregar la imagen en la declaración <li>
?
EDITAR: EL CAMINO FÁCIL
En realidad, hay una manera fácil de hacerlo dentro del paquete:
1 Copie el vendor/KnpMenu/src/Knp/Menu/Resources/views/knp_menu.html.twig
la plantilla vendor/KnpMenu/src/Knp/Menu/Resources/views/knp_menu.html.twig
en Acme/AcmeBundle/Resources/views/Menu/knp_menu.html.twig
y Acme/AcmeBundle/Resources/views/Menu/knp_menu.html.twig
siguiente manera:
{% extends ''knp_menu.html.twig'' %}
2 Modifique la plantilla de acuerdo a sus necesidades. Por ejemplo, si decide agregar una etiqueta span cada vez que usa $menu->addChild(''Your Title'');
, simplemente agrega la etiqueta span entre <a></a>
:
{% block linkElement %}
<a href="{{ item.uri }}"{{ _self.attributes(item.linkAttributes) }}>
<span>{{ block(''label'') }}</span>
</a>
{% endblock %}
3 Ahora puede elegir su diseño personalizado cuando usa el menú:
{{ knp_menu_render(''main'', {''template'': ''AcmeBundle:Menu:knp_menu.html.twig''}) }}
CSS funciona para este caso, pero a veces es posible que necesite agregar o cambiar el marcado de manera más significativa. Para eso puede usar un renderizador personalizado como se define aquí: https://github.com/KnpLabs/KnpMenuBundle/blob/master/Resources/doc/custom_renderer.md
Un ejemplo de paquete que hace esto es MopaBoostrapBundle He resaltado las partes importantes aquí.
La definición del servicio donde se knp_menu.renderer
etiqueta 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 }
y la plantilla de ramas se puede escribir así, por ejemplo.
<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>
Debe importar las macros desde la plantilla principal antes de poder usarlas.
{% 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 %}
Me pasé un tiempo descifrando esto.
Hay un parámetro que puede aplicar al definir el elemento de menú llamado ''etiqueta segura''. Al establecer esto en verdadero, muestra la imagen en la barra de navegación en lugar de html.
$image = "<img src=''/path/to/image'' />";
$menu->addChild( $image ,
array(
''route'' => ''url_route_name'',
''extras'' => array(
''safe_label'' => true
)
)
);
Espero que ayude
Para agregar clases y otros atributos HTML (por ejemplo, para integrar el menú con Twitter Bootstrap y sus clases e ID), puede usar los métodos proporcionados para ese tipo de personalización.
Aquí hay algunos recursos útiles:
- Aquí están todos los detalles de la documentación de KNP Menu Bundle: Creación de menús: los conceptos básicos: atributos del menú
- Aquí hay algunos ejemplos concretos: (en GitHub) KNP Menu Bundle con Bootstrap 3 y Font Awesome 4
KnpMenuBundles proporciona algunos métodos documentados como setAttributes, selLinkAttirbute o setLabelAttribute (y otros métodos también) que son útiles para personalizar la representación de menù.