Bug #103451
openLanguageMenuProcessor handles language availbility wrong
0%
Description
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:
languages:
-
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
}
}
}
Files
Updated by Georg Ringer 8 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?
Updated by Daniel Siepmann 7 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.
Updated by Thomas Oliver Moll 2 months ago
I have also problems with this function...
... although I'm tempted to think that it works as intended but the intention misses the point.
In https://docs.typo3.org/m/typo3/reference-typoscript/main/en-us/DataProcessing/LanguageMenuProcessor.html it is written:
" The array now contains information on all languages as defined in the site configuration. As the current page is not translated into German, the German language has the item.available set to false.
"
But this is not true for Languages that are configured with a fallback language (in the site config)
On a site with German, English and French I would expect to have available = 1
only for languages that are actually available in that specific language. but I also get it for languages that have an available fallback language.
Example:
I have a page only in German and English but not in French - although French is defined in the site config.
German (0) is default language
English(1) has fallback German (0)
French (2) has fallback English and German (1,0)
All three languages are shown as "available" for this page, even on pages that have no French translation and will fallback to English.
When I disable English, then only German remains available. And this is a strange behavior: French falls back to the disabled English but not to the still available German. English does not fallback on anything.
Maybe the problem lies somewhat in conflicting use cases: When I visit a site in say French, but the site's French translation is incomplete, I still want to see the non-translated content, even if I have to rely on my browser to translate for me. But in a Language Menu the case is different: When I'm on the same site but the language is set to English, I don't want a Link to "French" when in fact there is no French, but only English as a fallback.
The "available" should not mean "not available but there is a fallback", The Fact that the Language is theoretically available is well served by having the language in the list generated by LanguageMenuProcessor at all.
At the moment the available flag is useless for sites with Fallback enabled.
We could discuss the sanity of having incomplete translations, but 1) in reality this happens, even though it shouldn't and 2) We have the case of an German/English site with ONE page translated to Ukrainian with info for refugees. We now have decide whether we turn off fallback (stupid for those who can read English and came to us via the Ukrainian page) or whether we have Ukrainian available on the whole site - stupid as well.