サポート » マルチサイト » 親サイトで子サイトの投稿を更新日時順に表示したい

  • 解決済 hypnotherapy

    (@hypnotherapy)


    お世話になります。

    現在マルチサイトを構築中で、親サイトに子サイトの最新投稿を以下のコードで表示させるのはできました。

    
    <h2 class="top-gallery-midashi">更新情報</h2>
    <ul class="block-five">
    <?php
    $my_blogs = wp_get_sites(); 
    foreach ( $my_blogs as $blog ):
        switch_to_blog( $blog['blog_id'] );
    ?>
    	<?php
    		$args = array( 'posts_per_page' => 5 );
    		$the_query = new WP_Query( $args );
    		if ( $the_query->have_posts() ) :
    			while ( $the_query->have_posts() ) :
    				$the_query->the_post();
    	?>
    	<li class="item">
    	<div class="gallery-item">
    	<div class="item-img"><a href="<?php the_permalink(); ?>">
    	<?php
    		if ( has_post_thumbnail() ) the_post_thumbnail();
    		else echo '<img src="<?php network_home_url(); ?>/images/noimage-630x420.jpg" />'; ?></a></div>
    	<div class="item-title"><a href="<?php the_permalink(); ?>" target="_blank"><?php the_title(); ?></a></div>
    	<div class="item-date"><?php the_time(__('Y-m-d')) ?> | <a href="<?php echo home_url(); ?>"><?php bloginfo(name); ?></a></div>
    	</li>
    	<?php 
    		endwhile;
    	endif;
        restore_current_blog();
    endforeach;
    ?>
    

    ただし上記コードだと複数の子サイトを作った場合ID順に表示されてしまっておりまして、実際には子サイトで投稿された日付順でソートできるようにしたいです。

    また、現状では親サイトも出てきてしまうので子サイトのみにする方法も合わせてご教示いただければと思います。

