ui_icons-1.0.x-dev/modules/ui_icons_menu/ui_icons_menu.module

modules/ui_icons_menu/ui_icons_menu.module
<?php

/**
 * @file
 * Drupal hooks and global functions for ui_icons_menu module.
 */

use Drupal\Component\Render\FormattableMarkup;
use Drupal\Component\Utility\NestedArray;
use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\Core\Theme\Icon\IconDefinition;
use Drupal\Core\Url;

/**
 * Implements hook_help().
 */
function ui_icons_menu_help(string $route_name, RouteMatchInterface $route_match) {
  if ('help.page.ui_icons_menu' === $route_name) {
    $output = '';
    $output .= '<h3>' . t('About') . '</h3>';
    $output .= '<p>' . t('The UI Icons Menu module overtakes the core default widget for menu link content entities, allowing you to set icons on menu links.') . '</p>';
    return $output;
  }
}

/**
 * Implements hook_entity_base_field_info_alter().
 *
 * @todo set settings options, position and required as menu setting or global
 * for all menus.
 */
function ui_icons_menu_entity_base_field_info_alter(array &$fields, EntityTypeInterface $entity_type): void {
  if ($entity_type->id() !== 'menu_link_content') {
    return;
  }

  $moduleDiscovery = \Drupal::service('module_handler');
  $type = 'icon_link_widget';
  if ($moduleDiscovery->moduleExists('ui_icons_field_link_attributes')) {
    $type = 'icon_link_attributes_widget';
  }

  $fields['link']->setDisplayOptions('form', [
    'type' => $type,
    // Allow icon position and settings.
    'settings' => [
      'icon_required' => FALSE,
      'icon_position' => TRUE,
      'show_settings' => TRUE,
    ],
  ]);
}

/**
 * Implements hook_preprocess_menu().
 */
function ui_icons_menu_preprocess_menu(array &$variables): void {
  // Ignore preprocess if there are no items or the menu is a navigation one.
  if (empty($variables['items']) ||
    str_starts_with($variables['theme_hook_original'] ?? '', 'navigation_menu__')
  ) {
    return;
  }
  ui_icons_menu__preprocess_menu($variables['items']);
}

/**
 * Handle menu items to add our icon.
 *
 * @param array $items
 *   The menu items.
 */
function ui_icons_menu__preprocess_menu(array &$items): void {
  foreach ($items as &$item) {
    if (empty($item['url'])) {
      continue;
    }

    ui_icons_menu__preprocess_menu_item($item);

    if (!empty($item['below'])) {
      ui_icons_menu__preprocess_menu($item['below']);
    }
  }
}

/**
 * Handle a single menu item.
 *
 * @param array $item
 *   The menu item.
 */
function ui_icons_menu__preprocess_menu_item(array &$item): void {
  // Being extra defensive on the menu as other themes/modules can alter in
  // unknown ways.
  if (!isset($item['url'])) {
    return;
  }

  if (!$item['url'] instanceof Url) {
    return;
  }

  /** @var \Drupal\Core\Url $url */
  $url = &$item['url'];

  if (!$icon = $url->getOption('icon')) {
    return;
  }

  if ($url->getOption('ui_icons_processed')) {
    return;
  }

  $url->setOption('ui_icons_processed', TRUE);
  ui_icons_menu_generate_markup($item['title'], $icon['target_id'], $icon['settings'] ?? [], $url->getOption('icon_display') ?? 'before');
}

/**
 * Implements hook_link_alter().
 *
 * Allow the icon to be displayed on the menu administration context in
 * /admin/structure/menu/manage.
 */
function ui_icons_menu_link_alter(array &$variables): void {
  if (!isset($variables['url']) || !isset($variables['text'])) {
    return;
  }

  if (!$icon = $variables['url']->getOption('icon')) {
    return;
  }

  // Check if the link is from menu.
  if (isset($variables['options']['ui_icons_processed'])) {
    return;
  }

  // Do not handle link handled by field link in IconLinkFormatter.
  if ($variables['url']->getOption('ui_icons_processed')) {
    return;
  }

  // Do not handle link if no position found, possible if we have an icon but
  // the display is not set.
  if (!$icon_display = $variables['url']->getOption('icon_display') ?? NULL) {
    return;
  }

  $variables['url']->setOption('ui_icons_processed', TRUE);
  ui_icons_menu_generate_markup($variables['text'], $icon['target_id'], $icon['settings'] ?? [], $icon_display);
}

/**
 * Helper to generate the expected markup for the link with icon.
 *
 * @param mixed &$text
 *   The text reference to generate markup for.
 * @param string $icon_full_id
 *   The icon full id.
 * @param array $icon_settings
 *   The icon settings.
 * @param string $icon_display
 *   The icon position, `icon_only`, `after` or default `before`.
 */
function ui_icons_menu_generate_markup(mixed &$text, string $icon_full_id, array $icon_settings, string $icon_display = 'before'): void {

  $icon_renderable = IconDefinition::getRenderable($icon_full_id, $icon_settings);
  $icon = \Drupal::service('renderer')->renderInIsolation($icon_renderable);

  switch ($icon_display) {
    case 'before':
      $text = new FormattableMarkup('@icon <span class="ui-icons-menu-text">@title</span>', [
        '@title' => $text,
        '@icon' => $icon,
      ]);
      break;

    case 'after':
      $text = new FormattableMarkup('<span class="ui-icons-menu-text">@title</span> @icon', [
        '@title' => $text,
        '@icon' => $icon,
      ]);
      break;

    default:
      $text = new FormattableMarkup('@icon', [
        '@icon' => $icon,
      ]);
      break;
  }
}

/**
 * Implements hook_navigation_menu_link_tree_alter().
 */
function ui_icons_menu_navigation_menu_link_tree_alter(array &$tree): void {
  foreach ($tree as $item) {
    $definition = $item->link->getPluginDefinition()['options']['icon'] ?? NULL;
    if (!isset($definition['target_id'])) {
      continue;
    }

    [$icon_pack, $icon] = explode(':', $definition['target_id']);
    $definition['settings'] = NestedArray::mergeDeep($definition['settings'][$icon_pack] ?? [], ['class' => 'toolbar-button__icon']);

    $item->options['icon'] = $definition + ['pack_id' => $icon_pack, 'icon_id' => $icon];
  }

}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc