2

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

5
  • 1
    There is tree ways to add items to the admin toolbar, take a look at this question,
    – berramou
    Commented Oct 4, 2018 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 Commented Oct 4, 2018 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
    Commented Oct 4, 2018 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 Commented Oct 4, 2018 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
    Commented Oct 4, 2018 at 12:00

4 Answers 4

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;
}
2
  • Can you please tell me what you mean by 'contexts' => [ 'languages:language_interface', 'url', ], Commented Oct 9, 2018 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
    Commented Oct 9, 2018 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;
}
0

Ok, nowadays there is https://www.drupal.org/project/toolbar_language_switcher for solving this problem

-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 and acknowledge you have read our privacy policy.

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