According to #2904705, comment #96, there is reluctancy by the paragraph maintainers to implement asymmetric translation even for the "experimental" widget (actually this is the current recommended/default widget). So I'm filing this issue to also support the experimental widget and integrate the functionality of the current patch from #2904705 into this module.

CommentFileSizeAuthor
#2 3171810-2.patch3.43 KBrade

Comments

rgpublic created an issue. See original summary.

rade’s picture

Status: Active » Needs review
StatusFileSize
new3.43 KB

Here is a first version of a patch that could work together with the one from #2904705-115: Support asymmetric translation in experimental widget.

In this first version I have not yet implemented the changes in warning messages nor added any tests.

Edited to add proper credit: The implementation of hook_entity_translation_create() is entirely based on the one from patch #2904705-85: Support asymmetric translation in experimental widget so I did not write that code myself. The original implementation seems to be by @weseze in #2904705-68: Support asymmetric translation in experimental widget

weseze’s picture

Thanks for your work. I will try and review this by the end of next week so we can work towards a new release here. (small chance I can do it today)

I'm thinking we could also include your patch for paragraphs straight into this module through composer.json?
Just requiring "cweagans/composer-patches" and adding this:

    "extra": {
        "patches": {
            "drupal/paragraphs": {
                "Support asymmetric translation in experimental widget - https://www.drupal.org/project/paragraphs/issues/2904705": "https://www.drupal.org/files/issues/2020-09-25/2904705-115.patch"
            }
        }
    }
rade’s picture

Thanks @weseze!

Including the patch in this module's composer.json is a good idea, but ultimately I hope that it will be committed into paragraphs module :)

rgpublic’s picture

Yes, especially what's remaining ober there is only a few lines of code which are completely functionally equivalent. This is brilliant @Rade. Thank you so much for working on this. It looks pretty good from what I say. I have a larger site that uses asymmetric translation and will test and see what happens if I change it over to the new patches.

rade’s picture

Thanks @rgpublic, please let me know how it works out with your testing!

Glad that you like my approach :)

rgpublic’s picture

@Rade: With the classic/legacy widget, this module introduces a new widget "Paragraphs classic asymmetric". With the experimental/standard widget, your patch alters the behavior of the existing widget. Of course, the advantage of your approach is when you're currently using the patch and now switch to the module you don't have to change the form settings for your fields. But OTOH, I think it makes sense to have a separate widget - for example if you only need to have the asymmetric behavior for some fields etc. It also looks a bit "cleaner" to me if you explicitly need to select this widget. No matter what approach is better, I think it just doesn't make sense to differentiate here between the classic and the experimental widget, right?

rade’s picture

@rgpublic thanks for the feedback. At first I thought of making this a separate widget, precisely for the reason that we might want to have some fields translated and some not. But then I realised, that we make that decision when we tick the "Users may translate this field" checkbox in the field settings. In my opinion, the field settings is the correct place to define translatability, not the field widget. And that's exactly how all other fields work also, right?

In summary my idea is: If we want to have asymmetric translation for a paragraphs field, we make it translatable in field settings. If we want to have "normal" (non-asymmetric) translation, we do as instructed by the Paragraphs module, and do not make the field translatable, but rather the paragraphs entity types.

Edited to add: I understand your point of not differentiating between the old and the new widget. I think the implementation of the old widget is just fine as it is now, and I understand that my patch makes the logic inconsistent. With that in mind, and considering the name of this module which also refers to "widgets", maybe my patch should better fit in its own separate module. But I thought it was a bit overkill to create yet another module so I opted to extend this one instead :)

rgpublic’s picture

@Rade: Ah, yes, that sounds quite convincing. Makes sense to reuse the checkbox. I really think, though, that then the classic widget should be modified to do the same (perhaps in a separate issue) - if we keep both solutions in one module. I don't have a preference on using this module for both widgets vs. a separate module, though. If it's a separate module, we wouldn't have the issue with the different logic, of course.

weseze’s picture

Yes to this: :)

If we want to have asymmetric translation for a paragraphs field, we make it translatable in field settings.

Not so sure about this though:

I really think, though, that then the classic widget should be modified to do the same

That would require us to either maintain 2 solutions within this module or choose the above (which is the most logicak) and build a migration path for existing solutions... I much rather mark the classic widget support as deprecated.

rgpublic’s picture

@weseze: That would also be an option, absolutely. Marking the classic widget support as deprecated which is eventually removed in the next major version. For the long term, though, I'm only saying it just doesn't make sense to have this weird mix of different solutions we have now:

Classic widget <-> Triggered by dedicated form widget
Experimental widget <-> Triggered by standard translatibility checkbox of the paragraphs field (Users may translate this field)

But... If this turns into:

Classic widget <-> Triggered by dedicated form widget (Labeled: DEPRECATED)
Experimental widget <-> Triggered by standard translatibility checkbox of the paragraphs field (Users may translate this field)

And later into:

Classic widget <-> (NOT AVAILABLE)
Experimental widget <-> Triggered by standard translatibility checkbox of the paragraphs field (Users may translate this field)

I think it's a viable plan for the time ahead.

rade’s picture

I think it's a viable plan for the time ahead.

Definite +1 for the plan as described by @rgpublic.

rgpublic’s picture

@Rade: I've switched a large site on our staging to the new module with your patch. Everything seems to continue to run normally. I don't see any wrong language/content rendered and I tried editing some stuff - everything works as usual. Can't replace proper tests, of course, but it's an indication to me that you're definitively on the right track here. What are the next steps to get this comitted here? The patch provides a completely new option that wasn't provided at all by this module so I guess committing this isn't probably particularly risky business, right?

