Had need to add custom image field to menu items. First thing is to attach the field using this code in custom module.
function iop_entity_base_field_info(\Drupal\Core\Entity\EntityTypeInterface $entity_type) {
if ($entity_type->id() === 'menu_link_content') {
$fields['menu_link_image'] = BaseFieldDefinition::create('image')
->setLabel(t('Menu link image'))
->setDescription(t('Upload the image related to this menu item'))
->setDisplayOptions('form', array('type' => 'string', 'weight' => 0));
return $fields;
}
}
This will add the field, but we need to update the db now or when you save menu item it will complain about missing columns.
drush updatedb --entity-updates
Not the new field will show and save. But when you create a template for the menu, you will notice that this data isnt available, so you need to preprocess menu and add it.
function MYMODULE_theme_preprocess_menu(&$variables, $hook) {
// Add the custom image field so can theme in template.
if ($variables['theme_hook_original'] == 'menu__microsites_menu') {
foreach ($variables['items'] as $key => &$item) {
$entity = \Drupal::entityTypeManager()->getStorage('menu_link_content')->loadByProperties(array('uuid' => $item['original_link']->getDerivativeId()));
if (!empty($entity)) {
$entity = array_shift($entity);
$image = $entity->get('menu_link_image')->entity;
if (!empty($image)) {
$item['image'] = $image->getFileUri();
}
}
}
}
}
Then in the menu template, e.g menu--my-menu.html.twig put this:
{% import _self as menus %}
{{ menus.menu_links(items, attributes, 0) }}
{% macro menu_links(items, attributes, menu_level) %}
{% import _self as menus %}
{% if items %}
{% if menu_level == 0 %}
<ul{{ attributes.addClass('menu') }}>
{% 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) }}>
{% if item.image is empty %}
{{ link(item.title, item.url) }}
{% else %}
<a href="{{ item.url }}">
<img src="{{ item.image | image_style('microsites_logo') }}"/>
</a>
{% endif %}
{% if item.below %}
{{ menus.menu_links(item.below, attributes, menu_level + 1) }}
{% endif %}
</li>
{% endfor %}
</ul>
{% endif %}
{% endmacro %}
All done should now theme image in menu.
Comments
Add new comment