My Drupal website has 2 languages and I created blog view that lists articles (content type). Default language is English.

Problem is that some articles are only in German and then on my English view I get German articles.

I tried adding Content: Translation language Filter that I set to Interface text language selected for page but then on German page I only get articles that were created on German and the ones that were created in English but have German translation are missing.

Query :

SELECT node_field_data.created AS node_field_data_created, 
node_field_data.nid AS nid
FROM 
{node_field_data} node_field_data
LEFT JOIN {node__field_content_type} node__field_content_type ON 
node_field_data.nid = node__field_content_type.entity_id AND 
(node__field_content_type.deleted = '0' AND 
node__field_content_type.langcode = node_field_data.langcode)
WHERE (( (node_field_data.status = '1') AND (node_field_data.type IN  
('article')) AND (node__field_content_type.field_content_type_value = '1') 
))
ORDER BY node_field_data_created DESC
LIMIT 5 OFFSET 0

Query with Translation language filter:

SELECT node_field_data.created AS node_field_data_created, 
node_field_data.nid AS nid
FROM 
{node_field_data} node_field_data
LEFT JOIN {node__field_content_type} node__field_content_type ON 
node_field_data.nid = node__field_content_type.entity_id AND 
(node__field_content_type.deleted = '0' AND 
node__field_content_type.langcode = node_field_data.langcode)
LEFT JOIN {node__field_tags} node__field_tags ON node_field_data.nid = 
node__field_tags.entity_id AND node__field_tags.field_tags_target_id = '4'
WHERE (( (node__field_tags.field_tags_target_id IS NULL) )AND(( 
(node_field_data.status = '1') AND (node_field_data.type IN  ('article')) 
AND (node__field_content_type.field_content_type_value = '1') AND 
(node_field_data.langcode IN  ('en')) )))
ORDER BY node_field_data_created DESC
LIMIT 5 OFFSET 0

From queries, I see that LEFT JOIN is adding node__field_content_type.langcode = node_field_data.langcode and I think that is making problems when I add the language filter, any suggestion?

  • The LEFT JOIN is OK, it joins the entries with the same language in both tables. But your query is filtering english: (node_field_data.langcode IN ('en', 'en')) ))), so by looking at the filter this means the interface language is detected as english. – 4k4 May 18 '17 at 18:12
  • @4k4 still does not explain why I do not get translations only original language when I add filter – Marko Kunic May 18 '17 at 19:35
  • The node_field_data table contains all languages, it doesn't matter whether this is the original or translated version. There was no more information for me to debug this any further. My idea was to get you away from debugging the LEFT JOIN, because this joins only one bundle field to the main node data table, and pointing you at the filter in the query and the language detection. What have you configured there? (admin/config/regional/language/detection) – 4k4 May 18 '17 at 20:49
  • Maybe I'm on the wrong track, did think that the error is the English filter on a German page. The join could be the problem, if the field field_content_type in your node is not translatable, see this issue drupal.org/node/2451657 – 4k4 May 18 '17 at 21:21
  • @4k4 node__field_content_type.langcode has only original language while node_field_data.langcode has all languages, that is why I thought that that will make a problem. Detection prntscr.com/f9k62p, will check that issue. Thank you – Marko Kunic May 19 '17 at 6:24
up vote 2 down vote accepted

The problem was that I was doing condition in views with field that wasn't translatable and views are adding join on langcode, thanks to user 4k4 that linked to this issue that can be found here.

I fixed this by removing untranslated field from view and hooking into hook_views_query_alter and adding relationship myself :

<?php

use Drupal\views\ViewExecutable;
use Drupal\views\Plugin\views\query\QueryPluginBase;

function hook_views_query_alter(ViewExecutable $view, 
QueryPluginBase $query)
{
    if ($view->id() == 'blog') {
        $definition = [
            'table' => 'node__field_content_type',
            'field' => 'entity_id',
            'left_table' => 'node_field_data',
            'left_field' => 'nid',
        ];
        $join = Drupal::service('plugin.manager.views.join')->createInstance('standard', $definition);
        $query->addRelationship('node__field_content_type', $join, 'node__field_content_type');
        $query->addWhere('1', 'node__field_content_type.field_content_type_value', 1, '=');
    }
}

Also this hook has to be in MODULE.views_execution.inc file

  • Thank you for sharing the solution with us. I am not sure where you add this part of code, a file MY_MODULE.views_execution.inc has no impact in my environment. For me it worked to add it to my MY_MODULE.module-file as the function MY_MODULE_views_query_alter(ViewExe.... – btemperli Nov 14 at 7:51
  • @btemperli maybe something changed since I needed this, I didn't work with drupal for over a year now – Marko Kunic Nov 18 at 20:46

In "Filter Criteria", pick "Content: translation language" and choose "Interface text language selected for page".

The spanish content will be filtered if you path has the "/es/" langcode. And if there's no langcode specified, it will be the default langage in the site.

  • That would work if you do not have non-translatable field that you are using as filters for the view, but I have additional conditions based on some field that is not translatable and because of that your solution does not work. – Marko Kunic Jun 21 '17 at 11:50

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.