3

What is the correct way for adding Language Switcher (Dropdown) or links on the admin toolbar menu from my custom module or from a contributed module?

enter image description here

  • 1
    There is tree ways to add items to the admin toolbar, take a look at this question, – berramou Oct 4 '18 at 9:51
  • I've tried all of these ways, but I don't know how to add a language switcher on the top of admin menu – Mohamed Osama Gbril Oct 4 '18 at 10:24
  • 1
    4k4’s answer is how to do it. You’ll need to work out how to render the language switcher but that’s a simple google search away – Clive Oct 4 '18 at 10:25
  • I know how I can render the language switcher or list of language but the issue with me that I've tried the code and the menu link was added but not added on the top beside (Manage, Shortcut, ..), I can only see it on the /admin/structure/menu/manage/admin – Mohamed Osama Gbril Oct 4 '18 at 11:00
  • 2
    That's a list of tabs, it's not designed to have arbitrary elements in it. Not that it couldn't, theoretically...have a look at core/themes/stable/templates/navigation/toolbar.html.twig, that should make it clearer which variable you need to get the render array for the language switcher into – Clive Oct 4 '18 at 12:00
2

Well, I got something up and running via hook_toolbar. Only thing left is, that you can't click directly on the "Language: EN" string in the toolbar. You have to click slightly next to it. Maybe you can fix this.

enter image description here

Apart from that, please also have a look at the Devel module and their implementation of hook_toolbar where they have an extra src/ToolbarHandler.php class for everything. You better should rebuild the code below into a dedicated handler.


use Drupal\Core\Url;
use Drupal\Core\Link;

/**
 * Implements hook_toolbar().
 */
function MYMODULE_toolbar() {

  // Get languages, get current route.
  $current_language = \Drupal::languageManager()->getCurrentLanguage()->getId();
  $languages = \Drupal::languageManager()->getLanguages();
  $route = \Drupal::service('path.matcher')
    ->isFrontPage() ? '<front>' : '<current>';

  // Get links.
  $links = [];
  foreach ($languages as $language) {
    $url = new Url($route, [], ['language' => $language]);
    $links[] = [
      '#markup' => Link::fromTextAndUrl($language->getName(), $url)
        ->toString(),
    ];
  }

  // Set cache.
  $items['admin_toolbar_langswitch'] = [
    '#cache' => [
      'contexts' => [
        'languages:language_interface',
        'url',
      ],
    ],
  ];

  // Build toolbar item and tray.
  $items['admin_toolbar_langswitch'] += [
    '#type'   => 'toolbar_item',
    '#weight' => 999,
    'tab'     => [
      '#type'       => 'html_tag',
      '#tag'        => 'div',
      '#value'      => '<span>' . t('Language') . '</span>: <span class="current-language">' . strtoupper($current_language) . '</span>',
      '#attributes' => [
        'class' => ['toolbar-item-admin-toolbar-langswitch'],
        'title' => t('Admin Toolbar Langswitch'),
      ],
    ],
    'tray'    => [
      '#heading' => t('Admin Toolbar Langswitch'),
      'content'  => [
        '#theme'      => 'item_list',
        '#items'      => $links,
        '#attributes' => [
          'class' => ['toolbar-menu'],
        ],
      ],
    ],
  ];

  return $items;
}
  • Can you please tell me what you mean by 'contexts' => [ 'languages:language_interface', 'url', ], – Mohamed Osama Gbril Oct 9 '18 at 11:52
  • @MohamedOsamaGbril – These are cache contexts. They should be sensitive enough to ensure the language string in the toolbar gets updated when switching through languages. But when the title of your toolbar item will just be "Language" you can probably remove that. – leymannx Oct 9 '18 at 11:57
1

The example above for hook_toolbar is almost perfect. I fixed it, see code below. You just have to remove the span on the Language : EN then the click functionality works perfectly.

see my code:

/**
 * Implements hook_toolbar().
 */
function examplemodule_toolbar() {

  // Get languages, get current route.
  $current_language = \Drupal::languageManager()->getCurrentLanguage()->getId();
  $languages = \Drupal::languageManager()->getLanguages();
  $route = \Drupal::service('path.matcher')
    ->isFrontPage() ? '<front>' : '<current>';

  // Get links.
  $links = [];
  foreach ($languages as $language) {
    $url = new Url($route, [], ['language' => $language]);
    $links[] = [
      '#markup' => Link::fromTextAndUrl($language->getName(), $url)
        ->toString(),
    ];
  }

  // Set cache.
  $items['admin_toolbar_langswitch'] = [
    '#cache' => [
      'contexts' => [
        'languages:language_interface',
        'url',
      ],
    ],
  ];

  // Build toolbar item and tray.
  $items['admin_toolbar_langswitch'] += [
    '#type'   => 'toolbar_item',
    '#weight' => 999,
    'tab'     => [
      '#type'       => 'html_tag',
      '#tag'        => 'div',
      '#value'      => t('Language') . ': ' . strtoupper($current_language),
      '#attributes' => [
        'class' => ['toolbar-item-admin-toolbar-langswitch'],
        'title' => t('Admin Toolbar Langswitch'),
      ],
    ],
    'tray'    => [
      '#heading' => t('Admin Toolbar Langswitch'),
      'content'  => [
        '#theme'      => 'item_list',
        '#items'      => $links,
        '#attributes' => [
          'class' => ['toolbar-menu'],
        ],
      ],
    ],
  ];

  return $items;
}
-2

The link in the reply berramou posted doesn't mention the contrib module toolbar_menu, which makes adding stuff in the toolbar more convenient than what is mentioned in the link.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.