typo3multilingualtx-gridelements

Typo3 v10: Fix Translated ContentElements within Gridelements with language=all


I'm using Typo3 10.4.28 with gridelements 10.4.3 (not w/DataProcessing)

To minimize redundancy in a Multilanguage-Site I set Content Elements (CE) without own Text-Content to language=all and translate only CEs with Text. It feels very logical and useful to me, to set language=all on gridcontainers (where I'm not using its title or other own text-fields), to be able to set contained Plugins, Menu-Elements and Images to Language=all, even if it also includes a translated Text-CE (and I have seen this done in a Typo3 with gridelements where I have only regular backend access and don't know exactly how they achieved that).

But when translating CEs within language=all gridelements, this is not rendered correctly in the frontend on the translated page. Translated CEs are either rendered twice (fallbacktype: strict/fallback) or all language versions are rendered (fallbacktype: free).

According to gridelements maintainer @Jo Hasenau, putting translated elements into language=all containers is not supported directly with unmodified gridelements.

Thanks to his comments I found a setup which (while hacky) works more or less:

fallbacktype: free

[siteLanguage("languageId") == 1]
    lib.gridelements.defaultGridSetup.columns.default.renderObj.20.stdWrap.if {
        isInList.field = sys_language_uid
        # -1 is language=all
        value = -1,1
    }
[GLOBAL]
# allows only content in the correct language or "all"
# repeat for each other languageId

I found a problem with this setup though: in free-mode, translated elements get ordered in frontend based on their own "sorting" instead of their original element's. This means, translated elements might switch places with Language=all elements, compared to the default language. Fixing this in (translated) content would be a big hassle on a large site.

So I tried to find a fix for fallbacktype: strict (where "you get the original element with a translation overlay and after that the translation itself")

lib.gridelements.defaultGridSetup.columns.default.renderObj.20.stdWrap.if {
    isFalse.field = l18n_parent
}

I hoped this would exclude only "the translation itself", but sadly it also excluded the "translation overlay". In fact both seem to be identical to typoscript at this point.

Update:
A pure TS-Solution for strict and fallback is found, and my above solution for free technically works as well (free is just not suitable), so this case seems closed.

A small word of warning for anyone who wants to use this structure, though: sys_language_uid -1, aka Language All might be removed from Typo3 in upcoming versions:
https://decisions.typo3.org/t/rethinking-translation-handling-based-on-a-session-of-t3cmd-2022/734/16


Solution

  • As discussed in the Gridelements issue tracker, you should go for strict or fallback mode, since free can not work by definition.

    Still your approach with strict is wrong, since you don't have to include the target language records, but only default language records or those that got language all but after the translation overlay.

    This overlay will add a virtual field named _LOCALIZED_UID

    Reason: Both strict and fallback use overlays to render their content, and since there always is a record of the default language available, this will be the one to fetch, while the content will then be overlaid.

    So the solution should be:

    [siteLanguage("languageId") > 0]     
    lib.gridelements.defaultGridSetup.columns.default.renderObj.20.stdWrap.if {
      isFalse.field = _LOCALIZED_UID
      value = -1
      isGreaterThan.field = sys_language_uid
      negate = 1
    }
    [GLOBAL]
    

    Without additional conditions, since it will be the same for any target language.

    To explain the Syntax you need to know, that the TypoScript if-conditions only know AND but not OR, so if you want the result of an OR condition you need to negate the opposite AND condition, which is what the snippet does.

    It checks for a non existing _LOCALIZED_UID and the language of the record being greater than -1 - and if this is both true, it will negate the result. If any of the conditions is false, the negated result will be true.