[英]Typo3 10 Cropping and resizing images in Typo3 Fluid doesn't work right
[英]TYPO3 9,10,11 Languages fallback doesn't seem to work properly
我們目前正在創建一個 TYPO3 10.4 網站。 該網站僅包含基本的站點包擴展。 網站本身應該有多種語言,也可以有子語言。 所有語言都應該有一個后備。
舉個小例子:我們有 2 種語言 + 默認語言(也可以在隨附的配置中看到)。
語言en-de
應將英語(母版)作為后備。
在 TYPO3 本身中,我創建了 sys_languages 並將 1 頁翻譯成所有語言。 我還創建了一個測試內容項目,它被翻譯為英語(母版),但不是en-de
。
奇怪的是,默認的內容元素不是英語(主)翻譯,而是在前端顯示給我。
然而,頁面標題來自en-de
翻譯。 也適用於 TYPO3 9、10 和 11。有沒有人有解決方案或者這是一個已知的錯誤?
languages: - title: Default enabled: true languageId: 0 base: / typo3Language: de locale: de_DE.UTF-8 iso-639-1: de navigationTitle: Default hreflang: de direction: ltr flag: multiple - title: english (master) enabled: true languageId: 1 base: /en typo3Language: eu locale: en.UTF-8 iso-639-1: en navigationTitle: english (master) hreflang: en direction: ltr flag: eu - title: en-DE enabled: true languageId: 15 base: /en-de typo3Language: de locale: en_DE.UTF-8 iso-639-1: en navigationTitle: en-DE hreflang: en-de direction: ltr flag: de fallbackType: fallback fallbacks: "1"
我通過對負責的代碼進行 xclassing 來做到這一點。
ext_tables.php
$GLOBALS['TYPO3_CONF_VARS']['SYS']['Objects'][\TYPO3\CMS\Core\Domain\Repository\PageRepository::class] = [
'className' => MST\Site\XClass\PageRepository::class
];
比我擴展方法 getRecordOverlay 看第 116 行和 foreach-loop Site/Classes/XClass/PageRepository.php
class PageRepository extends \TYPO3\CMS\Core\Domain\Repository\PageRepository implements LoggerAwareInterface
{
/**
* Creates language-overlay for records in general (where translation is found
* in records from the same table)
*
* @param string $table Table name
* @param array $row Record to overlay. Must contain uid, pid and $table]['ctrl']['languageField']
* @param int $sys_language_content Pointer to the sys_language uid for content on the site.
* @param string $OLmode Overlay mode. If "hideNonTranslated" then records without translation will not be returned un-translated but unset (and return value is NULL)
* @return mixed Returns the input record, possibly overlaid with a translation. But if $OLmode is "hideNonTranslated" then it will return NULL if no translation is found.
* @throws \UnexpectedValueException
*/
public function getRecordOverlay($table, $row, $sys_language_content, $OLmode = '')
{
foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_page.php']['getRecordOverlay'] ?? [] as $className) {
$hookObject = GeneralUtility::makeInstance($className);
if (!$hookObject instanceof PageRepositoryGetRecordOverlayHookInterface) {
throw new \UnexpectedValueException($className . ' must implement interface ' . PageRepositoryGetRecordOverlayHookInterface::class, 1269881658);
}
$hookObject->getRecordOverlay_preProcess($table, $row, $sys_language_content, $OLmode, $this);
}
$tableControl = $GLOBALS['TCA'][$table]['ctrl'] ?? [];
$languageAspect = $this->context->getAspect('language');
if (!empty($tableControl['languageField'])
// Return record for ALL languages untouched
// @todo: Fix call stack to prevent this situation in the first place
&& (int)$row[$tableControl['languageField']] !== -1
&& !empty($tableControl['transOrigPointerField'])
&& $row['uid'] > 0
&& ($row['pid'] > 0 || in_array($tableControl['rootLevel'] ?? false, [true, 1, -1], true))) {
// Will try to overlay a record only if the sys_language_content value is larger than zero.
if ($sys_language_content > 0) {
// Must be default language, otherwise no overlaying
if ((int)$row[$tableControl['languageField']] === 0) {
// Select overlay record:
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
->getQueryBuilderForTable($table);
$queryBuilder->setRestrictions(
GeneralUtility::makeInstance(FrontendRestrictionContainer::class, $this->context)
);
if ($this->versioningWorkspaceId > 0) {
// If not in live workspace, remove query based "enable fields" checks, it will be done in versionOL()
// @see functional workspace test createLocalizedNotHiddenWorkspaceContentHiddenInLive()
$queryBuilder->getRestrictions()->removeByType(HiddenRestriction::class);
$queryBuilder->getRestrictions()->removeByType(StartTimeRestriction::class);
$queryBuilder->getRestrictions()->removeByType(EndTimeRestriction::class);
// We remove the FrontendWorkspaceRestriction in this case, because we need to get the LIVE record
// of the language record before doing the version overlay of the language again. WorkspaceRestriction
// does this for us, PLUS we need to ensure to get a possible LIVE record first (that's why
// the "orderBy" query is there, so the LIVE record is found first), as there might only be a
// versioned record (e.g. new version) or both (common for modifying, moving etc).
if ($this->hasTableWorkspaceSupport($table)) {
$queryBuilder->getRestrictions()->removeByType(FrontendWorkspaceRestriction::class);
$queryBuilder->getRestrictions()->add(GeneralUtility::makeInstance(WorkspaceRestriction::class, $this->versioningWorkspaceId));
$queryBuilder->orderBy('t3ver_wsid', 'ASC');
}
}
$pid = $row['pid'];
// When inside a workspace, the already versioned $row of the default language is coming in
// For moved versioned records, the PID MIGHT be different. However, the idea of this function is
// to get the language overlay of the LIVE default record, and afterwards get the versioned record
// the found (live) language record again, see the versionOL() call a few lines below.
// This means, we need to modify the $pid value for moved records, as they might be on a different
// page and use the PID of the LIVE version.
if (isset($row['_ORIG_pid']) && $this->hasTableWorkspaceSupport($table) && VersionState::cast($row['t3ver_state'] ?? 0)->equals(VersionState::MOVE_POINTER)) {
$pid = $row['_ORIG_pid'];
}
$fallbackChain = $languageAspect->get('fallbackChain');
$fallbackChain = [$sys_language_content, ...$fallbackChain];
foreach ($fallbackChain as $sys_language_content) {
$olrow = $queryBuilder->select('*')
->from($table)
->where(
$queryBuilder->expr()->eq(
'pid',
$queryBuilder->createNamedParameter($pid, \PDO::PARAM_INT)
),
$queryBuilder->expr()->eq(
$tableControl['languageField'],
$queryBuilder->createNamedParameter($sys_language_content, \PDO::PARAM_INT)
),
$queryBuilder->expr()->eq(
$tableControl['transOrigPointerField'],
$queryBuilder->createNamedParameter($row['uid'], \PDO::PARAM_INT)
)
)
->setMaxResults(1)
->executeQuery()
->fetchAssociative();
if (is_array($olrow)) {
break;
}
}
$this->versionOL($table, $olrow);
// Merge record content by traversing all fields:
if (is_array($olrow)) {
if (isset($olrow['_ORIG_uid'])) {
$row['_ORIG_uid'] = $olrow['_ORIG_uid'];
}
if (isset($olrow['_ORIG_pid'])) {
$row['_ORIG_pid'] = $olrow['_ORIG_pid'];
}
foreach ($row as $fN => $fV) {
if ($fN !== 'uid' && $fN !== 'pid' && array_key_exists($fN, $olrow)) {
$row[$fN] = $olrow[$fN];
} elseif ($fN === 'uid') {
$row['_LOCALIZED_UID'] = $olrow['uid'];
}
}
} elseif ($OLmode === 'hideNonTranslated' && (int)$row[$tableControl['languageField']] === 0) {
// Unset, if non-translated records should be hidden. ONLY done if the source
// record really is default language and not [All] in which case it is allowed.
$row = null;
}
} elseif ($sys_language_content != $row[$tableControl['languageField']]) {
$row = null;
}
} else {
// When default language is displayed, we never want to return a record carrying
// another language!
if ($row[$tableControl['languageField']] > 0) {
$row = null;
}
}
}
foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_page.php']['getRecordOverlay'] ?? [] as $className) {
$hookObject = GeneralUtility::makeInstance($className);
if (!$hookObject instanceof PageRepositoryGetRecordOverlayHookInterface) {
throw new \UnexpectedValueException($className . ' must implement interface ' . PageRepositoryGetRecordOverlayHookInterface::class, 1269881659);
}
$hookObject->getRecordOverlay_postProcess($table, $row, $sys_language_content, $OLmode, $this);
}
return $row;
}
}
如果翻譯頁面,還需要翻譯內容
我試圖在一個小的擴展中解決這個問題。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.