Bug #32573
closedlocallangXMLOverride is broken since the switch to XLIFF
100%
Description
Since TYPO3 4.6 the locallangXMLOverride mechanism does not work like before v4.6. There are some issues while loading translations from XML files, e.g. the target language will be mixed with the default language.
I use the following line oh php code to configure the override in a localconf-file:
$GLOBALS['TYPO3_CONF_VARS']['SYS']['locallangXMLOverride']['path/to/originalTranslationFile.xml'][] = 'path/to/otherTranslationFile.xml'
The content of the original translation file "originalTranslationFile.xml" is this:
<?xml version="1.0" encoding="utf-8" standalone="yes" ?> <T3locallang> <data type="array"> <languageKey index="default" type="array"> <label index="test_label_one">one (default)</label> <label index="test_label_two">two (default)</label> </languageKey> <languageKey index="de" type="array"> <label index="test_label_one">eins (german)</label> <label index="test_label_two">zwei (german)</label> </languageKey> </data> </T3locallang>
The content of the translation file "otherTranslationFile.xml", which is used to override translations, is this:
<?xml version="1.0" encoding="utf-8" standalone="yes" ?> <T3locallang> <data type="array"> <languageKey index="fr" type="array"> <label index="test_label_one">une (française)</label> </languageKey> </data> </T3locallang>
My testcase in typoscript is something like this, it only outputs two translations via the TS-TEXT object:
config { linkVars = L sys_language_uid = 0 language = en locale_all = en_EN.UTF-8 htmlTag_langKey = en } # DE [globalVar=GP:L=1] config { sys_language_uid = 1 language = de locale_all = de_DE.UTF-8 htmlTag_langKey = de } [global] # FR [globalVar = GP:L = 2] config { sys_language_uid = 2 language = fr locale_all = fr_FR.UTF-8 htmlTag_langKey = fr } [global] page = PAGE page.typeNum = 0 page.10 = TEXT page.10.data = LLL:path/to/originalTranslationFile.xml:test_label_one page.10.wrap = | <br /> page.20 = TEXT page.20.data = LLL:path/to/originalTranslationFile.xml:test_label_two
The output in english (the default language) is this:
une (française) // << that's wrong! It must be "one (default)"
two (default)
In german:
une (française) // << that's wrong! It must be "eins (german)"
zwei (german)
In french:
une (française)
two (default)
Also do tests with this "otherTranslationFile.xml" files:
otherTranslationFile V2:
<?xml version="1.0" encoding="utf-8" standalone="yes" ?> <T3locallang> <data type="array"> <languageKey index="default" type="array"> <label index="test_label_one">one (default NEW)</label> <label index="test_label_two">two (default NEW)</label> </languageKey> <languageKey index="de" type="array"> <label index="test_label_one">eins (german NEW)</label> </languageKey> <languageKey index="fr" type="array"> <label index="test_label_one">une (française)</label> </languageKey> </data> </T3locallang>
otherTranslationFile V3:
<?xml version="1.0" encoding="utf-8" standalone="yes" ?> <T3locallang> <data type="array"> <languageKey index="default" type="array"> <label index="test_label_two">two (default NEW)</label> </languageKey> <languageKey index="de" type="array"> <label index="test_label_one">eins (german NEW)</label> </languageKey> <languageKey index="fr" type="array"> <label index="test_label_one">une (française)</label> </languageKey> </data> </T3locallang>
After a lot of debugging i had replace the body of method "t3lib_l10n_parser_Llxml::doParsingFromRootForElement" with this:
protected function doParsingFromRootForElement(SimpleXMLElement $root, $element) { $bodyOfFileTag = $root->data->languageKey; // Check if the source llxml file contains localized records $localizedBodyOfFileTag = $root->data->xpath("languageKey[@index='" . $this->languageKey . "']"); if ($element === 'target' && count($localizedBodyOfFileTag) === 0) return array(); $parsedData = $this->getParsedDataForElement($bodyOfFileTag, $element); if ($element === 'source') return $parsedData; if ($element === 'target' && isset($localizedBodyOfFileTag[0]) && $localizedBodyOfFileTag[0] instanceof SimpleXMLElement) { $parsedTargetData = $this->getParsedDataForElement($localizedBodyOfFileTag[0], $element); $mergedData = array_merge($parsedData, $parsedTargetData); if ($this->languageKey === 'default') { foreach (array_keys($mergedData) as $key) { if (!isset($parsedData[$key])) { unset($mergedData[$key]); } } } else { foreach (array_keys($mergedData) as $key) { if (!isset($parsedTargetData[$key])) { unset($mergedData[$key]); } } } return $mergedData; } return $parsedData; }
This does work for my test cases very well, but i can imagine that there is a better way then unset all unneeded keys.
i also do a little optimization if the method was loading the translations for $element = 'source'.
Updated by Xavier Perseguers almost 13 years ago
- Subject changed from Bug in locallangXMLOverride mechanism since TYPO3 4.6 to locallangXMLOverride is broken since the switch to XLIFF
Updated by Gerrit Code Review almost 13 years ago
- Status changed from New to Under Review
Patch set 1 for branch master has been pushed to the review server.
It is available at http://review.typo3.org/7269
Updated by Lars no-lastname-given almost 13 years ago
I'm sorry, but the bug is a bit difficult. A fact is, that the result has changed from TYPO3 v4.5 to 4.6.
Currently i am using this version of the method "t3lib_l10n_parser_llxml::doParsingFromRootForElement":
protected function doParsingFromRootForElement(SimpleXMLElement $root, $element) { $bodyOfFileTag = $root->data->languageKey; // Check if the source llxml file contains localized records $localizedBodyOfFileTag = $root->data->xpath("languageKey[@index='" . $this->languageKey . "']"); // If no records found return empty array if ($element === 'target' && count($localizedBodyOfFileTag) === 0) return array(); $parsedData = $this->getParsedDataForElement($bodyOfFileTag, $element); if ($element === 'target' && isset($localizedBodyOfFileTag[0]) && $localizedBodyOfFileTag[0] instanceof SimpleXMLElement) { $parsedTargetData = $this->getParsedDataForElement($localizedBodyOfFileTag[0], $element); $mergedData = array_merge($parsedData, $parsedTargetData); if ($this->languageKey === 'default') { $mergedData = array_intersect_key($mergedData, $parsedTargetData); $parsedData = array_intersect_key($mergedData, $parsedData); } else{ $parsedData = array_intersect_key($mergedData, $parsedTargetData); } } return $parsedData; }
We have to test it with many cases like adding (new!) and overwriting translations (or whole new languages) inside the default- and any other languages.
Updated by Gerrit Code Review almost 13 years ago
Patch set 2 for branch master has been pushed to the review server.
It is available at http://review.typo3.org/7269
Updated by Gerrit Code Review almost 13 years ago
Patch set 3 for branch master has been pushed to the review server.
It is available at http://review.typo3.org/7269
Updated by Gerrit Code Review almost 13 years ago
Patch set 4 for branch master has been pushed to the review server.
It is available at http://review.typo3.org/7269
Updated by Gerrit Code Review almost 13 years ago
Patch set 5 for branch master has been pushed to the review server.
It is available at http://review.typo3.org/7269
Updated by Lars no-lastname-given almost 13 years ago
- Status changed from Under Review to Resolved
- % Done changed from 0 to 100
Applied in changeset 42e9452f1e102a54eff595f10324a61224723a33.
Updated by Xavier Perseguers almost 13 years ago
- Status changed from Resolved to Closed