コンテンツへ移動
SUMIBIBLOG
ねこ

WordPress自作テーマ!カテゴリーページのカスタマイズ

WordPress,自作テーマ

このページには広告が含まれています。

カテゴリーページを作りました。最近になってカテゴリーページにアクセスしてくださる方が増えたので、見た目を整えることにしました。一つの話題に絞った専門性の高いサイトだとトップのページが検索順位が高くなり、雑記のブログの場合はカテゴリーが高くなるようです。

WordPressでカテゴリーページは「category.php」が存在すれば「category.php」で、「category.php」が存在しなければ「archive.php」を使って出力されます。また、「archive-(スラッグ).php」「category-(スラッグ).php」を作成するとカテゴリーごとに大きく違うデザインで作成できます。

今回は3つのカテゴリーを例にします。カテゴリーの名前とスラッグは以下の通りです。

カテゴリー名 ブログ WordPress プログラム
スラッグ blog wordpress program

WordPressは初期状態では「archive.php」を利用して「カテゴリーページ」「日付アーカイブ」「タグアーカイブ」を出力します。「archive.php」に変更を加えると「日付アーカイブ」「タグアーカイブ」にも影響を及ぼすので「category.php」を使うほうが良いのですが、以下のコードを「functions.php」に加えることで「日付アーカイブ」「タグアーカイブ」が出力されなくなります。また、「タグアーカイブ」は「タグ」を設定しなければ出力されません。

// 日付アーカイブの削除
add_filter('date_rewrite_rules', '__return_empty_array');

// タグページの削除
add_filter('tag_rewrite_rules', '__return_empty_array');
目次
  1. カテゴリー別の画像を表示
  2. カテゴリー別の文章を表示
  3. パンくずリストとタイトルの表示
  4. メタタグ
  5. 記事の並び順を変える

カテゴリー別の画像を表示

カテゴリーの各ページに画像を表示させます。画像のファイル名に規則性を持たせることで同じコードで複数の画像を表示させます。

スマートフォン用の画像はデバイスの幅が500px以下の場合に表示します。解像度は縦横1000pxの大きさを用意します。画像のアスペクト比を変更する場合はwidthとheightなど、画像の大きさに関する値を変更して下さい。

スマートフォン用の画像 PC用の画像(小) PC用の画像(大)
category1s.webp category1m.webp category1l.webp

PC用は通常用、Retina用の両方を用意します。カテゴリーごとの画像末尾を変えることでカテゴリー別の画像を表示させます。

if (in_category('blog')) {
    $image = 'category1';
    $alt = '画像の説明';
} elseif (in_category('wordpress')) {
    $image = 'category2';
    $alt = '画像の説明';
} elseif (in_category('program')) {
    $image = 'category3';
    $alt = '画像の説明';
}
echo '<div class=tw>
    <div class=ti>
        <picture>
            <source srcset=/wp-content/themes/theme-name/images/'.$image.'s.webp media=(max-width:500px) width=500 height=500>
            <source srcset="/wp-content/themes/theme-name/images/'.$image.'m.webp 1x,/wp-content/themes/theme-name/images/'.$image.'l.webp 2x" media=(min-width:501px) width=600 height=300>
            <img src=/wp-content/themes/theme-name/images/'.$image.'s.webp alt='.$alt.' decoding=async fetchpriority=high width=500 height=500>
        </picture>
    </div>
</div>';

転職のためのプログラミングスクール【無料PHPスクール】

カテゴリー別の文章を表示

条件分岐でカテゴリーごとの文章を表示させています。

global $paged;
if($paged < 2){

    if (in_category('blog')) {
        echo '<p>ブログの文章</p>';
    } elseif (in_category('wordpress')) {
        echo '<p>WordPressの文章</p>';
    } elseif (in_category('program')) {
        echo '<p>プログラムの文章</p>';
    } 
}

カテゴリーの編集ページの説明を表示させる場合は下のコードになります。「category_description()」の出力にはPタグが含まれています。

echo category_description()

