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

Menu 如何在Drupal8的主菜单中创建语言切换器,menu,drupal-8,Menu,Drupal 8,这是我关于Drupal8的问题。我在一个网站上有三种语言。将来可以安装新的语言。 我想在主菜单中添加一个语言切换程序 我的第一次尝试是在UI中添加一个菜单项。我喜欢中国人。但是不可能这样说语言前缀。这也意味着,如果从Drupal中添加或删除语言,它将不会自动更新 第二次尝试: $item = \Drupal\menu_link_content\Entity\MenuLinkContent::create([ 'link' => ['uri' => 'internal:/zh-

这是我关于Drupal8的问题。我在一个网站上有三种语言。将来可以安装新的语言。 我想在主菜单中添加一个语言切换程序

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

第二次尝试:

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

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

您可以按照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));

您可以遵循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));

下面是我如何在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中设置“language”选项。

以下是我如何在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中设置“language”选项。

我已经查看了语言切换器,但这并不是我真正想要的。我想以一种动态的方式把这个东西放到Drupal的主菜单中。问题不在于真正获得链接。这是为了找到一种将这些链接以动态方式包含到主菜单中的方法。我已经查看了语言切换程序,但这并不是我真正想要的。我想以一种动态的方式把这个东西放到Drupal的主菜单中。问题不在于真正获得链接。这是为了找到一种将这些链接以动态方式包含到主菜单中的方法。这段代码正确地链接到英语节点的法语翻译。但是一旦进入法语节点,能够回到英语节点就好了。提供此选项将使此解决方案完整。@Bisonbleu编辑了MenuLanguageLink.php以包含返回默认语言的链接。几乎完美!然而我只能在作为管理员身份验证后才能看到此菜单项。我无法将该项目视为匿名用户或其他经过身份验证的用户。是否有任何方法可以让其他经过身份验证和未经身份验证的用户使用此代码?此代码正确链接到英语节点的法语翻译。但是一旦进入法语节点,能够回到英语节点就好了。提供此选项将使此解决方案完整。@Bisonbleu编辑了MenuLanguageLink.php以包含返回默认语言的链接。几乎完美!然而我只能在作为管理员身份验证后才能看到此菜单项。我无法将该项目视为匿名用户或其他经过身份验证的用户。是否有任何方法可以让其他经过身份验证和未经身份验证的用户使用此功能?