7件の返信を表示中 - 1 - 7件目 (全7件中)
  • こんにちは

    上記コードだと複数の子サイトを作った場合ID順に表示されてしまっておりまして、

    ID ではなく日付で降順に表示されていませんか?

    実際には子サイトで投稿された日付順でソートできるようにしたいです。

    日付で昇順ということでしょうか?
    この場合は、

    $args = array( 'posts_per_page' => 5 );

    $args = array( 'posts_per_page' => 5, 'orderby' => 'date', 'order' => 'ASC' );

    にすればいいのではないでしょうか?

    また、現状では親サイトも出てきてしまうので子サイトのみにする方法も合わせてご教示いただければと思います。

    $my_blogs = wp_get_sites(); 
    foreach ( $my_blogs as $blog ):
        switch_to_blog( $blog['blog_id'] );

    $current_blog_id = get_current_blog_id();
    $my_blogs = wp_get_sites(); 
    foreach ( $my_blogs as $blog ):
    	if ( $blog['blog_id'] == $current_blog_id ) continue;
    	switch_to_blog( $blog['blog_id'] );

    それとも、サイト毎のソートではなく、全ての子サイトを纏めてたソートということでしょうか?

    ありがとうございます。

    ID ではなく日付で降順に表示されていませんか?

    ID順+日付の降順ですね。

    それとも、サイト毎のソートではなく、全ての子サイトを纏めてたソートということでしょうか?

    あ、そのとおりです。
    通じていなかったみたいで失礼しました…

    なお、親サイトを表示しない方法はご教示いただいたもので実装できました(^^

    ID順+日付の降順ですね。

    ???
    get_posts のデフォルトは日付で降順にソートされるはすですが・・・
    https://wpdocs.osdn.jp/テンプレートタグ/get_posts#.E3.83.91.E3.83.A9.E3.83.A1.E3.83.BC.E3.82.BF

    とりあえずこのことは置いとくとして、

    すべてのサイトを対象(親サイトを除く)にソートした投稿を取得するには、SQL クエリ―で取得することになりそうです。
    長いコードなので、分割して投稿(functions.php 部とテンプレート部)します。

    functions.php に、

    /**
     * オプションに基づき投稿 ID の 配列を取得します。オプションは get_posts ライクです。
     *
     * @param array $site_ids サイト ID の配列。
     * @param array $args オプション。投稿を取得する引数。使用可能なすべての引数についてはコードを参照してください。
     * @return array サイト ID と投稿 ID のリスト。
     */
    function get_posts_by_sites( $site_ids, $args = null ) {
    	global $wpdb;
    
    	$args = wp_parse_args( $args, array( 
    		'post_type' => 'post',
    		'post_status' => 'publish',
    		'posts_per_page' => 10,
    		'paged' => max( 1, get_query_var( 'paged' ) ),
    		'orderby' => 'post_date',
    		'order' => 'DESC',
    	) );
    	extract( $args );
    
    	if ( ! is_array( $post_type ) ) {
    		$post_type = trim( strval( $post_type ) );
    		$post_type = preg_split( '/[,\s]+/', $post_type, -1, PREG_SPLIT_NO_EMPTY );
    		$post_type = array_map( 'esc_sql' , $post_type );
    	}
    	if ( ! is_array( $post_status ) ) {
    		$post_status = trim( strval( $post_status ) );
    		$post_status = preg_split( '/[,\s]+/', $post_status, -1, PREG_SPLIT_NO_EMPTY );
    		$post_status = array_map( 'esc_sql' , $post_status );
    	}
    
    	$sub_queries = array();
    	foreach ( $site_ids as $site_id ) {
    		switch_to_blog( $site_id );
    		$sub_queries[] = sprintf( 'SELECT %1$d AS blog_id,%2$s.* FROM %2$s WHERE post_type IN (%3$s) AND post_status IN (%4$s)',
    			$site_id,
    			$wpdb->posts,
    			"'" . implode( "','", $post_type ) . "'",
    			"'" . implode( "','", $post_status ) . "'"
    		);
    		restore_current_blog();
    	}
    
    	$limit = '';
    	if ( $paged > 1 ) {
    		$offset = ( intval( $paged ) - 1 ) * $posts_per_page;
    		$offset = max( 0, $offset );
    		if ( 0 < $offset ) {
    			$limit = sprintf( ' LIMIT %d,%d', $offset, $posts_per_page );
    		} else {
    			$limit = sprintf( ' LIMIT %d', $posts_per_page );
    		}
    	}
    
    	$query = sprintf( 'SELECT blog_id,ID FROM (%1$s) AS posts ORDER BY %2$s %3$s' . $limit,
    		implode( ' UNION ALL ', $sub_queries ),
    		esc_sql( $orderby ),
    		esc_sql( $order )
    	);
    	
    	$posts = $wpdb->get_results( $query );
    
    	return $posts;
    }

    テンプレートに、

    <?php
    // 現在のサイト ID を取得する。
    $current_blog_id = get_current_blog_id();
    // すべてのサイト ID の配列を取得する。
    $site_ids = get_sites( array ( 'fields' => 'ids' ) );
    // すべてのサイト ID の配列から現在のサイト ID を削除する。
    $site_ids = array_diff( $site_ids, array( $current_blog_id ) );
    
    $my_posts = get_posts_by_sites( $site_ids, array(
    	'post_type' => 'post',
    	'posts_per_page' => 10,
    ) );
    foreach ( $my_posts as $my_post ) {
    	switch_to_blog( $my_post->blog_id );
    	$post = get_post( $my_post->ID );
    	setup_postdata( $post );
    
    	echo '<p><a href="' . get_permalink() . '">' . get_the_date() . ' ' . get_the_title() . '</a></p>';
    
    	restore_current_blog();
    }
    wp_reset_postdata();
    ?>

    無事希望通り表示できるようになりました、ありがとうございました。

    なお

    ???
    get_posts のデフォルトは日付で降順にソートされるはすですが・・・

    については、最初のコードのままだと

    1.ID1(親サイト)の最新記事
    2.ID1の2番目に新しい記事
    3.ID2(子サイト)の最新記事
    4.ID3(子サイト2)の最新記事
    5.ID3の2番目に新しい記事

    …というように表示されていた、と書けばよかったでしょうかね。

    出来たようで、よかったです。
    ソートの件は、ID (サイト ID)を投稿 ID と勘違いしてしまいました。m(__)m

7件の返信を表示中 - 1 - 7件目 (全7件中)
  • このトピックに返信するにはログインが必要です。