仕事でやる必要があって調べたのでメモ。
移行先のWordPressが、カスタムポストタイプやACFを使ってたんで、ちょっと面倒くさかった。
大まかな流れ
自前CMSのデータから、WordPressインポートツールのWordPressのXMLを作成して、データ移行することにした。
ACFを使ってるWordPressサイトをXMLに書き出して中を見てみるとわかるけど、ACFはフィールドごとにfield_5671e74fc8c5eみたいな識別子が振られてるみたいで、WordPressのXMLを作る際にこれが必要。
なので、段取りは以下のとおり。
- 移行先のWordPressで、カスタムポストタイプやカスタムフィールドの設定をする。
- 移行先のWordPressで、カスタムフィールドの値もちゃんと入力した、サンプルデータを登録する。
- 移行先のWordPressで、XMLエキスポートする。その中身を見て、カスタムポストタイプやカスタムフィールドの識別子を確認する。
- 移行元の自前CMSのデータを、WordPressインポートツール用のXMLに変換する。画像は、URLでアクセスできるようにしとく。
- 移行先のWordPressで、作ったXMLをインポートする。
WordPressインポートツール用のXML
大まかな構造
XMLの大まかな構造は以下のとおり。
author、category、termは、そのまんまWordPressのユーザー、カテゴリー、タームに対応してる。
itemは、記事、ページだけじゃなくて、画像、ACFのカスタムフィールドとかもitemの中に入ってる。
各記事に登録したカスタムフィールドの値は、postmetaに入ってる。
author、category、term、itemには、それぞれIDがふられてて、親子関係とか、itemに定義された画像の指定とかに使われる。
ちなみに、 authorは、無くてもインポートできるっぽい。
画像
画像は、itemとして登録される。
画像のURLは、attachment_urlという名前の子要素として定義する。
記事を表すitemを親要素として登録しておけば、その記事に関連付けた画像として、ちゃんとインポートされる。
画像のカスタムフィールドには、itemに定義された画像のIDが入る。
カスタムフィールドのデータ
カスタムフィールドのデータは、postmetaに入ってるんだけど、例えば「year」って名前のテキストフィールドがあるときは、こんな感じ。
<wp:postmeta>
<wp:meta_key><![CDATA[year]]></wp:meta_key>
<wp:meta_value><![CDATA[2015]]></wp:meta_value>
</wp:postmeta>
<wp:postmeta>
<wp:meta_key><![CDATA[_year]]></wp:meta_key>
<wp:meta_value><![CDATA[field_5670f2bfd2c5a]]></wp:meta_value>
</wp:postmeta>
インポート用のXMLを作るためには、yearとfield_5670f2bfd2c5aを知っとかないといけない。
繰り返しフィールド
例えば、imagesって繰り返しフィールドがあって、その中にimageって画像と、captionってテキストフィールドが複数ある場合、下のようなpostmetaになる。
3行目の2は、定義された要素数が入ってるっぽい。
<wp:postmeta>
<wp:meta_key><![CDATA[images]]></wp:meta_key>
<wp:meta_value><![CDATA[2]]></wp:meta_value>
</wp:postmeta>
<wp:postmeta>
<wp:meta_key><![CDATA[_images]]></wp:meta_key>
<wp:meta_value><![CDATA[field_5670f0d3391f8]]></wp:meta_value>
</wp:postmeta>
<!-- 一つ目の画像 -->
<wp:postmeta>
<wp:meta_key><![CDATA[images_0_image]]></wp:meta_key>
<wp:meta_value><![CDATA[10]]></wp:meta_value>
</wp:postmeta>
<wp:postmeta>
<wp:meta_key><![CDATA[_images_0_image]]></wp:meta_key>
<wp:meta_value><![CDATA[field_5670f2bad2c5a]]></wp:meta_value>
</wp:postmeta>
<wp:postmeta>
<wp:meta_key><![CDATA[images_0_caption]]></wp:meta_key>
<wp:meta_value><![CDATA[Image 1]]></wp:meta_value>
</wp:postmeta>
<wp:postmeta>
<wp:meta_key><![CDATA[_images_0_caption]]></wp:meta_key>
<wp:meta_value><![CDATA[field_5670f2bfr2c5a]]></wp:meta_value>
</wp:postmeta>
<!-- 二つ目の画像 -->
<wp:postmeta>
<wp:meta_key><![CDATA[images_1_image]]></wp:meta_key>
<wp:meta_value><![CDATA[11]]></wp:meta_value>
</wp:postmeta>
<wp:postmeta>
<wp:meta_key><![CDATA[_images_1_image]]></wp:meta_key>
<wp:meta_value><![CDATA[field_5670f2bad2c5a]]></wp:meta_value>
</wp:postmeta>
<wp:postmeta>
<wp:meta_key><![CDATA[images_1_caption]]></wp:meta_key>
<wp:meta_value><![CDATA[Image 2]]></wp:meta_value>
</wp:postmeta>
<wp:postmeta>
<wp:meta_key><![CDATA[_images_1_caption]]></wp:meta_key>
<wp:meta_value><![CDATA[field_5670f2bfr2c5a]]></wp:meta_value>
</wp:postmeta>
生成したXMLがうまくインポートされない時には
インポート処理は、WordPress インポートツールプラグインのコードを見ればわかる。
2ファイルしかないんで、XMLを試行錯誤してがんばるよりも、WordPress インポートツールプラグインのコードにデバッグコード入れて試した方が速いと思う。
ちなみに、インポート処理は、大まかに以下の流れみたい。
- XMLをパースして、
authors、category・term、itemに分ける。 - それぞれインポート
-
itemの親子関係(記事と画像の関連付けなど)などを関連付ける
itemは(多分、categoryとかも)、IDを見て同じものをインポートしないように制御してるんで、ちゃんとIDを一意にふっとかないと、何故かインポートされんなぁ、ってことになる。(はまった。)
Python用のWordPress XML生成ライブラリ
仕事用に作ったPythonスクリプトをGitHubにあげてるんで、使えそうだったら使ってください。
日付周りの処理にarrowを使ってるんで、これだけpip install arrowで入れてください。
examples/my_wordpress.pyが、実際にXMLを生成するPythonスクリプトの例になってます。
なお、categoryやtermは、実際に使わなかったんで、試してないです。
自己責任でご利用お願いします。
