Problem/Motivation
Checking for a canonical link template when providing default values for translation info is inconsistent. It is checked in content_translation.module::content_translation_entity_type_alter().
This check doesn't happen in ContentTranslationManager::isEnabled()/isSupported().
The result is that the behavior is inconsistent. You can enable field translations for such an entity type but then the checkboxes aren't checked after saving.
Not having a canonical link template is common for entity types that are only edited within another entity type, like Paragraphs" or Field collection.
Steps to reproduce
To reproduce this issue, there should be a content entity type that is translatable but has no canonical link. For example the mentioned paragraphs module.
1. Enable the paragraphs_demo module.
2. Enable Content translation.
4. Add a second language.
5. Go to Content language and translation
6. Make paragraphed article translatable.
7. Make the various paragraph types translatable.
In HEAD, after saving, the paragraph checkboxes will remain unchecked. That's because the info is not properly passed through to the bundles.
Proposed resolution
By default, entity types without a canonical link template are disabled and can't enabled. Additionally, ntroduce a new flag "content_translation_ui_skip", that such entity types can add so that they can still be enabled. Paragraphs don't care about having a content translation UI, only that there is an easy way to make bundles and fields translatable.
Remaining tasks
User interface changes
With the patch and and entity types with a canonical link template, nothing changes. Those that have the flag set now behave the same way.
Those that don't now display an explicit message and can't be enabled:

