Problem/Motivation

If you have a D8/9 site with multilanguage, the "Image linked to content" for the Media switcher setting on the formatter, doesn't work as expected: instead of returning the translated link, it always returns the link to the source node language.

Steps to reproduce

- Create a D8/9 website with two languages.
- Create an article with a media image
- Create a view page with the media image using blazy formatter
- Select "Media switcher: image linked to content"
- Now create a node (with a media image) and translate it
- Go to the view page. On both language the link will refer to the same node (the original node)

Issue fork blazy-3214002

Command icon 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

FiNeX created an issue. See original summary.

gausarts’s picture

Status: Active » Postponed (maintainer needs more info)

Thank you.

I don't have a multilingual setup currently, but let's track it down for anyone who are feeling invited to provided patches.

Is it Blazy Filter as I cannot find any of its usages in Blazy Filter, and won't makes sense in Filter either:
https://git.drupalcode.org/project/blazy/-/blob/8.x-2.2/src/Plugin/Filte...

$ grep -r "content_url" ./src
./src/Dejavu/BlazyStylePluginTrait.php:          $settings['content_url'] = isset($image['rendered']['#url']) ? $image['rendered']['#url'] : '';
./src/Dejavu/BlazyStylePluginTrait.php:          if (empty($settings['media_switch']) && !empty($settings['content_url'])) {
./src/BlazyFormatter.php:    $settings['content_url']    = $settings['absolute_path'] = $absolute_path;
./src/BlazyManager.php:      if ($settings['media_switch'] == 'content' && !empty($settings['content_url'])) {
./src/BlazyManager.php:        $element['#url'] = $settings['content_url'];
./src/BlazyDefault.php:      'content_url'    => '',

> - Create a view page with the media image using blazy formatter
The usage is here:
https://git.drupalcode.org/project/blazy/-/blob/8.x-2.2/src/BlazyManager...

if ($settings['media_switch'] == 'content' && !empty($settings['content_url'])) {
  $element['#url'] = $settings['content_url'];
}

Since content_url comes from anywhere, we cannot do correction in the above lines.
A few candidates:

If it were a field within entities, such as Link as seen at any blazy-related Media/ Paragraphs, etc. formatters, we do have solution here:
https://git.drupalcode.org/project/blazy/-/blob/8.x-2.2/src/BlazyEntity....

Unfortunately your use case appears to fall into Views with image URL as identified above.
And indeed, I haven't been able to make it more language aware without proper setup.

Patches are welcome. Thanks.

UPDATED:
Deleted irrelevant lines to your use case since you said blazy formatter, not image formatter.
But because your use case is not Media/ Paragraphs entity formatters, alike, hence node, so the second applied.

finex’s picture

StatusFileSize
new1.02 KB

Hi, thank you for the hints. I've updated the BlazyFormatter.php loading the correct language address:

    // Deals with UndefinedLinkTemplateException such as paragraphs type.
    // @see #2596385, or fetch the host entity.
    if (!$entity->isNew() && method_exists($entity, 'hasLinkTemplate')) {
      if ($entity->hasLinkTemplate('canonical')) {

        // Check if multilingual is enabled (@see #3214002)
        if (\Drupal::languageManager()->isMultilingual()){
          // Load current language code
          $language_code = \Drupal::languageManager()->getCurrentLanguage()->getId();
          // Load the translated url
          $url = $entity->getTranslation($language_code)->toUrl();
        } else {
          // Otherwise keep the standard url
          $url = $entity->toUrl();
        }

        $internal_path = $url->getInternalPath();
        $absolute_path = $url->setAbsolute()->toString();
      }
    }

Now it seems working :-)

gausarts’s picture

Status: Postponed (maintainer needs more info) » Needs review

Thank you.

Just minor nits:
We should avoid calling non-di like \Drupal:: at non-static classes.

But I need your help to verify if still working or not, basically replacing \Drupal::languageManager()->getCurrentLanguage()->getId(); with $items->getLangcode();:
https://git.drupalcode.org/project/drupal/-/blob/9.0.13/core/lib/Drupal/...
https://git.drupalcode.org/project/drupal/-/blob/8.9.15/core/lib/Drupal/...

Then the previous mentioned sample might apply with minor adjustments:
https://git.drupalcode.org/project/blazy/-/blob/8.x-2.x/src/BlazyEntity....

Perhaps something like:

-        $url = $entity->toUrl();
+
+        // Check if multilingual is enabled (@see #3214002)
+        $language_code = $items->getLangcode();
+        if ($entity->hasTranslation($language_code)) {
+          // Load the translated url.
+          $url = $entity->getTranslation($language_code)->toUrl();
+        }
+        else {
+          // Otherwise keep the standard url.
+          $url = $entity->toUrl();
+        }
+

Other minor nits are no big-deal:
https://www.drupal.org/pift-ci-job/2065050

Please focus on verifying whether the above replacement work or not instead.
Feel free to update your patch if working. If not, we might need to figure out another alternative.

Thanks again.

finex’s picture

Hi, your solution doesn't work because $items->getLangcode(); always returns the default language even if the media entity type is translatable (and the translation exists).

gausarts’s picture

Bad suggestions, then :)

