プラグイン『WordPress Popular Posts』を分岐などで詳細にカスタマイズする
WordPress で人気記事のランキングを表示するなら、『WordPress Popular Posts』プラグインで簡単に実装できます。
インストールするとデータベースにランキング専用のテーブルが作成され、そこにデータがどんどん溜まっていくので、設定もなく使うことができます。
この記事では、基本のコードをベースに、詳細なカスタマイズの方法を紹介します。
基本のコード
$args = array(
'range' => 'weekly',
'order_by' => 'views',
'post_type' => 'post',
'stats_comments' => '0',
'limit' => 5,
'stats_views' => '0',
'wpp_start' => '<ol>',
'wpp_end' => '</ol>',
'post_html' => '<li><a href="{url}"><div class="image-left"><img src="{thumb}" alt="{text_title}"></div><div><p class="lank">位</p><p>{text_title}</p></div></a></li>',
);
wpp_get_mostpopular($args);
基本は wpp_get_mostpopular($args) 関数を呼び出して出力します。
基本のコードでは、ランキングの li 要素の中身はpost_html パラメータで設定します。
サムネイルを含めたい場合は、値に {thumb} タグを含めることで表示できます。
しかし、これに分岐設定を追加して「サムネイル画像未設定の場合はカテゴリに設定したカテゴリ画像を表示する。それも未設定ならデフォルトのサムネイルを表示する」というふうな難解な指定をしたいときは、基本のコードの方法では多分ムリです。
そこで functions.php にフィルターフックを設定してカスタマイズする方法を紹介します。
フィルターフックのコード
フィルターフックの種類
3. Filters · cabrerahector/wordpress-popular-posts Wiki · GitHub
フィルターフックの選択肢は 2 種類あります。
- wpp_custom_html
- wpp_post
今回は wpp_post フックを使います。
wpp_post フックは、主に基本のコードの post_html の中身をカスタマイズするフックです。
サムネイルがあれば表示し、未設定ならデフォルト画像を表示するコード
({thumb} タグがやっていることを再現)
// htmlの設定
function my_custom_single_popular_post( $post_html, $p, $instance ){
if (has_post_thumbnail($p->id)){//投稿にサムネイルがある場合の処理
$thumb_id = get_post_thumbnail_id($p->id);
$thumb_array = wp_get_attachment_image_src( $thumb_id, 'full');
$thumb = '<img src="'.$thumb_array[0].'" alt="'.$p->title.'">';
} else {//サムネイルなしの場合の処理
$thumb = '<img sec="'.get_template_directory_uri().'/images/default.jpg" alt="'.$p->title.'">';
}
$output = '<li><div class="image-left"><a href="' . get_the_permalink($p->id) . '">' . $thumb . '</a></div><div><p class="lank">位</p><p class="tit"><a href="' . get_the_permalink($p->id) . '">' . $p->title . '</a></p></div></li>';
return $output;
}
if ( !is_admin() ) add_filter( 'wpp_post', 'my_custom_single_popular_post', 10, 3 );//管理画面では除外
コードの解説
コールバック関数の呼び出し
if ( !is_admin() ) add_filter( 'wpp_post', 'my_custom_single_popular_post', 10, 3 );//管理画面では除外
フック適用時にコールバック関数を呼び出します。
wpp_post フックは管理画面での設定画面でも適用されるので、if で除外しておきます。
第3引数の 10 という値は、関数を呼び出すための優先値ですが、気にしなくて OK です。
そして、第4引数の 3 が何かというと、my_custom_single_popular_post 関数を呼び出すときに $post_html, $p, $instance の 3 つの値を渡すための設定です。
- $post_html:もともと設定されていた post_html の値
- $p:id やタイトルが格納された配列
- $instance:range などのパラメータ
3 つ引数を渡したのですが、今回は真中の $p しか使いません。
$p の中身
stdClass Object
(
[id] => 72
[title] => タイトルタイトル
[date] => 2017-06-15 14:00:23
[uid] => 2
[pageviews] => 2
)
投稿 ID から各データを引っ張ってくる
has_post_thumbnail($p->id)/サムネイルがあるか判定
get_the_permalink($p->id)//パーマリンクを取得
get_field('dummy',$p->id)//カスタムフィールドの値を取得
このように、基本的に投稿 ID を引数にすることで、各データを持ってくることが出来ます。
サムネイル画像未設定の場合はカテゴリに設定したカテゴリ画像を表示する。
それも未設定ならデフォルトのサムネイルを表示するコード
上記のコードをベースに、画像の表示方法を追加すればいけそうです。
まず、流れを整理しましょう。
サムネイル or デフォルト画像を表示するコードはこんな流れでした。
それに分岐を増やします。
「カテゴリ画像」設定方法
カテゴリ画像はデフォルトには無い項目なので、自分で設定しなければいけなません。
今回は、プラグイン『Advanced Custom Fields』を使って設定します。
(作成例では Pro 版の『Advanced Custom Fields PRO』を使っているのでフォーム内容に誤差があるかもしれません)
コード
// htmlの設定
function my_custom_single_popular_post( $post_html, $p, $instance ){
//カスタムフィールドを読み込み、デフォルト画像を表示するために、カテゴリIDを取得
$cats = get_the_category($p->id);
//カテゴリのデフォルト画像を探す
foreach($cats as $cat) {
if($cat->parent==0){
//親なし
$parent_id = $cat->cat_ID;
} else {
//親がある場合は一番上の親を取得
$cat_id = $cat->term_id;
$ancestors = array_reverse(get_ancestors( $cat_id, 'category' ));
$parent_id = $ancestors[0];
}
$post_id = 'category_'.$parent_id;
$attachment_id = get_field('default_img',$post_id);
if(!empty($attachment_id)) break;//カテゴリ画像見つけたらループ終了
}
if (has_post_thumbnail($p->id)){//投稿にサムネイルがある場合の処理
$thumb_id = get_post_thumbnail_id($p->id);
$thumb_array = wp_get_attachment_image_src( $thumb_id, 'full');
$thumb = '<img src="'.$thumb_array[0].'" alt="'.$p->title.'">';
} else if(!empty($attachment_id)) {//サムネイルがないのでデフォルトカテゴリ画像を表示
$thumb = wp_get_attachment_image($attachment_id,'full',false,array( 'class' => 'zoom-img' ));
$thumb = preg_replace( '/(width|height|srcset|sizes)="(.*?)"\s/', '', $thumb );
} else {//サムネイルなしの場合の処理
$thumb = '<img sec="'.get_template_directory_uri().'/images/default.jpg" alt="'.$p->title.'">';
}
$output = '<li><div class="image-left"><a href="' . get_the_permalink($p->id) . '">' . $thumb . '</a></div><div><p class="lank">位</p><p class="tit"><a href="' . get_the_permalink($p->id) . '">' . $p->title . '</a></p></div></li>';
return $output;
}
if ( !is_admin() ) add_filter( 'wpp_post', 'my_custom_single_popular_post', 10, 3 );//管理画面では除外
3 ~ 22 行目、28 ~ 30 行目が追加した箇所です。
その他の設定
人気記事 0 件のとき
表示できる記事が 1 件もないときは、デフォルトだと英語で表示されます。
日本語にするなら functions.php に以下を記述。
// 人気記事0件時のテキスト
function my_custom_no_posts_found( $no_data_html ){
$output = '<p class="wpp-no-data">表示できる記事がありません。</p>';
return $output;
}
add_filter( 'wpp_no_data', 'my_custom_no_posts_found', 10, 1 );
view 数が更新されない
wp_head() 関数が有効になっていないのかもしれません。
wp_head を読み込むと、サイトの上部にアドミンバーが表示されますが、邪魔な場合は以下を functions.php に記述して非表示に出来ます。
//admin_bar を非表示にする
add_filter( 'show_admin_bar', '__return_false' );
もしくは、Chrome の『WordPress Admin Bar Control』という拡張機能でも非表示に出来ます。
マルチサイトで有効化する場合
「ネットワークで有効化」ではなく、個別に有効化させて下さい。