【WordPress】カテゴリー別人気記事を表示する

2023年2月7日

私のサイトではカテゴリーがたくさん増えていてカテゴリごとに記事のランキングをしたいと思いました。
例えばラズパイ気になってきたのにC#の記事がランキングにあるのはあまり喜ばしいとは言えませんからね

※この記事は「WordPress Popular Posts」プラグインがインストールされていることを前提としています。

カテゴリー別の記事ランキングを取得する。

以下のコードをコピペしてfunction.phpに貼り付けます。当サイトのブログカードの作り方のショートコードをコピーしている場合、nm_get_excerpt_post関数が重複するのでエラーになります。その場合、nm_get_excerpt_postは同じソースコードなので、省いてコピーしてください。

//------------------------------------------
// カテゴリー別人気記事(Start)
//------------------------------------------
//ブログカードのレイアウトを生成
function nm_wpp_category_populer($url, $title, $excerpt, $image_url, $prefix)
{	
    return '<a href="'. $url .'" class="'. $prefix .'-wpp-href">' .
               '<div class="'. $prefix .'-wpp-box">' .
                   '<div class="'. $prefix .'-wpp-thumbnail">' . 
                       '<img src="' . $image_url . '" alt="' . $title . '"/>' .
                   '</div>' .
                   '<div class="'. $prefix .'-wpp-content">' .
                       '<div class="'. $prefix .'-wpp-title">'. $title .' </div>' .
                       '<div class="'. $prefix .'-wpp-excerpt">'. $excerpt .'</div>' .
                   '</div>' .		          
               '</div>' .               
           '</a>';
}

//記事の文章を抜粋して取得する
function nm_get_excerpt_post( $post_id, $length = 55 )
{
    //指定された投稿を取得
    $post = get_post( $post_id );
    //投稿からショートコードを削除
    $post_non_code_content = strip_shortcodes( $post->post_content );
    //指定した文字列文返却する
    return oldwp_trim_words($post_non_code_content, $length);
}
//ショートコード
function nm_wpp_get_category_populer_list($atts) 
{
    //imageがない場合の画像の設定
    $no_image = "";    
    //エラーになった時の文字を指定しておく
    $err_msg = "<p>人気記事取得失敗</p>";

    //初期値を設定して連想配列($atts)を変数($category_slug, $length, $prefix, $limit, $range, $type)に変換
    extract(shortcode_atts(array('category_slug'=>"", 'length'=>55, 'prefix'=>"nm", 'limit'=>10, 'range'=>"all", 'type'=>"" ), $atts));

    if (empty($category_slug))
    {
        //現在のカテゴリーを取得
        $category = get_the_category();
        $category = $category[0];
    }
    else
    {
        //カテゴリーIDをスラッグから取得する
        $category = get_category_by_slug($category_slug);
        //カテゴリー取得失敗したらエラー
        if (!$category) return $err_msg;
    }

    global $wpdb;
    //カテゴリー指定
    $where_category = " `postid` in ( SELECT object_id FROM {$wpdb->term_relationships} WHERE term_taxonomy_id = '{$category->term_taxonomy_id}'    )";

    //期間設定
    $where_range = "";

    switch ($range) {
        case "day":
			$date_from = date('Y-m-d',strtotime('-1 day'));
			$where_range = " and `view_date` > '" . $date_from. "'";
            break;
        case "week":
			$date_from = date('Y-m-d',strtotime('-1 week'));
			$where_range = " and `view_date` > '" . $date_from. "'";
            break;
        case "month":
			$date_from = date('Y-m-d',strtotime('-1 month'));
			$where_range = " and `view_date` > '" . $date_from. "'";
            break;
        default:
            if (is_numeric($range))
            {
				$date_from = date('Y-m-d',strtotime('-' . $range . ' day'));
                $where_range = " and `view_date` > '" . $date_from. "'";
            }
            break;
    }

    //sql文の生成
    $sql = "SELECT `postid` as postid , SUM( `pageviews` ) as pageviews FROM `{$wpdb->prefix}popularpostssummary` WHERE {$where_category} {$where_range} GROUP BY `postid` ORDER BY 2 DESC LIMIT 0 , {$limit}";

    //SQLの実行
    $results = $wpdb->get_results($sql);

    //記事リストを設定
    $list_tag = empty($type) ? "ul" : "ol type=\"{$type}\" "; 
    $popular_list = '<'. $list_tag. ' class="' . $prefix . '-wpp-list">';
    //SQLの結果を取得
    foreach($results as $row) {

        //postIDの取得
        $post_id = $row->postid;

		//urlの取得
		$url = get_permalink($post_id);
		
        //タイトルの取得
        $title = esc_html(get_the_title($post_id));

        //記事の抜粋
        $excerpt = esc_html(nm_get_excerpt_post($post_id, $length));

        //アイキャッチ画像を取得する
        if (has_post_thumbnail($post_id))
        {
            //アイキャッチ取得
            $image = oldwp_get_attachment_image_src(get_post_thumbnail_id($post_id),'medium');
            $image_url = $image[0];
        }
        else
        {
            //アイキャッチがなければ代わりの絵
            $image_url = $no_image;
        }

        //リンク用の枠を設定
        $popular_list .= "<li>" . nm_wpp_category_populer($url, $title, $excerpt, $image_url, $prefix) . "</li>";
    }

    //ショートコードを呼び出したところに挿入する場合、returnで返す。
    return $popular_list . "</" . (empty($type) ? "ul" : "ol") . ">";

}


