全新网站的分步指南 作者图片 | 来自 WordPress 和 GitHub 的标志

我在 2010 年开始写我的第一个博客。当时很明显使用 WordPress这是一个不错的选择,因为它易于使用并且拥有数以千计的设计主题和插件。 WordPress 是一个了不起的引擎,但它也有缺点。 它对资源要求很高,并且有许多与 WordPress 相关的漏洞。 一个可能的解决方案是将整个站点放在 CloudFront 上 或任何之后其他 CDN。 CDN 可以很好地扩展并确保站点安全,但在我的情况下,博客只是一个存档,我不想让我的服务器保持运行。 这是我选择的GitHub Pages原因。

GitHub Pages 是一个“穷人的托管解决方案”。 它是免费的,您可以将您的域指向它。 缺点是它只能托管静态站点,所以我不得不从我的 WordPress 博客生成一个静态站点。

幸运的是,WordPress 可以对齐整个站点导出(管理员上的工具/导出)到一个 XML 文件中,所以我只需要开发一个简单的静态站点生成器来生成导出的内容。 我选择 TypeScript 进行开发是因为我熟悉它,并且有许多很酷且易于使用的 JS 库可以执行此操作。

首先,我必须找到一个简单的-使用 XML 解析器。 经过简短的谷歌搜索,我发现了fast-xml-parser这个解析器从可操作的 XML 创建一个 JS 对象树。

我需要的另一件事是一个简单的模板引擎。 为此,ejs 是最好的。 它很容易学习,因为您可以将 JS 嵌入到您的 HTML 代码中,而且速度很快,因为引擎会在幕后将您的模板编译为 JS。 对于小型项目,我想不出更简单更好的解决方案。

我有我需要的一切,所以我开发了我的小型静态站点生成器。

为了创建 ejs 模板,我下载了 WordPress生成的 HTML 文件中添加了 ejs 标签。 我创建了两个模板。 一个用于帖子,一个用于目录。

导出的XML结构非常简单. 它是从该项目构建的 RSS 提要。 每个项目都有一个类型(帖子、附件等),但我只需要帖子和附件。 代码如下:

(async function () { const parser =新的 XMLParser(); 让 wp_export = parser.parse(readFileSync('wordpress-export.xml')); 让 posts = wp_export.rss.channel.item; 让 pinned_posts: any[] = [] 让 post_list: any[] = [] for (const post of posts) { // 下载附件 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(); }); }) } } } // 如果已发布则生成帖子页面 if (post['wp:post_type'] == 'post' && post['pubDate'] ) { post['content:encoded'] = post['content:encoded'].split(/?||/g).reduce((accumulator: string, currentValue: string) => accumulator + `

${currentValue}

`) 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) } } } // 生成 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) 自述文件 += `[${post.title}](https://thebojda.github.io/my-wordpress-blog /archives /${post.id})` writeFileSync('README.md', readme) // index.html const content = await ejs.renderFile("template_toc.ejs", { posts: merged_posts }, { async: true }) writeFileSync(`index.html`, content)})()

代码迭代项目和检查他们的类型。 如果类型是“attachment”,它将显示为_wp_attached_file 包含附件 URL 的元数据值并使用 HTTP 模块下载它。

如果项目类型是“post”并且有发布(pubDate 不为空),然后生成页面。 页面内容content:encoded 在 HTML 格式标签中,稍作改动。 每一行都是一个单独的段落,因此您必须将换行符转换为段落。 以下代码行执行此操作:

post['content:encoded' ] = post['content:encoded'].split(/?||/g) .reduce((accumulator: string, currentValue: string) => 累加器 + `

${currentValue}

`)

当我十年前开始写博客时,我对 SEO 一无所知,所以帖子链接看起来像这样:…/archives/ 123,其中最后一个数字是帖子 ID。 在更好的情况下,帖子 URL 更具表现力并且包含关键字,但在这两种情况下,你都会面临 GitHub Pages 不支持 HTML 页面不支持的问题“.html”扩展名。

如果您上传没有扩展名的 HTML 文件,浏览器将下载它而不是显示它。 因此,您必须转换这些 URL 以包含 index.html 文件的目录。 例如,/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 引擎,写新帖子,并更新新生成的页面 repo。 因此,如果您想使用 WordPress 写博客并使用 GitHub 托管您的页面,那也很好。

这是我从 WordPress 到 GitHub Pages 的方式短途旅行。 如果您喜欢,希望这篇简短的文章对您的博客迁移有所帮助。

(你可以在我的 GitHub 存储库 查找所有内容。)