Problem/Motivation
Similar to #2345607: Translated taxonomy terms not rendered in the entity display language
To reproduce:
- Install Drupal 8 standard. Enable Language, Content translation modules.
- Add a language.
- Add an entity reference field to the article content type. (To the simple page type)
- Configure Articles to be translatable. But not the reference field.
- Configure the referenced entity (simple page) to be translatable.
- Create a content to be referenced.
- Add an article with a reference.
- Translate the referenced content.
- Translate the article.
Now regardless of which translation of the article you are viewing, the same original language is used to render the reference fields.
Proposed resolution
Make the reference fields show up in the rendering language of the entity.
For this a new method should be introduced in \Drupal\entity_reference\Plugin\Field\FieldFormatter\EntityReferenceFormatterBase, which will provide the translated and accessible referenced entities for prepareView()
Remaining tasks
Discussion about these two unclear things (see comment #18):
- New method vs. prepareView()
- The default fallback behavior if the referenced entity has no translation
User interface changes
None.
API changes
A new method (see above).
Comments
Comment #1
Désiré commentedAttaching a test only patch.
This is very similar than for #2345607: Translated taxonomy terms not rendered in the entity display language, probably they can be merged.
Comment #3
Désiré commentedPatch updated fro the current HEAD.
Comment #5
Désiré commentedThe first fix is attached: it passes the test, it's very similar to taxonomy reference fields, but it's not deal yet with the auto create items.
I need some help about how can I test this with auto create items.
Comment #6
Désiré commentedComment #8
Désiré commentedWell, the tests failed in #5 were passing on my environment, I don't see what is the problem...
Now I'm updated it:
TranslatableInterfaceNext steps:
The current fix is implemented within the
prepareView()method, and it rewrite the $item->entity property whit the translated entity. After some conversation this should be changed: A$node->field_something->entity()call will return an entity with it's original language regardless to the actual language of$node, while$item->entityis the translated entity, and this can be confusing.So we need a new method which returns the accessible items with the correct translation, and use it everywhere instead of
$items.Comment #10
Désiré commentedThe test still passes for me, I don't know what is the difference here.
Now the new
getEntitiesToView()method is implemented, and used in all inherited class.Comment #12
Désiré commented\Drupal\entity_reference\Tests\EntityReferenceFieldViewTeststill passing for me...The other fails are fixed now.
Comment #14
Désiré commentedOK, now it should pass.
The problem was that test bot installs Drupal in subdirectory, and
$entity->url()returned the path with the prefix, also$this->drupalGet($path)added the prefix to the path before the request, so the real patch were double prefixed. I think it's some sort of bug in the test system.Comment #15
amateescu commentedInstead of all the changes done to EntityReferenceFormatterBase and its extending classes, couldn't we just write the logic of
getAccessibleTranslatedEntity()inEntityReferenceFormatterBase::prepareView()? That's exactly the purpose of that method :)Comment #16
amateescu commentedPlease see https://www.drupal.org/project/testbot, the testbots are installing Drupal in a subdirectory by design.
Comment #17
pp commentedI tested the patch and it works fine for me.
I suggest rename EntityReferenceFieldViewTest to something clearer eg.: EntityReferenceFieldViewLanguageVariationsTest
When I translate a referred entity, and I not translate the "host" entity and I go to the "translated url" the host fallback English and refered entity also. If it is fine, I suggest write an another test for testing this usecase also. (If isn't, I suggest write a test for a good usecase and correct the patch.)
Comment #18
Désiré commentedI agree, it's done.
I'm also agree with this, but I don't know what should be the default fallback behavior, so I not changed anything about this.
It's ok, I know it, my problem was that a test can behave differently on a subdirectory install that on a root dir install. But now I found, that
$entity->getSystemPath()can be used for getting the unprefixed path. I'm also changed the test to use it.Please see comment #8, there I explained why is the new method introduced, also the patch there is a working fix implemented in
prepareView().Maybe we should have more discussion about these two unclear things:
Comment #19
Désiré commentedComment #20
Désiré commentedAfter a consultation with webflow, I made some changes:
hasTranslation()becaulsegetTranslation()will create it on the fly, but breaks the default language fallback)Comment #21
schnitzel commentedI could see some cases, where we would like to have more granular control over the fallback behavior (like fallback chains), but of all the experience with client websites, every website is different. And the default language is suitable for most of cases. So I +1 that.
I agree with @amateescu that
prepareView()sounds a lot like what we would like to use, but the case that is made in #8 makes a lot of sense.So +1 for the new method.
Discussed this with @Gabor and @Désiré.
Also here I could see the case that on some websites would like to use the negotiated content language, rather the language of the parent entity.
But when the case happens that the parent entity is not translated the whole page will show anyway a big language mix. If we wanna fix that fully properly we should have an additional Language Negotiation system: Referenced Content Language Negotiation. But this would confuse so many sitebuilders even more (it's now already crazy). So I think this is a case for a contrib module.
Maybe rename $active_langcode to $parent_entity_langcode?
Comment #22
Désiré commentedVariable name changed, as suggested.
Comment #23
amateescu commentedRight, I think #8 makes sense as well. And further to #20, we can now simplify the code even more, something like the patch attached (note that the interdiff doesn't show it, but the patch includes the change from #22).
Comment #24
Désiré commentedI agree with the changes by @amateescu. Thank you.
Comment #30
Désiré commentedWell... The last few patches were failing, because they didn't respected if the
$item->accesswas alreadyTRUE, like before. Now I'm fixed this, the tests should pass.But I think that this is not a good solution: now (I mean the current HEAD and also this last patch) makes it possible to display entities through entity reference fields even if the user have no access to the entity. But since it is the current behavior I think it should be an other issue.
If you agree with this we should go back to RTBC.
Comment #31
amateescu commentedI think that's mostly done for easy testing purposes and, since it's already the current HEAD behavior, this looks good to go now. Thanks Désiré!
Comment #32
schnitzel commentedcan we get the changes from #22 back in there?
then I would also RTBC that :)
Comment #33
amateescu commentedIt's there allright :P
Comment #34
schnitzel commentedoh damn, ignore #32, this is already in, looks like the interdiffs are strange.
but found
we're removing the check for
if (!empty($item->entity) && !empty($item->target_id)). it's also not ingetEntitiesToView().Not sure for what that exactly is, but maybe
$item->target_idcan be empty?But there is a check for
$entity->id()which probably is true every as getEntitiesToView() will return an entity?same here
Comment #35
Désiré commentedThe entity should be auto created (with tag style fields), in this case the entity will have no id,
$item->target_idwill be empty, but$entity->id()will also return NULL, so the changed code should work the same way in these cases.Comment #36
schnitzel commentedok, cotcha. thanks for the explanation :)
back to RTBC
Comment #37
alexpottCan we get an issue filed for this and referenced in the code. See https://twitter.com/xjmdrupal/status/497852222600790016
Not used.
Comment #38
amateescu commentedI'm not sure why that @todo was introduced in this patch, that is the only way to access _attributes :)
Comment #39
amateescu commentedOk.. NR first.
Comment #40
amateescu commentedWhat a lazy bot! Re-uploading.
Comment #41
Désiré commented@amateescu the todo was introduced here, and I'm also created a new issue. I'm also not sure if it makes any sense, so maybe it can just closed. #2350831: Find a better solution for fetch '_attributes' in entity reference fields
Comment #42
amateescu commentedDésiré, I just did that :P And I have no idea why the bot doesn't like that patch :/ Let's try with a different file name.
Comment #45
Désiré commentedThen I think it's RTBC.
Comment #46
alexpottCommitted bf44ce4 and pushed to 8.0.x. Thanks!
Comment #49
yched commentedRelated: #2405469: FileFormatterBase should extend EntityReferenceFormatterBase
Currently file/image formatters do not follow the correct translation behavior that was added for ER fields here.