add_shortcode("nm_cat_pop_list", "nm_wpp_get_category_populer_list");
//------------------------------------------
// カテゴリー別人気記事(End)
//------------------------------------------

テーマエディターを起動します。

function.phpの末尾にコピーしたコードを貼り付けます。

ショートコードを実行します。例えば記事中に以下のように記載すると

[nm_cat_pop_list ]

現在のカレントで人気記事順に表示してくれます。デフォルトの期間は全期間です。

CSSでオシャレにする

CSSを使って出力したHTMLをデザインを変えていきます。

ショートコードをコピーした時と同様に、CSSをコピーしてテーマエディターのstyle.cssにペーストしファイル更新をします。

カード型の人気記事表示

/*-------------------------
  人気記事リスト
-------------------------*/
.nm-wpp-list
{
	width:100%;
	margin:0 !important;
	padding:0 !important;
    display: block;
}
ul.nm-wpp-list{
    list-style: none;
}

ul.nm-wpp-list li{
	display: inline-block;
	width: 32%;
    min-width: 200px;
	height: 350px;
	margin:0 !important;
	padding:10px;
}

a.nm-wpp-href {
	display: inline-block;
    margin: 1rem 1rem;
    width: 100%;
    overflow: hidden;
    border-radius: 8px;
    box-shadow: 0 4px 15px rgba(0,0,0,.2);
	text-decoration: none;
}
a.nm-wpp-href:hover {
    box-shadow: none;
    opacity: .8;
}

.nm-wpp-thumbnail {
    flex: 1;
    height:40%;
	text-align: center;
}

.nm-wpp-thumbnail img{
    height:150px;
	object-fit: cover;
}

.nm-wpp-content {
    flex: 2.5;
	height: 180px;
}

