主にWP_Query使って表示をがっつりカスタマイズしたいという場合の覚え書き。

Top 10 – Popular posts plugin for WordPress

WP_QueryのラッパークラスとしてTop_Ten_Queryが用意されているので便利。

基本の記述

<?php
	$top10_query = new Top_Ten_Query(
		array(
			// 'daily'          => true,
			'daily_range'    => 30,
			// 'limit'          => 20,
			// 'strict_limit'   => false,
			'posts_per_page' => 10,
			// 'offset' => 3,
			'tax_query'      => array(
				'relation' => 'AND',
				array(
					'taxonomy' => 'category',
					'field'    => 'slug',
					'terms'    => array( 'cathoo' ),
				),
				array(
					'taxonomy' => 'post_tag',
					'field'    => 'slug',
					'terms'    => array( 'tagbar' ),
				),
			),
		)
	);

	if ( $top10_query->have_posts() ) :
		?>
		<ul class="xxxxx-list">
		<?php
		while ( $top10_query->have_posts() ) :
			$top10_query->the_post();
			?>
			<?php get_template_part( 'template-parts/loop', 'xxxxx' ); ?>
		<?php endwhile; ?>
		</ul>
		<a href="<?php echo esc_url( home_url( '/' ) ); ?>category/topics/">もっと見る</a>
	<?php else : ?>
	<p>現在表示する投稿はありません。</p>
	<?php endif; ?>
	<?php wp_reset_postdata(); ?>

公式ドキュメント

※被リンク禁止っぽいのでリンク無しで…

//Top_Ten_Query
https://webberzone.com/support/knowledgebase/top_ten_query/

//その他基本事項
https://webberzone.com/support/knowledgebase/using-and-customising-top-10/

WordPress Popular Posts

テンプレートタグを使って表示(簡単だけど複雑なカスタマイズはできない)

テンプレートタグではカテゴリー&タグでフィルターなどの複雑なカスタマイズはできない。

基本の記述

<?php
if ( function_exists( 'wpp_get_mostpopular' ) ) :
	$popular_posts = array(
		'range'          => 'last30days',
		'order_by'       => 'views',
		'post_type'      => 'post',
		'stats_comments' => '0',
		'limit'          => 5,
		'stats_views'    => '0',
		'wpp_start'      => '<ul>',
		'wpp_end'        => '</ul>',

		'post_html'      => '<li><a href="{url}"><img src="{thumb}" alt="{text_title}"><p>{text_title}</p></a></li>',
	);
	wpp_get_mostpopular( $popular_posts );
endif;
?>

出力をカスタマイズ

基本の記述から ‘post_html’, ‘wpp_start’, ‘wpp_end’ 部分を削除してwpp_custom_htmlフィルターフックでカスタマイズする。

<time>要素はなぜか出力されないので使用しないこと。

function my_custom_popular_posts_html_list( $popular_posts, $instance ) {
	$output = '<ol class="wpp-list">';
	foreach ( $popular_posts as $popular_post ) {
		if ( has_post_thumbnail( $popular_post->id ) ) {
			$thumb_id    = get_post_thumbnail_id( $popular_post->id );
			$thumb_array = wp_get_attachment_image_src( $thumb_id, 'full' );
			$thumb       = '<img src="' . $thumb_array[0] . '" alt="' . $popular_post->title . '">';
		} else {
			$thumb = '<img src="' . get_template_directory_uri() . '/assets/images/common/no-img.png" alt="' . $p->title . '">';
		}
		$output .= '<li>';
		$output .= '<a href="' . get_permalink( $popular_post->id ) . '" title="' . esc_attr( $popular_post->title ) . '">';
		$output .= $thumb;
		$output .= '<time datetime="' . get_the_time( 'Y-m-d' ) . '">' . get_the_time( 'Y.m.d' ) . '</time>';
		$output .= $popular_post->title;
		$output .= '</a></li>' . "\n";
	}
	$output .= '</ol>';

	return $output;
}
add_filter( 'wpp_custom_html', 'my_custom_popular_posts_html_list', 10, 2 );
//複雑な設定
function my_custom_popular_posts_html_list( $popular_posts, $instance ) {
	$output = '';
	foreach ( $popular_posts as $p ) {
		$output .= '<article>';
		$output .= '<a href="' . get_permalink( $p->id ) . '">';
		if ( has_post_thumbnail( $p->id ) ) {
			$thumb_id    = get_post_thumbnail_id( $p->id );
			$thumb_array = wp_get_attachment_image_src( $thumb_id, 'thumbnail' );
			$thumb       = '<img src="' . $thumb_array[0] . '" alt="' . $p->title . '">';
		} else {
			$thumb = '<img src="' . get_template_directory_uri() . '/assets/images/common/no-img.png" alt="' . $p->title . '">';
		}
		$output .= '<div class="post-list__img-wrapper"><figure>' . $thumb . '</figure></div>';

		// カスタムフィールド
		if ( get_field( 'movie', $p->id ) ) {
			$output .= '<span class="post-list__osusume"><img src="' . esc_url( get_template_directory_uri() ) . '/assets/images/common/icon-movie.svg" alt="おすすめ"></span>';
		}

		$output .= '<div class="post-list__content"><div class="post-list__timecat">';
		$output .= '<span class="post-list__timecat-time" datetime="';
		$output .= get_the_time( 'Y-m-d', $p->id );
		$output .= '">';
		$output .= get_the_time( 'Y年m月d日', $p->id );
		$output .= '</span>';

		$output    .= '<span class="post-list__timecat-cat">';
		$categories = get_the_category( $p->id );
		if ( $categories ) {
			foreach ( $categories as $c ) {
				if ( $c->parent ) {
					$output .= esc_html( $c->cat_name );
					$output .= ' ';
				}
			}
		}
		$output .= '</span></div>';

		$ttl     = $p->title;
		$ttl     = mb_strlen( $ttl, 'UTF-8' ) > 31 ? mb_substr( $ttl, 0, 31 ) . '…' : $ttl;
		$output .= '<h3 class="post-list__title">' . $ttl . '</h3>';
		$output .= '</a></article>';
	}

	return $output;
}
add_filter( 'wpp_custom_html', 'my_custom_popular_posts_html_list', 10, 2 );

