如何将我的 WordPress 站点迁移到 GitHub 页面 – 迷途通

如何将我的 WordPress 站点迁移到 GitHub 页面

6月 1, 2023                      👁️ 25
如何将我的 WordPress 站点迁移到 GitHub 页面

我在 2010 年开始了我的第一个博客。当时使用WordPress是显而易见的(那是在HackerNoon和Medium之前)。这是一个不错的选择,因为它易于使用,并且有数以千计的主题和插件。

WordPress 是一个了不起的引擎,但它也有其缺点。它需要资源,并且存在许多与WordPress相关的漏洞。一种可能的解决方案是将整个站点置于 CloudFront 或任何其他 CDN 后面。

CDN 可以很好地扩展并确保站点安全,但就我而言,博客只是一个存档,我不想让我的服务器保持运行。这就是我选择 GitHub Pages 的原因。

GitHub Pages 是“穷人的托管解决方案”。它是免费的,您可以将您的域指向它。

它的缺点是它只能托管静态站点,所以我不得不从我的 WordPress 博客生成一个静态站点。

幸运的是,WordPress 可以将整个站点的内容导出(管理员上的工具/导出)到 XML 文件中,所以我唯一要做的就是开发一个简单的静态站点生成器,从导出中生成内容。

我选择TypeScript进行开发,因为我熟悉它,并且有很多很酷且易于使用的JS库可以做到这一点。

首先,我必须找到一个简单易用的 XML 解析器。经过短暂的谷歌搜索,我找到了一个快速的xml解析器。此解析器从 XML 创建一个可以轻松处理的 JS 对象树。

我需要的另一件事是一个简单的模板引擎。为此,ejs 是最好的。它很容易学习,因为你可以简单地将你的 JS 嵌入到 HTML 代码中,而且速度也很快,因为在后台,引擎会把你的模板编译成 JS。

对于小型项目,我无法想象一个更简单、更好的解决方案。

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

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

导出 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-blog
This 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)
})()

该代码循环访问项并检查其类型。如果类型为“attachment”,则它将读取包含附件 URL 的“_wp_attached_file”元数据的值,并使用 HTTP 模块下载它。

如果项目类型为“post”,并且已发布(pubDate 不为空),则生成页面。页面内容位于 HTML 格式的“content:encoded”标签中,略有变化。

每一行都是一个单独的段落,因此您必须将换行符转换为段落。这是通过以下代码行完成的:

post['content:encoded'] = 
  post['content:encoded']
  .split(/\r?\n|\r|\n/g)
  .reduce((accumulator: string, currentValue: string) => 
    accumulator + `<p>${currentValue}</p>`)

10 年前,当我开始写博客时,我对 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对其进行了检查。通过选中“强制执行 HTTPS”复选框,GitHub 生成了一个 HTTPS 证书,过了一会儿,站点就准备好了。在这里您可以观看结果:https://lf.estontorise.hu。

该博客是匈牙利语的,所以你可能不会理解内容,但你可以看到一切正常,URL与WordPress URL相同。

正如我所说,这个博客只是一个存档,我不打算创建新帖子,但如果我愿意,我可以将我的 WordPress 引擎安装到我的本地机器上。

我可以写新的帖子并更新存储库中新生成的页面,所以如果你想使用 WordPress 写博客和 GitHub 托管页面,这也是可能的。

这是我从 WordPress 到 GitHub Pages 的短暂旅程;我希望这篇简短的文章可以帮助你迁移自己的博客,如果你愿意的话。

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

发表回复

您的电子邮箱地址不会被公开。