(To simulate this, remove the flag from the paragraphs entity type and clear caches)
Comments
Comment #1
Anushka-mp commentedComment #2
Anushka-mp commentedComment #3
Anushka-mp commentedComment #4
gábor hojtsyComment #5
berdirAdding related issue for some more context: #2414913: Support entity translation of paragraphs
Comment #6
berdirPer discussion with @plach:
- Check isSupported() of entity types, don't extend the form if they are not
- Add a new skip ui option that enables it even if there is no link template, by checking it in isSupported()
- Add a warning/description for those, stating that no UI will be provided (or not? if an entity type opts-in, then he probably *has* his own UI and doesn't need a warning, which would just confuse users...)
Comment #7
plachGood point on the warning
Comment #8
Anushka-mp commentedAs discussed, isSupported check now checks for the skip ui flag.
Comment #9
berdirThanks, we probably need to at least document this key somewhere, but I'm not sure where... ?
Comment #10
plachI think the other CT-specifc keys are documented at
content_translation_entity_type_alter()or nearby.Comment #11
berdirLet's do that then.
Comment #12
Anushka-mp commentedNewly introduced key documented.
Comment #13
Anushka-mp commentedDocumentation changed a bit.
Comment #14
Anushka-mp commentedComment #15
plachLooks good to me, thanks, can we please enclose the key name in double quotes?
Comment #16
Anushka-mp commentedkey name enclosed in double quotes.
Comment #17
plachCool, I guess we are only missing some test coverage now.
Comment #18
plachComment #20
Anushka-mp commentedA test module added with two entities(translatable) that don't have a canonical link template and only one of them has the content_translation_ui_skip set to true.
While writing tests we decided to have a message about the translation checkbox being unavailable for the entities which are translatable but no canonical link provided + content_translation_ui_skip is not set to true.
Comment #21
Anushka-mp commentedAdding screens.
Comment #23
Anushka-mp commentedComment #24
Anushka-mp commentedTests only patch with the added test module.
Comment #26
Anushka-mp commentedComment #27
plachThanks, we are almost there!
Berdir suggested that the message might simply be confusing for users (see #6), I agree we should avoid it.
Please let's make the class names match the plugin ids to avoid confusion.
Comment #28
berdirI actually suggested the message. This is the opposite message of the one that I originally mentioned (which would have been on the one that *is* supported), I thought then that the non-supported entity types would be completely hidden, but now they are not, but can't be selected.
When we looked at the screenshot in #21, it looked pretty confusing to use without an explanbation
Comment #29
Anushka-mp commentedClass name changed as suggested.
IMHO we should keep the message in order to justify the unavailability of the checkbox (as explained in #28).
Comment #30
plachWhy do we need this ternary operator? Didn't we just check that
$content_translation_manager->isSupported($entity_type_id)isFALSEvia the$entity_type_translatablevariable?Also, I'd use a less technical wording for the warning: what about simply "Translation is not supported"?
This patch is including also the previous patches.
Comment #31
plachComment #32
sasanikolic commentedComment #34
sasanikolic commentedFixed the label and removed the patches and interdiffs from the previous patch.
Comment #35
berdirHm, that translation is less technical, but technically, it's also less correct :) It's still possible to translate it, but not in the UI :) Anyway, fine with me, @plach?
Comment #36
plachAfk atm, assigning to me so I don't forget about this
Comment #37
plachWrong indentation, sorry. RTBC otherwise.
Comment #38
sasanikolic commentedRerolled and corrected the indentation.
Comment #39
plachThanks!
Comment #40
miro_dietikerStill applies. And blocks us in multilingual contrib domain (Paragraphs, TMGMT, and partially Diff and more).
#2473721: Check multilingual settings for paragraphs
Comment #41
xjmThanks @Anushka-mp, @sasanikolic, @Berdir, and @plach for the patch, and thanks @miro_dietiker for clarifying the significance of the issue. Depending on how severe of a blocker this is, it might be worth bumping to major.
The test coverage looks great, and while I was a bit hesitant at first about stuffing another Boolean key into the entity type annotation, it looks like there is already precedent for that in
content_translationin general.+1 for this UI message; it's nice and clear. (Looks like the screenshot is out of date but I got the point when looking at it and then trying to find the comma splice in the patch.) ;)
This documentation doesn't really clarify for me what the usecase is for not having a canonical link template and wanting translation, nor what the UI has to do with it. Reading this, I don't know why whether or not my entity is translatable has anything to do with the UI. :) I also saw something on the issue about how these entity types are likely to provide their own UIs; maybe that should be explained as well?
content_translation_entity_type_alter(). Ideally it'd be a scannable list in key: explanation form, like we used to have onhook_entity_info(). Also, I think that there should be an@seetohook_entity_type_alter()andhook_entity_type_build()from the entity annotation definition so that I know these implementations add keys I can use as a developer. Anyone want to file a pair of followup issues for that (one for the@seeon the entity annotation definition, and another for improving the formatting ofcontent_translation_entity_type_alter())?hook_entity_type_build(), why is this key being defined onhook_entity_type_alter()instead of the build hook? I thought one was only supposed to use the alter hook to change existing keys, not to add new ones. But I never understood it all that well anyway.In summary I think the only blocking thing is a bit of docs improvement; the patch looks great overall. Thanks!
Comment #42
xjm(Adding reviewer patch credit.)
Comment #43
sasanikolic commentedComment #44
sasanikolic commentedAdded some description for #2 and opened a new issue for #3 (#2478535: Rewrite the documentation of content_translation_entity_type_alter()). Also, changed the issue description and explained how to reproduce with paragraphs (#5).
Comment #45
berdirOn 4. IMHO, _alter() is correct, because we are altering existing entity types, and someone might be adding new ones in _build() for which we want to apply this logic as well (entity creation kit, for example). But core is very inconsistent there.
We didn't understand the @see follow-up, not sure where to add a @see for what, in content_translation_entity_type_alter() to the hook documentation? but we already have the "Implements hook_entity_type_alter()" and when you're adding it to your own entity type, you add it directly in the annotation, not in the build/alter hook...
Comment #46
xjmThanks @sasanikolic for the docs and the followup!
Cool, this is the bit of info that was missing for me. :) Polishing the wording a little:
I'll file the other followup issue and link it here shortly. :)
Comment #47
xjmOh re: #45, the docs for
hook_entity_type_alter()say:I'll ask @tim.plunkett to weigh in.
Comment #48
xjmActually re: the other followup issue, there is a reference on the interface for the annotation definition, just not the class, so it's probably not worth duplicating that. Somehow though I managed to miss it.
Comment #49
tim.plunkettThe first check in content_translation_entity_type_alter() is
if ($entity_type->isTranslatable()) {, and because of that I think it should stay an alter. We're looking to make changes to the entity type based on information that could still be gathered during _build().If it were moved to _build(), you could end up with hook-invocation-ordering issues.
Comment #50
berdirUpdated the issue summary and added the suggested documentation from #46.
Comment #51
berdirHm, preview + edit conflict apparently eat my issue summary updates. Luckily I found them again in the browser history.
Comment #52
xjmI also filed: #2478855: Improve documentation for hook_entity_type_build() and hook_entity_type_alter()
Comment #53
berdirI just rerolled with the comment suggested by @xjm and worked on the issue summary, I think it's OK if I RTBC this again...
Comment #54
plach+1
Comment #56
xjmSo it's a bit nonstandard to have
UIin uppercase in this machine name, but as it's a test entity type used only for this test I don't think it really matters. (And I struggle to make my fingers lowercase acronymns like "UI" too.) ;)As a bugfix and a contributed project blocker with no disruption to speak of, this is a prioritized change during the beta phase per https://www.drupal.org/core/beta-changes. Committed and pushed to 8.0.x (with reviewer credit). Thanks!