TYPO3 v9.5创建含inline子元素自定义内容元素问题咨询
TYPO3 v9.5 核心实现带inline子内容的自定义元素问题
我希望仅使用TYPO3 v9.5核心功能创建自定义内容元素,该元素包含inline类型的子内容元素,每个子元素使用tt_content中的header和image字段。
目前已实现的效果:
- 带inline子元素的自定义内容元素
- 点击展开后子元素可编辑image和header字段
现在遇到两个问题:
- 前端页面渲染时,子元素没有嵌套在父元素内部,而是和父元素并列展示,需要子元素归属于父容器内部
- 如何将父元素及其所有子元素传递到fluid模板中,以便遍历子元素作为列表项输出,目前所有子元素已经存储了对应父元素的UID
要求:不使用第三方扩展,基于核心功能实现,学习底层原理
现有TCA配置(typo3conf/ext/[你的扩展]/Configuration/TCA/Overrides/tt_content.php)代码如下:
// 注册自定义内容类型 \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addTcaSelectItem( 'tt_content', 'CType', ['custom element', 'portfolio_list', 'content-text'], 'textmedia', 'after' ); \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addTcaSelectItem( 'tt_content', 'CType', ['custom element', 'portfolio_list2', 'content-text'], 'textmedia', 'after' ); $GLOBALS['TCA']['tt_content']['types']['portfolio_list2'] = [ 'showitem' => ' --div--;LLL:EXT:core/Resources/Private/Language/Form/locallang_tabs.xlf:general, --palette--;;general, image; Image, header; Title, portfolio_list2;Elemente, --div--;LLL:EXT:core/Resources/Private/Language/Form/locallang_tabs.xlf:access, --palette--;;hidden, --palette--;;access, ', 'columnsOverrides' => [ 'bodytext' => [ 'config' => [ 'enableRichtext' => true, 'richtextConfiguration' => 'default', ], ], 'portfolio_list2' => [ 'exclude' => true, 'label' => 'Einzelnes-Portfolio', 'config' => [ 'type' => 'inline', 'allowed' => 'tt_content', 'foreign_table' => 'tt_content', 'foreign_sortby' => 'sorting', 'foreign_field' => 'portfolio_list', 'minitems' => 0, 'maxitems' => 99, 'appearance' => [ 'collapseAll' => true, 'expandSingle' => true, 'levelLinksPosition' => 'bottom', 'useSortable' => true, 'showPossibleLocalizationRecords' => true, 'showRemovedLocalizationRecords' => true, 'showAllLocalizationLink' => true, 'showSynchronizationLink' => true, 'enabledControls' => [ 'info' => false, ], ], ], ], ], ]; // 新增关联字段 $temporaryColumn = [ 'portfolio_list2' => [ 'exclude' => true, 'label' => 'Einzelnes-Portfolio', 'config' => [ 'type' => 'inline', 'allowed' => 'tt_content', 'foreign_table' => 'tt_content', 'foreign_sortby' => 'sorting', 'foreign_field' => 'portfolio_list', 'minitems' => 0, 'maxitems' => 99, 'appearance' => [ 'collapseAll' => true, 'expandSingle' => true, 'levelLinksPosition' => 'bottom', 'useSortable' => true, 'showPossibleLocalizationRecords' => true, 'showRemovedLocalizationRecords' => true, 'showAllLocalizationLink' => true, 'showSynchronizationLink' => true, 'enabledControls' => [ 'info' => false, ], ], ], ], ]; \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addTCAcolumns( 'tt_content', $temporaryColumn );
疑问:是否需要创建Domain Model并配置1:n关系?
解答
问题1修复:子元素与父元素并列渲染
TYPO3默认会渲染所有非隐藏、colPos为0(默认内容列)的tt_content记录,你创建的子内容元素也属于tt_content,会被默认渲染逻辑单独查询输出,所以出现并列问题。
修复步骤:
- 在tt_content的TCA配置中新增布尔类型字段
is_portfolio_child,默认值为0,执行数据库比较更新表结构 - 修改inline字段的TCA配置,给子元素设置默认属性:
'config' => [ // 原有配置保留,新增以下配置 'foreign_record_defaults' => [ 'colPos' => 999, // 设为不会被默认内容列渲染的数值 'is_portfolio_child' => 1 ], ]
配置生效后所有新创建的子元素colPos为999,不会被默认渲染逻辑识别,自然不会和父元素并列展示。
问题2修复:父子数据传递到Fluid模板
不需要创建自定义Domain Model,用TYPO3核心的DataProcessor即可实现:
步骤1:配置TypoScript渲染逻辑
在你的模板扩展/站点扩展的Configuration/TypoScript/setup.typoscript中添加以下配置:
tt_content { portfolio_list2 =< lib.contentElement portfolio_list2 { templateName = PortfolioList2 dataProcessing { // 读取父元素的图片资源 10 = TYPO3\CMS\Frontend\DataProcessing\FilesProcessor 10 { references.fieldName = image as = parentImage } // 读取关联的子元素 20 = TYPO3\CMS\Frontend\DataProcessing\DatabaseQueryProcessor 20 { table = tt_content pidInList = this where.dataWrap = portfolio_list={field:uid} orderBy = sorting as = portfolioChildren // 嵌套读取子元素的图片资源 dataProcessing { 10 = TYPO3\CMS\Frontend\DataProcessing\FilesProcessor 10 { references.fieldName = image as = childImage } } } } } }
步骤2:创建Fluid模板
在模板路径下新建Templates/Content/PortfolioList2.html:
<div class="portfolio-parent"> <h2>{data.header}</h2> <f:if condition="{parentImage}"> <f:image image="{parentImage.0}" alt="{data.header}" width="800" /> </f:if> <ul class="portfolio-child-list"> <f:for each="{portfolioChildren}" as="child"> <li class="portfolio-child-item"> <h3>{child.header}</h3> <f:if condition="{child.childImage}"> <f:image image="{child.childImage.0}" alt="{child.header}" width="300" /> </f:if> </li> </f:for> </ul> </div>
补充注意事项
你当前的配置存在字段不统一问题:inline字段的foreign_field设置为portfolio_list,但你新增的字段名为portfolio_list2,需要统一字段名否则关联会失效。
内容的提问来源于stack exchange,提问作者codingIsLove
相关产品推荐
相关产品推荐

