Как я перенес свой сайт WordPress на страницы GitHub
6 января 2023 г.Я начал свой первый блог в 2010 году. Использование WordPress было очевидным в то время (это было до HackerNoon и Medium). Это был хороший выбор, потому что он прост в использовании и для него существуют тысячи тем и плагинов.
WordPress — отличный движок, но у него есть свои недостатки. Он требователен к ресурсам, и существует множество уязвимостей, связанных с WordPress. Одним из возможных решений является размещение всего сайта за CloudFront. или любой другой CDN.
CDN хорошо масштабируется и обеспечивает безопасность сайта, но в моем случае блог был только архивом, и я не хотел, чтобы мой сервер работал. Именно поэтому я выбрал страницы GitHub.
GitHub Pages — это «хостинг для бедных». Это бесплатно, и вы можете указать на него свой домен.
Недостатком этого является то, что он может размещать только статические сайты, поэтому мне пришлось создать статический сайт из моего блога WordPress.
К счастью, WordPress может экспортировать (Инструменты/Экспорт в админке) весь контент сайта в файл XML, поэтому единственное, что мне нужно было сделать, это разработать простой генератор статического сайта, который генерирует контент из экспорта.
Я выбираю TypeScript для разработки, потому что я знаком с ним, и для этого есть много классных и простых в использовании JS-библиотек.
Прежде всего, мне нужно было найти простой и удобный XML-парсер. После непродолжительного поиска в Google я нашел fast-xml-parser. Этот синтаксический анализатор создает дерево объектов JS из XML, которое можно легко обрабатывать.
Еще одна вещь, которая мне была нужна, — это простой механизм шаблонов. Для этой цели лучше всего подходит ejs. Его легко освоить, потому что вы можете просто встроить свой JS в код HTML, а также быстро, потому что в фоновом режиме движок компилирует ваш шаблон в JS.
Для небольших проектов я не могу представить себе более простое и лучшее решение.
У меня было все, что мне нужно, поэтому я начал разрабатывать свой небольшой генератор статических сайтов.
Чтобы создать шаблоны ejs, я просто загрузил HTML-файлы, созданные WordPress, и добавил к ним теги 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})nn`
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.
Если тип элемента «публикация» и он опубликован (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>`)
10 лет назад, когда я начинал свой блог, я ничего не знал о SEO, поэтому ссылки на посты выглядели так: …/archives/123, где последняя цифра — это идентификатор поста.
В лучшем случае URL поста будет более выразительным и содержит ключевые слова, но в обоих случаях вы столкнетесь с проблемой, что GitHub Pages не поддерживает HTML-страницы без расширения «.html».
Если вы загрузите файл HTML без расширения, браузер загрузит файл, а не покажет его. По этой причине вам необходимо преобразовать эти URL-адреса в каталоги, содержащие файл index.html.
Например, /archives/123 необходимо преобразовать в /archives/123/index.html. С этой новой структурой все работает как часы.
Последний блок кода генерирует ToC HTML и файл readme.md. Второй может быть очень полезен, если кто-то найдет вашу страницу на GitHub, потому что он может легко перейти к вашим сообщениям.
Когда создание статической страницы завершено, я просто загрузил свой сайт на GitHub и включил страницы GitHub в настройках.
После того, как я установил запись CNAME для администратора моего провайдера DNS, GitHub проверил ее. Установив флажок Enforce HTTPS, GitHub сгенерировал HTTPS-сертификат, и через некоторое время сайт был готов. Здесь вы можете посмотреть результат: https://lf.estontorise.hu.
Блог на венгерском языке, поэтому вы, вероятно, не поймете содержание, но вы можете видеть, что все работает хорошо, а URL-адреса совпадают с URL-адресами WordPress.
Как я уже сказал, этот блог — всего лишь архив, и я не планирую создавать новые записи, но если бы я хотел, я мог бы установить свой движок WordPress на свой локальный компьютер.
Я мог бы писать новые сообщения и обновлять только что созданные страницы в репозитории, поэтому, если вы хотите использовать WordPress для ведения блога и GitHub для размещения страниц, это также возможно.
Это был мой короткий путь от WordPress до GitHub Pages; Я надеюсь, что эта короткая статья поможет вам перенести свой собственный блог, если вы хотите.
(Вы можете найти все в моем репозитории GitHub.)
Оригинал