仕事でやる必要があって調べたのでメモ。
移行先の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
は、実際に使わなかったんで、試してないです。
自己責任でご利用お願いします。