你的预发布服务器完成TYPO3缓存重建——一条内容变更需要四十三秒,而这个过程本应只需两秒。前端开发刷新浏览器,看到更新,然后低声嘟囔一些关于TypoScript的内容,这些话你大概不该在站会上重复。这幕戏每天都在欧洲各地的企业中上演,那些被TYPO3支撑了二十年的政府门户网站和公司网站。这个CMS在技术上仍在运行。但Drupal的组件优先架构、其无头工具包,以及十倍规模的贡献者基础使得迁移谈话变得不可避免。问题不在于是否要迁移——而在于如何迁移8000个页面、保留二十年的URL价值,并在过渡期间让你的内容编辑保持理智。在过去十八个月里,我们已经执行过这个计划六次,而干净迁移与灾难之间的差异取决于你在第一周做出的四个决策。

在过去几年里,我深入参与了几个TYPO3到Drupal的迁移项目,这是一段相当的旅程,需要解开现实中的内容模型。它们通常是一团乱麻。这份指南是我希望在第一次迁移前有人递给我的东西。我将涵盖所有细致的技术细节、规划必做项,以及那些令人讨厌的陷阱,如果你不小心应对,它们可能会摧毁你的时间表。

目录

TYPO3迁移至Drupal:实用开发者指南

为何组织离开TYPO3

先说明白:TYPO3不是一个糟糕的CMS。它极其灵活,原生支持多站点和多语言设置,在DACH地区尤其拥有忠实的粉丝群体。那么为什么人们要跳船呢?

我听到的基本上都是同样的理由:

**开发者可用性。**在中欧之外,找TYPO3开发者就像大海捞针。另一方面,Drupal根据Drupal.org 2024年社区报告声称全球约有130万名开发者。TYPO3?远不如此。如果你的资深TYPO3开发者决定离职,填补这些空缺可能需要很久。

**生态系统势头。**随着2024年底Drupal 11的发布,在管理UI、新的recipes系统和强大的API优先功能上取得了巨大进展。当然,TYPO3 v13很扎实,但Drupal的创新速率,特别是在无头设置方面,明显更快。

**无头/解耦架构。**计划为一个漂亮的Next.js或Astro前端提供内容?Drupal的JSON:API和GraphQL插件经验丰富。TYPO3有自己的无头扩展,但它不那么成熟,支持者较少。

**总体拥有成本。**托管TYPO3通常花费更多。它的专业化基础设施意味着你最终可能要花更多钱。Drupal的内容可以在几乎任何地方运行,从Pantheon到Acquia,甚至基本的LAMP堆栈也能让它运行良好。

TYPO3与Drupal:诚实的比较

在匆忙迁移之前,确保Drupal真正会解决你的痛点。以下是2026年的情况:

功能 TYPO3 v13 Drupal 11
内容建模 灵活但依赖TCA Entity/Field系统与字段管理UI
多语言 卓越的原生支持 同样卓越的原生支持
多站点 标准多站点与内容树 可能,通常更适合Domain Access或独立安装
无头/API 有无头扩展 JSON:API核心,GraphQL贡献
模板 Fluid模板+TypoScript Twig模板
扩展/模块生态 TER上约1,800个扩展 Drupal.org上50,000+个模块
管理UI 强大但陈旧(v13即将改进) Drupal 11中光滑现代
开发者社区 约500名活跃贡献者 8,000+名活跃贡献者
托管选项 自托管或专业 自托管、Pantheon、Acquia、Platform.sh、Lagoon
PHP要求 PHP 8.2+ PHP 8.3+
典型代理费率 €100-180/小时(DACH地区) $80-200/小时(全球)

TYPO3的页面树模型是一个罕见的瑰宝。习惯于在TYPO3中管理复杂页面层级的编辑可能会发现Drupal的方式——内容类型和分类的结合——需要一些调整。安排一些编辑培训来缓解这种过渡。

迁移前审计与规划

这个阶段决定了大多数迁移的命运。成功在于规划,而非技术时间。

内容清单

