もっとスマートな方法があると思います。これは何故かCSVでインポートできない人のための力技です
現状の自分の条件
- CSVでデータ移行しようとすると想定外の箇所で区切られてタイトルと日付がくっつくような謎なデータ異常が起きる
- entryがだいたい700件ぐらい、ページが1000弱ぐらい
- freoのデータはMySQLで作成している(一応SQLiteでもできると思う)
freoからWordPressに変更する理由
- PHP8に正式対応していない
- 対応したとしてもかなり自分の好き勝手に弄り倒しているので今更修正や書き換えが対応できる気がしない
- 自分のレンタルしているサーバーがPHP8に対応した
変更後の想定
- 今までentryで行っていたブログはWordPressでは通常の投稿で行う
- 今までpageで行っていた小説や同人誌一覧などはカスタム投稿タイプを使用して行う
現状の行った流れ
※かなり自己流+ちから技がエグいので、できる人は自力でどうにかできないか試したほうが良いです
そのままデータをぶち込むのは失敗した際がとてもとても怖いので、LocalでローカルのWordPressを作成し、こちらで移行データを全部作成してからAll-in-One WP Migrationのプラグインでデータを一括移行し、その後はサーバー上のデータで使用することにする。
freoからCSVでデータを出力する
SQLite使用している場合は、(みさきるさんの記事)[https://3d-arts.misanyan.com/5449]を見てSQLからCSVでデータ出力をする。
MySQLを使用している場合はphpMyAdminからデータを取り出す。

まずはentryから作業する。
出力するのは下記
- freo_entries
- freo_categories
- freo_category_sets
CSVで出力したものをgoogleドライブ経由でgoogleスプレッドシートで開く
ある人はExcelでもなんでも好きにしてくれ。わたしはExcel非所持なのでgoogleスプレッドシートで開いた。
freo_entriesを開いたらファイル>インポート>googleドライブ内のファイル指定する際にCSVを選ぶ→インポート場所で「新しいシートに挿入」でfreo_categoriesとfreo_category_setsを追加で挿入する
entryにcategoryを紐づける
スプレッドシートのVLOOKUPを使用して、freo_categoriesのカテゴリー名(name)をfreo_category_setsの横に表示させる。
2つ3つあるものはなんかいい感じに結合させる。
自分の場合は、if(上の行とentry_idが同じ,上の行のカテゴリー名&”,“&この行のカテゴリー名,この行のカテゴリー名)でまとめた。
その上で全選択して範囲の並び替え→キーをentry_idの行A→Zと上記if文でカテゴリー名を結合させた行Z→Aにする。
更にデータ>データクリーンアップ>重複の削除で必要そうなのだけ残った。
その上で、freo_entriesのidを使ってVLOOKUPでカテゴリ名を取得して横に表示させておく
entryから必要そうな列だけ残していらないのは削除する
自分の場合は下記だけ残した
- datetime
- status
- title
- text
- 無理矢理ねじ込んだカテゴリー名
データをxml用に整形する
この手間がなければCSVで全部ぶっこめたんだよ。
スプレッドシートでいい感じに整形する。
最終的には下記の形にしたい。titleやcontentなどは順不同。
<item><title><![CDATA[★ここにタイトル★]]></title><content><![CDATA[★ここに本文★]]></content><date><![CDATA[★ここに日付★]]></date><status><![CDATA[★ここに公開状況★]]></status><category><![CDATA[★ここにカテゴリ★]]></category></item>列と列の間に1列追加し、ちまちまと <item>★★★<title><![CDATA などと打ち込んでいく。
この★★★は後で出力してから改行にするためのもので、自分がブログで使わなそうな文字列だったら何でも良し。
出来上がったCSVデータをエクスポートで出力する。
元がCSVデータなのでいらん箇所に,や”がついてるので一括置換で削除する。(<title><![CDATA[,みたいなカラム区切りのための,や、文章を囲むための<content><![CDATA[,"ブログ記事の,や”など。だいたいついてる場所が決まってるので一括置換でどうにでもなる)
★★★を改行に変更する。(正規表現で\r\nあたりと取り替える)
<!-- pagebreak -->を<!-- more -->にする
リンクなどの<a href="hogehoge.com">が全部<a href=""hogehoge.com"">(CSVなのでダブルクオーテーションが2個になる)になっているので”に修正
頭と尻にxml用の<?xml version="1.0" encoding="UTF-8"?><wpiedata>と</wpiedata>を挿入する。
<item><title><![CDATA[ブログ記事のタイトル]]></title><content><![CDATA[ブログ記事の内容<br><p>という形にどうにかしているわけですが、</p>途中で改行があっても大丈夫。]]></content><date><![CDATA[2020/01/01 01:01:01]]></date><status><![CDATA[publish]]></status><category><![CDATA[Blog,Memo]]></category></item>最後にファイルを.csvから.xmlに変更する。
wordpressにデータを入れる
Import any XML or CSV File to WordPressを使う。これはXMLも取り込める優れもの。
先程作成してごちゃごちゃ手を加えたxmlを取り込ませる。新しいアイテム、投稿にする。
表示されるitemの数が自分が作成したデータ数と同じなことを確認する。違う場合はデータ作成時にどっかミスってると思うので再チェック。
自分の場合はタクソノミー、カテゴリ、タグで以下のようにしている。

これでデータが取り込める。カテゴリーは事前に作っておかなくとも無いのはいい感じに取り込んでくれる(ただしスラッグとかそこらへんは死んでる)。
お疲れ様でした、力技でentryは取り込めました。
次はページ
pageの作業
主に小説、それから同人誌に使用していたpageの移行作業。
基本的にはentryと同じだけれども少しだけ違う箇所がある。
また、私は小説ページのみの取り込みとした。
理由としては、同人誌詳細ページはオプション使いまくって作ってるのでオプションの移行が死ぬほどだるいこと、また表紙用の画像が10年前に作成したものはサイズがちっちゃいので大きく作り直したいことがある。
30件弱ならまあ手作業でなんとかなるだろ。
データの出力
entryと同じ方法でデータをCSVで出力する。
何度もいうけれどもCSVで取り込める場合はCSV取り込んだ方がいい、絶対良い。
出力データはページ格納テーブルfreo_pages。
やる気があるならオプション格納テーブルとオプション関連付けテーブルも引っ張ってきてどうにすれば良いのかもしれないが、このあたりは手作業でするからいいかと諦めた。
いらないものの削除
ここで問題が起きた。
私の場合は文字数がめちゃくちゃに多かったのでcassava editorで開くのも困難になり、googleスプレッドシートに移動したのものそれでもめちゃくちゃ重たかった。
とはいっても全体のデータ量で見ると21Mぐらいなので、複数セルに文字がわけられているのではなく、ひとつのセル(本文部分)に大量に文字が入ってるのが悪かったんだろう。多い小説では7万字ぐらいぶち込んである。
開いたら、本体のテーブル構成を見て必要なものだけ残していく。
私が残したのは下記
- id
- pid
- status
- title
- datetime
- text
小説の表示にfreoのページ一括表示プラグインを使用していた。
ジャンル1├カプA│├小説│├小説│└小説├カプB(略)ジャンル2(略)こんな感じに複数のジャンルとカプを使用していたので、そのあたりの変換に便利かなとpidを残した(めっちゃ使った)
pid(親ID)を利用してタームを入れられるようにする
まずはpidをどうにかする。
Import any XML or CSV File to WordPressは入力時にタクソノミーの指定もできる。
小説はWordPressではカスタム投稿タイプを使用すると決めていた。そのため、タクソノミーを事前に作成して紐づけておく(ターム自体はまだ作ってない)。
その上で、親IDを利用してタクソノミーのタームに流し込めるようにする。タームとかタクソノミーとか正直書きながら合ってるか?って不安だから違ったら脳内変換掛けて……
ジャンル1(genre1)├カプA(genre1/cpA)│├小説(genre1/001)│├小説(genre1/002)│└小説(genre1/003)├カプB(genre1/cpB)(略)ジャンル2(genre2)(略)ここから手作業。できる人はどうにか自動化してほしい。
CSVファイルを上から見ていって、pidのセルに入っているのがgenre1/cpAだったらジャンル1>CP1となるように一括置換をかけていく。
同じようにgenre1/cpBだったらジャンル1>CP2になるようにと上から作業していく。
ついでに本文が空のもの(私の場合は上記の場合genre1やgenre1/cpAなどは一括表示プラグインでずらっと表示させる分類のために使用しており、本文は何も入っていない)は行ごと削除する。
更にはidにnovelが入っていないもの(小説以外のもの)は全部削除する。
xmlに必要なものをつける。
上記と同じく囲んでいく。
このあたりで別にidとかauthoridとか何でもいいな?取り込むときには同じもので囲んでいるかしか見てないな?と気付いたので、手を抜いてかなり汚いかたちにねじ込んだ。
<item><id><![CDATA[★ここにid★]]></id><authorid><![CDATA[★ここにpid★]]></authorid><date><![CDATA[★ここにdatetime★]]></date><status><![CDATA[★ここにstatus★]]></status><title><![CDATA[★ここにtitle★]]></title><content><![CDATA[★ここに本文★]]></content></item>CSV整形
entryと同じく出力してから,だの”だのを削除。
WordPressにデータをいれる
できたものをImport any XML or CSV File to WordPressを使用して流し込む。

これのうち、「投稿sがある階層」のほうを選択(画像撮り忘れたので使いまわし)。
下階層のみの設定をした。これで後からタクソノミー.phpあたりで一括表示させるときにやりやすい。
それ以外はだいたいentryと同じ。
だいたいエラーが発生するので修正
本来あるはずのデータ数と取り込むはずのデータ数がずれてたら、表示できる最後のデータを見て、その近辺のデータ見てどこがおかしいのか確認する。閉じ忘れ、古いTwitterの表示にCDATAを使用していたなどいろいろあるので根気よく対応していく。
気が向いたら画像も取り込んで出来上がり
画像はWordPressだと保存場所が違うのでもう諦めろ。どうにか自力で手修正して出来上がり!!!
何度も書くけれども、これは何故かCSVで取り込めない人のための面倒くさい方法です。CSVで取り込めるならそのほうが絶対楽です。
私の場合は何故かデータ内容,データ内容でも"データ内容","データ内容"でも区切りが認識されない箇所があったため、わざわざxmlに一度変更する羽目になりました。でもやらんでいいならそのほうが絶対良い。
文字コード変更も駄目、""ではなく’に変更も全部駄目、CSV取り込みプラグインを変更しても駄目、何を消せば入力できるのかと確認したら『2』を消したときだとか『更』があると駄目とかでも別の行だとOKだとかわけわからんのでいちいち原因抽出するのが手間すぎてやめました。
こんな特殊な状態の人ほとんどいなくて普通にCSVで移行できるんだろうけれども、誰かの役にたったなら幸い。