サポート » 使い方全般 » インポートすると同じ名前のカテゴリが増殖する

  • ワードプレス2.5.1で運営しているブログの記事をエクスポートし、

    別のワードプレス2.5.1で運営しているブログへインポートしたところ、

    エクスポートした側のブログで、スラッグを設定していたカテゴリのみ、
    同じカテゴリ名で、二つずつのカテゴリがインポートされました。

    増殖した二つのカテゴリは、カテゴリ名こそ同じですが、
    カテゴリスラッグは違っていました。

    具体的には、

    一つは
    カテゴリスラッグが、自分で設定していた内容(エクスポートした側のブログ)で、
    記事などもこのカテゴリに入っていました。

    そして
    もう一つは、日本語でカテゴリ名を決めたときに、デフォルトで付く文字化けしたようなカテゴリスラッグ名になっていました。
    このカテゴリには記事は入っていません。
    このカテゴリは完全に無駄なカテゴリでした。

    このように無駄なカテゴリが増殖しないように、
    一つのカテゴリが、一つのみインポートされるようにするには、どうすればいいのでしょうか?

    よろしくお願いします。

4件の返信を表示中 - 1 - 4件目 (全4件中)
  • モデレーター IKEDA Yuriko

    (@lilyfan)

    これは WordPress コアのバグです。回避策は、「スラッグを変更しない」しかありません。今回のように、元のウェブログでカテゴリースラッグを変更している場合、エクスポート前に、「日本語のカテゴリー名から変換された %nn 型式のスラッグ」に変更して、インポート後に、適切なスラッグに戻してやるという手順ぐらいしかないです。

    trac で報告してはいるんですが、それはキーワードタグだけの対応でして、カテゴリーのインポートでも起きるとなると、追加報告が必要ですね……。

    同じ問題に行き当たり、検索によりこの投稿にたどり着きました。

    lilyfan様の投稿からヒントを得て、

    /wp-admin/import/wordpress.php

    に変更を加えることによりカテゴリースラッグを変更したままの状態で無駄なカテゴリが増殖されずにインポートを行うことができました。

    ▼修正前

    $post_title     = $this->get_tag( $post, 'title' );

    ▼修正後(1行追加)

    $category_slug     = $this->get_tag( $post, 'category_slug' );
    $post_title     = $this->get_tag( $post, 'title' );

    ▼修正前

    $slug = sanitize_term_field('slug', $category, 0, 'category', 'db');

    ▼修正後(コメントアウトし1行追加)

    //$slug = sanitize_term_field('slug', $category, 0, 'category', 'db');
    $slug = $category_slug;

    ▼xmlファイルの記述について
    インポートするxmlファイルの<item></item>間に

    <category><![CDATA[★★★]]></category>
    <category_slug>☆☆☆</category_slug>

    を挿入する。
    ★★★はカテゴリー名(日本語表記可能)
    ☆☆☆はカテゴリースラッグ(半角英数字)

    エクスポートしたxmlとはカテゴリースラッグの記述方式が異なるため変換の必要があります。

    変更を加えたwordpressのバージョンは2.7です。
    問題点がございましたらご指摘をお願いいたします。

    (上記の変更をプラグイン化する手順をご教授いただけましたら幸いです)

    //$slug = sanitize_term_field('slug', $category, 0, 'category', 'db');
    $slug = $category_slug;

    の箇所は

    //$slug = sanitize_term_field('slug', $category, 0, 'category', 'db');
    $slug = $category_slug;
    if (!strlen($slug)){
    $slug = sanitize_term_field('slug', $category, 0, 'category', 'db');
    }

    とするべきでした。訂正いたします。

    技量不足により、私には

    <category domain="category" nicename="★★★">

    の★★★部分に記述されたカテゴリースラッグを取り出す方法がわかりません。

    エクスポートされたxmlを変更することなくインポートが行える方法、および先述いたしましたプラグイン化の方法等について、どなたかご教授いただけましたら幸いです。

    私も同じ現象に行き当たりました。WordPress2.8 でも問題は修正されていないようです。

    maxline さんの修正をヒントに下記のように /wp-admin/import/wordpress.php の該当箇所を from から to に変更しました。

    /*
     * line 403-404:
     */
    		// from:
    		preg_match_all('|<category>(.*?)</category>|is', $post, $categories);
    		$categories = $categories[1];
    
    		// to:
    		preg_match_all('|<category domain="category" nicename="([0-9a-z%\-_]*?)">(.*?)</category>|is', $post, $categories);
    		$nicenames  = $categories[1];
    		$categories = $categories[2];
    
    /*
     * Line 462-482
     */
    			// from:
    			if (count($categories) > 0) {
    				$post_cats = array();
    				foreach ($categories as $category) {
    					if ( '' == $category )
    						continue;
    					$slug = sanitize_term_field('slug', $category, 0, 'category', 'db');
    					$cat = get_term_by('slug', $slug, 'category');
    					$cat_ID = 0;
    					if ( ! empty($cat) )
    						$cat_ID = $cat->term_id;
    					if ($cat_ID == 0) {
    						$category = $wpdb->escape($category);
    						$cat_ID = wp_insert_category(array('cat_name' => $category));
    						if ( is_wp_error($cat_ID) )
    							continue;
    					}
    					$post_cats[] = $cat_ID;
    				}
    				wp_set_post_categories($post_id, $post_cats);
    			}
    
    			// to:
    			if ($c = count($categories) > 0) {
    				$post_cats = array();
    				for ($i = 0; $i < $c; $i++ ) {
    					if ( '' == $categories[$i] || '' == $nicenames[$i] )
    						continue;
    					$cat = get_term_by('slug', $nicenames[$i], 'category');
    					if ( empty($cat) || $cat->name != $categories[$i] ) {
    						$slug = sanitize_term_field('slug', $categories[$i], 0, 'category', 'db');
    						$cat = get_term_by('slug', $slug, 'category');
    					}
    					$cat_ID = 0;
    					if ( ! empty($cat) )
    						$cat_ID = $cat->term_id;
    					if ($cat_ID == 0) {
    						$category = $wpdb->escape($categories[$i]);
    						$cat_ID = wp_insert_category(array('cat_name' => $category));
    						if ( is_wp_error($cat_ID) )
    							continue;
    					}
    					$post_cats[] = $cat_ID;
    				}
    				wp_set_post_categories($post_id, $post_cats);
    			}

    これで xml ファイル (WXR) の方を書き換えなくても正常にインポートできるはずです。互換性については、 WP_Import::process_post() の該当箇所を各バージョンで比較した感じ、WP2.6.5 以上では少なくとも動作するのではないかと思います。

    懸念としては nicename 属性を持つ category 要素がどのバージョンの WordPress インポート用 RSS に追加されたかで、WXR ファイルの構造によっては下位互換性が取れないこともあるかもしれません。

    <category><![CDATA[未分類]]></category>
    <category domain="category" nicename="uncategorized"><![CDATA[未分類]]></category>

    それから、カテゴリーの正確さを検証する際のポリシーがよく分からないこと。カテゴリー名の重複を許可する一方、スラッグは単一、しかしながらインポート時にはカテゴリー名を基準にする、というインポーターの挙動に混乱します。

    スラッグ名とカテゴリー名が既存のものと一致する場合にのみ、そのカテゴリーの投稿としてインポートする、というのでいいと最初は思っていたんですが、投稿のインポートの前に走るカテゴリーのインポート時に、カテゴリー名が異なるがスラッグは同じというカテゴリーがインポート元のブログに既に存在し、インポートされるカテゴリーのスラッグが WXR ファイルに記述されているのではない、ユニークな別のものに変更されていた場合には、新たなスラッグを追跡する必要があるのですが、適切な方法が分かりません。

    そこでとりあえずそのような場合も結局、新規に同名のカテゴリーを追加するという従来の処理に任せてみるのですが、カテゴリーの正確さを検証するポリシーがあるのであれば、それに準拠しないとコミットできないので、、、という。

    長々と書きましたが、添削を含め、どなたか情報をお持ちでしたらご教示ください。

    > maxline さん

    プラグイン化については、 WP_Import を継承したクラスで process_post() メソッドを定義し直して、 register_importer() すれば出来そうですね。

4件の返信を表示中 - 1 - 4件目 (全4件中)
  • トピック「インポートすると同じ名前のカテゴリが増殖する」には新たに返信することはできません。