rade’s picture

Glad to hear it works for you!

What are the next steps to get this comitted here?

I'm not sure. I guess it depends on the maintainer of this module. Is it still @efpapado?

weseze’s picture

Status: Needs review » Needs work

I can commit this, but not in it's current state... 3 issues remain before this can go in:

1/ See my comment in #3: this approach requires a patch on paragraphs module itself, that needs be required through composer

2/ This piece of code seems to hardcode to our overriden widget. I don't think we should do that? We can't assume every and all paragraphs widget will be the async experimental type. Or am I missing something?

function paragraphs_asymmetric_translation_widgets_field_widget_info_alter(&$info) {
  if (!empty($info['paragraphs'])) {
    $info['paragraphs']['class'] = 'Drupal\paragraphs_asymmetric_translation_widgets\Plugin\Field\FieldWidget\ParagraphsAsymmetricWidget';
  }
}

3/ We will need to document how this works and why.

rgpublic’s picture

@weseze: Agree for the most part except perhaps the composer change. Instead, I'd try to get this committed in paragraphs ASAP. As we are only taking about very few lines that are semantically identical, I really hope this gets in quickly once we have the functionality here in this module in place. And: this module should continue to work with the classic/legacy widget even when the patch for some reason doesn't apply, right? Therefore, I guess it might be better to just loosely couple this and test explicitly for the new method in paragraphs with method_exists or reflection and just don't offer the functionality otherwise.

weseze’s picture

OK, also a good plan. I can update the project page to mention the patch is needed for the experimental widget. Do we already heave a issue number for that over at paragraphs' issue queue?

I would like to get this done and release a new version by the end of week. So your help is very much appreciated!

rade’s picture

Do we already heave a issue number for that over at paragraphs' issue queue?

Well, isn't it the same issue in which I posted the patch already? https://www.drupal.org/project/paragraphs/issues/2904705#comment-13836790

Regarding your points in #15:

1. I agree on this with @rgpublic

2. The machine name of the stable (previously experimental) paragraphs widget is paragraph, so it only overrides that one, not the legacy (previously classic) widget. And as I #8, the users/site builders can still choose themselves if they enable translation on the field or not, by checking the checkbox in field settings. Our patch provides support for asymmetric translations, but doesn't enforce it.

3. I can probably add some documentation tomorrow during Friday. Is there some particular place where you'd want such documentation, in code or in d.org?

  • weseze committed ef6a2e9 on 8.x-1.x authored by Rade
    Issue #3171810 by Rade, rgpublic, weseze: Support experimental widget
    
weseze’s picture

Status: Needs work » Fixed

The commit is in. I'm a bit swamped at work atm so I still need to review and test before I tag a release.

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.

jesconstantine’s picture

This is exciting functionality, thanks so much for working on it!

I was hoping someone could document how to test / make use of this functionality?

I am currently unsuccessful at being able to create asymmetric paragraph translations and want to make sure I'm doing everything correctly.

Here's what I have installed:

Core: 9.1.5

Admin theme: Gin Admin Theme 8.x-3.0-alpha33

Paragraphs: 1.12.0 (8.x-1.12) with patch:
- https://www.drupal.org/files/issues/2020-09-25/2904705-115.patch

Paragraphs asymmetric translation widgets: dev-1.x (ef6a2e91ccbb98f5c8ce00dfada2b04b8aeb4aaa) with patches:
- https://www.drupal.org/files/issues/2020-09-25/3171810-2.patch
- https://www.drupal.org/files/issues/2020-11-06/3181039-2.patch

Here's my implementation:

- Page node bundle has field_page_sections paragraphs field
- field_page_sections is configured to use Experimental widget
- Page node bundle is translatable, field_page_sections is set to allow translation
- Paragraph types are not translatable (I've also tried making paragraph types and given paragraph fields translatable)

I create a page node and add 2 paragraph x's to field_page_sections

I create a translation of the page node

On that page node I expect to see the two paragraph x's in my field_page_sections field, but I also expect to be able to remove any of those paragraphs.

Currently, I am only able to edit or collapse them.

Is there a different version/patch that I need to install or a different set up step that I'm missing? Or is my expectation inaccurate? Any help would be greatly appreciated.

Thanks!

crzdev’s picture

Latest included changes from this issue generates me some doubts about implementation, "paragraphs_asymmetric_translation_widgets_entity_translation_create" seems being creating duplicated paragraphs for all pg referenced into any paragraph revision field, but just when paragraph field is translatable.

- First: classic widget already manage paragraph duplication into "createDuplicateWithSingleLanguage" method, does this latest changes wouldn't generate a duplicated clone when classic asymmetric widget is being used (into widget and by hook_entity_translation_create hook)? (at least that part will be executed and is not necessary when classic widget is being used).
- Second: clone in hook is taking into account when nested field is translatable, that will cause all nested paragraphs to be cloned, but just of those coming from translation enabled fields, that can be and issue when first translatable level has nested but not translatable pg fields (parent pg will be cloned but child pgs will remain the same so when parent child is modified into translation, it will be modified into source too).

So to resume: why nested clonning implementation is different that used into classic widget method, and what happens when first level is translatable (reference field) but, it is not, into any other nested level?

By the way, enabling entity content translation for a paragraph using asymmetric translations seems not being required (langcode will remain just as the parent langcode and all translations will be resolved by cloning source and adjusting langcode).

I'm just trying to clarify most solid implementation, for now seems using paragraphs with no patches and beta4 of this module using classic widget instead of experimental, thanks and great work!