Project

General

Profile

Actions

Bug #103451

open

LanguageMenuProcessor handles language availbility wrong

Added by Pascal Geldmacher 9 months ago. Updated 3 months ago.

Status:
New
Priority:
Should have
Assignee:
-
Category:
Localization
Target version:
-
Start date:
2024-03-21
Due date:
% Done:

0%

Estimated time:
TYPO3 Version:
12
PHP Version:
8.3
Tags:
Complexity:
Is Regression:
Sprint Focus:

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

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

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?

Actions #2

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.

Actions #3

Updated by Riccardo De Contardi 7 months ago

  • Category set to Localization
Actions #4

Updated by Thomas Oliver Moll 3 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.

Actions

Also available in: Atom PDF