核心思路
整个过程可以概括为三个核心步骤:

(图片来源网络,侵删)
- 数据清洗与标准化:将 DedeCMS 中可能存在的“脏”数据或不规范数据,整理成一套标准、干净、易于现代系统读取的数据。
- 模板现代化改造:将原有的、基于表格和固定宽度的旧模板,改造为使用现代前端框架(如 Bootstrap, Tailwind CSS, Vue/React 等)的响应式模板。
- 数据迁移与渲染:将清洗好的数据,通过后端程序(如 PHP)动态地填充到新的自适应模板中,并确保在各种设备上都能正确显示。
第一步:数据清洗与标准化 (后端准备)
在导入数据之前,千万不要直接用 DedeCMS 自带的导入导出功能,DedeCMS 的数据结构比较混乱,字段冗余,且数据格式可能不规范。
导出原始数据
- 登录你的 DedeCMS 后台。
- 进入“系统” -> “数据库备份/还原”。
- 选择“数据备份”,勾选你需要迁移的核心数据表,主要是:
dede_archives(文章主表,包含文章ID、标题、作者、来源、发布时间等)dede_addonarticle(文章附加表,包含文章内容)dede_arctype(文章栏目表)dede_admin(管理员表,如果需要迁移用户)dede_category(栏目分类表,和arctype类似)- 执行备份,你会得到一个
.sql文件。
数据清洗与转换
- 工具:使用 Navicat、phpMyAdmin 或 MySQL Workbench 等数据库管理工具。
- 操作:
- 创建新数据库:在你的新网站环境中(可能是 Laravel, ThinkPHP, 或者一个全新的 PHP 项目),创建一个新的数据库。
- 设计新表结构:根据现代开发的规范,重新设计数据表,将
archives和addonarticle合并为一个articles表,使用 JSON 或单独的字段来存储标签、缩略图等信息。 - 编写转换脚本 (强烈推荐):这是最关键的一步,写一个 PHP 脚本,连接到 DedeCMS 的旧数据库,读取数据,进行处理,然后插入到新数据库中。
转换脚本示例 (伪代码/思路):

(图片来源网络,侵删)
// 1. 连接旧 DedeCMS 数据库
$oldDb = new PDO('mysql:host=localhost;dbname=dede_old;charset=utf8mb4', 'user', 'pass');
// 2. 连接新数据库
$newDb = new PDO('mysql:host=localhost;dbname=new_website;charset=utf8mb4', 'user', 'pass');
// 3. 查询旧文章数据
$query = $oldDb->query("SELECT a.*, b.body FROM dede_archives a LEFT JOIN dede_addonarticle b ON a.id = b.aid ORDER BY a.id DESC");
$articles = $query->fetchAll(PDO::FETCH_ASSOC);
foreach ($articles as $article) {
// 4. 数据清洗与处理
$title = htmlspecialchars(trim($article['title']));
$content = $this->cleanDedeContent($article['body']); // 自定义函数,处理 DedeCMS 的特殊标签和图片路径
$pubTime = date('Y-m-d H:i:s', $article['pubdate']);
$keywords = $article['keywords'];
$description = mb_substr(strip_tags($content), 0, 150, 'utf-8'); // 从内容中提取摘要
// 5. 插入到新数据库
$stmt = $newDb->prepare("INSERT INTO articles (title, content, keywords, description, published_at) VALUES (?, ?, ?, ?, ?)");
$stmt->execute([$title, $content, $keywords, $description, $pubTime]);
}
echo "数据导入完成!";
// 处理 DedeCMS 内容的函数
function cleanDedeContent($content) {
// 移除 DedeCMS 的特殊标签,如 {dede:pagebreak/}
$content = preg_replace('/\{dede:pagebreak\/\}/i', '', $content);
// 修正相对路径的图片链接
$content = preg_replace('/\<img\s+src=\"(\/uploads\/.*?)\"/i', '<img src="https://your-new-domain.com/$1"', $content);
// 其他清理逻辑...
return $content;
}
关键处理点:
- 内容字段:DedeCMS 的内容里充满了
{dede:xxx}这样的模板标签,必须全部清除。 - 图片路径:旧站点的图片路径是相对的(如
/uploads/...),在新站点上需要修正为绝对路径(https://your-new-domain.com/uploads/...)。 - HTML 格式可能包含过时的 HTML 标签(如
<font>,<center>),使用Tidy扩展或正则表达式进行清理。 - 字符编码:确保所有数据都转换为
UTF-8编码,避免乱码。
第二步:模板现代化改造 (前端核心)
这是实现“自适应”的核心,抛弃所有基于表格 (<table>) 的布局,拥抱现代 CSS 框架。
选择前端框架
- Bootstrap: 最成熟、文档最全、组件最丰富的选择,非常适合快速开发。
- Tailwind CSS: 更加原子化,能让你从零开始构建高度自定义的设计,灵活性极高。
- Element Plus / Ant Design Vue: 如果你使用 Vue 或 React,这些是基于组件库的框架,效率更高。
我们以 Bootstrap 5 为例,因为它对新手友好且功能强大。

