Story #70311
closedGeneral question about translations and extbase
Added by Philipp Wrann about 9 years ago. Updated about 7 years ago.
0%
Description
How can i achieve that typo3 keeps translated fields synced? I usually define fields, that are not relevant for translation (like the type or some 1:1 relation-data) as l10n_mode=exclude, and l10n_display=defaultAsReadonly. When an editor modifies the value in the original-language it will not be adjusted in the translation.
That breaks many plugins because the query extbase generates to retrieve records can not hit.
IMO it would make sense to keep those fields synced. So when you save a record with language=[-1|0] all fields configured as exclude should be set in the translation as well.
The concrete installation runs on TYPO3 6.2 but i think this "problem" exists in all versions.
Updated by Philipp Wrann about 9 years ago
Just found a similar topic i started in the typo3 board:
https://forum.typo3.org/index.php/t/209310/
maybe a new l10n_mode (keep or synced) would make things much easier. That configuration would suite typical single-select elements or any value that does not need a translation but should be able to be used in queries with translations...
Updated by Philipp Wrann about 9 years ago
Can someone please give me feedback on this topic, its very important because records are not loaded in foreign languages when the type-field is not synced.
Updated by Philipp Wrann about 9 years ago
https://forge.typo3.org/issues/62921
https://forge.typo3.org/issues/57272
http://typo3blogger.de/inkonsistenzen-bei-der-lokalisierung-von-inhalten-mit-typo3/
Do i simply not understand translation handling or are there massive issues regarding multilanguage support?
I think this needs to be tackled for the next LTS release.
If you keep fields with l10_mode=exclude|mergeIfNotBlank synced when the original language is saved the frontend support would increase big time...
just load the translation, compare fields and update all that are configured as 'exclude' as well as all that are 'mergeIfNotBlank' AND empty, then update the translation.
Updated by Philipp Wrann about 9 years ago
Also - when you create translations for records with type field set to something, the type field is set to the sql default value and you can not use that translation in certain language-handling-configurations.
I can not be the only person facing that problem.
Updated by Philipp Wrann about 9 years ago
Page config:
sys_language_mode = ignore
sys_language_overlay = hideNonTranslated
Updated by Philipp Wrann about 9 years ago
With a tcemain hook that basically works as follows (typo3 version 6.2) it seems i can fix the issue:
(without any warranty)
<?php namespace Vendor\Package\Hook; use TYPO3\CMS\Core\DataHandling\DataHandler; class TCEmainHookFixTranslations implements \TYPO3\CMS\Core\SingletonInterface { protected static $tablesToFix = array( 'tx_package_domain_model_record' ); /** * @param DataHandler $dataHandler * @return void */ public function processDatamap_afterAllOperations(DataHandler $dataHandler) { foreach ($dataHandler->datamap as $table => $items) { if (in_array($table,self::$tablesToFix)) { $this->process($table,$items,$dataHandler->substNEWwithIDs); } } } /** * @param string $table * @param array $collection * @param array $newUids * @return void */ protected function process($table, $collection, $newUids) { while ($key = key($collection)) { if (array_key_exists($key,$newUids)) { $key = $newUids[$key]; } $record = current($collection); if ($this->shouldBeSynced($table,$record)) { $this->sync($table,$key,$record); } next($collection); } } /** * @param string $table * @param array $record * @return boolean */ protected function shouldBeSynced($table,$record) { $ctrl = $GLOBALS['TCA'][$table]['ctrl']; if (!isset($ctrl['languageField']) || !isset($ctrl['transOrigPointerField'])) { return FALSE; } return (isset($record[$ctrl['languageField']]) && $record[$ctrl['languageField']] <= 0); } /** * @param string $table * @param integer $uid * @param array $record * @return void */ protected function sync($table, $uid, $record) { $languageField = $GLOBALS['TCA'][$table]['ctrl']['languageField']; $transOrigPointerField = $GLOBALS['TCA'][$table]['ctrl']['transOrigPointerField']; $currentLanguage = (integer) $record[$languageField]; if ($currentLanguage === 0 && $this->hasTranslation($table, $uid, -1)) { // dont process, if [all languages] exists it acts as template for other languages > 0 return; } // overlay current record on all translations $overlayFields = $this->getOverlayFields($table); $update = array(); foreach ($overlayFields as $fieldName) { if (!isset($record[$fieldName])) { continue; } switch ($GLOBALS['TCA'][$table]['columns'][$fieldName]['config']['type']) { case 'inline': break 2; case 'group': case 'select': // @todo this only works for current needs if (strpos($record[$fieldName],'|') !== FALSE) { $value = array_shift(explode('|',$record[$fieldName])); } else { $value = $record[$fieldName]; } break; default: $value = $record[$fieldName]; break; } $update[$fieldName] = $value; } $this->getDatabaseConnection()->exec_UPDATEquery($table, $languageField . ' > 0 AND ' . $transOrigPointerField . '='. $uid, $update); } /** * @param string $table * @return array */ protected function getOverlayFields($table) { $overlayFields = array(); foreach ($GLOBALS['TCA'][$table]['columns'] as $columnName => $columnConfig) { if ($columnConfig['l10n_mode'] === 'exclude') { $overlayFields[] = $columnName; } } return $overlayFields; } /** * @param type $table * @param type $uid * @param type $sysLanguageUid * @return boolean */ protected function hasTranslation($table, $uid, $sysLanguageUid) { $languageField = $GLOBALS['TCA'][$table]['ctrl']['languageField']; $transOrigPointerField = $GLOBALS['TCA'][$table]['ctrl']['transOrigPointerField']; $result = $this->getDatabaseConnection()->exec_SELECTgetSingleRow('uid', $table, $transOrigPointerField . '=' . $uid . ' AND ' . $languageField . '=' . $sysLanguageUid); return empty($result) === FALSE; } /** * @return \TYPO3\CMS\Core\Database\DatabaseConnection */ protected function getDatabaseConnection() { return $GLOBALS['TYPO3_DB']; } /** * @param string $table * @return void */ public static function addTable($table) { self::$tablesToFix[] = $table; } }
Updated by Riccardo De Contardi about 7 years ago
- Category changed from Localization to Extbase + l10n
Updated by Benni Mack about 7 years ago
- Status changed from New to Closed
With TYPO3 v8, fields in translations ARE synced for l10n_mode exclude. So we're fine on this side. For Extbase-specific changes, see https://review.typo3.org/#/c/53974/