WordpressからPicoへデータ移行

投稿日:2019-01-17

まず、事前にpicoのブログ化が完了しているものとします
CMSのpicoをブログ化

かなりの力技です
綺麗な方法ではないのでご了承ください

Wordpressからのイメージ取得

まずWordpressから画像ファイル一式をダウンロードしてきます。
Wordpressの/wp-content/uploads/配下のファイルを
全てpico内にダウンロードしてきます。

今回の例ではpico直下にimagesディレクトリを作成し、
そこにダウンロードするとします。
階層としてはpico/images/2019/01/hogehoge.pngのようになります。

Wordpressからの記事取得

WordpressのDBから記事情報を取得します。

MySQL Workbenchにて以下のSQLを実行し、
結果をjsonで出力しておきます

SELECT p.ID, p.post_date, u.user_nicename, p.post_title, p.post_content, t.tags
FROM wp_posts p
LEFT JOIN wp_users u ON u.ID = p.post_author
LEFT JOIN (
    SELECT tr.object_id AS post_id, group_concat(t.name) AS tags
    FROM wp_term_relationships tr
    LEFT JOIN wp_term_taxonomy tt ON tt.term_taxonomy_id = tr.term_taxonomy_id
    LEFT JOIN wp_terms t ON t.term_id = tt.term_id
    WHERE tt.taxonomy = 'post_tag'
    GROUP BY tr.object_id
) t ON t.post_id = p.ID
WHERE post_status = 'publish';

次に出力したjsonからpico用の記事mdファイルを生成します
以下のようなPHPスクリプトを実行すれば取得したJSONファイルから
mdファイルを生成できます

<?php
// 出力したjsonは「tmp_insert.json」だとします
$jsonStr = file_get_contents('./tmp_insert.json');
$json = json_decode($jsonStr);

foreach ($json as $post) {
    // Descriptionはページの本文から先頭を切り出す
    $description = strip_tags($post->post_content);
    $description = str_replace("\n", '', $description);
    $description = mb_substr($description, 0, 64);
    $description .= '...';

    // 画像ファイルのパスを修正
    $body = str_replace('https://your-wp-site.com/wp-content/uploads/', '/images/', $post->post_content);
    // 記事へのパスを修正
    $body = str_replace('https://your-wp-site.com/?p=', '/articles/', $body);
    // Markdownなので行末にスペース2つが入るようにする
    $body = str_replace(["\r\n", "\r", "\n"], '  '.PHP_EOL, $body);

    $content = <<< EOF
---
Title: $post->post_title
Description: $description
Tags: $post->tags
Author: $post->user_nicename
Date: $post->post_date
Template: article
---
$body
EOF;
    file_put_contents($post->ID.'.md', $content);
}

あとは必要に応じて生成されたmdファイルを微調整するだけです。
また、pico/content/tags配下にWordpressにて利用していたタグを追加してください。

※補足

環境によってはmdファイル内に記載しているとエラーとなってしまうHTMLタグがあるようです。
エラーとなったHTMLタグは削除するかMarkdown記法に置換しておきましょう。

Wordpress時のURLからpicoのURLにリダイレクトする

最後にWordpress時の記事URLを新URLにリダイレクトさせれば完了です。
(必須ではないですが、Google検索などから旧記事へ来てしまう人のため)

Apacheの場合は以下のようになります。
設定ファイルかhtaccessに記載してください。

<IfModule mod_rewrite.c>
    RewriteEngine On

    # 旧ブログからのリダイレクト
    RewriteCond %{QUERY_STRING} p=([0-9]*)$
    RewriteRule .* /articles/%1? [R=301,L]
</IfModule>

Nginxの場合は設定ファイルに以下を記載します。

if ($args ~ "p=(.*)") {
    set $articleId $1;
    rewrite ^.*$ /articles/wp/$articleId? permanent;
}

これでhttps://your-site.com/?p=1234へアクセスがあると
https://your-site.com/articles/1234へリダイレクトしてくれます。
記事の階層を変える場合は適宜読み替えてください。

関連する記事