Problem/Motivation
Experience builder fields should be translatable
We need 2 types of translation
Symmetric Translation
This means all the components on an entity are the same across all languages, but each component can different values per language. This is useful for sites that want the same layout and look across languages
Asymmetric Translation
The means each entity would have totally different components per language.
Steps to reproduce
Proposed resolution
We should be able to set the properties of the component_tree field to be translatable to achieve this
Symmetric Translation
For this tree property should not be translatable because it store which components are on the page
The props property would be translatable
Asymmetric Translation
For this both the tree and props properties should be translatable.
Remaining tasks
User interface changes
API changes
Data model changes
Hopefully none as the Content Translation module should allow this functionality
Issue fork experience_builder-3454257
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #3
tedbowComment #4
tedbowAll passing
Created follow-up for #3456000: If Experience Builder field is not translatable the dynamic source properties do not use the translated entity field value
Comment #5
tedbowI figure out the problem with viewing entity as a translation and having the XB field being untranslated and showing the title of the default translation.
I figured out why this happens.
\Drupal\Core\Entity\ContentEntityBase::get()calls\Drupal\Core\Entity\ContentEntityBase::getTranslatedFieldSo in the case the XB field is not translated it do a recursive call to
getTranslatedField()but his time usingLanguageInterface::LANGCODE_DEFAULTgetTranslatedField()then this is calledSo
$this->getTranslation($langcode)means the field item list will be created with the default,LanguageInterface::LANGCODE_DEFAULTtranslation, even though the entity that had the original call to\Drupal\Core\Entity\ContentEntityBase::get()in step above could have been the translation of another language.The change was made in #2513094: ContentEntityBase::getTranslatedField and ContentEntityBase::__clone break field reference to parent entity
was changed to
I will read up that issue. But presumably there was a good reason to need the translation instead of the original entity object.
I was able to use
hook_entity_prepare_viewto set the fields entity parent to the correct translationComment #6
tedbowI think maybe we can close #2513094: ContentEntityBase::getTranslatedField and ContentEntityBase::__clone break field reference to parent entity as I think the use of
hook_entity_prepare_viewis an okay solution here. But I will research #2513094: ContentEntityBase::getTranslatedField and ContentEntityBase::__clone break field reference to parent entity a little more to be sure.but I think
hook_entity_prepare_viewis a least a good solution for now and we could leave #2513094: ContentEntityBase::getTranslatedField and ContentEntityBase::__clone break field reference to parent entity open if we want to ask for some core changeComment #7
lauriii@larowlan could we merge this and open a follow-up for the feedback? @tedbow is currently on PTO and it would be great to merge this if we think it's close enough 😇
Comment #8
larowlanWill take a look early next week @lauriii
Comment #9
wim leersBack from vacation. I reviewed all other issues that you worked on, @tedbow, because they seemed to be where your current attention is at.
Will review on Monday, unless @larowlan beats me to it.
Comment #10
wim leersDidn't get to it last week, but @tedbow was already working on the more urgent #3455728: FieldType: Support storing component *trees* instead of *lists*, which is now in 👍
Updated the MR to pass on the latest
0.x.Questions on the MR.
Comment #11
wim leersComment #12
tedbowComment #13
tedbowfixing phpcs
Comment #14
tedbowFixed the phpcs problem expect for 1 in
themes/engines/semi_coupled/semi_coupled.enginewhich was not changed. I guess there is new rule in core?Anyways I could fix this other file too if we want to get green
Comment #15
tedbowfixed the other file, can revert if needed
Comment #16
wim leers#3456024: Lift most logic out of ComponentTreeItem::preSave() and into a new validation constraint landed and conflicted, merged in upstream + resolved conflicts.
Comment #17
wim leersAlmost there: https://git.drupalcode.org/project/experience_builder/-/merge_requests/5...
Comment #18
tedbowSee MR comment
Comment #19
wim leersThat MR comment is great — thank you! Pushed a commit that captures it for future readers.
As I was making a final pass, I realized that this MR is not actually using/updating the
translation: symmetric|asymmetricsetting yet 😅 See https://git.drupalcode.org/project/experience_builder/-/merge_requests/5....Comment #20
tedbowLet me know if you agree with this and I can implement it https://git.drupalcode.org/project/experience_builder/-/merge_requests/5...
Comment #22
wim leersDiscussed with @tedbow and @effulgentsia — we agreed that a setting might offer nicer UX, but that's for some very distant day in the future, that is nowhere near urgent. It doesn't even merit a follow-up issue. Because the current UX for configuring this also might be sufficient 👍
Comment #23
tedbowI made the changes I think you asked for and resolved the threads. Not sure where in the UI to mark this as resolved
Comment #24
wim leersTantalizingly close — there's one thing I don't understand 😭
Comment #25
tedbowComment #26
berdirNot caught up on the whole discussion or experience builder storagae in general. I do want to add that the real complexity around translations starts to show when you add pending revisions, aka content_moderation/workflows to the mix. Because that's when you need to start to merge revision data on a per-field or even field-property (in case of ERR/paragraphs, in this case on whatever partial thingies you store/define here).
See also https://berdir.github.io/entities-explained/#/7/4 and slides before and after that.
Mostly an issue for symmetric translations. As an example, assume you have a thing that has a translatable text field, a partially translated image field (file id is synced, alt/title is per-translation) and an untranslatable list/reference field. You might create 3 draft translations in parallel for different languages and at the same time also change the untranslatable list field in the default translation. Then you publish all those in order and the resulting revision should then contain all translations and the untranslatable value from the default translations.
You don't need to and very likely don't want to support that complexity in this initial issue, but it needs to be on the radar, because this is is how content on multilingual sites works (you need to prepare changes on multiple languages and publish them all basically together). Paragraphs/ERR supports this fairly well, getting as far as we are was a large amount of work but people are still struggling with a number of scenarios (for example #3007233: Draft translations should be based on the latest revision of the source language, not the published version and there are several open issues in ERR that I'm struggling to understand).
Comment #27
wim leersThank you so much for that, @Berdir!
This issue represents a big step forward, but I acknowledge it does not guarantee that everything works.
So:
Comment #29
wim leers