首先审计你的TYPO3设置中的所有内容:

  • **页面:**拉出页面树,记录你正在使用的每个doktype(页面类型)。
  • **内容元素:**每个CType(内容类型)都需要关注——无论是文本、带图像的文本、HTML还是通过maskcontent_defender的自定义内容。
  • **扩展:**记录你拥有的每个扩展。找出是否有Drupal等价物。
  • **文件引用:**TYPO3的FAL(文件抽象层)处理媒体。将这些映射到Drupal的媒体位置。
  • **后端用户和权限:**TYPO3的复杂后端用户组,带有页面和字段级别的访问权限,应该整齐地转换为Drupal角色和权限。

这是一个来自你的TYPO3数据库的内容元素摘要的便捷SQL查询:

SELECT CType, COUNT(*) as count 
FROM tt_content 
WHERE deleted = 0 AND hidden = 0 
GROUP BY CType 
ORDER BY count DESC;

通过这个,你可以快速了解你正在处理的内容类型。在一个案例中,我发现了一个TYPO3实例拥有40多个自定义内容元素类型,其中只有十几个被积极使用。不要拖累死重量。

保留什么,删除什么

这是你清理房间的机会。使用内容审计工具如Screaming Frog或Sitebulb来找出:

  • 过去一年中没有流量的页面
  • 重复或几乎相同的内容
  • 破损的内部链接
  • 孤立的媒体文件

通常,大型TYPO3迁移中有30-50%的内容被删除。更少的页面意味着更快的迁移。

TYPO3迁移至Drupal:实用开发者指南——架构

内容建模:TYPO3映射至Drupal

卷起你的袖子。这是重型知识工作。TYPO3和Drupal处理内容的方式非常不同。

TYPO3的模型

TYPO3围绕页面展开。一切都塞进页面树中。内容元素(tt_content中的记录)插入页面的列中(colPos)。通过Extbase模型或TCA定义的自定义记录存在于单独的表中,但通常从页面链接。

Drupal的模型

Drupal全是关于实体。你创建内容类型(节点包),每个都有专用字段。页面只是许多内容类型中的一个。分类法、段落(使用段落模块),以及布局构建器主导结构化内容组合。

映射

这是我用作指南针的典型映射表:

TYPO3概念 Drupal等价物
页面(doktype:standard) 节点(内容类型:Page)
页面(doktype:shortcut) URL重定向
页面(doktype:link) 带链接字段的节点或重定向
内容元素(CType:text) 段落类型或正文字段
内容元素(CType:image) 媒体实体引用
内容元素(CType:textpic) 带文本+媒体的段落类型
内容元素(CType:gridelements) 布局构建器部分
FAL文件引用 媒体实体
sys_category 分类法术语
fe_users Drupal用户实体
be_users 带管理员角色的Drupal用户实体
TypoScript模板 Twig模板
Extbase插件 自定义Drupal模块
Mask/DCE内容元素 段落类型

最大的转变?将内容元素移至段落。TYPO3在页面列中堆叠内容元素,这与Drupal的段落模块相映成趣。编辑从可重用段落类型中堆叠页面——这出人意料地无缝。

迁移工具与技术方法

Drupal的迁移API太棒了。但要注意,它缺乏本地TYPO3源插件。你将需要创建一些自定义源插件来从TYPO3的数据库中提取。

方法1:直接数据库迁移

将Drupal的迁移API直接插入你的TYPO3 MySQL/MariaDB数据库:

// TYPO3页面的迁移源插件示例
namespace Drupal\typo3_migrate\Plugin\migrate\source;

use Drupal\migrate\Plugin\migrate\source\SqlBase;
use Drupal\migrate\Row;

/**
 * @MigrateSource(id = "typo3_pages")
 */
class Typo3Pages extends SqlBase {

  public function query() {
    return $this->select('pages', 'p')
      ->fields('p', ['uid', 'title', 'slug', 'abstract', 'doktype', 'crdate', 'tstamp'])
      ->condition('p.deleted', 0)
      ->condition('p.hidden', 0)
      ->condition('p.doktype', [1, 4], 'IN');
  }

  public function fields() {
    return [
      'uid' => $this->t('Page ID'),
      'title' => $this->t('Page title'),
      'slug' => $this->t('URL slug'),
      'abstract' => $this->t('Abstract/summary'),
    ];
  }

