Currently the {{page.primary_menu}} created the extra divs and default d8 classes as below:
<div class="region region-primary-menu">
<nav role="navigation" aria-labelledby="block-demo-main-menu-menu" id="block-demo-main-menu">
<h2 class="sr-only" id="block-demo-main-menu-menu">Main navigation</h2>
<ul class="menu menu--main nav navbar-nav">
<li class="first">
Home
</li>
<li>
Home
</li>
<li class="last">
ABOUT US
</li>
</ul>
</nav>
</div>
However, I want to generate the menu structure as like:
<ul id="top-menu" class="nav navbar-nav navbar-right mu-main-nav">
<li>HOME</li>
<li>ABOUT US</li>
<li>MENU</li>
<li>RESERVATION</li>
<li>GALLERY</li>
<li>OUR TEAM</li>
<li>BLOG</li>
<li>CONTACT</li>
</ul>
I've created a file name demo.theme and pasted the code but it did not give me the expected result.
<?php
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Template\Attribute;
/**
* Implements hook_preprocess_HOOK() for HTML document templates.
*
* Adds body classes if certain regions have content.
*/
function demo_menu_tree(&$variables) {
return '<ul id="top-menu" class="nav navbar-nav navbar-right mu-main-nav">' . $variables['tree'] . '</ul>';
}
Any suggestion?
Make sure you have twig debugging enabled, it will make your life a lot easier, by adding comments to your mark up (which you can see inline in the web inspector). Using those comments you can figure out what you should name your theme file.
Create a new custom twig file in the /templates directory of your theme like so themes/[your-theme-name-here]/templates/menu.html.twig. As a starting point I'd suggest either using the default classy theme menu.html.twig template, or clone use the file referenced inline in the markup comments of your site when you have twig debugging enabled.
Edit the menu.html.twig file to meet your needs, something like this:
{% import _self as menus %}
{#
We call a macro which calls itself to render the full tree.
#see http://twig.sensiolabs.org/doc/tags/macro.html
#}
{{ menus.menu_links(items, attributes, 0) }}
{% macro menu_links(items, attributes, menu_level) %}
{% import _self as menus %}
{% if items %}
{% if menu_level == 0 %}
<ul id="top-menu" {{ attributes.addClass('nav navbar-nav navbar-right mu-main-nav') }}>
{% else %}
<ul class="menu">
{% endif %}
{% for item in items %}
{%
set classes = [
'menu-item',
item.is_expanded ? 'menu-item--expanded',
item.is_collapsed ? 'menu-item--collapsed',
item.in_active_trail ? 'menu-item--active-trail',
]
%}
<li{{ item.attributes.addClass(classes) }}>
{{ link(item.title, item.url) }}
{% if item.below %}
{{ menus.menu_links(item.below, attributes, menu_level + 1) }}
{% endif %}
</li>
{% endfor %}
</ul>
{% endif %}
{% endmacro %}
Related
I have some issue with drupal 9 and the menu. Basically i want to add some extra fields for menu link, like icon (image or svg upload) and some text for description. I use Simplify menu for the menus.
I already tried with Menu item extras module but i can't print the added fields in twig file.
Someone know how to fix this and get the fields value in twig template? (menu.html.twig)?
Thanks
You can print it in *.html.twig file, the below code I rendered the main menu like:
{% set items = simplify_menu('main') %}
{{ menu_item.NEW_FIELD }}
<nav class="nav">
<ul class="navbar-ul">
{% for menu_item in items.menu_tree %}
<li class="nav-item">
<a class="nav-link" href="{{ menu_item.url }}">{{ menu_item.text }}</a>
</li>
{% endfor %}
</ul>
</nav>
I want get the current page and give an active class without duplicate code in symfony 5.
Here is the code example :
<li class="{{ app.request.get('_route_')=='home' ? 'active':''}}">
Home
</li>
<li class="{{ app.request.get('_route_')=='contact' ? 'active':''}}">
Contact
</li>
</ul>
As an extension of the answer of #DhiaDjobbi
I've you really want to reduce "duplicate" code, I'd go with defining the menu in an array as well
{% set active_page = app.request.get('_route') %}
{% for page in pages %}
<li {% if page == active_page %} class="active" {% endif %} >
{{ page }}
</li>
{% endfor %}
U can create a twig variable in Template its better readable.
{% set page = app.request.get('_route') %}
Then use If Condition to test.
<li {% if page == 'home' %} class="active" {% endif %} >
Home
</li>
<li {% if page == 'contact' %} class="active" {% endif %} >
Contact
</li>
I am looping through a list of social profiles to render the logo. Each social item has a field of svg_icon_code that looks like "twitter" or "facebook". I want to use this code to render the correct file. Currently I am just hardcoding in "twitter" resulting in all logos being the Twitter svg. How can I use the icon_code to render the correct svg?
{% for item in options.social_media_links %}
<li class="header__social-media-links__item">
<a href="{{item.link}}" target="_blank">
{% include 'component/svg-twitter-icon.twig' %}
</a>
</li>
{% endfor %}
You need to concat the icon like this,
{% for item in options.social_media_links %}
<li class="header__social-media-links__item">
<a href="{{item.link}}" target="_blank">
{% include 'component/svg-'~item.svg_icon_code~'-icon.twig' %}
</a>
</li>
{% endfor %}
If an icon doesn't have a template or the template is missing you can do this to render a default icon
{% for item in options.social_media_links %}
<li class="header__social-media-links__item">
<a href="{{item.link}}" target="_blank">
{% include [ 'component/svg-'~item.svg_icon_code~'-icon.twig', 'component/svg-default-icon.twig' ] %}
</a>
</li>
{% endfor %}
I have a simple reusable twig (generic.html.twig) template which look like:
<ul>
{% for item in list %}
<li>
...
</li>
{% endfor %}
</ul>
I use it many times in my code like this:
{% include "#Toto/generic.html.twig" with {"list": toto} %}
My problem is that I sometimes want to include a CSS class on the <ul> generated by my twig template. So sometimes I would like for it to render like this:
<ul class="myclass">
while other times I'd like for it to render without the class, like this:
<ul>
How do I implement optional classes in my twig template?
I prefer the use of defined
<ul{% if ulClass is defined %} class="{{ ulClass }}"{% endif %}>
{% for item in list %}
<li>
...
</li>
{% endfor %}
</ul>
I would use something like:
{% include "#Toto/generic.html.twig" with {"list": toto, "status": true} %}
And check against status boolean
<ul {{ status ? 'class="myclass"' : '' }}>
I have a layout which has a sidebar. Inside sidebar, there is a block for displaying list of categories. I have called a controller (fetches list of categories) to be rendered inside this block. Here is how my sidebar looks like:
Here is my main layout file containing sidebar:
<!-- siteLayout.html.twig -->
<div id="sidebar">
{% block sidebarBlock1 %}
{% render "TestBundle:Index:categoryList" %}
{% endblock %}
</div>
TestBundle:Index:categoryList fetches list of categories from database and returns as below:
<ul>
<li>Category 1</li>
<li>Category 2</li>
</ul>
All my other views extends siteLayout.html.twig. What i want is that when users loads this url "/category/1" i want to add css class to li tag.
For example if someone clicks /category/1 then the output should be
<li class="active">.......</li>
How can I achieve this?
<li {% if app.request.attributes.get('_route') == 'category_view' %}
class="active"
{% endif %}>
</li>
Check route and set class if route matches your category route. Replace category_view with the route name of /category
{%if app.request.server.get('REQUEST_URI')== path('viewCategoryItems', {'slugName': category.slugName})%} class="active"{%endif%}
This worked for me