言語アイテムのリンクを変更するにはどうすればよいですか?


7

特定の状況での言語スイッチャーであるリンクのDrupal 8のデフォルト出力を変更しようとしています。理想的には、twigテンプレートでそれを実行でき、リンク生成システム全体を上書きする大規模なphpファイルを作成し、上書きが必要な場合にBIGを追加する必要がないようにしたいです。

出力レイアウトは、この回答と同様にtwigテンプレートで制御できるはずです(この回答はすべての言語で同じURLを出力します)

ブートストラップを基本テーマとして使用しているので、リンクにブートストラップマークアップを使用したい(btn btn-primary、ドロップダウン)

これが私が作ろうとしている私のコードです links--language-block.html.twig

{%- if links|length == 2 -%}
    {# show only alternate language button #}
    {%- for key, item in links -%}
        {%- if not item.attributes['#options']['set_active_class'] -%} {# <--- this is always true!? #}
            <a href="{{ item.link['#url'] }}" class="btn btn-primary">{{ item.link['#title'] }}</a> {# #url is always the same what ever the language it is pointing to! #}
        {%- endif -%}
    {%- endfor -%}
{%- elseif links|length > 2  -%}
    {# show selected language in button and other languages in drop down #}
    <button class="btn btn-primary dropdown-toggle" type="button" data-toggle="dropdown">{{ selectedLanguage }}<span class="caret"></span></button>
    <ul class="dropdown-menu">
        {% for key, item in links %}
            {%- if not item.attributes['#options']['set_active_class'] -%} {# <--- this is always true!? #}
            <li><a href="{{ item.link['#url'] }}">{{ item.link['#title'] }}</a></li>
            {% endif %}
        {% endfor %}
    </ul>
{%- endif -%}

誰でもこれを行う方法についてアイデアがありますか?

回答:


13

わかりました、それを行う2つの方法を見つけました。

1.カスタムテーマ

my_theme.themeファイル内の変数を変更できます。必要な関数の名前を理解する必要があります。例:my_theme_preprocess_twig_file()私の場合、私は必要でしmy_theme_preprocess_links__language_block()た。twigファイル名を受け取り、すべて-をに置き換える必要があります_

my_theme.theme

function my_theme_preprocess_links__language_block(&$variables) {
  $currentLanguageCode = \Drupal::languageManager()
    ->getCurrentLanguage()
    ->getId();
  // replace key of active language with 'activeLink'
  foreach ($variables['links'] as $i => $link) {
    /** @var \Drupal\language\Entity\ConfigurableLanguage $linkLanguage */
    $linkLanguage = $link['link']['#options']['language'];
    if ($currentLanguageCode == $linkLanguage->get('id')) {
      $variables['links']['activeLink'] = $link;
      unset($variables['links'][$i]);
    }
  }
  // if there is only 2 languages remove active one
  if (sizeof($variables['links']) == 2) {
    unset($variables['links']['activeLink']);
    // give class 'btn btn-primary' to alternate language
    /** @var \Drupal\Core\Url $alternate */
    $alternate = current($variables['links']);
    $alternate['link']['#options']['attributes']['class'][] = 'btn';
    $alternate['link']['#options']['attributes']['class'][] = 'btn-primary';
    $variables['links'] = [$alternate];
  }
}

2.カスタムモジュール

同じ変数を変更するモジュールを作成することもできます。この前処理はフローの早い段階で行われたため、変数の値には大きな違いがあります。関数の名前もまったく異なりますmy_module_api_to_modify_alter()。例:私の場合、language_switch_linksからを変更する必要がありましたlanguage.api.php*.api.phpdrupal 8 でファイルを検索すると、すべての変更機能を見つけることができます。これらは、正確に参照するためのものです。

my_module.module

function my_module_language_switch_links_alter(&$variables) {
  $currentLanguageCode = \Drupal::languageManager()
    ->getCurrentLanguage()
    ->getId();
  // replace key of active language with 'activeLink'
  foreach ($variables as $i => $link) {
    /** @var \Drupal\language\Entity\ConfigurableLanguage $linkLanguage */
    $linkLanguage = $link['language'];
    if ($currentLanguageCode == $linkLanguage->get('id')) {
      $variables['activeLink'] = $link;
      unset($variables[$i]);
    }
  }
  // if there is only 2 languages remove active one
  if (sizeof($variables) == 2) {
    unset($variables['activeLink']);
    // give class 'btn btn-primary' to alternate language
    /** @var \Drupal\Core\Url $alternate */
    $alternate = current($variables);
    $alternate['attributes']['class'][] = 'btn';
    $alternate['attributes']['class'][] = 'btn-primary';
    $variables = [$alternate];
  }
}

そして、両方の場合の私のTwigテンプレートl inks--language-block.html.twig

{% if links -%}
    {%- if links|length == 1 -%}
        {# show only alternate language button #}
        {{ (links|first).link }}
    {%- else -%}
        {# show selected language in button and other languages in drop down #}
        <button class="btn btn-primary dropdown-toggle" type="button" data-toggle="dropdown">{{ links['activeLink'].text }} <span class="caret"></span></button>
        <ul class="dropdown-menu">
            {% for key, item in links %}
                {% if key is not same as("activeLink") %}
                <li>{{ item.link }}</li>
                {% endif %}
            {% endfor %}
        </ul>
    {%- endif -%}
{%- endif %}

1

この適応を言語スイッチャーにしたので、articleタイプのノードが見つかった場合、これは別の言語の翻訳ではなく、リンクがホームページに変更されます。

これは、テーマではなくモジュールで作成する必要がありました。

言語ごとに翻訳された記事の数に大きな違いがあったので、これが必要でした。

function HOOK_language_switch_links_alter(array &$links, $type, \Drupal\Core\Url $url){
$currentLanguageCode = \Drupal::languageManager()
->getCurrentLanguage()
->getId();
// look at all links.
foreach ($links as $link) {
  // Only work on links that are not in the current page language.
  $lang_id = $link['language']->get('id');
  if ($currentLanguageCode != $lang_id) {
    // Trying to get the node.
    $node = \Drupal::request()->attributes->get('node');
    // Making sure its an object and has the method getType and is Article.
    if (!empty((object) $node) 
      && method_exists($node, 'getType')
      && $node->getType() == 'article') {
      //  We know its an article, checking for languages.
      $flipped = array_flip(array_keys($node->getTranslationLanguages()));
      // Using flipped array rather than in_array
      if (!isset($flipped[$lang_id])) {
        // Translation not available.
        $links[$lang_id]['url'] = Url::fromRoute('<front>');
      }
    }
  }
 }
}

Drupal \ Core \ Urlのuseステートメントを追加して、関数の引数から削除することを忘れないでください。これは、新しいルートの生成にも使用されます。

また、URLを変更するには、新しく生成されたUrlオブジェクトを使用する必要があることに注意してください。既存のURL( '<current>')を変更するためのsetメソッドはありません。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.