2011年02月12日

WordPress3.0 マルチブログ化(ネットワーク機能ON)時の新着記事一覧取得

WordPress3.0.5でサイト構築をしているのですが、初めて使ったネットワーク機能、はまりました。ふらふら

マルチサイトにして、子サイトごとに書き込みなどの権限管理をすることになりました。トップページなどに、子サイト・親サイトの新着記事をまぜこぜにして○件表示、ということをしなければなりません。しかし、そのものずばりのタグが見つかりません。マルチサイトを組む場合標準的に必要な機能だと思うのですが、なぜかないんですね。これは仕方がない、作らなければ、と作業を始めたのですが、なかなか動いてくれません。

まだいろいろと不安定なのか、それとも使い方が悪いのか... バージョンが上がればこんな苦労はしなくてよくなるかもしれませんが、一応メモしておきます。


● マルチ関係のタグがうまく動かない場合あり

ループを回して複数サイトにまたがった記事一覧を表示しようと、
<?php
$posts = 記事一覧を array('blog_id' => blog_id, 'post' => post) の配列でget;
if ($posts) {
    foreach ($posts as $one_post) {
        switch_to_blog($one_post['blog_id']);
        setup_postdata($one_post['post']);
?>
        <a href="<?php the_permalink(); ?>"><?phpthe_title(); ?></a><br />
<?php
    }
    restore_current_blog();
}
?>
<a href="<?php echo get_category_link(1); ?>">もっと読む</a>
と、こんなループにしてみました。ところが、ちゃんと動きません。パーマリンクはブログごとに切り替わらなくて変なURLになるし、「もっと読む」のリンクは http://サイト/blog1/blog2/カテゴリ みたいにへんなURLになるし。

$wpdb->set_blog_id($one_post['blog_id']) とか使ってもダメ、パーマリンクを $post->guid とかにしてもダメ、その他いろいろ試行錯誤し、やっと動いたのがこれ。
<?php
$posts = 記事一覧を array('blog_id' => blog_id, 'post' => post) の配列でget;
if ($posts) {
    foreach ($posts as $one_post) {
        switch_to_blog($one_post['blog_id']);
        $post = $one_post['post'];
        setup_postdata($post);
?>
        <a href="<?php the_permalink(); ?>"><?php the_title(); ?></a><br />
<?php
    }
    restore_current_blog();
}
?>
<a href="<?php echo get_category_link(1); ?>">もっと読む</a>
違いは、$post = $one_post['post']; をかましてあるかどうかだけです。この文の位置も重要で、switch_to_blog の前に持っていったりすると動かない。いったいどういう実装になっているんでしょう? まあ、ソースコードを追う時間はないから、このまま先に進みますが...


● get_blog_list() は“This function has been deprecated.”

wp-config.php でデバッグモードをtrueにしている(define('WP_DEBUG', true);)と、 get_blog_list() はWordPress3.0では非推奨だから使うなよ、というNoticeが表示されます。じゃあ、代わりの関数は何だろう、と調べに行くと“No alternative available.”??? 代わりはないの? パフォーマンスの問題から非推奨となったようですね。

http://wordpress.org/support/topic/replacement-for-get_blog_list

小さなサイトでは使っていいよ、とありますが、使い続けるのも気になります。いろいろ調べて、get_last_updated() で代用してみました。いいんだろうか?


● とりあえず動いた新着記事一覧表示コード

他にも試行錯誤した気がしますが、最終的にはこんな感じのコードになりました。

関数(テーマのfunction.phpに入れる)
if ( ! function_exists( 'get_recentposts_from_all_blog' ) ) :

function get_recentposts_from_all_blog( $start = 0, $num = 10, $cond = '' ) {
    // 各ブログの記事を全件取得する
    $blog_lists = get_last_updated();
    $cond = $cond ? '&'.$cond : '';
    $post_dates = array();
    $post_list = array();
    foreach ($blog_lists as $blog) {
        switch_to_blog( $blog['blog_id'] );
        $posts = get_posts( 'numberposts=-1'.$cond );
        if( $posts ) {
            foreach( $posts as $post ) {
                $post_dates[] = $post->post_date;
                $post_list[] = array('blog_id' => $blog['blog_id'], 'post' => $post);
            }
        }
        restore_current_blog();
    }

    // 投稿日時で並べ替える
    if ($post_list) {
        array_multisort($post_dates, SORT_DESC, $post_list);
    }
    return ($post_list ? array_slice( $post_list, $start, $num, true ) : array());
}
endif;

テンプレート
<?php
    $posts = get_recentposts_from_all_blog(0, 5, 'category=8');
    if ($posts) {
        foreach ($posts as $one_post) {
            switch_to_blog($one_post['blog_id']);
            $post = $one_post['post'];
            setup_postdata($post);
?>
            <a href="<?php the_permalink(); ?>"><?php the_title(); ?></a>
            &nbsp;<?php the_time('Y年n月j日'); ?><br />
<?php
        }
        restore_current_blog();
    }
?>
    <a href="<?php echo get_category_link(8); ?>">もっと読む</a>
numberposts=-1で全ポストを取得しているところは、投稿が増えると重くなるかな? 場合によっては見直さないといけませんね。一応動いてはいるけど、ちょっとアレンジしたりすると動かなくなったりします。ネットワーク機能がまだ不安定なのでしょうけど、早く安定するといいですね。
posted by 急いでジャンプ at 15:59| Comment(0) | TrackBack(0) | CMS | このブログの読者になる | 更新情報をチェックする
この記事へのコメント
コメントを書く
お名前: [必須入力]

メールアドレス: [必須入力]

ホームページアドレス:

コメント: [必須入力]

認証コード: [必須入力]


※画像の中の文字を半角で入力してください。
※ブログオーナーが承認したコメントのみ表示されます。

この記事へのトラックバック