WxT Library warning when viewing the latest version node page in some cases

Created on 20 November 2023, about 1 year ago
Updated 23 November 2023, about 1 year ago

Problem/Motivation

I was changing the moderation state of a few basic pages from "Published" to "Draft" in order to apply some changes before going live again, and suddenly I am seeing this warning triggered from the wxt_library module:

Warning: Undefined array key "en" in Drupal\wxt_library\Plugin\Block\LanguageBlock->build() (line 164 of modules/contrib/wxt_library/src/Plugin/Block/LanguageBlock.php).
Drupal\wxt_library\Plugin\Block\LanguageBlock->build() (Line: 171)
Drupal\block\BlockViewBuilder::preRender(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, 1) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, 1) (Line: 160)
Drupal\Core\Render\Renderer->Drupal\Core\Render\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 159)
Drupal\Core\Render\Renderer->renderPlain(Array) (Line: 175)
Drupal\Core\Render\Renderer->renderPlaceholder('callback=Drupal%5Cblock%5CBlockViewBuilder%3A%3AlazyBuilder&args%5B0%5D=languageswitcher&args%5B1%5D=full&args%5B2%5D&token=nsR3jJa8bJz_M5rp3ogwQZ8Ownrs-S1wckm2wsrv1BY', Array) (Line: 693)
Drupal\big_pipe\Render\BigPipe->renderPlaceholder('callback=Drupal%5Cblock%5CBlockViewBuilder%3A%3AlazyBuilder&args%5B0%5D=languageswitcher&args%5B1%5D=full&args%5B2%5D&token=nsR3jJa8bJz_M5rp3ogwQZ8Ownrs-S1wckm2wsrv1BY', Array) (Line: 547)
Drupal\big_pipe\Render\BigPipe->sendPlaceholders(Array, Array, Object) (Line: 305)
Drupal\big_pipe\Render\BigPipe->sendContent(Object) (Line: 112)
Drupal\big_pipe\Render\BigPipeResponse->sendContent() (Line: 377)
Symfony\Component\HttpFoundation\Response->send() (Line: 20)

Steps to reproduce

1. Create an EN/FR node of type "Basic Page" (or any type), set the state of the node to "Published", apply the French/English translation as well
2. Change the status of either of these nodes to "Draft" again (make sure the other translation is published):

Save the node, you will be redirected to "/node/[nid]/latest".

3. You shall see the warning after that.

Proposed resolution

This warning is triggered from this snippet of code at modules/contrib/wxt_library/src/Plugin/Block/LanguageBlock.php (from line 148 to 167):

    $links = $this->languageManager->getLanguageSwitchLinks($type, $url);

    if (isset($links->links)) {
      // Don't show all defined languages in language switcher.
      if (!empty($links->links[$language])) {
        unset($links->links[$language]);
      }
      $wxt_active = str_replace('-', '_', $wxt_active);
      $wxt_active = str_replace('theme_', '', $wxt_active);

      if ($wxt_active == 'gcweb') {
        if ($language == 'en') {
          $title_fr = $links->links['fr']['title'];
          $links->links['fr']['title'] = Markup::create('<span class="hidden-xs">' . $title_fr . '</span><abbr title="' . $title_fr . '" class="visible-xs h3 mrgn-tp-sm mrgn-bttm-0 text-uppercase">fr</abbr>');
        }
        elseif ($language == 'fr') {
          $title_en = $links->links['en']['title'];
          $links->links['en']['title'] = Markup::create('<span class="hidden-xs">' . $title_en . '</span><abbr title="' . $title_en . '" class="visible-xs h3 mrgn-tp-sm mrgn-bttm-0 text-uppercase">en</abbr>');
        }
      }

Under these conditions mentioned above, the call to $this->languageManager->getLanguageSwitchLinks($type, $url) returns an empty $links->links array, I am not sure why exactly, but as a temporary fix, we can put a condition that checks if the array element $links->links['en'] or $links->links['fr'] exists (and is not empty), something like:

      if ($wxt_active == 'gcweb') {
        if ($language == 'en') {
          if (isset($links->links['fr']) && !empty($links->links['fr'])) {
            $title_fr = $links->links['fr']['title'];
            $links->links['fr']['title'] = Markup::create('<span class="hidden-xs">' . $title_fr . '</span><abbr title="' . $title_fr . '" class="visible-xs h3 mrgn-tp-sm mrgn-bttm-0 text-uppercase">fr</abbr>');
          }
        }
        elseif ($language == 'fr') {
          if (isset($links->links['en']) && !empty($links->links['en'])) {
            $title_en = $links->links['en']['title'];
            $links->links['en']['title'] = Markup::create('<span class="hidden-xs">' . $title_en . '</span><abbr title="' . $title_en . '" class="visible-xs h3 mrgn-tp-sm mrgn-bttm-0 text-uppercase">en</abbr>');
          }
        }
      }

The snippet above will make the "Language Switcher" block not to be rendered on the /node/[nid]/latest page, but I guess it's better than seeing the warning:

Remaining tasks

User interface changes

API changes

Data model changes

🐛 Bug report
Status

Fixed

Version

5.0

Component

WxT Library

Created by

🇨🇦Canada danrod Ottawa

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

Comments & Activities

Production build 0.71.5 2024