关于 typo3-update
面向开发和维护 TYPO3 v14 项目的开发技能,适用于扩展开发者。内容强调使用 TYPO3 API,并提供 PHP、控制器、视图、事件和服务注册的 v14 特定模式。
主要功能
- 01仅针对 TYPO3 v14 的版本指南
- 02PHP 8.2 及以上版本要求与模式
- 03Extbase 和后台控制器模式
- 04ViewFactory 与 Fluid 指引
- 05PSR-14 事件监听器实践
- 06Services.yaml 注册指引
适用场景
- 01开发新的 TYPO3 v14 扩展
- 02为 TYPO3 v14 实现控制器和视图
- 03选择基于事件的扩展点
- 04检查版本约束和 PHP 要求
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ dirnbauer/ webconsulting-skills --skill typo3-update安装后在 Claude Code 中输入/typo3-update确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/06-backend-module-registration-typo3-v14.md07-tca-configuration-typo3-v14.md08-database-operations-typo3-v14.md09-cli-commands-typo3-v14.md10-testing.md11-upgrade-process.md12-resources.md13-v14-only-changes-manual-not-handled-by-rector.mdcredits-and-attribution.mdfull-guide.md详细介绍
TYPO3 v14 开发
**策略:**本合集仅面向 TYPO3 v14.x。此处的模式均基于 v14 代码库。 从更早的主版本迁移时,请先使用
typo3-rector、typo3-extension-upgrade、Fractor 和官方升级指南。
**TYPO3 API 优先:**创建自定义实现前,请始终优先使用 TYPO3 内置 API、核心功能和成熟约定。不要重复实现 TYPO3 已提供的功能。请始终查阅 TYPO3 官方文档,确认所用 API 和方法在 TYPO3 v14 中存在且未弃用。
1. 版本策略
目标:仅支持 TYPO3 v14.x
| 版本 | 本合集中的定位 |
|---|---|
| v14.x | 支持的目标版本 — 示例和限制均基于 TYPO3 v14 |
| 更早的主版本 | 不在目标范围内 — 请先完成核心升级,再使用这些模式 |
**最佳实践:**对于新项目,请在 composer.json 和 ext_emconf.php 中声明仅支持 TYPO3 v14 的约束。
版本约束
<?php
// ext_emconf.php — TYPO3 v14
$EM_CONF[$_EXTKEY] = [
'title' => 'My Extension',
'version' => '2.0.0',
'state' => 'stable',
'constraints' => [
'depends' => [
'typo3' => '14.0.0-14.99.99',
'php' => '8.2.0-8.5.99',
],
'conflicts' => [],
'suggests' => [],
],
];
// composer.json — TYPO3 v14
{
"name": "vendor/my-extension",
"type": "typo3-cms-extension",
"require": {
"php": "^8.2",
"typo3/cms-core": "^14.0"
},
"extra": {
"typo3/cms": {
"extension-key": "my_extension"
}
}
}
Content Blocks:
friendsoftypo3/content-blocks可能要求typo3/cms-core^14.3 或更高版本(当前 2.4.5 版本要求^14.3)——仅固定为^14.0前,请匹配 Packagist 约束。
2. PHP 要求
最低 PHP 版本:8.2
TYPO3 v14 要求 PHP 8.2 或更高版本。请使用现代 PHP 功能:
<?php
declare(strict_types=1);
namespace Vendor\Extension\Service;
// ✅ Constructor property promotion (PHP 8.0+)
final class MyService
{
public function __construct(
private readonly SomeDependency $dependency,
private readonly AnotherService $anotherService,
) {}
}
// ✅ Named arguments (PHP 8.0+)
$result = $this->doSomething(
name: 'value',
options: ['key' => 'value'],
);
// ✅ Match expressions (PHP 8.0+)
$type = match ($input) {
'a' => 'Type A',
'b' => 'Type B',
default => 'Unknown',
};
// ✅ Enums (PHP 8.1+)
enum Status: string
{
case Draft = 'draft';
case Published = 'published';
}
3. 控制器模式(TYPO3 v14)
Extbase Action 控制器
<?php
declare(strict_types=1);
namespace Vendor\Extension\Controller;
use Psr\Http\Message\ResponseInterface;
use TYPO3\CMS\Extbase\Mvc\Controller\ActionController;
use Vendor\Extension\Domain\Repository\ItemRepository;
final class ItemController extends ActionController
{
public function __construct(
private readonly ItemRepository $itemRepository,
) {}
// ✅ Must return ResponseInterface (required in TYPO3 v14)
public function listAction(): ResponseInterface
{
$items = $this->itemRepository->findAll();
$this->view->assign('items', $items);
return $this->htmlResponse();
}
public function showAction(int $item): ResponseInterface
{
$item = $this->itemRepository->findByUid($item);
$this->view->assign('item', $item);
return $this->htmlResponse();
}
// ✅ JSON response
public function apiAction(): ResponseInterface
{
$data = ['success' => true, 'items' => []];
return $this->jsonResponse(json_encode($data));
}
// ✅ Redirect
public function createAction(): ResponseInterface
{
// Process creation...
$this->addFlashMessage('Item created');
return $this->redirect('list');
}
}
后端模块控制器
<?php
declare(strict_types=1);
namespace Vendor\Extension\Controller;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use TYPO3\CMS\Backend\Attribute\AsController;
use TYPO3\CMS\Backend\Template\ModuleTemplateFactory;
#[AsController]
final class BackendModuleController
{
public function __construct(
private readonly ModuleTemplateFactory $moduleTemplateFactory,
) {}
public function indexAction(ServerRequestInterface $request): ResponseInterface
{
$moduleTemplate = $this->moduleTemplateFactory->create($request);
$moduleTemplate->assign('items', []);
return $moduleTemplate->renderResponse('Backend/Index');
}
}
4. 视图与模板(TYPO3 v14)
ViewFactory(首选模式)
<?php
declare(strict_types=1);
namespace Vendor\Extension\Service;
use Psr\Http\Message\ServerRequestInterface;
use TYPO3\CMS\Core\View\ViewFactoryData;
use TYPO3\CMS\Core\View\ViewFactoryInterface;
final class RenderingService
{
public function __construct(
private readonly ViewFactoryInterface $viewFactory,
) {}
public function renderEmail(ServerRequestInterface $request, array $data): string
{
$viewFactoryData = new ViewFactoryData(
templateRootPaths: ['EXT:my_extension/Resources/Private/Templates/Email'],
partialRootPaths: ['EXT:my_extension/Resources/Private/Partials'],
layoutRootPaths: ['EXT:my_extension/Resources/Private/Layouts'],
request: $request,
);
$view = $this->viewFactory->create($viewFactoryData);
$view->assignMultiple($data);
return $view->render('Notification');
}
}
Fluid 模板最佳实践
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers"
xmlns:core="http://typo3.org/ns/TYPO3/CMS/Core/ViewHelpers"
data-namespace-typo3-fluid="true">
<f:layout name="Default" />
<f:section name="Main">
<div class="content">
<h1>{item.title}</h1>
<f:format.html>{item.bodytext}</f:format.html>
<f:if condition="{items}">
<f:then>
<f:for each="{items}" as="item">
<f:render partial="Item" arguments="{item: item}" />
</f:for>
</f:then>
<f:else>
<p>No items found.</p>
</f:else>
</f:if>
<f:link.action action="show" arguments="{item: item.uid}">
View Details
</f:link.action>
</div>
</f:section>
</html>
5. 事件系统(TYPO3 v14)
PSR-14 事件监听器
PSR-14 事件是 TYPO3 v14 中的标准方式。请始终优先使用事件,而不是钩子。
<?php
declare(strict_types=1);
namespace Vendor\Extension\EventListener;
use TYPO3\CMS\Core\Attribute\AsEventListener;
use TYPO3\CMS\Frontend\Event\ModifyCacheLifetimeForPageEvent;
#[AsEventListener(identifier: 'vendor-extension/modify-cache-lifetime')]
final class ModifyCacheLifetimeListener
{
public function __invoke(ModifyCacheLifetimeForPageEvent $event): void
{
// Reduce cache lifetime for certain pages
if ($event->getPageId() === 123) {
$event->setCacheLifetime(300); // 5 minutes
}
}
}
常见事件(TYPO3 v14)
| 事件 | 用途 |
|---|---|
ModifyPageLinkConfigurationEvent | 修改链接构建 |
ModifyCacheLifetimeForPageEvent | 调整页面缓存 |
BeforeStdWrapFunctionsInitializedEvent | 修改 stdWrap |
| (DataHandler) | 核心不提供通用的 BeforeRecordOperationEvent / AfterRecordOperationEvent;请使用 SC_OPTIONS DataHandler 钩子,或文档中记录的 TYPO3\CMS\Core\DataHandling\Event\*(仅限这些)(列表) |
Services.yaml 注册
# Configuration/Services.yaml
services:
_defaults:
autowire: true
autoconfigure: true
public: false
Vendor\Extension\:
resource: '../Classes/*'
exclude:
- '../Classes/Domain/Model/*'
# Event listener (alternative to #[AsEventListener] attribute)
Vendor\Extension\EventListener\MyListener:
tags:
- name: event.listener
identifier: 'vendor-extension/my-listener'
详细参考
如果任务需要详细示例、长模板、故障排除矩阵、附录或上文未包含的章节,请阅读完整指南。对于范围较窄的任务,请勿加载此文件,以便技能遵循渐进式披露原则。