Updated: Comment #0

Problem/Motivation

#2161845: Node views (front page, admin) do not use the proper language filter is not quite the expected behavior.

If
node 1 is in en (source), es, af
node 2 is in es (source)
node 3 is in af (source), en

And people create a view (like the front page) which is "List all the nodes in the page's current language",
the expected result is to see 3 nodes (all the nodes). Assumes fallback, see list in proposed resolution section, is show node in source language.

If the page language is en, then expected is: node 1 in en, node 2 in es, node 3 in en, is expected. (Optional expectation is that users with translation permission could see a link to translate node 2 into en. Separate issue?)

If the page language is es, then expected is: node 1 in es, node 2 in es, node 3 in af.

Proposed resolution

Add fallback to language filter, with choices of what to do when there is a result, but not a result in the language being filtered by.

Fallback choices could be:
a) show node in source language (the "language of the node", note that nodes do not have to exist in the site default. For example a site default might be en, but a node, like node 2 above could have been created in es, or node 3 created in af)
b) show node in site default language
c) show node in X language detection and negotiation method... like user account preferred language, browser language
d) hide node.

Remaining tasks

  • Decide what is actually expected, or common use cases.
  • Decide if this is core or contrib territory.
  • After done here, might have to return to make another issue to update the default front page view.
Contributor tasks needed
Task Novice task? Contributor instructions Complete?
Update the issue summary Instructions
Update the issue summary noting if allowed during the beta Instructions

User interface changes

No?

API changes

No?

Comments

klonos’s picture

Just added #2162113: When listing content in a language-filtered view, provide links to translate content that is included due to fallback. as a child issue to this one to take care of the "optional expectation" mentioned in the issue summary ;)

jhodgdon’s picture

Just a note that we should do this for all entity types, not just Node. Should this issue be limited to Node or encompass all?

skyredwang’s picture

c) show node in X language detection and negotiation method... like user account preferred language, browser language

Make most sense to me.

Regarding to #2, ideally this rule should apply to other entities, but I don't know how feasible this is at the moment.

jhodgdon’s picture

All entities are treated the same way for translation. So if this works for nodes it should work for anything.

Gábor Hojtsy’s picture

There is already a language fallback system in Drupal. EntityManager::getTranslationFromContext() will work with an entity_view operation for entity views and a views_query operation for Field views (see Field::query(). A module can provide a UI to configure fallbacks for entity displays and fields generally (for fields, this is only used in views, so it can target views in general, for entity views, this is site-wide). It is not possible to configure that on a view by view basis, but do we need that? Sounds very complicated.

jhodgdon’s picture

So it sounds like we should just close this issue as 'works as designed' then?

Gábor Hojtsy’s picture

This issue proposes to have per-view settings, not on a global level. So its not the same as implemented. I don't think there is any chance for this issue in D8 but no reason to close for that.

jhodgdon’s picture

Actually, it looks like this issue is asking for a fallback for the ***filter*** not for the display. In other words, it's saying "If you filter for Spanish, have a setting so that you can return an English node if there is no Spanish node" for instance.

YesCT’s picture

Issue summary: View changes
Issue tags: +Needs issue summary update

needs beta evaluations (especially since this is a normal task). added instructions to the summary.

anthony.bouch’s picture

UPDATED: Okay - having read the original post a little more carefully, the requirements above are a little more sophisticated than mine ;-)

This solves what I was trying to do... http://drupal.stackexchange.com/questions/192782/how-do-i-get-views-cont...

+1 however, for the original request above - where a fallback could be set if the node is created in a language other than the default and multiple languages exist..

ORIGINAL POST

Not clear if the OP's use of the word 'filter' is accurate, however, we have a large multilingual project about to start, and will be looking for this behavior - i.e. anonymous users choose their native language from the language menu, and should be shown a list of results that are either in their language if the entity exists in their language, or fallback to the default language (English in this case).

Also all of the methods in EntityManager, including getTranslationFromContext - have been marked as deprecated.

https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Entity%21...

At the moment, the front page view will only show the user selected language. So if we have three node entities:

Article 1 (English)
Article 2 (Vietnamese, English)
Article 3 (English)

Only one will be shown - 'Article 2 (Vietnamese)' , if the user selects Vietnamese (and not all three).

I've yet to test this with a custom view - but will be working on this over the weekend. Any tips or advice greatly appreciated.

Version: 8.0.x-dev » 8.1.x-dev

Drupal 8.0.6 was released on April 6 and is the final bugfix release for the Drupal 8.0.x series. Drupal 8.0.x will not receive any further development aside from security fixes. Drupal 8.1.0-rc1 is now available and sites should prepare to update to 8.1.0.

Bug reports should be targeted against the 8.1.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.2.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.1.x-dev » 8.2.x-dev

Drupal 8.1.9 was released on September 7 and is the final bugfix release for the Drupal 8.1.x series. Drupal 8.1.x will not receive any further development aside from security fixes. Drupal 8.2.0-rc1 is now available and sites should prepare to upgrade to 8.2.0.

Bug reports should be targeted against the 8.2.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.3.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.2.x-dev » 8.3.x-dev

Drupal 8.2.6 was released on February 1, 2017 and is the final full bugfix release for the Drupal 8.2.x series. Drupal 8.2.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.3.0 on April 5, 2017. (Drupal 8.3.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.3.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.4.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.3.x-dev » 8.4.x-dev

Drupal 8.3.6 was released on August 2, 2017 and is the final full bugfix release for the Drupal 8.3.x series. Drupal 8.3.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.4.0 on October 4, 2017. (Drupal 8.4.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.4.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.5.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

oakulm’s picture

Just to make this clear for myself, this issue relates also to the issue that I can't force view to only display users current language and ignore language fallback?

mErilainen’s picture

If you add a filter "Translation language" and set it to Interface language, then you will see content only in the interface language if the content has been translated. Note that Rendering Language has to be also set to Interface language.

Version: 8.4.x-dev » 8.5.x-dev

Drupal 8.4.4 was released on January 3, 2018 and is the final full bugfix release for the Drupal 8.4.x series. Drupal 8.4.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.5.0 on March 7, 2018. (Drupal 8.5.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.5.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.6.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

beltofte’s picture

Created a small module that allow configuration of entity fallback languages per language. See https://www.drupal.org/project/entity_language_fallback. This works as in the above usecase, except that the fallback languages are set per language globally in Drupal, and not per view.

beltofte’s picture

Version: 8.5.x-dev » 8.6.x-dev

Drupal 8.5.6 was released on August 1, 2018 and is the final bugfix release for the Drupal 8.5.x series. Drupal 8.5.x will not receive any further development aside from security fixes. Sites should prepare to update to 8.6.0 on September 5, 2018. (Drupal 8.6.0-rc1 is available for testing.)

Bug reports should be targeted against the 8.6.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.7.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

ElessarTelcontar’s picture

Concerning Drupal 8.5.6 (I didn't update to 8.6.2 because it brakes my site and I don't have time to go error hunting right now)

I am confused about this topic. I just found out that when selecting the "translation language" filter in Views to be "interface text language selected for page" the nodes that don't have a translation in that language are not displayed.

I wanted to go around that issue. I want that my view (the frontpage and other views) display all nodes/content (types). Those that aren't translated into the selected language should be displayed in the original language.
My first idea was to filter for the original language. I thought I could filter to keep only those nodes that are the source/original. If applicable/required I would have used the entity_language_fallback module to change the entities into the fallback language. The idea was to select both used languages (EN and DE-German). But that filter seems to be broken and simply outputs all translations. So I end up with both originals and translations displayed. The nodes that have a translation are shown as duplicates. It seems that the German translation is displayed as the original English version of the node.

After playing around what worked is to set following filters:
Content: Promoted to front page (= Yes)
Content: Published (= Yes)
Content: Translation source IS NOT: English, German.

Why does that work? If I set the filter to "IS (one of) English [or] German" only nodes that have a translation into German are displayed (being translated into the set language—also English). It seems as if the translations are displayed but, nevertheless, the correct translation is shown.

I am confused about this filter. Do I understand correctly that it only targets translations and NOT the source/original nodes. If so, I am glad it works. Especially that the nodes are displayed in the set language serves my scenario.

On the one hand nodes and their translations seem to be treated as equal in the sense that both of them can be displayed in the set language, which makes it possible to have duplicates. On the other hand the Translation Source filter can target only the translations, which would be the opposite of what the name suggests. It does not target the source but the translation. It may be that it targets the source if there is a translation. But the negation only removes the duplicates, i.e. the reverse translated translations, but not the source node.

earlofsandwich’s picture

I can't take any credit for this but this solution on Stack Overflow worked for me (for simple fallback to page language):

https://drupal.stackexchange.com/questions/192782/how-do-i-get-views-con...

  1. Add the "Default Translation" filter to a view. That basically ensures that all your nodes are shown once because each node can only have one default translation.
  2. Select "Interface text language selected for page" for "Rendering" language. That will attempt to display the site in the current language and fall back if that's not available. (Interface text sounds a bit misleading, but unless you explicitly enabled separate content language negotiation, that's the same as the content language).
ejanus’s picture

Bump: This is still an important ask from many clients. Has anyone had any success applying this feature request to views?

Version: 8.6.x-dev » 8.8.x-dev

Drupal 8.6.x will not receive any further development aside from security fixes. Bug reports should be targeted against the 8.8.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.9.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

golddragon007’s picture

Status: Active » Closed (won't fix)

I close this issue, you can do it exactly this behaviour as the #22 comment or the StackExchange issue says (in that comment).

herved’s picture

I have a similar need ATM and I don't think #22 solves this.
Indeed Views will retrieve all the entities with default translation and render them according to the current interface language.
But it doesn't work if we try to apply a filter or sort using a field that is translated. Because in that case it will be filtered or sorted according to the field values from the original language (and not the translated field values, which is what I would need).

ATM the only resource I could find to achieve this is select_translation module https://www.drupal.org/project/select_translation

edit:
Instead of using select_translation, which looks very heavy in terms of joins it adds to the queries,
I'm thinking of creating an extra table (via an entity property updated on entity operation?) that will keep track of the language fallback to use.
Given:
- A site in 5 languages: EN, FR, DE, NL, IT
- An EN node with 1 translation: FR
The table would store the fallback language for each entity (pbly retrieved by \Drupal\Core\Entity\EntityRepositoryInterface::getTranslationFromContext)
EN => EN
FR => FR
DE => EN
NL => EN

I would then use that table in the Views filter and join it with the base table.
This way, it wouldn't impact performance too much and the logic can be as complex as we want since it's executed on entity operation.

Amerie’s picture

If anyone trying to accomplish this is running into the same problem as #26 - in our case we were using facets from core_views_facets and it was picking up filter values from the original language node rather than the translation - we were able to solve it by creating a custom filter plugin that adds a subquery to the query. For example in our case we want to get all nodes that are in Spanish plus all English nodes that don't have a Spanish translation:

SELECT * 
FROM node_field_data AS nfd1
WHERE nfd1.langcode='es' OR  
	(nfd1.langcode='en'
	 AND NOT EXISTS
		(SELECT 1 FROM node_field_data AS nfd2
		 WHERE nfd2.nid=nfd1.nid AND nfd2.langcode='es')
	);

In the query() function this is accomplished with code similar to this:

$this->ensureMyTable();
$current_langcode = \Drupal::languageManager()->getCurrentLanguage()->getId();
$database = \Drupal::database();
$sub_query = $database->select('node_field_data', 'nfd2')
  ->fields('nfd2', ['nid'])
  ->condition('nfd2.langcode', $current_langcode, '=')
  ->where('nfd2.nid = ' . $this->tableAlias . '.nid');
$condition = ($this->query->getConnection()->condition('OR'))
  ->condition($this->tableAlias . '.langcode', $current_langcode, '=')
  ->notExists($sub_query);
$this->query->addWhere($this->options['group'], $condition);