
在typo3中创建自定义内容元素(custom content element, cce)是扩展其功能和满足特定业务需求的关键方式。这允许开发者定义具有独特数据结构和渲染逻辑的页面内容块。本教程将引导您完成一个自定义内容元素的创建过程,并重点解决开发过程中常见的模板解析错误。
一个完整的TYPO3自定义内容元素通常涉及以下几个方面:
以下是创建名为oneColumnFlipbox的自定义内容元素的具体步骤,该元素包含一个用于代码语言选择的下拉字段。
首先,在您的扩展(例如my_sitepackage_for_flipbox)的ext_localconf.php文件中,添加新的数据库字段到tt_content表。
<?php
defined('TYPO3') || die('Access denied.');
// ... 其他配置
// 添加数据库字段
TYPO3CMSCoreUtilityExtensionManagementUtility::addTCAcolumns(
'tt_content',
[
'code_language' => [
'exclude' => true,
'label' => 'LLL:EXT:my_sitepackage_for_flipbox/Resources/Private/Language/locallang_db.xlf:tt_content.code_language',
'config' => [
'type' => 'select',
'renderType' => 'selectSingle',
'itemsProcFunc' => 'B13\MySitepackageForFlipbox\DataProvider\CodeLanguages->getAll', // 自定义数据提供者
'default' => '',
],
],
]
);注意:完成此步骤后,请务必更新TYPO3安装工具中的数据库结构。
在您的扩展的Configuration/TCA/Overrides/tt_content.php文件中,配置新字段code_language的TCA,并将其添加到tt_content表的某个CType中。
<?php
defined('TYPO3') || die('Access denied.');
// 添加下拉菜单字段到TCA
$additionalColumns = [
'code_language' => [
'label' => 'LLL:EXT:my_sitepackage_for_flipbox/Resources/Private/Language/locallang_db.xlf:tt_content.code_language',
'config' => [
'type' => 'select',
'default' => '',
'itemsProcFunc' => 'B13\MySitepackageForFlipbox\DataProvider\CodeLanguages->getAll',
'renderType' => 'selectSingle',
],
],
];
TYPO3CMSCoreUtilityExtensionManagementUtility::addTCAcolumns('tt_content', $additionalColumns);
// 将字段添加到自定义内容类型 'oneColumnFlipbox' 的显示项中
TYPO3CMSCoreUtilityExtensionManagementUtility::addToAllTCAtypes(
'tt_content',
'code_language',
'oneColumnFlipbox', // 确保这里是您的CType名称
'before:bodytext'
);在您的扩展的Configuration/TCA/Overrides/tt_content.php文件中,注册新的内容类型oneColumnFlipbox。
<?php
// ... 其他TCA配置
// 将内容元素添加到"CType"下拉列表
TYPO3CMSCoreUtilityExtensionManagementUtility::addPlugin(
[
'1 Column Flipbox', // 后台显示名称
'oneColumnFlipbox', // CType标识符
'EXT:my_sitepackage_for_flipbox/Resources/Public/Icons/T3Icons/content/content-carousel-image.svg' // 图标路径
],
'CType',
'my_sitepackage_for_flipbox'
);继续在Configuration/TCA/Overrides/tt_content.php文件中,配置oneColumnFlipbox内容类型在TYPO3后台的编辑字段。
<?php
// ... 其他TCA配置
// 配置内容元素的默认后端字段
$frontendLanguageFilePrefix = 'LLL:EXT:frontend/Resources/Private/Language/locallang_ttc.xlf:';
$GLOBALS['TCA']['tt_content']['types']['oneColumnFlipbox'] = [
'showitem' => '
--palette--;' . $frontendLanguageFilePrefix . 'palette.general;general,
--palette--;;headers,
bodytext;' . $frontendLanguageFilePrefix . 'bodytext_formlabel,
code_language, --linebreak--,
--div--;' . $frontendLanguageFilePrefix . 'tabs.appearance,
--palette--;' . $frontendLanguageFilePrefix . 'palette.frames;frames,
--palette--;;appearanceLinks,
--div--;' . $frontendLanguageFilePrefix . 'tabs.access,
--palette--;' . $frontendLanguageFilePrefix . 'palette.visibility;visibility,
--div--;LLL:EXT:core/Resources/Private/Language/Form/locallang_tabs.xlf:language,
--palette--;;language,
--div--;LLL:EXT:core/Resources/Private/Language/Form/locallang_tabs.xlf:categories,
categories,
--div--;' . $frontendLanguageFilePrefix . 'tabs.extended,
--palette--;;hidden,
--palette--;;access,
',
'columnsOverrides' => [
'bodytext' => [
'config' => [
'enableRichtext' => true,
'richtextConfiguration' => 'default',
],
],
],
];请注意,这里我们将code_language字段也添加到了showitem中。
在ext_localconf.php中引入PageTSConfig文件,然后在这些文件中定义新内容元素的向导配置。
ext_localconf.php:
<?php
// ... 其他配置
// 引入PageTSConfig
TYPO3CMSCoreUtilityExtensionManagementUtility::addPageTSConfig('<INCLUDE_TYPOSCRIPT: source="FILE:EXT:my_sitepackage_for_flipbox/Configuration/TsConfig/Page/All.tsconfig">');Configuration/TsConfig/Page/All.tsconfig:
@import 'EXT:my_sitepackage_for_flipbox/Configuration/TsConfig/Page/ContentElements/*.tsconfig'
Configuration/TsConfig/Page/ContentElements/oneColumnFlipbox.tsconfig:
mod.wizards.newContentElement.wizardItems {
common {
elements {
oneColumnFlipbox {
iconIdentifier = content-dashboard
title = 1 column flipbox
description = one flipbox
tt_content_defValues {
CType = oneColumnFlipbox
}
}
}
show := addToList(oneColumnFlipbox)
}
}数据处理器允许您在将数据传递给Fluid模板之前对其进行操作。例如,下面的HeighleightProcessing.php用于代码高亮。
Classes/DataProcessing/HeighleightProcessing.php:
<?php
namespace B13MySitepackageForFlipboxDataProcessing;
use TYPO3CMSCoreUtilityGeneralUtility;
use TYPO3CMSFrontendContentObjectContentObjectRenderer;
use TYPO3CMSFrontendContentObjectDataProcessorInterface;
use HighlightHighlighter; // 假设您已引入高亮库
class HeighleightProcessing implements DataProcessorInterface
{
/**
* Process data for a content object
*
* @param ContentObjectRenderer $cObj The data of the content element
* @param array $contentObjectConfiguration The configuration of the content element
* @param array $processorConfiguration The configuration of the processor
* @param array $processedData The processed data of the content element
* @return array The processed data of the content element
*/
public function process(ContentObjectRenderer $cObj, array $contentObjectConfiguration, array $processorConfiguration, array $processedData)
{
$fieldName = $processorConfiguration['field'];
$targetVariableName = $cObj->stdWrapValue('as', $processorConfiguration, 'bodytext_formatted');
$highlight = GeneralUtility::makeInstance(Highlighter::class);
// 根据配置决定是否自动检测语言
if (!$processedData['data']['code_language']) {
$languages = $highlight->listLanguages();
$highlight->setAutodetectLanguages($languages);
$highlighted = $highlight->highlightAuto($processedData['data'][$fieldName]);
} else {
$highlighted = $highlight->highlight($processedData['data']['code_language'], $processedData['data'][$fieldName]);
}
$processedData[$targetVariableName]['code'] = $highlighted->value;
$processedData[$targetVariableName]['language'] = $highlighted->language;
$processedData[$targetVariableName]['lines'] = preg_split('/
|
|
/', $highlighted->value);
return $processedData;
}
}前端渲染是自定义内容元素最终在网站上显示的关键。这主要通过TypoScript配置和Fluid模板来实现。
在您的扩展的Configuration/TypoScript/setup.typoscript文件中,定义模板、局部模板和布局文件的路径,并注册您的内容元素。
Configuration/TypoScript/setup.typoscript:
###########################################
# Path #
###########################################
# 引入内容元素和辅助TypoScript
@import 'EXT:my_sitepackage_for_flipbox/Configuration/TypoScript/ContentElements/'
@import 'EXT:my_sitepackage_for_flipbox/Configuration/TypoScript/Helper/'
# 模板、局部模板、布局文件的路径
lib.contentElement {
templateRootPaths {
100 = EXT:my_sitepackage_for_flipbox/Resources/Private/Templates/
// 确保这里包含所有可能需要的模板路径
}
partialRootPaths {
100 = EXT:my_sitepackage_for_flipbox/Resources/Private/Partials/
}
layoutRootPaths {
100 = EXT:my_sitepackage_for_flipbox/Resources/Private/Layouts/
}
}在Configuration/TypoScript/ContentElements/oneColumnFlipbox.typoscript中,注册您的内容元素并指定其模板名称。
# 注册内容元素 oneColumnFlipbox
tt_content {
oneColumnFlipbox =< lib.contentElement
oneColumnFlipbox {
templateName = OneColumnFlipbox // 关键点:模板名称首字母大写
dataProcessing {
10 = B13MySitepackageForFlipboxDataProcessingHeighleightProcessing
10 {
field = bodytext
as = bodytext_formatted
}
}
}
}当您在前端尝试显示自定义内容元素时,可能会遇到类似以下错误:
TYPO3FluidFluidViewExceptionInvalidTemplateResourceExceptionTried resolving a template file for controller action "Standard->oneColumnFlipbox" in format ".html", but none of the paths contained the expected template file (Standard/OneColumnFlipbox.html). The following paths were checked: ...
这个错误明确指出Fluid视图未能找到预期的模板文件。在TYPO3的fluid_styled_content上下文中,当您使用lib.contentElement来定义自定义内容元素时,Fluid会尝试根据templateName的值,结合默认的模板解析规则,来查找模板文件。
问题的根源在于Fluid的模板命名约定。当templateName被设置为oneColumnFlipbox(小写开头)时,Fluid默认会尝试寻找Standard/oneColumnFlipbox.html。然而,在许多TYPO3和Fluid的惯例中,尤其是当使用templateName属性时,期望的模板文件通常是PascalCase(首字母大写)的,并且直接位于templateRootPaths下,或者在ControllerName/ActionName.html的结构中。
正确的做法是:
将TypoScript中的templateName首字母大写。
# 注册内容元素 oneColumnFlipbox
tt_content {
oneColumnFlipbox =< lib.contentElement
oneColumnFlipbox {
templateName = OneColumnFlipbox // 修改为首字母大写
dataProcessing {
10 = B13MySitepackageForFlipboxDataProcessingHeighleightProcessing
10 {
field = bodytext
as = bodytext_formatted
}
}
}
}确保您的模板文件也以首字母大写命名。 在EXT:my_sitepackage_for_flipbox/Resources/Private/Templates/目录下,创建名为OneColumnFlipbox.html的模板文件。
示例模板文件 (Resources/Private/Templates/OneColumnFlipbox.html):
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" data-namespace-typo3-fluid="true">
<f:layout name="Default" />
<f:section name="Main">
<div class="one-column-flipbox">
<h2>{data.header}</h2>
<f:if condition="{bodytext_formatted.code}">
<pre><code class="language-{bodytext_formatted.language}">{bodytext_formatted.code -> f:format.raw()}</code></pre>
<f:else>
<f:format.html parseFuncTSPath="lib.parseFunc_RTE">{data.bodytext}</f:format.html>
</f:else>
</f:if>
<p>Selected language: {data.code_language}</p>
</div>
</f:section>
</html>完成这些修改后,TYPO3的Fluid视图将能够正确解析并找到您的模板文件,从而解决前端渲染错误。
创建TYPO3自定义内容元素涉及多个配置层面,从数据库到前端渲染。其中,Fluid模板的命名和TypoScript中的templateName配置是前端渲染成功的关键。通过遵循Fluid的命名约定,并确保模板文件与TypoScript配置中的templateName(首字母大写)一致,可以有效解决“模板文件未找到”的常见错误,从而成功地在TYPO3前端展示您的自定义内容。理解TYPO3的内部工作机制和调试技巧,将极大提高您的开发效率。
以上就是TYPO3自定义内容元素开发:模板解析错误与解决方案的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号