WordPressで複数ブログの投稿・カスタム投稿を一覧表示する
WordPressのマルチサイトを利用しているとき、複数のブログから投稿や、カスタム投稿の情報を1箇所に集約してきて『新着情報』のような形で一覧表示するケースがあると思います。
そのようなケースではWP_Query等では対応できないので、SQL文を作成しデータベースから直接データを引っ張ってこなければなりません。と言ってもさほど複雑なことはないので下記コードを参考にして頂ければ問題ないと思います。
当社DOEのホームページで言うところの、新着情報一覧ページはまさに上記のパターンです。
このWordPressのネタを紹介しているブログを含めて『3つのブログの投稿』と、DOE本体サイトの『お知らせ』を集約させています。しかも『お知らせ』は通常の投稿ではなく『カスタム投稿タイプ』です。
それと同時に、一覧ページなので『ページャー(ページ送り)機能』を設定しなければなりません。ページャーもこのケースでは通常のプラグイン(WP-PageNavi等)は使用できません。
まずは複数のブログ(マルチサイト使用)から投稿を集めて表示
新着の一覧を表示するページは固定ページとして作成してあります(page-news_blog.php)。
その固定ページテンプレートに下記のようなサンプルコードを記述します。
<?php
/*
各ブログの記事と、本体サイトのカスタム投稿「news」から記事一覧を取得する。
*/
$sql = '';
$blog_id_arr = array(1,5,8,9);//取得するブログIDの配列
$tmp = $blog_id_arr;
foreach($blog_id_arr as $b_id){
$pg = get_query_var( 'page' );//現在何ページ目なのか取得
if($pg == 0) $pg = 1;//1ページ目は「0」になってしまうのでそれを「1」とする
next($tmp);
switch_to_blog($b_id);
$sql .= <<<HERE
(SELECT *, $b_id as blog_id
FROM $wpdb->posts
WHERE (post_type = 'post' OR post_type = 'news')
AND post_status = 'publish')
HERE;
if(current($tmp) !== false){
$sql .= "UNION\n";
}
restore_current_blog();
}
$sql .= "ORDER BY post_date DESC\n";
$posts = $wpdb->get_results($sql);//記事のセットを取得
$total = ceil(count($posts)/30);//条件にマッチした記事の総数を取得
$sql .= "LIMIT " . ($pg-1) * 30 . ", 30";//記事を0番目から30個、30番目から30個、…という流れで取得する
$posts = $wpdb->get_results($sql);//改めて記事のセットを取得
?>
<table>
<?php
foreach ($posts as $post):
switch_to_blog($post->blog_id);
setup_postdata($post);
?>
<?php get_template_part('loop', 'news-blog'); ?>
<?php endforeach;?>
</table>
おおまかな処理の流れ
- 対象とするブログのIDを配列に入れて、その配列をforeach文でまわします。
- ブログを切り替えるときはswitch_to_blog関数を使用します。
- それぞれのブログから投稿を取得するSQLを作成します。
- SQL文を『UNION』でつなぎ、ひとつのテーブルを作成します。
- 『news』という名前のカスタム投稿タイプを使用しているため、『WHERE』で次のように指定します。
WHERE (post_type = 'post' OR post_type = 'news') - 『ORDER BY』でソート順を決定します。
- 『LIMIT』で1ページに表示する投稿件数を決定します。ここでは30件です。
- 『$wpdb->get_results』で全ての条件に合致した投稿の一覧を取得します。
- ループ処理で投稿の一覧を出力します。
ページャーの表示
直接データベースから引っ張ってきている都合上、ページャー用のプラグイン等は使えないはずです。
下記コードのように『paginate_links』関数に各種引数を設定して表示させます。
<?php
//ページャー引数設定
$main_blog_url = get_blogaddress_by_id(1);
$args = array(
'base' => $main_blog_url . 'news_blog/%_%',
'format' => '?page=%#%',
'total' => $total,
'current' => $pg,
'show_all' => False,
'end_size' => 1,
'mid_size' => 5,
'prev_next' => true,
'prev_text' => __('«'),
'next_text' => __('»'),
'type' => 'plain',
'add_args' => False,
'add_fragment' => ''
);
?>
<div class="wp-pagenavi">
<?php echo paginate_links( $args );//ページャー出力 ?>
</div>
以上でマルチサイト使用の複数ブログから投稿一覧を取得・表示させることができます。
少し分かりづらい部分もあるかもしれませんが、WordPressでこのようなパターンはけっこう出てくると思いますし、使い回しのきくコードなのでご参考になればと思います。