Bug #103451


LanguageMenuProcessor handles language availbility wrong

Added by Pascal Geldmacher 3 months ago. Updated 25 days ago.

Should have
Target version:
Start date:
Due date:
% Done:


Estimated time:
TYPO3 Version:
PHP Version:
Is Regression:
Sprint Focus:


I think something with the LanguageMenuProcessor not work correctly.

Following situation. I created a page in the default language and in german language. I also have the languages austria and swiss. Both languages have a fallback chain to german but both have no page. The frontend creates the language menu for swiss and austria which leads to a 404 page because there is no page in this language. If I change the fallback chain from german to the default language. swiss and austria is hidden.

Here's the language.yaml settings:

        title: English Int
        enabled: true
        languageId: '0'
        base: /en/
        typo3Language: default
        locale: 'en_GB.UTF-8,en_GB'
        iso-639-1: en
        navigationTitle: English International
        hreflang: en
        direction: ltr
        flag: en-us-gb
        title: German
        enabled: true
        languageId: '3'
        base: /de/
        typo3Language: de
        locale: 'de_DE.UTF-8,de_DE'
        iso-639-1: de
        navigationTitle: Deutsch
        hreflang: de
        direction: ltr
        flag: de
        solr_core_read: '%env(SOLR_CORE_PREFIX_READ)%_de'
        fallbackType: fallback
        fallbacks: '0'
        title: German Austria
        enabled: true
        languageId: '4'
        base: /de-at/
        typo3Language: de
        locale: 'de_AT.UTF-8,de_AT'
        iso-639-1: de
        navigationTitle: Deutsch (AT)
        hreflang: de-AT
        direction: ltr
        fallbackType: fallback
        fallbacks: '3'
        flag: at
        title: German Swiss
        enabled: true
        languageId: '5'
        base: /de-ch/
        typo3Language: de
        locale: 'de_CH.UTF-8,de_CH'
        iso-639-1: de
        navigationTitle: Deutsch (CH)
        hreflang: de-CH
        direction: ltr
        fallbackType: fallback
        fallbacks: '3'
        flag: ch

the typoscript settings:

page = PAGE
page {
    20.dataProcessing {
        40 = TYPO3\CMS\Frontend\DataProcessing\LanguageMenuProcessor
        40 {
            languages = 0,3,4,5
            as = languagenavigation


page.png (80.9 KB) page.png Pascal Geldmacher, 2024-03-21 12:52
Actions #1

Updated by Georg Ringer 3 months ago

IMO the language processor is correct as those pages should really be rendered but shown as fallback. can you reproduce that on an empty installation?

Actions #2

Updated by Daniel Siepmann about 2 months ago · Edited

One of our customers had a very similar issue on 12.4.

We debugged it and the USERDEF condition within prepareMenuItemsForLanguageMenu() method of AbstractMenuContentObject seems to be broken. It doesn't work with fallbackChain to default language 0. This is not respected.

We hacked this into the core:

diff --git a/typo3/sysext/frontend/Classes/ContentObject/Menu/AbstractMenuContentObject.php b/typo3/sysext/frontend/Classes/ContentObject/Menu/AbstractMenuContentObject.php
index 9d9832f47c..c5e598e0ce 100644
--- a/typo3/sysext/frontend/Classes/ContentObject/Menu/AbstractMenuContentObject.php
+++ b/typo3/sysext/frontend/Classes/ContentObject/Menu/AbstractMenuContentObject.php
@@ -601,7 +601,10 @@ abstract class AbstractMenuContentObject
             if ($pageTranslationVisibility->shouldHideTranslationIfNoTranslatedRecordExists() && $sUid &&
                 empty($lRecs) || $pageTranslationVisibility->shouldBeHiddenInDefaultLanguage() &&
                 (!$sUid || empty($lRecs)) ||
-                !($this->conf['special.']['normalWhenNoLanguage'] ?? false) && $sUid && empty($lRecs)
+                (
+                    !($sUid && empty($lRecs) && in_array(0, $languageAspect->getFallbackChain(), true))
+                    && !($this->conf['special.']['normalWhenNoLanguage'] ?? false) && $sUid && empty($lRecs)
+                )
             ) {
                 $iState = $currentLanguageId === $sUid ? 'USERDEF2' : 'USERDEF1';
             } else {

This seems to work and properly populate the available property for each language.

To me it seemed like the last condition is an issue. The first one will be false as the LanguageMenuProcessor doesn't set the property. sUid is true as it is not the default language. But due to not having an overlay the lRecs is also empty, which is fine as the default language is the fallback.

Actions #3

Updated by Riccardo De Contardi 25 days ago

  • Category set to Localization

Also available in: Atom PDF