逆にメタタグなどにカテゴリーの説明を表示させたい場合は、Pタグが不要なので下のコードになります。

$category_description = trim(strip_tags(category_description()));

パンくずリストとタイトルの表示

WordPressのカテゴリーアーカイブの表示は「カテゴリー:カテゴリー名」のように前に「カテゴリー:」が表示されるので、これを消すために「functions.php」に下のコードを追加します。

add_filter('get_the_archive_title', function ($title) {
    if (is_category()) {
        $title = single_cat_title('', false);
    }
    return $title;
});

パンくずリストとタイトルを同じにします。カテゴリーページの2ページ以降にはページ数を表示します。

<nav aria-label=現在位置>
    <a href="<?php echo home_url();?>">ホーム</a>
    <span>
        <?php
        global $paged;
        if ($paged >= 2) {
            $ti = 'カテゴリー' . get_the_archive_title() . 'ページ' . $paged;
        } else {
            $ti = 'カテゴリー' . get_the_archive_title() . '';
        }
        echo $ti;
        ?>
    </span>
</nav>
<h1><?php echo $ti;?></h1>

メタタグ

カテゴリーページ用のメタタグはカテゴリーの編集ページの説明をメタディスクリプションとして表示させています。各ページ用の画像を用意して下さい。

global $paged;
    $description = trim(strip_tags(category_description()));
    $url = get_pagenum_link($paged);
    if ($paged >= 2) {
        $title = 'カテゴリー' . esc_attr(get_the_archive_title()) . 'ページ' . $paged ;
    } else {
        $title = 'カテゴリー' . esc_attr(get_the_archive_title());
    }
    echo '<title>' . esc_attr($title) . '</title>';
    echo '<meta name=description content="' . esc_attr($description) . '">';
    if ($paged < 2){
        echo '<link rel=canonical href=' . esc_url($url) . '>';
    }
    echo '<meta property=og:locale content=ja_JP>';
    if (is_category('blog')) {
        echo '<meta property=og:image content="ブログの画像URL">';
    } elseif (is_category('wordpress')) {
        echo '<meta property=og:image content="WordPressの画像URL">';
    } elseif (is_category('プログラム')) {
        echo '<meta property=og:image content="プログラムの画像URL">';
    }
    echo '<meta property=og:title content="' . esc_attr($title) . '">';
    echo '<meta property=og:description content="' . esc_attr($description) . '">';
    echo '<meta property=og:url content=' . esc_url($url) . '>';
    echo '<meta property=og:site_name content=' . esc_url(bloginfo('name'));
    echo '<meta name=twitter:card content=summary_large_image>';
    if (get_previous_posts_link()) {
        echo '<link rel=prev href=' . esc_url(get_pagenum_link($paged - 1)) . '>';
    }
    if (get_next_posts_link()) {
        echo '<link rel=next href=' . esc_url(get_pagenum_link($paged + 1)) . '>';
    }

記事の並び順を変える

標準では投稿日の新しい順番に並んでいる、カテゴリーページ内の記事の順番を下記のように変更します。

まずはGoogle Analytics APIを使ってデータを取得します。一度のデータの取得数の上限は1000ですが、大きいほど処理が重くなります。

[2023]Google Analytics APIを利用した人気記事ランキングを表示する[WordPress]
https://sumibi-blog.com/
Google

ページIDを並べ替える処理の負荷が高いので、Transient APIを使って7日間キャッシュしています。下のコードを「functions.php」に加えると並び順が変更されます。

// アーカイブページの順番変更
add_action('pre_get_posts', 'custom_sort_category_by_pageviews');

