まえがき
WordPressで運用していたこのページですが、夏休みの自由研究ということで、この度Hugoを利用して再構築することにしました。
理由としては、
- WordPressは重いから
- WordPressの更新が面倒だから
あたりでしょうか。
Hugoで生成すると、全部のページが単なるHTMLになるので、重いという問題はなくなります。 また、WordPressの更新に悩まされることもなくなります。
一方で、
- ページをビルドしないといけない
- ビルド結果をサイトにアップしないといけない
といったあたりは手間が増えることになります。
移行概要
自分で管理しているVPSにWordPressを入れていたので、WordPressのプラグインではなく、データベース(MySQL)から直接データを取得して、全部の投稿を1つずつのファイルにすることにします。
また、URLについては、WordPressの設定により、
/archives/%post_id%
となっており、これはそのまま活かすよう、記事IDをファイル名にすることにします。 記事数もそこそこあるので、記事は年ごとのディレクトリを作って、その中に入れるようにします。
今後作成する記事については記事ID=YYYYMMDDとすればいいのかな、例えば
2026/20260722.md
みたいな感じに。
Copilotが書いてくれた移行ツールの仕様は以下のような感じ。
データ移行ツール仕様
方針
- URLは維持する
- HTML本文は維持する
- 画像URLは維持する
- WordPressの記事IDをファイル名に利用する
- コメントは無視する
入力・出力
WordPress の MySQL データベースを直接参照する。
利用するテーブルは以下の通り。
wp_postswp_termswp_term_taxonomywp_term_relationships
各記事は以下のファイルに出力する。
content/posts/YYYY/ID.md
例:
content/posts/2025/799.md
投稿日の年ごとにディレクトリを分ける。
content/posts/
├── 2004/
├── 2005/
├── ...
├── 2024/
├── 2025/
└── 2026/
ファイル名には、WordPressの記事IDをそのまま利用する。
799.md
800.md
801.md
対象記事
以下の条件を満たす記事のみ変換対象とする。
post_type = 'post'
post_status = 'publish'
Front Matter
出力例:
---
title: "Ubuntu24.04でSkinny.phpが警告を出すことへの対処"
date: 2025-02-26 00:00:00
categories:
- "コンピュータ"
---
対応表:
| Hugo | WordPress |
|---|---|
| title | post_title |
| date | post_date |
| categories | category taxonomy |
本文の変換
本文は Markdown へ変換しない。
基本的に WordPress の HTML をそのまま出力する。
Gutenberg コメントのみ削除する。
例:
<!-- wp:paragraph -->
<!-- /wp:paragraph -->
<!-- wp:code -->
<!-- /wp:code -->
以下のような HTML はそのまま保持する。
<p>本文</p>
<pre><code>...</code></pre>
...
<a href="...">
画像 URL は変更しない。
記事内の
```html
<img srcss/wp-content/uploads/...
はそのまま出力する。
画像ファイルは後で
static/wp-content/uploads
へコピーすることにする。
移行ツール
上記の仕様を元に生成したソースコードは以下の通り。
#!/usr/bin/env perl
use strict;
use warnings;
use utf8;
use DBI;
use File::Path qw(make_path);
use POSIX qw(strftime);
my $dbh = DBI->connect(
'DBI:mysql:database=DBNAME;host=localhost',
'USER',
'PASS',
{
RaiseError => 1,
mysql_enable_utf8mb4 => 1,
}
);
my $posts = $dbh->prepare(q{
SELECT
ID,
post_title,
post_content,
post_date
FROM wp_posts
WHERE post_type = 'post'
AND post_status = 'publish'
ORDER BY ID
});
$posts->execute();
while (my $post = $posts->fetchrow_hashref) {
my $id = $post->{ID};
my $title = $post->{post_title};
my $content = $post->{post_content};
my $date = $post->{post_date};
my ($year) = $date =~ /^(\d{4})/;
#
# Gutenbergコメント除去
#
$content =~ s/<!--\s*wp:[^>]*-->//g;
$content =~ s/<!--\s*\/wp:[^>]*-->//g;
#
# カテゴリ取得
#
my $cats = $dbh->selectcol_arrayref(q{
SELECT t.name
FROM wp_terms t
JOIN wp_term_taxonomy tt
ON tt.term_id = t.term_id
JOIN wp_term_relationships tr
ON tr.term_taxonomy_id = tt.term_taxonomy_id
WHERE tr.object_id = ?
AND tt.taxonomy = 'category'
ORDER BY t.name
}, undef, $id);
my $dir = "content/posts/$year";
make_path($dir);
my $file = "$dir/$id.md";
open(my $fh, '>:encoding(UTF-8)', $file)
or die "$file: $!";
print $fh "---\n";
print $fh qq(title: "$title"\n);
print $fh "date: $date\n";
if (@$cats) {
print $fh "categories:\n";
for my $cat (@$cats) {
print $fh qq( - "$cat"\n);
}
}
print $fh "---\n\n";
print $fh $content;
print $fh "\n";
close $fh;
print "wrote $file\n";
}
$dbh->disconnect;
WSL2でのビルドが遅い件
Windowsのデスクトップ上にファイルを並べて、WSL2からhugoを実行してみると、200弱の記事をビルドするのに27秒ほどかかりました。しかし、timeを測定したところ、実際にはほとんど待ち時間のようです。
Start building sites …
hugo v0.154.5+extended linux/amd64 BuildDate=2026-01-13T19:59:22Z VendorInfo=ubuntu:0.154.5-1
│ JA
──────────────────┼─────
Pages │ 278
Paginator pages │ 70
Non-page files │ 0
Static files │ 184
Processed images │ 0
Aliases │ 13
Cleaned │ 0
Total in 27718 ms
real 0m27.833s
user 0m1.395s
sys 0m2.702s
そこで、これはWSL2からWindowsのNTFSにアクセスするのが遅いのだろうと思い、Windows版のHugoコマンドをダウンロードしてWindows側でHugoを実行することにしました。
Start building sites …
hugo v0.164.0-ce2470e7012b5ab5fc4e10ebe4027e9f8d9e00dc windows/amd64 BuildDate=2026-07-06T16:39:30Z VendorInfo=gohugoio
WARN deprecated: .Language.LanguageDirection was deprecated in Hugo v0.158.0 and will be removed in a future release. Use .Language.Direction instead.
WARN deprecated: .Language.LanguageCode was deprecated in Hugo v0.158.0 and will be removed in a future release. Use .Language.Locale instead.
│ JA
──────────────────┼─────
Pages │ 278
Paginator pages │ 70
Non-page files │ 0
Static files │ 184
Processed images │ 0
Aliases │ 13
Cleaned │ 0
Total in 580 ms
27秒かかっていたものが0.6秒となりました。これで快適にビルドできますね。
ページの配置
サーバへページを配置するために、WSL2上でrsyncを使うことにしました。
これもWindowsネイティブのものの方が速いのでしょうけど、そこまで遅くもなかったので良しとします。