(图片来源网络,侵删)
创建基础布局文件
创建一个 master.blade.php (如果你使用 Laravel) 或 layout.php (通用 PHP) 文件,作为所有页面的基础框架。
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">@yield('title', '我的新网站')</title>
<!-- Bootstrap 5 CSS -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
<!-- 自定义 CSS -->
@stack('styles')
</head>
<body>
<!-- 导航栏 -->
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
<div class="container">
<a class="navbar-brand" href="/">我的新网站</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarNav">
<ul class="navbar-nav ms-auto">
<!-- 这里可以通过 PHP 动态生成栏目列表 -->
<li class="nav-item"><a class="nav-link" href="/">首页</a></li>
<li class="nav-item"><a class="nav-link" href="/about">lt;/a></li>
</ul>
</div>
</div>
</nav>
<!-- 主要内容区域 -->
<main class="container my-5">
@yield('content')
</main>
<!-- 页脚 -->
<footer class="bg-dark text-white text-center p-3">
<p>© <?php echo date('Y'); ?> 我的新网站. All rights reserved.</p>
</footer>
<!-- Bootstrap 5 JS Bundle with Popper -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
<!-- 自定义 JS -->
@stack('scripts')
</body>
</html>
创建文章列表页模板 (articles.index.php)
这个页面用于展示文章列表。
@extends('layout') <!-- 继承基础布局 -->
@section('title', '文章列表 - 我的新网站')
@section('content')
<div class="row">
<!-- 左侧主要内容区 -->
<div class="col-lg-8">
<h1>最新文章</h1>
<hr>
<?php if (!empty($articles)): ?>
<?php foreach ($articles as $article): ?>
<div class="card mb-4">
<div class="card-body">
<h2 class="card-title">
<a href="/articles/<?php echo $article['id']; ?>" class="text-decoration-none">
<?php echo $article['title']; ?>
</a>
</h2>
<p class="card-text text-muted">
<small>发布于:<?php echo $article['published_at']; ?></small> |
<small>作者:<?php echo $article['author']; ?></small>
</p>
<p class="card-text">
<?php echo $article['description']; ?>
</p>
<a href="/articles/<?php echo $article['id']; ?>" class="btn btn-primary">阅读更多 →</a>
</div>
</div>
<?php endforeach; ?>
<?php else: ?>
<p>暂无文章。</p>
<?php endif; ?>
<!-- 分页 -->
<?php echo $articles->links(); ?> <!-- 如果你使用 Laravel Eloquent 分页 -->
</div>
<!-- 右侧边栏 -->
<div class="col-lg-4">
<?php include 'partials/sidebar.php'; ?> <!-- 包含侧边栏组件 -->
</div>
</div>
@endsection
创建文章详情页模板 (articles.show.php)
这个页面用于展示单篇文章。
@extends('layout')
@section('title', $article['title'] . ' - 我的新网站')
@section('content')
<article class="mb-5">
<h1><?php echo $article['title']; ?></h1>
<p class="lead text-muted">
发布于:<?php echo $article['published_at']; ?> | 作者:<?php echo $article['author']; ?>
</p>
<hr>
<!-- 使用 XSS 防护,输出处理好的 HTML 内容 -->
<div class="article-content">
<?php echo $article['content']; ?>
</div>
</article>
@endsection
响应式设计的关键
- 栅格系统:Bootstrap 的
container,row,col-*类是实现响应式的基石。col-lg-8在大屏幕上占 8/12 列,在小屏幕上会自动堆叠。 - 图片自适应:给所有
<img>标签添加img-fluid类,<img src="..." class="img-fluid" alt="...">,这样图片就会自动缩放,不会超出容器。 - 导航栏:使用
navbar-expand-lg这样的类,控制导航栏在什么屏幕尺寸下从汉堡菜单展开为全宽导航。
第三步:数据迁移与渲染 (后端整合)
你需要将第一步处理好的数据和第二步做好的模板连接起来。
后端路由
- 列表页路由:
GET /articles-> 调用一个控制器方法,从数据库获取文章列表,并渲染articles.index.php模板。 - 详情页路由:
GET /articles/{id}-> 调用一个控制器方法,根据 ID 从数据库获取单篇文章,并渲染articles.show.php模板。
控制器逻辑 (PHP 伪代码)
// ArticleController.php
class ArticleController {
public function index() {
// 从数据库获取文章列表,每页10条
$articles = Article::orderBy('published_at', 'desc')->paginate(10);
// 将数据传递给视图
return view('articles.index', ['articles' => $articles]);
}
public function show($id) {
// 根据 ID 查找文章
$article = Article::findOrFail($id);
// 将数据传递给视图
return view('articles.show', ['article' => $article]);
}
}
总结与最佳实践
- 不要直接迁移模板:DedeCMS 的模板是“紧耦合”的,无法直接适配,必须重新设计前端。
- 数据是核心:花足够的时间在数据清洗和标准化上,这会让你后续的开发事半功倍,避免无穷无尽的 Bug。
- 拥抱现代工具链:使用 Composer (PHP), npm/yarn (前端) 等现代工具来管理你的项目依赖。
- 分阶段上线:如果网站内容很多,可以先迁移一部分内容(比如最新的 100 篇文章)进行测试,确认无误后再全量迁移。
- 设置 301 重定向:为了 SEO 和用户体验,务必在服务器上配置将旧 DedeCMS 的 URL (如
/plus/view.php?aid=123) 301 重定向到新网站的 URL (如/articles/123),这可以传递大部分的权重。
通过以上三个步骤,你就可以成功地将 DedeCMS 的数据导入到一个功能强大、外观现代、完全自适应的新模板中了,这个过程虽然繁琐,但结果是非常值得的。
