TYPO3 11自定义Box内容元素嵌套tt_content的后端布局及拖拽实现问题
解决方案
要实现自定义Box内容元素的嵌套拖拽后端布局,无需借助第三方扩展,通过TYPO3 11核心自带的预览渲染器+专属列标识配置即可完成,步骤如下:
步骤1:调整TCA配置,约束子元素属性
修改你现有TCA代码,给子元素绑定专属colPos值(示例用999,可自行替换为不冲突的数值,避免出现在顶层布局列),同时注册自定义预览渲染器:
$col = [ 'content_relation' => [ 'exclude' => true, 'label' => 'content', 'config' => [ 'type' => 'inline', 'allowed' => 'tt_content', 'foreign_table' => 'tt_content', 'foreign_field' => 'content_relation', 'foreign_sortby' => 'sorting', // 新增:约束子元素的colPos值 'foreign_match_fields' => [ 'colPos' => 999, ], 'minitems' => 0, 'maxitems' => 99, 'appearance' => [ 'collapseAll' => true, 'expandSingle' => true, 'levelLinksPosition' => 'bottom', 'useSortable' => true, 'showPossibleLocalizationRecords' => true, 'showRemovedLocalizationRecords' => true, 'showAllLocalizationLink' => true, 'showSynchronizationLink' => true, 'enabledControls' => [ 'info' => TRUE, 'new' => TRUE, 'dragdrop' => TRUE, 'sort' => TRUE, 'hide' => TRUE, 'delete' => TRUE, 'localize' => TRUE, ], ], ], ], ]; // 新增:给Box类型注册自定义预览渲染器,命名空间替换为你自己扩展的对应值 $GLOBALS['TCA']['tt_content']['types']['dg_template_box']['previewRenderer'] = \YourVendor\YourExtension\Preview\BoxPreviewRenderer::class; \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addToAllTCAtypes('tt_content', 'content_relation'); \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addTCAcolumns('tt_content', $col); $GLOBALS['TCA']['tt_content']['types']['dg_template_box'] = [ 'showitem' => ' --div--;LLL:EXT:core/Resources/Private/Language/Form/locallang_tabs.xlf:general, --palette--;;general, header;Internal title (not displayed), content_relation;Elemente, ', ];
你现有的SQL代码无需修改。
步骤2:配置页面TSconfig,隐藏顶层布局的专属列
在站点根页面的TSconfig中添加以下配置,避免属于Box的子元素出现在页面顶层的公共布局列中:
mod.web_layout.tt_content.colPos_999 = 0
步骤3:编写自定义预览渲染类
在你的扩展目录下创建Classes/Preview/BoxPreviewRenderer.php,代码如下:
<?php declare(strict_types=1); // 命名空间替换为你自己扩展的对应值 namespace YourVendor\YourExtension\Preview; use TYPO3\CMS\Backend\Preview\StandardContentPreviewRenderer; use TYPO3\CMS\Backend\View\BackendLayout\Grid\GridColumnItem; use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\CMS\Backend\View\PageLayoutView; class BoxPreviewRenderer extends StandardContentPreviewRenderer { public function renderContentElementPreview(GridColumnItem $item): string { $parentRecord = $item->getRecord(); $parentUid = $parentRecord['uid']; $pid = $parentRecord['pid']; // 渲染Box自身的基础信息(比如内部标题) $output = parent::renderContentElementPreview($item); // 初始化页面布局视图,用于渲染Box内部的子内容 $pageLayoutView = GeneralUtility::makeInstance(PageLayoutView::class); $pageLayoutView->id = $pid; $pageLayoutView->thumbs = $GLOBALS['TYPO3_CONF_VARS']['BE']['thumbnailsByDefault']; $pageLayoutView->showIcon = 1; $pageLayoutView->no_noWrap = 1; $pageLayoutView->ext_CE = ['tt_content']; // 渲染带核心拖拽识别属性的容器区域 $output .= '<div class="t3-page-ce-wrapper t3-page-ce-dropzone" data-colpos="999" data-pid="' . $pid . '" data-uid="' . $parentUid . '" style="padding: 10px; margin: 10px 0; border: 2px dashed #cacaca; border-radius: 4px;">'; // 渲染当前Box下的所有子内容 $output .= $pageLayoutView->getList($pid, "tt_content.colPos=999 AND tt_content.content_relation=" . (int)$parentUid); $output .= '</div>'; return $output; } }
步骤4:清除缓存生效
清除TYPO3全部系统缓存后即可生效,此时Box元素内部会显示独立的可拖拽区域,子元素只会在Box内部展示,支持直接拖拽内容元素移入移出,不会出现在顶层的colPos 0列中。
内容的提问来源于stack exchange,提问作者devgass
相关产品推荐
相关产品推荐

