You are here

translatable_menu_link_uri.module in Translatable menu link uri 2.x

Same filename and directory in other branches
  1. 1.x translatable_menu_link_uri.module

File

translatable_menu_link_uri.module
View source
<?php

/**
 * @file
 * Contains translatable_menu_link_uri.module.
 */
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\Core\Field\BaseFieldDefinition;
use Drupal\link\LinkItemInterface;

/**
 * Implements hook_help().
 */
function translatable_menu_link_uri_help($route_name, RouteMatchInterface $route_match) {
  switch ($route_name) {

    // Main module help for the translatable_menu_link_uri module.
    case 'help.page.translatable_menu_link_uri':
      $output = '';
      $output .= '<h3>' . t('About') . '</h3>';
      $output .= '<p>' . t('This module enables support for translation of link field in menu_link_content entity.') . '</p>';
      return $output;
    default:
  }
}

/**
 * Implements hook_entity_base_field_info().
 */
function translatable_menu_link_uri_entity_base_field_info(EntityTypeInterface $entity_type) {
  $fields = [];

  // We modify only menu_link_content entity type.
  if ($entity_type
    ->id() == 'menu_link_content') {

    // Add second link field. This one is translatable.
    $fields['link_override'] = BaseFieldDefinition::create('link')
      ->setLabel(t('Link override'))
      ->setDescription(t('The location this menu link points to. (translatable version)'))
      ->setTranslatable(TRUE)
      ->setRevisionable(TRUE)
      ->setRequired(FALSE)
      ->setSettings([
      'link_type' => LinkItemInterface::LINK_GENERIC,
      'title' => DRUPAL_DISABLED,
    ])
      ->setDisplayOptions('form', [
      'type' => 'link_default',
      'weight' => -2,
    ]);
  }
  return $fields;
}

/**
 * Implements hook_preprocess_menu().
 */
function translatable_menu_link_uri_preprocess_menu(&$variables, $hook) {

  // Let's apply this on menu theme (menu block).
  if ($hook === 'menu' || preg_match('%^menu__%', $hook)) {

    // Iterate through all items in menu tree.
    foreach ($variables['items'] as &$item) {
      translatable_menu_link_uri_iterate_menu($item);
    }
  }
}

/**
 * Iterate over the menu and check for sublevel menu links.
 */
function translatable_menu_link_uri_iterate_menu(&$item) {
  try {
    if ($item['below']) {
      foreach (array_keys($item['below']) as $key) {
        translatable_menu_link_uri_iterate_menu($item['below'][$key]);
      }
    }

    /** @var \Drupal\Core\Menu\MenuLinkInterface $link */
    $link = $item['original_link'];
    if ($link) {
      $plugin_id = $link
        ->getPluginId();
    }
    $url = NULL;

    // If menu link is generated by menu_link_content, let's go deeper into details.
    if (strpos($plugin_id, 'menu_link_content') !== FALSE && !is_null($link
      ->getDerivativeId())) {
      $link_entity = \Drupal::service('entity.repository')
        ->loadEntityByUuid('menu_link_content', $link
        ->getDerivativeId());
      if ($link_entity instanceof EntityInterface) {

        // We have entity, now, let's translate it.
        $translated_entity = \Drupal::service('entity.repository')
          ->getTranslationFromContext($link_entity);

        /** @var Drupal\link\Plugin\Field\FieldType\Linkitem $url */
        $url = $translated_entity->link_override
          ->first();
      }

      // We inherit options from current (overridden) element.
      $options = $item['url']
        ->getOptions();

      // Never inherit query string.
      unset($options['query']);
      if ($url !== NULL) {
        $item['url'] = $url
          ->isEmpty() ? $item['url'] : $url
          ->getUrl();
      }
      if (!empty($options)) {

        // Inherit only options that have not been overridden.
        $overridden_options = $item['url']
          ->getOptions();
        $overridden_options += $options;
        $item['url']
          ->setOptions($overridden_options);
      }
    }
  } catch (\Exception $e) {
    \Drupal::logger('translatable_menu_link_uri')
      ->warning($e
      ->getMessage());
  }
}

Functions

Namesort descending Description
translatable_menu_link_uri_entity_base_field_info Implements hook_entity_base_field_info().
translatable_menu_link_uri_help Implements hook_help().
translatable_menu_link_uri_iterate_menu Iterate over the menu and check for sublevel menu links.
translatable_menu_link_uri_preprocess_menu Implements hook_preprocess_menu().