.nm-wpp-title {
    font-size: 18px;
    font-weight: 600;
    color: #428bca;
    padding-bottom: 5px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.nm-wpp-excerpt {
    border-top: solid 1px #428bca;
    color: #808080;
    font-size: 13px;
    padding: 10px;
}

サイドバーにも使える縦につながった人気記事

ショートコード例
[nm_cat_pop_list category_slug="csharp" limit=5]

.nm-wpp-list
{
    width:100%;
    margin:0 !important;
    padding:0 !important;
    display: block;
}
ul.nm-wpp-list{
    list-style: none;
}

ul.nm-wpp-list li {
    display: block;
    width: 100%;
    min-width: 200px;
    margin: 0 !important;
    height: 130px;
    border-bottom: dotted 1px #000000;
}

a.nm-wpp-href {
    display: block;
    margin: 1rem 0;
    width: 100%;
    height: 120px;
    text-decoration: none;
}
a.nm-wpp-href:hover {
    box-shadow: none;
    opacity: .8;
}
.nm-wpp-box {
    position: relative;
}

.nm-wpp-thumbnail {
    float: left;
    position: absolute;
    left: 0px;
    top: 0px;
    text-align: center;
    padding: 10px;
    width: 120px;
}

.nm-wpp-thumbnail img{
    height:100px;
    width:100px;
    object-fit: cover;
}

.nm-wpp-content {
    float: left;
    position: absolute;
    left: 0px;
    top: 0px;
    padding-left: 120px;
    width: 100%;
}

.nm-wpp-title {
    font-size: 1.4rem;
    font-weight: 600;
    color: #428bca;
    padding-bottom: 5px;
    line-height: 1.2 !important;
    /* overflow: hidden; */
    /* text-overflow: ellipsis; */
    /* white-space: nowrap; */
}
.nm-wpp-excerpt {
    border-top: solid 1px #428bca;
    position: relative;
    max-height: calc(13 * 1.2 * 3 * 1px);
    font-size: 13px;
    line-height: 1.2 !important;
    word-break: break-all;
    overflow: hidden;
}

.nm-wpp-excerpt::before,
.nm-wpp-excerpt::after {
position: absolute;
background: #fff;
}
.nm-wpp-excerpt::before {
content: '...';
top: calc(16 * 1.8 * (3 - 1) * 1px);
right: 0;
width: 1em;
}
.nm-wpp-excerpt::after {
content: '';
width: 100%;
height: 100%;
}

ランキング表示用ショートコード例
[nm_cat_pop_list category_slug="csharp" limit=5 type="1″]

  1. 【C#】ダイアログを自作してみる
    【C#】ダイアログを自作してみる
    こんにちは、ノムノムです。 今回は自分でダイアログを自作する方法をお話しします。 ダイアログ ダイアログとはユ…
  2. Visual Studio Installerを使ってWindowsインストーラー(msi)の作成の仕方
    Visual Studio Installerを使ってWindowsインストーラー(msi)の作成の仕方
    今回は、Windowsインストーラーを作成する方法を紹介します。 Visual Studio Installe…
  3. 【C#】OpenCVを使って画像認識(テンプレートマッチング)
    【C#】OpenCVを使って画像認識(テンプレートマッチング)
    こんにちは、ノムノムです。 今回はC#で画像認識をやってみたいと思います。 OpenCVの記事を探すとWebカ…
  4. どこでも使える汎用性の高いプログレスバーダイアログを考えてみた
    どこでも使える汎用性の高いプログレスバーダイアログを考えてみた
    こんにちは、ノムノムです。 マルチスレッドのところでプログレスバーを使ったサンプルを作成しましたがもっと汎用性…
  5. 【C#】ファイルの属性(プロパティ)情報を取得する方法
    【C#】ファイルの属性(プロパティ)情報を取得する方法
    こんにちは、ノムノムです。 今回は、ファイルの持っているプロパティの情報を取得する方法を説明したいと思います。…
.nm-wpp-list
{
    width:100%;
    margin:0 !important;
    padding:0 !important;
    display: block;
}
ol.nm-wpp-list li {
    position: relative;
    margin-bottom: 20px;
    counter-increment: li;
    list-style-type: none;
}
ol.nm-wpp-list li::before {
    content: 'Rank ' counter(li);
    display: block;
    position: absolute;
    top: -1em;
    left: 10px;
    color: #666;
    font-size: 14px;
    line-height: 1;
    font-weight: bold;
}
ol.nm-wpp-list li:nth-of-type(1)::before {
    color: #e4aa1d;
}
ol.nm-wpp-list li:nth-of-type(2)::before {
    color: #9eaeb9;
}
ol.nm-wpp-list li:nth-of-type(3)::before {
    color: #b76901;
}
a.nm-wpp-href {
    display: block;
    margin: 1rem 0;
    width: 100%;
    height: 120px;
    text-decoration: none;
}
a.nm-wpp-href:hover {
    box-shadow: none;
    opacity: .8;
}
.nm-wpp-box {
    position: relative;
}

.nm-wpp-thumbnail {
    float: left;
    position: absolute;
    left: 0px;
    top: 0px;
    text-align: center;
    padding: 10px;
    width: 120px;
}

.nm-wpp-thumbnail img{
    height:100px;
    width:100px;
    object-fit: cover;
}

.nm-wpp-content {
    float: left;
    position: absolute;
    left: 0px;
    top: 0px;
    padding-left: 120px;
    width: 100%;
}

.nm-wpp-title {
    font-size: 1.4rem;
    font-weight: 600;
    color: #428bca;
    padding-bottom: 5px;
    line-height: 1.2 !important;
    /* overflow: hidden; */
    /* text-overflow: ellipsis; */
    /* white-space: nowrap; */
}
.nm-wpp-excerpt {
    border-top: solid 1px #428bca;
    position: relative;
    max-height: calc(13 * 1.2 * 3 * 1px);
    font-size: 13px;
    line-height: 1.2 !important;
    word-break: break-all;
    overflow: hidden;
}

.nm-wpp-excerpt::before,
.nm-wpp-excerpt::after {
    position: absolute;
    background: #fff;
}
.nm-wpp-excerpt::before {
    content: '...';
    top: calc(13 * 1.2 * (3 - 1) * 1px);
    right: 0;
    width: 1em;
}
.nm-wpp-excerpt::after {
    content: '';
    width: 100%;
    height: 100%;
}

使い方

[nm_cat_pop_list category_slug="カテゴリーのスラッグ" limit=件数 length=記事抜粋文字数 prefix="cssクラスprefix" range="取得期間" type="olのtype"]

以下が各パラメータの内容です

名称説明初期値
category_slugランキングを取得するカテゴリーのスラッグを設定します。
未設定だと現在のカテゴリーのスラッグを取得します。
現在のカテゴリー
limit取得する最大件数を取得します。10
length記事から抜粋する文字数を設定します。55
prefixタグクラスの名称にprefixを設定します。
これによりデザインを分けて利用することができます。
nm
range集計期間を日数で指定します。
また予約されている文字を入力することもできます。
day・・・1
week・・・7
month・・・1か月
all・・・全期間
all
typeolのtype属性を指定、指定されない場合はulタグになる指定なし

カスタマイズ

ショートコードをカスタマイズする

出力されるHTML文を変更したい場合、ショートコードで使用しているPHPを変更することで出力されるHTML文が変わります。

出力されるHTML文を変更したい

function.phpのnm_wpp_category_populer関数を編集します。
編集のことを考えてHTML出力部分をあえて関数化し、先頭に持ってきているのでわかりやすいと思います。

ショートコードで使用されている初期値を変更したい

function.phpの39行目の以下の部分がパラメータが設定されなかった時の初期値部分です。

//初期値を設定して連想配列($atts)を変数($category_slug, $length, $prefix, $limit, $range, $type)に変換
    extract(shortcode_atts(array('category_slug'=>"", 'length'=>55, 'prefix'=>"nm", 'limit'=>10, 'range'=>"all", 'type'=>"" ), $atts));

デザインをカスタマイズする

ショートコードのパラメータでprefixを設定することで様々なデザインを適用することができます。

cssを駆使してさまざまなデザインを考えてみてみるのもいいでしょう。

ここまで読んで頂いてありがとうございます。