function custom_sort_category_by_pageviews($query) {
    // 管理画面、メインクエリ以外、カテゴリーアーカイブページ以外では何もしない
    if (is_admin() || !$query->is_main_query() || !is_category()) {
        return;
    }

    // カテゴリ別キャッシュキー
    $current_id = get_queried_object_id();
    $transient_key = 'category_' . $current_id;

    // --- キャッシュチェック ---
    $cached_ids = get_transient($transient_key);
    if ($cached_ids !== false && is_array($cached_ids)) {
        $query->set('orderby', 'post__in');
        $query->set('post__in', $cached_ids);
        return;
    }
    // --- 1. ページビューデータの読み込み ---
    $analytics_path = get_stylesheet_directory() . 'テーマ内のjsonファイル';
    if (!file_exists($analytics_path)) {
        return;
    }

    $json_content = file_get_contents($analytics_path);
    if ($json_content === false) {
        return;
    }

    $page_views_data = json_decode($json_content, true);
    // JSONデコードが成功し、配列であることを確認
    if (!is_array($page_views_data)) {
        return;
    }

    // URLスラッグ => ページビュー数の連想配列を作成
    $pageviews_map = [];
    foreach ($page_views_data as $entry) {

        if (isset($entry['url'], $entry['page_views']) && is_string($entry['url'])) {
            $path = wp_parse_url($entry['url'], PHP_URL_PATH);
            $slug = trim($path, '/');
            if (!empty($slug)) {
                 $pageviews_map[$slug] = (int) $entry['page_views']; 
            }
        }
    }

    // 有効なページビューデータがない場合は終了
    if (empty($pageviews_map)) {
        return;
    }

    // --- 2. カテゴリ内の全投稿IDを取得 ---
    $category_id = $query->get('cat'); 

    $args = [
        'posts_per_page' => -1,
        'post_type'      => 'post',
        'post_status'    => 'publish',
        'cat'            => $category_id,
        'fields'         => 'ids',
    ];
    $all_post_ids_in_category = get_posts($args);


    // カテゴリに投稿がない場合は終了
    if (empty($all_post_ids_in_category)) {
        return;
    }

    // --- 3. 投稿をスコアリングして分類 ---
    $scored_posts   = [];
    $no_score_posts = [];

    foreach ($all_post_ids_in_category as $post_id) {
        $slug = get_post_field('post_name', $post_id);

        if (!empty($slug) && isset($pageviews_map[$slug])) {
            $scored_posts[$post_id] = $pageviews_map[$slug];
        } else {
            $no_score_posts[$post_id] = $no_score_posts[$post_id] = get_post_modified_time('U', false, $post_id);
        }
    }
    // --- 4. 各グループをソート ---
 
    arsort($scored_posts, SORT_NUMERIC);
    arsort($no_score_posts, SORT_NUMERIC);

    // --- 5. 最終的な投稿IDの順序を作成 ---
    $sorted_post_ids = array_merge(array_keys($scored_posts), array_keys($no_score_posts));

    // 並び替え後のIDリストが空なら何もしない
    if (empty($sorted_post_ids)) {
        return;
    }

    set_transient($transient_key, $sorted_post_ids, 1 * WEEK_IN_SECONDS);

    // --- 6. メインクエリを変更 ---
    $query->set('orderby', 'post__in'); 
    $query->set('post__in', $sorted_post_ids); 

}

最後までお読みいただき、誠にありがとうございます。

はてな Pocket Feedly 𝕏
「アイコンフォントの死」とSVGへの移行とBase64でのファビコン表示 Icon Fonts SVG 間違って生成したURLをGoogle Search Consoleから削除する方法 google-search-console プラグインなしでWordPressブログを運用するメリットと方法 wordpress-blog-without-plugins WordPressのキャッシュについて整理しキャッシュシステムを自作する [2023]Google Analytics APIを利用した人気記事ランキングを表示する[WordPress] Google Analytics API Microsoft Clarityを使ってアクセスランキングを作る[WordPress] Microsoft Clarity access ranking Amazon PA-API v5.0を利用した商品紹介リンクを作る Amazon Products Advertising API 5.0 PageSpeed Insightsのスコアを下げずにウェブフォントを使う pagespeed insights web fonts
管理者

ほんだ

当サイトの管理者 : 炭火で美味しいものを作ることを中心に、日々の趣味についてを文章にすることで、WordPressを使ってのWebページ作成を忘れないようにしてるブログです。熱帯魚の世話や野菜の栽培、Linuxについてなど、興味のあることを書いています。兵庫県在住。