Problem/Motivation
Executive summary
There are several language-related fields/filters available for translated entities in Views.
They have somewhat confusing names/descriptions, and the Original Language field does not work.
Details follow.
Original language vs. Translation language
All translatable entities have a field called Original Language, which is [base table].langcode (e.g., node.langcode for Node entities). They also have a field called Translation Language, which is [field data table].langcode (e.g., node_field_data.langcode for Node entities). Also keep in mind that in translatable entity Views currently, each row of the view output is one translation of the entity.
So. Original Language works fine as a filter (or presumably a sort) -- it allows you to filter to nodes (for example) that were originally written in a particular language. So does Translation Language -- it allows you to filter for node translations in a particular language. These are both clear and OK.
However, Original Language doesn't work as a field. The problem is that we are now using Entity field rendering for Views fields (which is generally a good thing, since it allows us to get the right translations and control field access correctly). So although the view thinks it is getting node.langcode as the field (which would give you the original language), when it comes to rendering time what it's really doing is asking the entity for the 'langcode' field. This is giving us node_field_data.langcode instead -- meaning it is always the same output as Translation language.
As far as I know, you cannot access the original language of the node currently via Entity field rendering.
So, the field labeled "Original language" in the UI doesn't work as a Field (though it's fine as a filter/sort).
Other field descriptions
Most/all of the entities have kind of lame descriptions on the language-related fields. This is a more minor problem, but the field labels are misleading or wrong in some cases. Here's a list of ones that should be updated (see comments 17-22):
- All entities: Many of the descriptions say "language code" and none of them should, since what is displayed is not a language code but a language name. So they should all just say "language". (The reason they say "language code" is that the descriptions come from the entity class's baseFieldDefinitions() method and there it is 'langcode' so it is a language code; the entity views data classes need to override these.)
- Taxonomy, Comment, and Custom block: The descriptions for the Translation language field need to be fixed so that they say they are the language of the translation, which they currently do not do.
Proposed resolution
The field description fixes are easy and could/should probably be put into a separate issue.
The problem with the Original Language field could be fixed in two ways:
a) Easy fix - don't expose this field because we cannot actually output it. Just have it as a filter and sort.
b) Complicated fix - figure out how to render this using entity rendering. Probably we would need to add an Original Language field to translatable entities, and then figure out how to tell Views that when rendering node.langcode, it should use that new entity field instead of asking the entity for "langcode".
(b) is the Right Thing to do. It is a D7 regression that we cannot display the original language.
Remaining tasks
Determine if this is still a problem.
Fix. Test.
User interface changes
- Original language field will work.
- Other fields will have better descriptions.
API changes
Shouldn't be.
Data model changes
Probably not, but I'm not sure if we change the entity views data for fields like node.langcode, how much of it gets stored in the View?
| Comment | File | Size | Author |
|---|---|---|---|
| #33 | 2450195-33.patch | 7.94 KB | lendude |
| #33 | 2450195-33-TEST_ONLY.patch | 1.39 KB | lendude |
| #32 | 2450195-32.patch | 6.55 KB | lendude |
| #32 | interdiff-2450195-30-32.txt | 715 bytes | lendude |
| #30 | 2450195-30.patch | 5.67 KB | lendude |
Comments
Comment #1
gábor hojtsyWe'll need to add test coverage for it.
Comment #2
jhodgdonUck. Good catch.
Comment #3
jhodgdonSince Entities do not have a field or pseudo-field that will give you the language of the default translation, it doesn't seem like once we move to #2384863: Translation language base field handler should use views field handler, provide unified options that we would be able to use the same treatment for this views field, right? So it would just need to be a field using the bare Views language handler plugin, not the Entity Field plugin, and it would go against the langcode database field on the base entity table?
In other words, what we'd want to do I think is to special case the 'langcode' field in the EntityViewsData class, so that we are using the Field handler for the langcode database field on the entity field data table, and the bare Views language handler for the langcode database field on the base table.
Comment #4
gábor hojtsyYeah I rescoped #2384863: Translation language base field handler should use views field handler, provide unified options to resolve the translation language field so we can keep this one for the default language field (which is broken currently either way and not in a way it would be in scope for #2384863: Translation language base field handler should use views field handler, provide unified options to fix). We can add tests here similar to #2384863: Translation language base field handler should use views field handler, provide unified options to verify it renders properly so this will not happen again. So let's get #2384863: Translation language base field handler should use views field handler, provide unified options in then? :)
Comment #5
gábor hojtsy#2384863: Translation language base field handler should use views field handler, provide unified options landed! We can make this work for default languages then!
Comment #6
jhodgdonAnnnnd, there was much rejoicing!
Comment #7
plachI think it makes sense to special case the
langcodefield on the base table, but only to provide filter, contextual filter, and sort handlers. This would allow to support use cases like:fras default langcodeExposing a field handler not being an instance of the usual Entity Field API handler would trigger the usual issues with field access. What about having a subclass of the Entity Field API field handler dedicated to the entity langcode, exposing an option to use the default language as value? If not selected it would behave as the usual translation language. If needing to list both, one could add two
langcodefields: one with the option enabled and the other with the option disabled.Comment #8
gábor hojtsy@plach: well, in views you are supposed to pick the field from a list not pick a meta-field and then pick the field under it?
Comment #9
plachI don't see it that way: we don't have a "default/original language" field, so there's nothing to pick. It's a common practice to have an option that affects the rendered value, so having a checkbox saying "Display default/original language" does not sound that weird to me.
Comment #10
plachAn alternative could be providing a fake "Default language" field, not tied to any actual column, to be used only for display.
Comment #11
gábor hojtsyI do think that the fake field would be better. I think its sane that people think about the original language and the translation language as conceptually different data.
Comment #12
gábor hojtsyIt does not look like anyone is working on this one :/
Comment #13
dawehnerIt is absolutely true, that we have quite some places in core (for example field formatters), which affect the shown value depending on some option.
I don't care much honestly, whether we want to follow that particular pattern here, as it all comes down to whether the site builders think about default language/translation language as something distinct or similar and hey, I'd say just go with one solution.
Given that for base/data table we have a split up in the database, I'd go with two fields instead of one.
+1
We already load the entity, so it should be accessible.
Comment #14
jhodgdonDo we need to revive this issue? If not we should close it as Won't Fix.
Comment #15
gábor hojtsyWe need this issue to be fixed. That there was no action on it does not mean it is fixed or that we don't need it. Its a major bug. Drupal 8 can be released without it, but it needs to be fixed sometime :)
Comment #16
jhodgdonOK we still need to revive this issue...
Comment #17
jhodgdonI tested this today:
- Install with Standard profile in English.
- Turn on the 4 multilingual modules.
- Add Spanish language.
- Make Node translatable (both content types).
- Add an English Article node translated to Spanish, and a Spanish Page node
translated to English.
- Add another node, originally marked as being in English. Edit it, changing the marked language to Spanish. Edit it again, this time turning on revisions, and change it back to English.
Then I made a Node view. When I go to add fields, I see this (filtering to things with "lang" in them):

