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