If a database field can be NULL (and has no default value), and the TCA l10n_mode for the field is noCopy, the default language content is shown in a translation even if you disallow it in your TypoScript setup:
config {
sys_language_overlay = hideNonTranslated
sys_language_mode = strict
}
I think this happens, because in \TYPO3\CMS\Frontend\Page\PageRepository::getRecordOverlay() (Line 502) the isset($olrow[$fN]) returns false also for NULL (see http://php.net/isset). It would be better, if the check is array_key_exists($fN, $olrow) and not isset.
A good example where this happens is the EXT:news teaser field, but I think this is not the only example.
A workaround is easy: just use an empty string as default value in the table definition:
CREATE TABLE tx_news_domain_model_news (
teaser text DEFAULT '' NOT NULL,
);
Even if this is clearly a bug (haven't found this behaviour documented somewhere), I think it will never be fixed in TYPO3 7.6.
Can someone else approve this?
The forge ticket is https://forge.typo3.org/issues/79012
Related
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
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.
Basically this is the same behaviour as with pages, which are kind of top level containers themselves.
If you want just one single element of that page to be translated, you need to create a translated page record before. So having a page with the "language => all" behaviour will only work together with a properly configured fallback, if there is no translated content on that page at all.
So you don't have to switch the frontend rendering TS template, but just follow the rule you already described.
I set Content Elements (CE) without own Text-Content to language=all
and translate only CEs with Text
Since a Gridelements container is a CE and the child elements are basically content of that CE, just as with pages you always have to translate a container element as soon as it contains at least one translated element.
So language "all" should only be applied to containers that don't contain any translated child element at all.
I upgraded a TYPO3 installation from 8.6 to 9.5. On pages with contents with language setting "all languages" those elements are not shown in frontend.
It seems that in ContentObjectRenderer->getQueryConstraints the constraint AND (tt_content.sys_language_uid in (0,-1)) is only added, if i open the same page in other languages. In the default language it's always AND (tt_content.sys_language_uid = 0). In TYPO3 8.5 the expected constraint is also added in the default language.
Is this a bug or am I missing something? My relevant TypoScript setup looks like this:
config {
linkVars = L(0-1)
defaultGetVars.L = 0
sys_language_uid = 0
sys_language_mode = content_fallback
sys_language_overlay = hideNonTranslated
}
EDIT:
I made some additional tests and it seems, that extbase and even the RECORDS TypoScript object type works as expected. The problem only occurs if CONTENT object type is used (which is the case for styles.content.get in EXT:frontend)
EDIT:
I created an issue: https://forge.typo3.org/issues/87093
This is a reported bug, have a look here >> https://forge.typo3.org/issues/86762
I am adding a field to the pages table (is a relation to a file) and would like the value of the field in the pages record to be copied to the translated record by default.
Currently, the copied field is empty (default value), which is probably a good idea in most cases.
I am thinking of something that behaves like l10n_mode = prefixLangTitle without the prefix.
Depending on the TYPO3 version this should be possible with one of the following behaviours for the inline field:
https://docs.typo3.org/typo3cms/TCAReference/7.6/Reference/Columns/Inline/Index.html#behaviour
https://docs.typo3.org/typo3cms/TCAReference/8.7/ColumnsConfig/Type/Inline.html#localizechildrenatparentlocalization
https://docs.typo3.org/typo3cms/TCAReference/latest/ColumnsConfig/Type/Inline.html#allowlanguagesynchronization
Sine the localizeChildrenWithParentLocalization feature is broken with pages and pages_language_overlay though, I guess the only working versions would be CMS 8 or 9 with properly configured language synchronization.
https://forge.typo3.org/issues/78743
Use
['behaviour']['allowLanguageSynchronization'] => true
if the translated record will use the value from the default field by
default (will effectively be copied), but it should be possible to change
this later.
See pages.author as example.
When "Custom value" is selected, the value can be overridden.
Alternativively, use
l10n_mode = exclude
if the field should always have the value of the default language and you
should not be able to change it in the translated record.
Small problem with translated content in TYPO3 8.7.13:
Translation in connected mode. In default language there is one element hidden which should be visible in translation. In the backend it looks like it would be visible but in the frontend the element is missing. (The other way round there is no problem: when the element in default language is visible i can always hide it in the translation.)
My language configuration:
[sys_language_mode] = content_fallback
[sys_language_overlay] = hideNonTranslated
Translation in connected mode (we use L10N-Manager)
Is there a possiblity to make the translated element visible in the foreign language even when the element in the default language is hidden?
Thanks!
I'm not sure if my informations are up to date, but when I had similar case in older TYPO3 versions there were no way to achieve that. The workaround which I've used was to change type type (CType) of content element to "Empty", which was custom content element prepared especially for such cases. It is possible also to change the type to "Plain HTML" and just leave the bodytext empty.
Is there a way to 'reset' or db entries to delete or something else without deleting all content already translated... (and would that solve the issue?)
In the first go all translation went well, I chose a 'one tree' setup pressing translate rather then copy, but adding and modifying the content over time certain elements where not available for translation anymore ...
at one point the second step in translation asked for the origin language (if I recall well) and trying to resolve I chose another language than the default, now I do not have the choice anymore and the record summary proposes elements from german rather than from my default language (italian) which might be the problem since I can only introduce new content in the default language.
if I try to localize from the list view clicking the language flag, in the language selection field I get [INVALID VALUE("1")] and as only option (Default) [0] to select ...
I use TYPO3 V7.6.13, EXT:gridelements and EXT:t3sbootstrap (the nested CE's where the first to show trouble)
content of my database table sys_language: (my default lang is italian)
uid | pid | tstamp | hidden | title | flag |
1 0 ... 0 English gb
2 0 ... 0 German de
does anyone know good reference or a solution to this problem ?
That sounds like your sys_language records (in yoour root-page, id = 0) are disabled or missing.
Those records make languages available for translation.
The other factor for translation selection is the translation of the current page. You need to have the page translated to a language (given above) to be able to translate any record in that page. That also is neccessary for pages which contain only data.
first check (as suggested by bernd) if your language setup is valid:
do you have a sys_language record for every added language in your
root-page ? (you can control the sys_language table with phpMyAdmin)
is the page translated ?
in my case that was all fine but I needed a thorough cleanup:
I deleted all hidden records in the backend
I activated the system extension 'recycler' and deleted all in the
list (from root-page recursive)
I then checked with phpMyAdmin which records in tt_content where
hidden (and did not show in the backend) and deleted those manually
once I did that the translate request answered perfectly and I could restore the missing CE's translations
note: I still had gridelements showing up in wrong sequence for the translation in the backend but correctly in the frontend, the nested CE's seem though, and of course 'CLEAR CASH FREQUENTLY' to avoid surprises ...