  public function getIds() {
    return ['uid' => ['type' => 'integer']];
  }

  public function prepareRow(Row $row) {
    // 加载关联的内容元素
    $pid = $row->getSourceProperty('uid');
    $content = $this->select('tt_content', 'tt')
      ->fields('tt')
      ->condition('tt.pid', $pid)
      ->condition('tt.deleted', 0)
      ->orderBy('tt.sorting')
      ->execute()
      ->fetchAll();
    $row->setSourceProperty('content_elements', $content);
    return parent::prepareRow($row);
  }
}

我喜欢这个方法。它是关于拥有完全控制权,让你在你的代码库中处理TYPO3的特殊性(如软删除和工作区覆盖)。

方法2:通过JSON或XML导出/导入

有些团队选择将TYPO3内容导出为结构化格式(比如通过自定义TYPO3扩展或CLI命令),然后将其导入到Drupal中。当然,这增加了一层,但当你对在迁移过程中维护直接数据库连接感到担忧时,它会派上用场。

方法3:混合与手动审查

有一个更小的网站(少于500页)?将结构化数据迁移自动执行,同时手工制作关键登陆页面可以很好地工作。这看起来可能很基础,但当内容与TYPO3特定的渲染逻辑交织时,自动化迁移通常会产生胡言乱语。

处理TYPO3 TypoScript与扩展

TypoScript

让我们直言不讳:TypoScript不会迁移。它是一种TYPO3特定的配置语言,在其他地方没有真正的对应物。你的工作是用外行术语记录每个TypoScript模板的用途,然后将其重建为Twig模板和Drupal配置。这很痛苦但必要。

扩展

这是常见TYPO3扩展及其Drupal对应物的便捷比较:

TYPO3扩展 Drupal等价物
news 核心内容类型+视图
powermail Webform模块
solr (ext:solr) 搜索API+Solr
realurl / routing Pathauto+核心路由
gridelements 布局构建器或段落
mask 段落
tt_address 自定义内容类型或CiviCRM
ke_search 搜索API
femanager 用户模块+自定义
cal/events 自定义内容类型+视图

自定义Extbase扩展需要改写为Drupal模块。没有捷径——确保为其预算。

URL结构与SEO保留

搞砸这个,你会失去有机流量。我见过组织在迁移后由于处理不当的重定向而失去了高达40%的搜索流量。

步骤

  1. **从TYPO3导出所有URL。**使用CLI工具或爬虫获取每个索引URL。
  2. **将这些映射到Drupal URL。**使用Drupal的Pathauto生成URL别名,尽可能贴近现有URL。
  3. **为所有改变的内容创建重定向。**在Drupal中部署重定向模块。对于大量重定向,通过CSV导入。
  4. **处理语言前缀。**TYPO3使用/de//en//fr/——确保Drupal的语言设置反映这一点。
  5. 立即向Google Search Console提交更新的站点地图。
# Drupal重定向模块的重定向导入CSV格式示例
source,redirect,status_code,language
/alte-seite,/new-page,301,de
/old-page/subpage,/new-page/subpage,301,en
/kontakt,/contact,301,de

专业提示:在迁移后最少保持旧TYPO3实例在线(尽管只读),保持三个月。你会发现遗漏的URL。

迁移后走向无头架构

Drupal在走向解耦前端的道路上闪闪发光。有了Drupal 11,JSON:API模块坚如磐石,无头Drupal生态系统蓬勃发展。

如果你正在考虑无头方法——而在2026年,对于大多数内容驱动的网站,这值得考虑——我们在/solutions/headless-cms-development上深入讨论过这个。

将流行的前端与Drupal配对:

首先迁移到Drupal的好处是使用Drupal的默认Twig前端启动。稍后,你可以切换到解耦的。不要同时尝试两个迁移——那是在要求项目混乱。

时间表、成本与人员估算

来自我参与过的项目或有准确数据的项目的真实数字(近年):

网站大小 页面 时间表 预算范围 团队
<500页 2-3个月 $30,000-60,000 2-3名开发者
500-5,000页 4-6个月 $60,000-150,000 3-5名开发者
5,000-50,000页 6-12个月 $150,000-400,000 5-8名开发者
企业 50,000+页 12-18个月 $400,000-1,000,000+ 8-15名开发者

