如何在Drupal8的主菜单中创建语言切换器

时间:2017-07-07 13:44:44

标签: menu drupal-8

这是我在Drupal8上的问题。我在一个网站上有3种语言。将来可以安装新语言。 我想在主菜单中放置一个语言切换器。

我的第一次尝试是使用UI添加菜单项。喜欢"中文"。但是不可能说出那样做的语言前缀。这也意味着如果在Drupal中添加或删除语言,它将不会自动更新。

第二次尝试:

$item = \Drupal\menu_link_content\Entity\MenuLinkContent::create([
    'link' => ['uri' => 'internal:/zh-hans/'],
    'title' => 'Chinese',
    'menu_name' => 'main',
]);
$item->save();

它在主菜单中添加了一个新项目,但它不会使用语言前缀。无论如何,这不是动态解决方案,因为您必须在添加或删除语言时重建菜单。此外,语言的顺序将一劳永逸地设置......我更喜欢将当前语言放在顶部,这取决于您现在使用的是哪种语言。

2 个答案:

答案 0 :(得分:2)

这是我在Drupal菜单中实现语言切换器链接(对于法语)的方式。 该代码可以满足您的特定需求。

.links.menu.yml:

<my_module>.switch:
  class: Drupal\<my_module>\Plugin\Menu\MenuLanguageLink
  menu_name: main
  route_name: '<current>'
  options:
    attributes:
      hreflang: 'fr'

将“菜单名称”更改为您的Drupal菜单。
将“ hreflang”更改为您的语言代码。

src / Plugin / Menu / MenuLanguageLink.php:

namespace Drupal\<my_module>\Plugin\Menu;

use Drupal\Core\Menu\MenuLinkBase;
use Drupal\Core\Language\LanguageManagerInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;

class MenuLanguageLink extends MenuLinkBase implements ContainerFactoryPluginInterface {

  /** @var array Available languages */
  protected $languages = [];

  /** @var Drupal\Core\Language\Language */
  protected $defaultLanguage;

  /** @var Drupal\Core\Language\Language */
  protected $currentLanguage;

  /**
   * {@inheritdoc}
   */
  public function __construct(
    array $configuration,
    $plugin_id,
    $plugin_definition,
    LanguageManagerInterface $language_manager
  ) {
    parent::__construct($configuration, $plugin_id, $plugin_definition);
    $this->languages = $language_manager->getLanguages();
    $this->defaultLanguage = $language_manager->getDefaultLanguage();
    $this->currentLanguage = $language_manager->getCurrentLanguage();
  }

  /**
   * Dependency injection.
   */
  public static function create(
    ContainerInterface $container,
    array $configuration,
    $plugin_id,
    $plugin_definition
  ) {
    return new static(
      $configuration,
      $plugin_id,
      $plugin_definition,
      $container->get('language_manager')
    );
  }

  /**
   * {@inheritdoc}
   */
  public function updateLink(array $new_definition_values, $persist) {
    return $this->pluginDefinition;
  }

  /**
   * {@inheritdoc}
   */
  public function getOptions() {
    $options = parent::getOptions();
    $langcode = $options['attributes']['hreflang'];
    $langcode_default = $this->defaultLanguage->getId();

    if ($langcode_default === $this->currentLanguage->getId()) {
      if (isset($this->languages[$langcode])) {
        $options += ['language' => $this->languages[$langcode]];
      }
    }
    else {
      $options += ['language' => $this->languages[$langcode_default]];
      $options['attributes']['hreflang'] = $langcode_default;
    }

    return $options; 
  }

  /**
   * {@inheritdoc}
   */
  public function getTitle() {
    $langcode = $this->getOptions()['attributes']['hreflang'];
    $langcode_default = $this->defaultLanguage->getId();
    if ($langcode_default === $this->currentLanguage->getId()) {
      return $this->languages[$langcode]->getName();
    }
    else {
      return $this->languages[$langcode_default]->getName();
    }
  }

  /**
   * {@inheritdoc}
   */
  public function getDescription() {
    return $this->t('Switch language');
  }

}

技巧是在getOptions()中设置“语言”选项。

答案 1 :(得分:0)

您可以关注Drupal的核心语言切换器代码:

core/modules/language/src/Plugin/Block/LanguageBlock.php

首先确保使用PathMatcherInterface和LanguageManagerInterface

use Drupal\Core\Path\PathMatcherInterface;
use Drupal\Core\Language\LanguageManagerInterface;

然后查看获取语言链接列表(第88和90行):

$route_name = $this->pathMatcher->isFrontPage() ? '<front>' : '<current>';

$links = $this->languageManager->getLanguageSwitchLinks($type, Url::fromRoute($route_name));