WordPress

この投稿は2年半前の記事です。 情報が古くなっている可能性があるので、その点ご了承ください。
2014 年 12 月 6 日 931日前)
4,086文字 (読了時間10分)

SPONSORED LINK

WordPressには記事のインポートおよびエクスポートの機能があります。WordPress同士の場合はWordPress Importerというツールがあるので、これを使うのですが、いわゆる引越しやドメイン変更の場合などによく使われますね。

この手順についてはたくさんあるのですが、困るのが「サイトAとサイトBをマージしたい」という場合です。

たとえば、このサイトが高橋文樹.comだったとして、高橋文樹ニュースというサイトをやっていたとしましょう。

で、アクセスが少ないので、ニュースサイトを閉じましょうということになります。とはいえ、もったいないので、ニュースサイトの方の投稿のうち、「告知」と「メディア掲載情報」だけを高橋文樹.comのカスタム投稿タイプnewsにして、インポートしたいとかそういうことですね。

この場合、気をつけなくてはいけないのは以下の点です。

  • すべての投稿タイプが必要とは限らず、いるものといらないものがある
  • なんらかのカスタマイズを施しており、添付画像の投稿IDなどがカスタムフィールドに保存されている

ようするに、インポートするときにいろいろとカスタマイズしたいことがあるよね、というわけです。

WordPress ImporterのXMLをカスタマイズ

もしかしたらプラグインでそういうのがあるのかもしれませんが、WordPress Importerの吐き出すXMLをちょっとカスタマイズするだけでなんとかなったりするので、その方法を説明します。

PHPスクリプトを用意

変換はPHPスクリプトで行います。まず、converter.phpというファイルを用意して、ターミナルから php converter.phpj [元のファイルパス] [出力ファイルパス] とか入力することで、求めるXMLを取得します。

このファイルの中身はこんな感じです。

