全新网站的分步指南 作者图片 | 来自 WordPress 和 GitHub 的标志
我在 2010 年开始了我的第一个博客。当时使用 WordPress 是显而易见的。这是一个不错的选择,因为它易于使用并且拥有数以千计的主题和插件。WordPress 是一个了不起的引擎,但它也有缺点。它对资源要求很高,并且存在许多与 WordPress 相关的漏洞。一种可能的解决方案是 将整个站点置于 CloudFront 或任何其他 CDN 之后。CDN 可以很好地扩展并保持站点安全,但就我而言,博客只是一个存档,我不想让我的服务器保持运行。这就是我选择 GitHub Pages的原因。
GitHub Pages 是“穷人的托管解决方案”。它是免费的,您可以将您的域指向它。缺点是它只能托管静态站点,所以我不得不从我的 WordPress 博客生成一个静态站点。
幸运的是,WordPress 可以将整个站点的内容导出(管理员上的工具/导出)到一个 XML 文件中,所以我只需要开发一个简单的静态站点生成器来生成导出的内容。我选择 TypeScript 进行开发是因为我熟悉它,并且有许多很酷且易于使用的 JS 库可以做到这一点。
首先,我必须找到一个简单易用的 XML 解析器。经过简短的 Google 搜索后,我找到了 fast-xml-parser。该解析器从易于处理的 XML 中创建 JS 对象树。
我需要的另一件事是一个简单的模板引擎。为此, ejs 是最好的。它易于学习,因为您可以将 JS 嵌入到 HTML 代码中,而且速度也很快,因为引擎会在后台将您的模板编译为 JS。对于小型项目,我想不出更简单更好的解决方案。
我拥有我需要的一切,所以我开发了我的小型静态站点生成器。
为了创建 ejs 模板,我下载了 WordPress 生成的 HTML 文件并向其中添加了 ejs 标签。我创建了两个模板。一个用于帖子,另一个用于目录。
导出 XML 的结构非常简单。它是一个从项目构建的 RSS 提要。每个项目都有一个类型(帖子、附件等),但我只需要帖子和附件。代码如下所示:
(async function () { const parser = new XMLParser(); let wp_export = parser.parse(readFileSync('wordpress-export.xml')); let posts = wp_export.rss.channel.item; let pinned_posts: any[] = [] let post_list: any[] = [] for (const post of posts) { // download attachments if (post['wp:post_type'] == 'attachment') { const url = post['wp:attachment_url']; for (const post_meta of post['wp:postmeta']) { if (post_meta['wp:meta_key'] == '_wp_attached_file') { const file_path = post_meta['wp:meta_value'] const full_path = `wp-content/uploads/${file_path}` mkdirSync(dirname(full_path), { recursive: true }); const file = createWriteStream(full_path); http.get(url, (resp) => { resp.pipe(file); file.on("finish", () => { file.close(); }); }) } } } // generate post page if it's published if (post['wp:post_type'] == 'post' && post['pubDate']) { post['content:encoded'] = post['content:encoded'].split(/\r?\n|\r|\n/g).reduce((accumulator: string, currentValue: string) => accumulator + `<p>${currentValue}</p>`) const content = await ejs.renderFile("template.ejs", { post: post }, { async: true }) mkdirSync(`archives/${post['wp:post_id']}`, { recursive: true }); writeFileSync(`archives/${post['wp:post_id']}/index.html`, content) const element = { id: post['wp:post_id'], title: post.title, summary: truncate(post['content:encoded'].replace(/<[^>]*>?/gm, ''), 300) } if (pinned_post_ids.includes(post['wp:post_id'])) { pinned_posts.push(element) } else { post_list.push(element) } } } // generate toc pinned_posts.sort((a, b) => { return b.id - a.id }) let merged_posts = pinned_posts.concat(post_list.sort((a, b) => { return b.id - a.id })) // readme.md let readme = `# my-wordpress-blogThis is a backup of my WordPress blog. (http://lf.estontorise.hu/)` for (const post of merged_posts) readme += `[${post.title}](https://thebojda.github.io/my-wordpress-blog/archives/${post.id})\n\n` writeFileSync('README.md', readme) // index.html const content = await ejs.renderFile("template_toc.ejs", { posts: merged_posts }, { async: true }) writeFileSync(`index.html`, content)})()
代码迭代项目并检查它们的类型。如果类型是“附件”,它会读取 _wp_attached_file
包含附件 URL 的元数据的值,并使用 HTTP 模块下载它。
如果项目类型为“post”并且已发布(pubDate
不为空),则生成页面。页面内容 content:encoded
在 HTML 格式的标签中,稍作改动。每行都是一个单独的段落,因此您必须将换行符转换为段落。以下代码行执行此操作:
post['content:encoded'] = post['content:encoded'] .split(/\r?\n|\r|\n/g) .reduce((accumulator: string, currentValue: string) => accumulator + `<p>${currentValue}</p>`)
十年前,当我开始写博客时,我对 SEO 一无所知,所以帖子链接如下所示:…/archives/123,其中最后一个数字是帖子 ID。在更好的情况下,帖子 URL 更具表现力并包含关键字,但在这两种情况下,您都会面临 GitHub Pages 不支持没有“.html”扩展名的 HTML 页面的问题。
如果您上传没有扩展名的 HTML 文件,浏览器将下载它而不是显示它。因此,您必须将这些 URL 转换为包含 index.htm
l 文件的目录。例如,/archives/123 必须转换为 /archives/123/index.html。有了这个新结构,一切都像魅力一样。
代码的最后一个块生成 ToC HTML 和一个 readme.md
文件。如果有人在 GitHub 上找到您的页面,第二个将非常有用,因为他们可以轻松导航到您的帖子。
静态页面生成完成后,我将网站上传到 GitHub 并在设置中启用了 GitHub Pages。
在我的 DNS 提供商的管理员上设置 CNAME 记录后,GitHub 对其进行了检查。通过选中 Enforce HTTPS 复选框,GitHub 生成了一个 HTTPS 证书,片刻之后,网站就准备好了。您可以在这里查看结果: https://lf.estontorise.hu。 该博客是匈牙利语的,因此您可能看不懂内容,但您可以看到一切正常,并且 URL 与 WordPress 的 URL 相同。
正如我所写,这个博客只是一个存档,我不打算创建新帖子,但如果我愿意,我可以在我的本地机器上安装我的 WordPress 引擎,写新帖子,并更新新生成的页面回购。所以如果你想用 WordPress 写博客,用 GitHub 托管页面,也是可以的。
这是我从 WordPress 到 GitHub Pages 的短暂旅程。如果您愿意,我希望这篇简短的文章可以帮助您迁移您的博客。
(您可以在我的 GitHub 存储库中找到所有内容。)