new \WordPressPopularPosts\Query を使う

$args          = array(
	'post_type' => 'post', // 投稿タイプ
	'range'     => 'monthly', // 集計期間
	'limit'     => 10, // 表示件数
);
$popular_posts = new \WordPressPopularPosts\Query( $args );
if ( $popular_posts ) :
	foreach ( $popular_posts->get_posts() as $popular_post ) :
		?>
	<a href="<?php the_permalink( $popular_post->id ); ?>">
		<?php echo esc_html( get_the_date( 'Y-m-d', $popular_post->id ) ); ?>
		<?php echo esc_html( $popular_post->title ); ?>
	</a>

		<?php
	endforeach;
endif;
wp_reset_postdata();

WP_Query で扱えるようにする

データのリセットが効かないのでこれはおすすめしない

公式な使い方では無いかもしれないが、プラグイン作者がSupportで方法伝授してくれている。

https://wordpress.org/support/topic/how-to-sorting-a-custom-query-by-views-all-time-monthly-weekly-or-daily/

wpp_get_viewsの値をカスタムフィールドに保存して、それをWP_Queryの meta_key の値として使用する感じです。
DBへのアクセスは負荷がかかるのでアクセス数の多いサイトなどでは$accuracyの数値は少なく(例えば10)設定するのが良さそうです。

記述例

月刊で取得する場合

functions.php
function custom_wpp_update_postviews($postid) {
    // Accuracy:
    //   10  = 1 in 10 visits will update view count. (Recommended for high traffic sites.)
    //   30  = 30% of visits. (Medium traffic websites.)
    //   100 = Every visit. Creates many db write operations every request.

    $accuracy = 50;

    if ( function_exists('wpp_get_views') && (mt_rand(0,100) < $accuracy) ) {
        update_post_meta(
            $postid,
            'my_views_monthly',
            wpp_get_views($postid, 'monthly', false)
        );
    }
}
add_action('wpp_post_update_views', 'custom_wpp_update_postviews');
テンプレートの表示したい場所に

tax_queryで表示絞り込みする例

$popular_posts = new WP_Query(
	array(
		'post_type'      => 'post',
		'meta_key'       => 'my_views_monthly', // phpcs:ignore
		'orderby'        => 'meta_value_num',
		'order'          => 'DESC',
		'posts_per_page' => '3',
		'tax_query'      => array(
			'relation' => 'AND',
			array(
				'taxonomy' => 'category',
				'field'    => 'slug',
				'terms'    => array( 'cathoo' ),
			),
			array(
				'taxonomy' => 'post_tag',
				'field'    => 'slug',
				'terms'    => array( 'tagbar' ),
			),
		),
	)
);
if ( $popular_posts->have_posts() ) :
	?>
	<ul class="xxxxx-list">
	<?php
	while ( $popular_posts->have_posts() ) :
		$popular_posts->the_post();
		?>
		<?php get_template_part( 'template-parts/loop', 'xxxxx' ); ?>
	<?php endwhile; ?>
	</ul>
	<a href="<?php echo esc_url( home_url( '/' ) ); ?>category/topics/">もっと見る</a>
<?php else : ?>
<p>現在表示する投稿はありません。</p>
<?php endif; ?>
<?php wp_reset_postdata(); ?>
プラグイン作者のフルコード
/**
 * Stores views of different time periods as meta keys.
 *
 * @author  @migueleste / @radgh
 * @link    https://wordpress.org/support/topic/how-to-sort-a-custom-query-by-views-all-time-monthly-weekly-or-daily/
 * @param   int     $postid     The ID of the current post/page/custom post type.
 */
function custom_wpp_update_postviews($postid) {
    // Accuracy:
    //   10  = 1 in 10 visits will update view count. (Recommended for high traffic sites.)
    //   30  = 30% of visits. (Medium traffic websites.)
    //   100 = Every visit. Creates many db write operations every request.

    $accuracy = 50;

    if ( function_exists('wpp_get_views') && (mt_rand(0,100) < $accuracy) ) {
        // Remove or comment out lines that you won't be using!!
        update_post_meta(
            $postid,
            'views_total',
            wpp_get_views($postid, 'all', false)
        );
        update_post_meta(
            $postid,
            'views_daily',
            wpp_get_views($postid, 'daily', false)
        );
        update_post_meta(
            $postid,
            'views_weekly',
            wpp_get_views($postid, 'weekly', false)
        );
        update_post_meta(
            $postid,
            'views_monthly',
            wpp_get_views($postid, 'monthly', false)
        );
    }
}
add_action('wpp_post_update_views', 'custom_wpp_update_postviews');
// Get the 3 top viewed posts for the week.
$args = array(
    'post_type' => 'post',
    'meta_key' => 'views_weekly',
    'orderby' => 'meta_value_num',
    'order' => 'DESC',
    'posts_per_page' => '3',
);
$top_posts = new WP_Query($args);

公式ドキュメント

テンプレートタグ

https://github.com/cabrerahector/wordpress-popular-posts/wiki/2.-Template-tags

フィルターフック

https://github.com/cabrerahector/wordpress-popular-posts/wiki/3.-Filters

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です