<?php
try{

     // 引数のチェック
     if( count($argv) < 3){
          throw new Exception(’Too few arguments.', 404);
     }
     $file = $argv[1];
     if( !file_exists($file) ){
          throw new Exception('XML File not found.', 404);
     }
     $new_file = $argv[2];

     // XMLの読み込み
     $xml = simplexml_load_file($file);

     // インデックス
     $index++;
     // 削除すべきノードのインデックスを保存
     $node_to_delete = array();
     foreach( $xml->channel->item as $item ){
          /** @var SimpleXMLElement $item */
          // Do Stuff!
          echo '.’; // 終わったよという意味でピリオドを出力
          $index++;
     }

     // 新しいXMLを保存
     if( !$xml->saveXML($new_file) ){
          throw new Exception(‘Sorry, but failed to save XML.’, 500);
     }

     // 名前空間が付いてしまうので、削除。
     // ※ やり方がよくわからなかった。
     file_put_contents($new_file, str_replace(' xmlns:wp="wp"', '', file_get_contents($new_file)));

     // 終わったよというメッセージを表示
     echo PHP_EOL.sprintf('Saved as %s', $new_file).PHP_EOL;
}catch ( Exception $e ){
     // 例外が発生したらメッセージ表示
     echo sprintf('[Error %s] %s', $e->getCode(), $e->getMessage()).PHP_EOL;
}
exit;

上記のコードのうち、”Do Stuff!”とかいてあるところで投稿を表現するXMLノード$itemに対して操作を行えばいいんですね。

具体的に何が必要かはケースバイケースなので、ありがちな操作を書いておきます。

投稿タイプを取得&変更

これは簡単です。postとpageおよびattachment(添付ファイル)以外の投稿タイプはいらないから削除し、ページを投稿にするケースを考えます。

// 投稿タイプの取得
$post_type = (string) $item->children('wp', true)->post_type;
if( ‘page’ == $post_type ){
    // 投稿タイプがpageだったら、投稿タイプを変更
    $item->children('wp', true)->post_type = 'post';
}elseif( false === array_search($post_type, array(‘post’, ‘attachment')) ){
     // 投稿タイプがattachmentおよびpostではなかったら削除キューに追加
     array_unshift($node_to_delete, $index);
}

ポイントとしては、SimpleXMLが名前空間の扱いで謎の挙動を見せるということでしょうか。

あと、要素の削除はunsetなのですが、 foreach内でやってしまうと、次のノードの取得に影響が出ます。イテレータ実装だからでしょう。

したがって、削除すべきノードの番号を一旦配列に保存しておいて、あとから削除します。番号を大きい順に保存したのは、削除によって対象ノードが変わってしまうからです。

foreach( $node_to_delete as $index){
     // 削除
     unset($xml->channel->item[$index]);
}

ここら辺、もっとうまいやり方がありそうですが、とりあえずこんな感じで。

カスタムフィールドを追加

カスタムフィールドを追加するケースを考えてみましょう。今回は以前あった投稿IDをカスタムフィールドに保存しておくようにします。

// 投稿IDを取得
$post_id = (int) $item->children('wp', true)->post_id;
// カスタムフィールド用のノードを追加
$pm = $item->addChild('wp:postmeta', '', 'wp');
$pm->addChild('wp:meta_key', '_old_post_id', 'wp');
$pm->addChild('wp:meta_value', $post_id, 'wp');

これで以前の投稿IDが_old_post_idとして保存されました。

こうして保存しておけば、上述した「添付ファイルのIDがカスタムフィールドでひも付けられている」というようなケースでも問題ないでしょう。

ちなみに、アイキャッチはカスタムフィールドに添付ファイルのIDが保存される仕組みだったと思いますが、その部分をWordPress Importerがケアしているのかどうかはよく知りません。知っている人はコメントください。

まとめ

というわけで、インポートする際にある程度事前処理をしておけば楽になります。移行後にバッチ処理を走らせる場合も、事前にカスタムフィールドなどでフラグを立てておけば楽になるでしょう。ポイントは……

  • データの削除はちょっと面倒。更新と追加は割と簡単。
  • とりあえずインポート元のデータは全部エクスポートしてしまい、それから加工すると楽。
  • 添付画像の登録処理と紐付けは自分で作ると結構めんどくさいので、このツールに任せましょう。

はじめに紹介した例の他に、大人の事情でサーバ管理者と入稿者とWordPress開発者が分断されている場合、入稿の準備ができてるのにサーバの準備ができませんなどという面倒くさい事情も考えられます。そういうとき、便利ですね。終わり。

いちばんやさしいWordPressの教本 人気講師が教える本格Webサイトの作り方 第2版 WordPress 4.x対応 (「いちばんやさしい教本」シリーズ)

いちばんやさしいWordPressの教本 人気講師が教える本格Webサイトの作り方 第2版 WordPress 4.x対応 (「いちばんやさしい教本」シリーズ) [書籍]

著者石川 栄和, 大串 肇, 星野 邦敏

出版社インプレス

出版日2014 年 11 月 14 日

商品カテゴリー単行本(ソフトカバー)

ページ数256

ISBN4844337092

Supported by amazon Product Advertising API

 

フォローしてください

ここで会ったのもなにかの縁。
高橋文樹.comの最新情報を見逃さないためにもフォローをお願いします。
めったに送らないメルマガもあります。

SPONSORED LINK

この記事について

この記事はが2014 年 12 月 6 日にプログラミングの記事として公開しました。

高橋先生の電子書籍

高橋先生の電子書籍

Amazonで電子書籍も買えます。

好きな言葉

なにもしなかったということは、悪いことをしなかったということではない

— マルクス・アウレリス・アントニヌス

高橋先生の処女作

『途中下車』高橋文樹

2001年幻冬舎NET学生文学大賞受賞作です。

Web制作やります

Web制作やります

Web制作のご依頼は株式会社破滅派へ

不定期メルマガ

高橋文樹.comでは、不定期でニュースレターを配信しています。滅多に送らないので是非購読してください。

高橋文樹.comではプライバシーポリシーに準じて登録情報を取り扱います。