The last, ugly, resort is moving that \Drupal::languageManager() into static method such as here:
https://git.drupalcode.org/project/blazy/-/blob/8.x-2.x/src/Blazy.php#L489

Please update your patch by adding this method into Blazy.php:

/**
   * Returns a wrapper to pass tests, or DI where adding params is troublesome.
   */
  public static function languageManager() {
    return \Drupal::languageManager();
  }

Then replace \Drupal::languageManager() in your patch by Blazy::languageManager()

This should do till we have proper DI, perhaps at Blazy 3+.

gausarts’s picture

We need to have a more permanent solution as it appears we have other similar warnings, not errors, of course:

FILE: .../drupal/drupal9/loc/web/modules/custom/blazy/src/Dejavu/BlazyVideoBase.php
--------------------------------------------------------------------------------
FOUND 0 ERRORS AND 1 WARNING AFFECTING 1 LINE
--------------------------------------------------------------------------------
 70 | WARNING | \Drupal calls should be avoided in classes, use dependency
    |         | injection instead
--------------------------------------------------------------------------------


FILE: ...ules/custom/blazy/src/Plugin/Field/FieldFormatter/BlazyOEmbedFormatter.php
--------------------------------------------------------------------------------
FOUND 0 ERRORS AND 1 WARNING AFFECTING 1 LINE
--------------------------------------------------------------------------------
 80 | WARNING | \Drupal calls should be avoided in classes, use dependency
    |         | injection instead
--------------------------------------------------------------------------------

#6 is just temporary.
Perhaps adding it in as service tags will be less temporary, although still temporary till the next branch works.

gausarts’s picture

StatusFileSize
new7.08 KB

Attached to add the language manager service and also to address the other similar issue once.

  • gausarts committed a56cd1f on 8.x-2.x authored by FiNeX
    Issue #3214002 by gausarts, FiNeX: Media switcher output doesn't work...
gausarts’s picture

Component: Blazy Filter » Code
Status: Needs review » Fixed

Fixed minor CS.

Be sure to run the update, or clear cache in the least as we are adding a service.

Committed. Thank you for contribution.

anybody’s picture

Status: Fixed » Needs work

Sadly, I just ran into an issue with this fix:

The website encountered an unexpected error. Please try again later.

InvalidArgumentException: Invalid translation language (en) specified. in Drupal\Core\Entity\ContentEntityBase->getTranslation() (line 873 of core/lib/Drupal/Core/Entity/ContentEntityBase.php).

Drupal\blazy\BlazyFormatter->buildSettings() (Line: 25)

This part isn't enough as it seems. The site is multilingual but that doesn't mean the selected translation exists:

// Check if multilingual is enabled (@see #3214002).
        if ($this->languageManager->isMultilingual()) {
          // Load the translated url.
          $url = $entity->getTranslation($settings['current_language'])->toUrl();
        }

We further need a

$entity->hasTranslation($settings['current_language'])

check:

// Deals with UndefinedLinkTemplateException such as paragraphs type.
    // @see #2596385, or fetch the host entity.
    if (!$entity->isNew() && method_exists($entity, 'hasLinkTemplate')) {
      if ($entity->hasLinkTemplate('canonical')) {

        // Check if multilingual is enabled (@see #3214002).
        if ($this->languageManager->isMultilingual() && $entity->hasTranslation($settings['current_language'])) {
          // Load the translated url.
          $url = $entity->getTranslation($settings['current_language'])->toUrl();
        }
        else {
          // Otherwise keep the standard url.
          $url = $entity->toUrl();
        }

        $internal_path = $url->getInternalPath();
        $absolute_path = $url->setAbsolute()->toString();
      }
    }

Tested and works! I'll create a merge request.

anybody’s picture

Status: Needs work » Needs review

MR created. Would ne nice to have a new stable release containing this fix.

gausarts’s picture

Too late to the party but ok 😂

Can we remove $this->languageManager->isMultilingual() && as said in #4?

anybody’s picture

Well yes I guess we could. On the other hand the $this->languageManager->isMultilingual() is very fast, so the combination is smart as only the first condition is evaluated on non-multilang projects. You decide :)

Logically the first condition is not needed.

gausarts’s picture

Yes, please. Nobody complained at two other places with just that so far.

anybody’s picture

Updated!

  • gausarts committed 535d9dd on 8.x-2.x authored by Anybody
    Issue #3214002 by Anybody, gausarts, FiNeX: Media switcher output doesn'...
gausarts’s picture

Status: Needs review » Fixed

I had delayed 2 weeks for 2.3 from the initial plan to accommodate these kinds of misses.
I released 2.3 before this weekend to test the waters, normally full releases got attentions better than DEV.

We'll release another hot fix by weekend before weekend warriors attack. And also to re-check other potential misses, if any.

Committed. Thank you for contribution.

volker23’s picture

Thanks @Anybody, switching from 2.3.0 to the current dev fixes the error i was encountering after the update to 2.3.0

InvalidArgumentException: Invalid translation language (de) specified. in Drupal\Core\Entity\ContentEntityBase->getTranslation() (Zeile 873 in /docroot/core/lib/Drupal/Core/Entity/ContentEntityBase.php).
finex’s picture

Thanks for the fix!

kreatil’s picture

Encountered the same error as #20. Switching to current dev fixed it for me.

Status: Fixed » Closed (fixed)

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