NILTO

技術 2024-10-04

WordPress から書き込み API を利用してデータ移行した話

shintani

WordPressから書き込みAPIを利用してNILTOにデータ移行した話

こんにちは。NILTO のウェブエンジニア真谷(シンガイ)です。

フェンリルのとあるプロダクトで WordPress を利用をしており、そのデータを NILTO に移行する対応を考えていました。その際書き込み API (β)Media 書き込みAPI(β)がリリースされたので、これを活用して実施をしました。

前提

今回は小規模な内容、且つ利用している機能は大まかにタイトル・記事・サムネイル・タグ・カスタムフィールドとシンプルな WordPress から NILTO への移行です。

WordPress 内の XML や CSV +メディアのエクスポートをするプラグイン等を経由しての書き込み API の利用を考えていましたが、元々 WP REST API 経由でのデータ操作をしていたのもあり、WP REST API でコンテンツ取得をし、データを加工しながら書き込み API を利用して NILTO に移行をしています。

移行対象のモデルとフィールドセット

WordPress からの移行後のモデルに関しては、下記の図のようになります。

WordPress からデータを移すにあたり、重要な要素であるカスタムフィールドに関してはフィールドセットを用意しました。

2024/10/04 時点ではまだフレキシブルテキストへの書き込みはまだできません。
それにあたり「旧WPのエディター」という複数行テキストフィールドを用意をしており、データ移行の際はこのフィールドに書き込みをします。
データ移行後の運用に関しては、「記事」のフレキシブルテキストを更新していく想定です。

※フレキシブルテキストへの書き込みAPIは今後リリース予定です。

繰り返しフィールドの中にキーは1行テキストフィールド、に関しては WordPress のカスタムフィールドの値は改行コミのデータを入れる事が可能なので、複数行テキストフィールドを入れています。

実装例

今回試した NILTO の書き込み API の利用の実装例を記載します。
コードは TypeScript ベースで、実行環境は Nodejs になっています。

WP REST API で移行するコンテンツデータを取得

// WP API用のパラメータの型定義
interface Params {
post_type?: string
parent?: number
meta_key?: string
meta_value?: string
orderby?: string
order?: string
per_page?: number
posts_per_page?: number
slug?: string
}

// 情報取得用パラメータ
const wp_api_params: Params = {
parent: xxxx,
meta_key: '_wp_page_template',
meta_value: 'page-xxxx.php',
orderby: 'date',
order: 'desc',
per_page: 30
}

const wp_api_url = 'https://example.com/wp-json/wp/v2/pages?'
const response = await fetch(wp_api_url + new URLSearchParams(wp_api_params).toString())
const data = await response.json() // ← このデータを利用する

今回の例だとまず特定の親 ID のある固定ページ一覧を取得をし、そのレスポンスを加工をしながら書き込み API に渡します。

NILTO の書き込み API へ POST

// 書き込み API 用
interface CustomField {
key: string
value: string
}

interface CustomFields {
repeat: CustomField[]
}

interface Content {
title: string
slug: string
bg_thmb: number
old_editor: string
tag_list: number[]
custom_fields: CustomFields //カスタムフィールド
}

interface PostData {
fields: Content
}

interface UploadImage {
id: number
}

// 書き込み API に送信
for (let key in data) {
const content = data[key]
let post_data = { fields: {} } as PostData
post_data.fields.title = content.title //タイトル
post_data.fields.slug = content.slug //スラッグ
post_data.fields.old_editor = content.content //WordPress の移行記事

// サムネイル用の画像 URL からメディアをダウンロード後にメディア書き込み API 経由でアップロード。
// アップロードしたメディアの ID を付与する
const thumb = (await push_img(content.thumbnail.url, api_key)) as UploadImage
post_data.fields.bg_thmb = thumb.id

//カスタムフィールド
post_data.fields.custom_fields = {} as CustomFields
post_data.fields.custom_fields.repeat = []
for (let key in content.custom_fields) {
post_data.fields.custom_fields.repeat.push({ key: key, value: content.custom_fields[key] })
}

// 該当する名前と同じタグの ID を付与。タグ自体は事前登録済。
post_data.fields.tag_list = []
for (let key in content.tags) {
const find_tags = tags.data.find((data) => data._title === content.tags[key].name)
if (find_tags) {
post_data.fields.tag_list.push({ tag: find_tags._id })
}
}

await axios.post('https://cms-api.nilto.com/v1/contents?model=xxxxxx', post_data, {
headers: {
'content-type': 'application/json',
'X-Nilto-Api-Key': api_key
}
})
}

WP REST API で受け取ったレスポンスから、書き込み API 用に加工をしながら POST します。
サムネイルのフィールドには事前にメディア書き込み API に向けて画像のアップロード後、レスポンスで返ってきたメディア ID を指定します。
タグに関しては繰り返しフィールド、カスタムフィールドに関してはフィールドセット内に繰り返しフィールドを置いているのでそれぞれ該当フィールド用に適応します。

書き込み API に送るデータ

{
fields: {
title: 'タイトル1',
slug: 'article1',
old_editor: '<div>sample</div>',
bg_thmb: 1234567890,
tag_list: [
{ tag: 0123456789 },
{ tag: 1123456789 },
{ tag: 2123456789 }
],
custom_fields: {
repeat: [
{ key: 'key1', value:'val1' },
{ key: 'key2', value:'val2' },
{ key: 'key3', value:'val3' }
]
}
}
}

実際の1件あたりの書き込み API に POST するデータは上記のようになります。

書き込み API に POST 後は、対象のモデルに下書き状態で追加され、下書きから公開に関しては個別に行います。

おわりに

元々個人的に WP REST API を利用していたのもあり、WordPress からエクスポートされた XML や CSV を利用するよりも直観的にデータ移行ができました。
WordPress から NILTO への移行の参考になればと思います。

ご意見・ご要望がありましたら、NILTOのお問い合わせページまたは公式X(旧Twitter)からお気軽にご連絡ください。これからもNILTOをよろしくお願いいたします。

shintani

エンジニア/Engineer

バックエンド→フロントエンド→インフラと様々な技術を経験し、「インフラレベルから考える」ウェブサイトを構築します。
目指せ全てのフェンリルウェブサイトの pagespeed insights 100点。