1

I set up a multilingual blog with Drupal 8 (in English and Chinese), I want to list articles according to current language in the front page.

However, if an article does not has an translation in the current language, I want it to default to the original untranslated version(whatever language), with a hint like "This content is not available in Chinese, we are showing the original article in English."

Assuming that I have 3 blog articles (nodes), with or without translation:

  • Article 1 (original language: English; translated to: Chinese)
  • Article 2 (original language: Chinese; translated to: English)
  • Article 3 (original language: English)

When a user visits the English front page at example.com/en, they will see:

  • Article 1 (in English, original)
  • Article 2 (in English, translated)
  • Article 3 (in English, original)

which is the default behaviour of Drupal 8.


Now, when a user visits the Chinese front page at example.com/zh-hans, I would like them to see:

  • Article 1 (in Chinese, translated)
  • Article 2 (in Chinese, original)
  • Article 3 (in English, with a hint)

However, Drupal 8 out of the box will display:

  • Article 1 (in Chinese, translated)
  • Article 2 (in Chinese, original)

I tried editing the front page as it is a view in Drupal 8, but with the filters in view I could not achieve this.

Language filter in view

(Filters in view)

Do I need to implement a custom filter for the front page view? Please suggest where should I start, I have no idea how to do this.

Thanks!

  • Hi Radium, have you been able to resolve this? – Ondrej Jun 21 '16 at 13:47
1

See the solution to How do I get Views content items in "my language" but fall back to "default" if the content isn't translated? whether it helps just by configuring in admin. It seems to solve the same problem.

Unfortunately, I have the same problem, and I can't get the solution described there to work. Reading all the issues linked in meta Make multilingual views work, it seems to me that there is no built-in solution. I tried to implement a hook_views_post_execute() and to filter the ViewExecutable $view manually, like in the following, but it did not work - either still shows multiple translations per entity, or entities are missing:

# File modules/contrib/modulename/modulename.module
# Enabled in admin/extend
function modulename_views_post_execute(ViewExecutable $view)
{
  $contentLangcode = \Drupal::languageManager()->getCurrentLanguage(LanguageInterface::TYPE_CONTENT)->getId();

  # trying either one of:
  # $Filtered = filterLangcodeOrEn($contentLangcode, $view->result);
  $Filtered = filterNodeOnce($view->result);

  $view->result = $Filtered;
  $view->total_rows = count($Filtered);
}

function filterNodeOnce($rows)
{
  $Nodes = array();
  foreach ($rows as $row) {
    $Nodes[$row->nid] = $row;
  }

  return array_values($Nodes);
}

function filterLangcodeOrEn($contentLangcode, $rows)
{
  # group by nid
  $EntitiesLangcodesRow = array();
  foreach ($rows as $row) {
    $EntitiesLangcodesRow[$row->nid][$row->node_field_data_langcode] = $row;
  }

  # select
  $Filtered = array();
  foreach ($EntitiesLangcodesRow as $LangcodesRow) {
    if (isset($LangcodesRow[$contentLangcode])) {
      $Filtered[] = $LangcodesRow[$contentLangcode];
    }
    else if (isset($LangcodesRow["en"])) {
      $Filtered[] = $LangcodesRow["en"];
    }
  }
  return $Filtered;
}

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.