Experimental widget displays the original language on translation

Created on 22 August 2022, over 2 years ago
Updated 20 September 2024, 3 months ago

Problem/Motivation

Layout Paragraphs Builder Experimental widget displays the original language (source) when editing a translation. This makes it impossible to translate or edit translated content from the frontend.

Steps to reproduce

- Install Drupal as multilingual system or use Umami
- Create a layout Paragraph type for layouts
- Create a paragraph type with a text field
- Configure the text field as translatable
- Create a new Content type with a Paragraph field and allow the use of the two Paragraph types created above
- Under Manage Display, use the Layout Paragraphs Builder Experimental widget
- Create a new content in any language
- Create a translation into another language and edit the paragraphs via frontend
- When editing, the original language is displayed

πŸ› Bug report
Status

Needs work

Version

2.1

Component

Code

Created by

πŸ‡©πŸ‡ͺGermany J-Lee πŸ‡©πŸ‡ͺπŸ‡ͺπŸ‡Ί

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Merge Requests

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

  • πŸ‡ΊπŸ‡ΈUnited States COBadger

    Updated patch attached.

  • πŸ‡©πŸ‡ͺGermany stmh

    The patch from #14 works as advertised, but not 100% correct, at least for my scenario. Say I have 2 languages en and de. I create content in en and add a translation for de. Editing the translation works as expected, but the preview shows then the english page. Reloading the page shows then the updated content in the correct language.

  • πŸ‡¬πŸ‡§United Kingdom joachim
    1. +++ b/src/Form/LayoutParagraphsBuilderForm.php
      @@ -93,7 +93,8 @@ class LayoutParagraphsBuilderForm extends FormBase {
      -    string $view_mode = NULL) {
      +    string $view_mode = NULL
      +  ) {
      

      Unrelated change.

    2. +++ b/src/Form/LayoutParagraphsBuilderForm.php
      @@ -225,8 +245,7 @@ class LayoutParagraphsBuilderForm extends FormBase {
      -    }
      -    else {
      +    } else {
      

      Unrelated, and incorrect change - elses should not be coddled.

  • πŸ‡¬πŸ‡§United Kingdom joachim
  • πŸ‡¬πŸ‡§United Kingdom joachim

    Surprisingly, the MR's branch (which is currently hidden) *doesn't* have the problem described in #15, the incorrect return to the default language when working with a translation.

    However, that currently conflicts with the 2.0.x branch and needs a rebase.

    (BTW it gets confusing when an issue has BOTH a MR and patches!)

  • Assigned to joachim
  • πŸ‡¬πŸ‡§United Kingdom joachim

    Trying to rebase the branch...

  • πŸ‡©πŸ‡ͺGermany J-Lee πŸ‡©πŸ‡ͺπŸ‡ͺπŸ‡Ί

    I think justin2pin closed the MR because of the many changes since the MR was created. That is why the MR is out of date.

    The patch from #14 changes the field values to the translated values. But the field with the source language is inserted into the LayoutParagraphsLayout (Line 129 in patched Drupal\layout_paragraphs\Form\LayoutParagraphsBuilderForm) which is used to create the tempstore key. If the field language is changed, the correct language will be displayed in the UI after saving the changes.

          if ($entity->hasField($default_langcode_key)) {
            $entity = $entity->getTranslation($langcode);
    +      $entity->$field_name->setLangcode($langcode);
            foreach ($entity->$field_name as $delta => $item) {
    
  • πŸ‡¬πŸ‡§United Kingdom joachim

    Does anyone know why the MR removes this code from LayoutParagraphsBuilderForm::submitForm():

        // The entity may have been altered by another process, and needs to be
        // loaded from storage to ensure edits to other fields are not overwritten.
        // @see https://www.drupal.org/project/layout_paragraphs/issues/3275179
        $entity_id = $this->layoutParagraphsLayout->getEntity()->id();
        $entity_type = $this->layoutParagraphsLayout->getEntity()->getEntityTypeId();
        $entity = $this->entityTypeManager->getStorage($entity_type)->load($entity_id);
        $field_name = $this->layoutParagraphsLayout->getFieldName();
        $entity->$field_name = $this->layoutParagraphsLayout->getParagraphsReferenceField();
    
  • πŸ‡©πŸ‡ͺGermany J-Lee πŸ‡©πŸ‡ͺπŸ‡ͺπŸ‡Ί

    Maybe because the entity is cloned at buildEntity()?

  • πŸ‡¬πŸ‡§United Kingdom joachim

    Filed πŸ› Get the request time to set on the updated entity in LayoutParagraphsBuilderForm Active for the use of the time service which is in the MR here, and unrelated to this issue.

  • πŸ‡¬πŸ‡§United Kingdom joachim

    This code (and related changes) probably also needs moving to a separate issue:

    +  /**
    +   * Should new revisions created on default.
    +   *
    +   * @return bool
    +   *   New revision on default.
    +   */
    +  protected function getNewRevisionDefault($entity) {
    +    $new_revision_default = FALSE;
    +    $bundle_entity = $this->getBundleEntity($entity);
    +    if ($bundle_entity instanceof RevisionableEntityBundleInterface) {
    +      // Always use the default revision setting.
    +      $new_revision_default = $bundle_entity->shouldCreateNewRevision();
    +    }
    +    return $new_revision_default;
    +  }
    
  • πŸ‡¬πŸ‡§United Kingdom joachim

    Thanks for the feedback @J-Lee.

    You're right, the MR is really out of date.

    Also, it's trying to fix the problem by removing the use of the custom form element, which surely isn't right:

        $form['layout_paragraphs_builder_ui'] = [
          '#type' => 'layout_paragraphs_builder',
          '#layout_paragraphs_layout' => $this->layoutParagraphsLayout,
        ];
    

    If the custom form element is showing the wrong language, it needs to be fixed, not bypassed!

    Things in the patch don't look right either though:

          // Load the correct translation for the layout paragraphs layout field.
          $default_langcode_key = $entity->getEntityType()->getKey('default_langcode');
          $langcode_key = $entity->getEntityType()->getKey('langcode');
          $langcode = $entity->get($langcode_key)->value;
          if ($entity->hasField($default_langcode_key)) {
            $entity = $entity->getTranslation($langcode);
    

    $entity is already in the correct language at this point, because it's loaded by the routing system which takes into account the current language.

              $entity->$field_name[$delta]->entity = $paragraph;
    

    Setting the paragraph BACK into the entity looks really wrong!!!

    I've tried your suggested fix for the patch:

    +      $entity->$field_name->setLangcode($langcode);
    

    It doesn't work - when I click the Save button, I see the original language for the paragraph and not the translation.

    I'm not sure about doing that to the $field anyway -- it's an entity reference field, so it won't be set to translatable.

  • πŸ‡¬πŸ‡§United Kingdom joachim

    I think we need to add the $entity as a constructor parameter to LayoutParagraphsLayout:

    $this->layoutParagraphsLayout = new LayoutParagraphsLayout($field, $layout_paragraphs_settings);
    

    I don't think we can get the right language from what it currently receives.

    We get $entity->activeLangcode set to the translation language, but $entity->FIELD->parent->entity->activeLangcode is set to the **default language**. So we can't get hold of the correct language to use.

  • πŸ‡©πŸ‡ͺGermany J-Lee πŸ‡©πŸ‡ͺπŸ‡ͺπŸ‡Ί

    @joachim You are right. It doesn't seem to be possible to get the currently used language from the field.
    Either the entity must be specified or the language, which in turn would have to be taken into account in LayoutParagraphsLayout.

  • πŸ‡©πŸ‡ͺGermany J-Lee πŸ‡©πŸ‡ͺπŸ‡ͺπŸ‡Ί

    In the LayoutParagraphsLayout class, there is a getEntity() method that gets the entity from the entity reference field, but there is also a setEntity() method that sets the entity dynamically and is not used. This looks a bit strange. Maybe this is the point where you could start.

    /**
       * Returns the layout's parent entity with updated paragraphs reference field.
       *
       * @return \Drupal\Core\Entity\EntityInterface
       *   The entity.
       */
      public function getEntity() {
        $entity = $this->paragraphsReferenceField->getEntity();
        return $entity;
      }
    
      /**
       * Set the entity that this layout is attached to.
       *
       * @param \Drupal\Core\Entity\EntityInterface $entity
       *   The entity to set.
       *
       * @return $this
       */
      public function setEntity(EntityInterface $entity) {
        $this->entity = $entity;
        return $this;
      }
    
  • Status changed to Needs review over 1 year ago
  • πŸ‡¬πŸ‡§United Kingdom joachim

    I've got this working!

    Thanks for your help @J-Lee!

    Work is on a new branch '3305070-set-language-on-layout' with a new MR.

  • Status changed to RTBC over 1 year ago
  • πŸ‡©πŸ‡ͺGermany J-Lee πŸ‡©πŸ‡ͺπŸ‡ͺπŸ‡Ί

    Looks good. Thank you.

  • Status changed to Needs work over 1 year ago
  • πŸ‡©πŸ‡ͺGermany J-Lee πŸ‡©πŸ‡ͺπŸ‡ͺπŸ‡Ί

    Ah, there are still the tests missing ... back to needs work.

  • πŸ‡¨πŸ‡­Switzerland grumpy74 Geneva, CH πŸ‡¨πŸ‡­

    @joachim, @J-Lee thank you guys, you are life savers on that issue !

    The patch works !

    Hope the MR will be approved and released in the next module's version.

  • πŸ‡©πŸ‡ͺGermany J-Lee πŸ‡©πŸ‡ͺπŸ‡ͺπŸ‡Ί

    I can confirm the problem and have left a comment at the appropriate place in MR. With $entity->hasTranslation($this->langcode) and $entity->addTranslation($this->langcode) we can solve this.

  • πŸ‡¨πŸ‡­Switzerland grumpy74 Geneva, CH πŸ‡¨πŸ‡­

    Thank you again @J-Lee.

    Another issue remains however. When clicking the "Save button" at the bottom of the layout paragraph builder interface (to save paragraphs items order) the page is reloaded and paragraphs are displayed using the default language like described in the comment #15. Then if you click the "Close button", the paragraphs are back in the correct language. I don't know if it is linked with your proposed solution in the MR, but it would avoid confusion for editors and need to be fixed too.

  • πŸ‡ΊπŸ‡ΈUnited States COBadger

    @jleehr thanks so much for the suggested changes to MR122. πŸ› Experimental widget displays the original language on translation Needs work I included them in a patch file β†’ and tested locally.

    My experience was that the error that @grumpy74 described πŸ› Experimental widget displays the original language on translation Needs work did not appear, so that's great.

    However, in my testing the new paragraph that I added on the site's main language did not show up when I edited the page in an alternate language.

    I'd be curious to hear whether others experience the same thing using patch 36 β†’ .

  • πŸ‡¨πŸ‡­Switzerland grumpy74 Geneva, CH πŸ‡¨πŸ‡­

    @COBadger thank you for the provided patch. I tested it and it seems to fix the issue with the language code I was pointed out.

    However. There is still another problem remaining.

    Reproduce the steps described in my comment #33.

    Then, when you have a node with paragraphs created and you have already the translated node created afterward, the paragraphs exist on the translated node too. But as soon as you re-edit the default language node paragraphs to add new one for example, here comes the issue.

    Basicaly at that point the default language has a new paragraph added to the items list, but the translated node do not have that reference yet. So if you go to the translated node front page you see the newly added paragraph in the widget preview (which is correct), but as soon as you click "Edit components", the display switch to the edit display and the paragraph disappears (because actually the paragraph translation do not exists). I think when the widget switch to edit mode, the same kind of test on the paragraph translation existence must be done. Like if the paragraph do not exists for the translation language, in edit mode, we must create a new paragraph translation when clicking "edit" icon to be able to add the translation instance of the paragraph to the translated node.

    On the other hand (and it is not part of that specific issue), the widget should not propose the controls "add", "duplicate" or "delete" on a non default language entity, as this is forbidden by design by the paragraphs principles (paragraphs are ISO between languages).

    I hope my description is clear enough for the context overall understanding.

    On my side for instance, I took the decision to write custom code to force node translation creation and paragraphs translation creation on node post save to avoid that issue (which is not ideal, but it fits my needs so far), but it should be handle by the widget IMHO.

    Hope this will help resolving the issue. I'm sorry to not contribute actively on the code part of this, but I can help by testing patches.

  • πŸ‡¬πŸ‡§United Kingdom joachim

    I'm not managing to reproduce the error described in #33.

    I tried both with a node that didn't have a translation, and one which did.

    Please could we stick to the MR and not also make patches? It's going to get really confusing if we have both MRs and patches floating around.

  • Open in Jenkins β†’ Open on Drupal.org β†’
    Core: 10.1.x + Environment: PHP 8.1 & MariaDB 10.3.22
    last update over 1 year ago
    56 pass
  • Issue was unassigned.
  • Status changed to Needs review over 1 year ago
  • Open in Jenkins β†’ Open on Drupal.org β†’
    Core: 10.1.x + Environment: PHP 8.1 & MariaDB 10.3.22
    last update over 1 year ago
    55 pass
  • πŸ‡¬πŸ‡§United Kingdom joachim

    Added test.

  • Status changed to Needs work over 1 year ago
  • πŸ‡ΊπŸ‡ΈUnited States COBadger

    Changing status back to "Needs work".

    In my test of the merge request I took the following steps:

    1. Created a new paragraph in the original language of a node
    2. Navigated to a translation of the node
    3. Opened the layout editor
    4. Observed that the new paragraph from Step 1 above did not render in the layout editor as expected

    With the logic from my comment on the merge request when I performed the above steps I did see the new paragraph in the layout editor, and it saved as expected.

  • πŸ‡¬πŸ‡§United Kingdom joachim

    > 4. Observed that the new paragraph from Step 1 above did not render in the layout editor as expected

    Do you mean that the new paragraph *should* appear there?

  • πŸ‡©πŸ‡ͺGermany J-Lee πŸ‡©πŸ‡ͺπŸ‡ͺπŸ‡Ί

    Strange that sometimes my suggestion is needed and sometimes not. Maybe it is due to different language settings?
    To make the codebase more robust, I would suggest to apply the check to the language/translation.

  • Open in Jenkins β†’ Open on Drupal.org β†’
    Core: 10.1.x + Environment: PHP 8.1 & MariaDB 10.3.22
    last update over 1 year ago
    56 pass
  • Status changed to RTBC over 1 year ago
  • πŸ‡ΊπŸ‡ΈUnited States COBadger

    As the tests have passed I'm marking this RBTC.

  • Status changed to Needs review over 1 year ago
  • πŸ‡¬πŸ‡§United Kingdom joachim

    Thanks for the fix.

    However, people who've worked on the MR shouldn't set it to RTBC - that should be done by reviewers.

  • Status changed to RTBC over 1 year ago
  • πŸ‡©πŸ‡ͺGermany J-Lee πŸ‡©πŸ‡ͺπŸ‡ͺπŸ‡Ί

    The nit-pick could be done on commit.

    Thank you all for the work.

  • Status changed to Needs work over 1 year ago
  • πŸ‡ΊπŸ‡ΈUnited States justin2pin

    Thanks for all the work on this. Unfortunately, I think this needs a little more work. I don't think we want to add translation functionality directly into the LayoutParagraphsLayout class, as it assumes a little too much about possible use cases. Specifically, I'm concerned that this does not accommodate asymmetric paragraph translations.

    So... I think we need to keep functionality specific to translations in the widget / formatter, and not in the underlying API classes. It might be worth abstracting the translation functionality into either a service or trait that both the widget and formatter can use, or refactoring the formatter so it just invokes the widget -- rather than directly using the layout paragraphs builder render element.

  • First commit to issue fork.
  • Open in Jenkins β†’ Open on Drupal.org β†’
    Core: 10.1.x + Environment: PHP 8.1 & MariaDB 10.3.22
    last update over 1 year ago
    55 pass, 2 fail
  • Open in Jenkins β†’ Open on Drupal.org β†’
    Core: 10.1.x + Environment: PHP 8.1 & MariaDB 10.3.22
    last update over 1 year ago
    57 pass
  • πŸ‡­πŸ‡ΊHungary prompt-h Hungary

    We're currently sticking with version 2.0.0-beta9 for this module due to its compatibility with multi-language websites. Newer versions of the module aren't suitable for such websites. Any help would be appreciated.

  • πŸ‡¨πŸ‡­Switzerland ytsurk Switzerland

    I'm using the module's version 2.0.4 with this MR's patch (https://git.drupalcode.org/project/layout_paragraphs/-/merge_requests/12...) for symmetric paragraph translation.

    This module forces you to use go with asymmetric translation, which is not official supported (nor recommended) by the paragraphs module itself.

    If you can explain the incompatibility issues you have, we can try to guide you?

  • πŸ‡­πŸ‡ΊHungary prompt-h Hungary

    We were able to update to 2.0.4 on several multi-language websites and use async translation successfully with the provided patch. Thank you!!

  • First commit to issue fork.
  • πŸ‡©πŸ‡ͺGermany J-Lee πŸ‡©πŸ‡ͺπŸ‡ͺπŸ‡Ί
Production build 0.71.5 2024