这些包括从发现、内容建模、迁移、前端主题设计、QA和编辑培训的所有内容。持续维护不包括在内。

最大的成本因素不仅仅是页面数量——它是复杂性。一个有30个自定义内容类型和4种语言的2,000页网站成本将高于一个简单的10,000页网站。

考虑你的具体情况的细节?查看/pricing直接联系

迁移后检查清单

不要跳过这个清单。相信我。

  • 验证所有重定向。确保它们是301。
  • 用你的新站点地图更新Google Search Console。
  • 测试所有表单:联系、新闻通讯、登录。
  • 确保每种语言的多语言内容准确性。
  • 准确迁移媒体文件,带有替代文本和元数据。
  • 检查每个角色的编辑权限。
  • 捕获性能指标(Core Web Vitals)。
  • 验证分析跟踪(GA4事件、目标)。
  • 配置并测试CDN/缓存。
  • 启用安全标头(CSP、HSTS)。
  • 测试备份和灾难恢复系统。
  • 完成编辑培训并提供文档。
  • 保持旧TYPO3实例处于只读模式可用。

常见问题

TYPO3到Drupal的迁移通常需要多长时间?
对于中等规模的网站(500-5,000页),从开始到启动大约需要4-6个月。第一个月?纯发现和内容建模。迁移脚本通常需要6-8周的工作。QA和编辑培训?再算上一个月。如果这是一个复杂的多语言、多站点设置,带有自定义扩展,你正在看9-12个月。

我可以自动迁移TYPO3内容,或者需要手动操作?
像页面、新闻记录或类别这样的结构化内容?绝对可以使用Drupal的迁移API自动完成。但TYPO3的复杂渲染逻辑内容可能需要一些手动护理。大多数迁移?大约70-80%自动,20-30%手动。

在迁移期间我会失去Google排名吗?
不会,如果你对重定向很小心。为任何URL更改设置301,尽可能坚持你的URL结构,立即提交更新的站点地图。你可能会看到下降,比如2-6周。但反弹是典型的——网站通常在4-8周内反弹回迁移前水平,三个月后经常看到由于更好性能而改进。

对于内容编辑来说,Drupal比TYPO3更难学吗?
不同,不是更难。那些习惯TYPO3页面树模型的人可能需要时间来适应Drupal的实体中心方法。段落模块确实提供了某种类似的内容构建体验。记住为编辑预算大约2-3天的培训,并为他们提供内容类型和工作流特定的文档。

迁移期间我的TYPO3扩展会发生什么?
每个扩展都值得个别评估。许多有直接的Drupal等价物(例如,powermail→Webform、ext:news→自定义内容类型+视图、ext:solr→搜索API+Solr)。自定义Extbase扩展?它们需要作为Drupal模块进行完全重写。没有转换器——你需要定制。

迁移TYPO3到Drupal时我应该走无头路线吗?
这取决于你的目标和时间表。如果你的迁移是由开发者或可维护性问题驱动的,从简单的Drupal Twig主题开始,稍后目标是无头。但如果你的前端团队热爱React或类似的设置,并且渴望现代交付架构,考虑从一开始就规划无头。只记住:同时进行两个迁移和前端变化?那是高风险领地。

我如何在迁移中处理多语言内容?
TYPO3的语言设置(sys_language_uid、l10n_parent)与Drupal的内容翻译模块很好地对齐。诀窍?在你的脚本中钉住语言到语言的映射,并确保回退匹配你的期望。谨慎对待部分翻译的内容——TYPO3的语言覆盖模式(自由、连接、严格)没有精确的Drupal对应物。对不完整翻译的编辑决定可能是必要的。

从TYPO3迁移到Drupal的ROI是什么?
ROI在哪里?主要来自削减开发支出和加快功能推出速度。从历史上看,我指导的团队在第一年看到了大约20-40%的开发成本削减,主要是由于更容易的人才招聘和拥有更大的模块池,减少了定制开发的需求。初始迁移成本可能很高,但大多数应该在18-24个月内收支平衡。