TYPO3 Extbase多语言查询:如何为子表/ObjectStorage指定语言?
解决Extbase列表视图中子表翻译缓存复用问题
针对你遇到的Extbase在列表视图中复用子表缓存、导致多语言内容混乱的问题,以下是几个可行的解决方案:
1. 在Repository查询时强制过滤子表语言
直接在主表的列表查询中,通过QueryBuilder手动关联子表并指定sys_language_uid,绕过Extbase自动的关联加载逻辑,从根源避免缓存复用问题。
示例代码(主表Repository):
use TYPO3\CMS\Core\Utility\GeneralUtility; public function findAllForLanguage(int $languageUid): array { $queryBuilder = GeneralUtility::makeInstance(\TYPO3\CMS\Core\Database\ConnectionPool::class) ->getQueryBuilderForTable('tx_jobfinder_domain_model_stellenausschreibung'); $result = $queryBuilder ->select('main.*', 'sub.*') ->from('tx_jobfinder_domain_model_stellenausschreibung', 'main') ->leftJoin( 'main', 'tx_jobfinder_domain_model_subtable', // 替换为你的子表名 'sub', $queryBuilder->expr()->andX( $queryBuilder->expr()->eq('sub.stellenausschreibung', 'main.uid'), // 替换为主表关联字段 $queryBuilder->expr()->eq('sub.sys_language_uid', $queryBuilder->createNamedParameter($languageUid, \PDO::PARAM_INT)) ) ) ->where( $queryBuilder->expr()->eq('main.sys_language_uid', $queryBuilder->createNamedParameter($languageUid, \PDO::PARAM_INT)) ) ->executeQuery() ->fetchAllAssociative(); // 可将数组转换为Extbase模型,或直接传递到视图使用 return $result; }
2. 重写模型的子表Getter方法,按需查询对应语言
在主表模型中新增一个带语言参数的Getter方法,每次调用时直接从子表Repository查询对应语言的记录,不依赖Extbase自动加载的ObjectStorage缓存。
示例代码(主表模型):
use TYPO3\CMS\Extbase\Persistence\ObjectStorage; use TYPO3\CMS\Core\Utility\GeneralUtility; /** * @var ObjectStorage<\Vendor\Jobfinder\Domain\Model\Subtable> */ protected $languageSpecificSubrecords; /** * 获取指定语言的子表记录 * @param int $languageUid * @return ObjectStorage */ public function getSubrecordsForLanguage(int $languageUid): ObjectStorage { if ($this->languageSpecificSubrecords === null) { /** @var \Vendor\Jobfinder\Domain\Repository\SubtableRepository $subRepo */ $subRepo = GeneralUtility::makeInstance(\Vendor\Jobfinder\Domain\Repository\SubtableRepository::class); $query = $subRepo->createQuery(); $query->getQuerySettings()->setLanguageUid($languageUid); $query->matching($query->equals('stellenausschreibung', $this)); // 替换为主表关联字段 $this->languageSpecificSubrecords = $query->execute(); } return $this->languageSpecificSubrecords; }
在视图中调用这个方法替代默认的getSubrecords(),确保每次获取的都是当前语言的子记录。
3. 检查并优化TCA配置
确保子表的TCA配置正确开启语言支持,避免继承默认语言的记录导致缓存混乱:
- 子表的
sys_language_uid字段配置l10n_mode为exclude,让每个语言版本的子记录独立存储 - 子表的关联字段(关联主表的字段)配置
l10n_mode为exclude,确保翻译后的子记录正确关联到对应语言的主记录
为什么单条查询有效、列表失效?
单条详情查询时,Extbase会单独加载主记录和对应的子记录,缓存范围仅限当前请求的单条数据;而列表视图中,Extbase会批量加载所有主记录,然后批量关联子记录,此时对象缓存会复用之前加载过的子记录实例(忽略语言属性),导致后续记录错误复用首个加载的子记录内容。
内容的提问来源于stack exchange,提问作者Andreas K
相关产品推荐
相关产品推荐