So some of the descriptions may be slightly lame (like maybe they shouldn't have the word Node in them), but they are all OK and there is definitely a field for Original Language. Filter looks identical.
So then I added the 3 language fields to a Node view. Each row in the results is a node translation. The output is:
a) English article
Original: English
Translation: English
Translation source: Not specified
b) Spanish translation of (a)
Original: Spanish
Translation: Spanish
Translation source: English
c) Spanish page
Original: Spanish
Translation: Spanish
Translation source: Not specified
d) English translation of (c)
Original: English
Translation: English
Translation source: Spanish
e) Node whose language has changed a few times, and is now English:
Original: English
Translation: English
Translation source: Not specified
[Note: I also looked at the field values after I had changed the language to Spanish, and they were Spanish / Spanish / Not specified]
So. It looks like what these actually mean is:
- Original language is supposedly node.langcode. This should be the current language of the base node, but ... it isn't working right on output. I think the problem is that we are now using entity rendering for all field output, not results from a database query. So it says "Oh, langcode, I know what field that is." and renders langcode, which is the translation language, instead of getting the value of node.langcode, which would be the current language of the base node.
- Translation language node_field_data.langcode. It should be the language of the translation, and this is working right.
- Translation source is apparently node_field_data.content_translation_source. This seems to be working as I expect it to.
Now. On Filter, I can successfully use Original Language to filter based on what the original language of the node is. That works as I expect it -- when I filter to Spanish, I get only my originally-Spanish page. Translation language works too on Filter -- I get the translations/originals that are Spanish. And Translation Source works fine too.
But on Field, Original Language doesn't work. The only way to fix it would be to make it so we can access the node.langcode field as an Entity Field, and also somehow also have a way to render it in Views.
I will repeat this test with other entities, but I think this comment is long enough for Node.
Comment #18
jhodgdonI tested Taxonomy terms - similar test to #17 with similar content/translations (except they are Tag terms not Article nodes). Results:
a) The language fields need better descriptions. They are:
- Original language - The term language code.
- Translation language - The term language code.
- Translation source - The source language from which this translation was created.
===> Translation should say "of term or translation" like Node does, and none of them should say "language code", since what they are outputting is definitely the language not a "code".
b) The output using fields and filters works the same as for Node. So filters work; field Original Language doesn't.
Comment #19
jhodgdonNext test: User.
I found a bug (one of many I filed while testing today, sigh): when I made a view of users, the links shown were not localized to the languages. That is, both the translations linked to user/1 and one of them should have gone to es/user/1 to display in Spanish. This works correctly for Node and Taxonomy term views, but User isn't working right. But that's a separate issue.
So. The field labels are OK for User language fields, except that the Original one has "code" in it: "The user language code.". There are 5 fields:

Fields and filters work same as Node and Taxonomy.
Comment #20
jhodgdonIssue filed for the user link localization problem: #2582499: User views - user links are not localized
Comment #21
jhodgdonOh holy .... OK. Now that I have made User translatable, and added a translation for user 1 (the author of all my content), when I go to the admin/content page I am getting 2 copies of everything. Filed: #2582535: Duplicated rows on admin/content if author is translated
Comment #22
jhodgdonTested comment. Has the same duplication problem as User, which is generic and not really a bug per se. Being discussed a bit on #2582535: Duplicated rows on admin/content if author is translated.
Field labels need some tweaking. Functionality same as node/taxonomy/user as far as the language fields and filters.

Comment #23
jhodgdonAnd finally I looked at the fields for custom blocks, but I got tired and didn't make content and fully test the functionality... it should be the same as the other entities. The field descriptions do need some tweaking:

So. Updating the summary.
Comment #25
lendudeI took a look at the 'Original language' field not working, and it looks like the only problem is that the base 'field' views field handler is used, and not the 'language' views field handler. Switching the 'original language' over to the right handler seems to do the trick.
Not sure if this is the right place to set this, but since this is the place where the titles get set I figured it was a good place to start.
I haven't done a lot of manual testing, just a content view displaying both the translated and original language next to each other, and this is completely different then the discussed fixes . But I thought I'd share anyway.
So this still needs tests.
Comment #26
gábor hojtsy@Lendude: that is pretty amazing. We do need some automated testing to cover this feature though.
Comment #28
lendude@Gabor Hojtsy, yeah was looking around for some kernel tests that set up translated content to display in a view, but couldn't find any, so no easy copy/paste tests for now. Moved the fix to a more logical spot I think and that clears up some of the tests fails locally, but not all, and lets see if it gives some new fails.
Still works with manual testing.
Comment #30
lendudeOk some more cleanup. Commenting out some of the tests feels weird, but since the langcode now no longer uses the 'field' handler when using the base table, running tests for it like it does use the 'field' handler doesn't make sense (and there are a number of commented assertions in those test for some reason).
Moving the tests in EntityTestViewsFieldAccessTest over to entity_test_mul so the langcode can use the data table makes those tests pass. Nice illustration that the base/data table switching works for the langcode field.
This should move this closer to being green for existing tests, but still needs tests for the fix.
Comment #32
lendudeMissed one, not sure if the update tests are related, lets find out.
Comment #33
lendudeNow with a test, lets see what happens.
Interdiff is the test-only file.
Comment #35
dawehnerCann't we also use it for the translation langcode in the data table?
Comment #36
gábor hojtsySo the issue summary says:
Is there an explanation as to why this is the case? The issue summary proposes to somehow make it work as a field (because you know those have access control and field formatters for them). The current patch does not allow the use of the field formatters for language to eg. display in native language or as langcode or whatever. So while the immediate bug is fixed by the patch, there is a difference in functionality.
Comment #37
lendude@dawehner well we could but then you would run into the issues that @Gabor describes in #36 for that field as well.
@Gabor well if I understand this correctly, the current fix only fixes the Views problem. The larger problem seems to be
The current fix is actually a option c) for fixing this
c) Use a Views specific 'language' handler to render the original language field. This will not allow the use of field formatters but will allow the value to be shown.
Option b) is still the right way to go, but I do feel it's outside the scope of Views and probably more a global entity thing.
So the question would be, do we want a Views specific fix for now and follow up with a entity issue?
Comment #38
gábor hojtsy@Lendude: the main challenge is we need to support all ways going forward because of backwards compatibility requirements in Drupal 8. The more ways we introduce the more to maintain in Drupal 8 going forward.
Comment #43
MaskOta commentedI have noticed that with this patch we lost the {{ langcode__value }} replacemenet pattern which was usefull to create a link back to the original language of the entity.
Is this something that can be avoided?
Comment #45
joseph.olstadComment #48
laraortiz commentedIs this issue still being worked on? It looks like it has been 9 months since the last activity but I still see this problem in the main content view when the Original language field is included. Instead of displaying the node's original language, it always displays the same value as the translation language.
Comment #51
quietone commentedIs this still a problem?
I tested this on 9.4.x, standard install with Italian and Spanish added, and was not able to reproduce this error. I had nodes and terms in a variety of original languages and translations. I setup a view that had fields to display the original and translation language for each entity. In all cases the original language and translation language were correct.
There hasn't been work on this problem for 6 years and maybe it has been fixed in the meantime. However, one year ago, @laraortiz, reports that they still have the problem, although the version of Drupal wasn't provided. So, instead of closing this as cannot reproduce I am setting the status to Postponed (maintainer needs more info) so that anyone experiencing this problem can confirm and provide complete steps to reproduce the issue (starting from "Install Drupal core").
Thanks!
Comment #54
quietone commentedAnother seven months have passed and there has been no confirmation that this problem still exists. Therefor, I am closing this issue.
If you are experiencing this problem on a supported version of Drupal reopen the issue, by setting the status to 'Active', and provide complete steps to reproduce the issue (starting from "Install Drupal core").
Thanks!
Comment #55
eli-tReopening.
Here is a video showing the issue starting from a Standard install of 10.3.9 on SimplyTest.me
https://www.youtube.com/watch?v=CZBmAEukp5g
Comment #56
eli-tActually setting the status to Active rather than Needs work as explicitly requested by @quietone in #54
Comment #57
quietone commented@eli-t, thanks for providing proof of the problem. Do you know if this happens on 11.x as well?
Comment #58
eli-t@quietone I've just tested this on Drupal 11.0.9 and can confirm the problem exists there too.
Comment #59
quietone commented@eli-t, thanks.
Updating version because changes are made on on 11.x (our main development branch) first, and are then back ported as needed according to the Core change policies.