カテゴリーページで並べ替え(ソート)ができるボタンを作る方法
目次
WordPressのカテゴリーページ(例: https://example.com/category/)で、
記事を「新着順」「古い順」にソートできるボタンを追加する方法を解説します。
1 実装のポイント
- functions.php にクエリ変更用のコードを追加する
- JavaScriptでボタンをクリックするとソート条件を切り替える
- CSSで見やすいボタンデザインにする
- LightningやCocoonテーマに合わせた調整サンプルも紹介
- カテゴリ・タグページのクエリパラメータやページ分割での重複を防ぐコードも追加
2 functions.php にコードを追加
- カテゴリーページでのソート処理を追加します。
- カテゴリ・タグページのクエリパラメータやページ分割での重複を防ぐコードを追加します。詳しくは、▶ カテゴリ・タグページのクエリパラメータやページ分割での重複を防ぐ方法をご覧ください。
//-------------------------------------------
// カテゴリーページでソート機能を有効化
//-------------------------------------------
function my_category_order( $query ) {
if( $query->is_main_query() && !is_admin() && is_category() ) {
$order = isset($_GET['order']) ? $_GET['order'] : 'desc';
$query->set( 'order', $order ); // desc:新着順, asc:古い順
}
}
add_action( 'pre_get_posts', 'my_category_order' );
//functions.php で canonical を明示的に出力する
add_action('wp_head', function() {
if (is_category()) {
$canonical = get_category_link(get_queried_object_id());
echo '' . "\n";
}
});
//-------------------------------------------
// カテゴリ・タグ・アーカイブの重複ページ対策
//-------------------------------------------
function custom_handle_duplicate_pages($mode = 'canonical') {
// クエリパラメータ ?order
if ((is_category() || is_tag() || is_archive()) && isset($_GET['order'])) {
if ($mode === 'canonical') {
$canonical = get_queried_object()->term_id
? get_term_link(get_queried_object())
: get_permalink();
echo '<link rel="canonical" href="' . esc_url($canonical) . '" />' . "\n";
} elseif ($mode === 'noindex') {
echo '<meta name="robots" content="noindex, follow">' . "\n";
}
}
// RSSフィード (/feed)
if (is_feed()) {
if ($mode === 'canonical') {
$canonical = get_post_type_archive_link(get_post_type()) ?: home_url();
echo '<link rel="canonical" href="' . esc_url($canonical) . '" />' . "\n";
} elseif ($mode === 'noindex') {
echo '<meta name="robots" content="noindex, follow">' . "\n";
}
}
// ページ分割 (/page/2 など)
if (is_paged()) {
if ($mode === 'canonical') {
$canonical = get_queried_object()->term_id
? get_term_link(get_queried_object())
: get_permalink();
echo '<link rel="canonical" href="' . esc_url($canonical) . '" />' . "\n";
} elseif ($mode === 'noindex') {
echo '<meta name="robots" content="noindex, follow">' . "\n";
}
}
}
// head にフックして実行
add_action('wp_head', function() {
// サイト方針に応じて 'canonical' か 'noindex' を選択
custom_handle_duplicate_pages('canonical');
});
3 テーマ別サンプルphp
アーカイブ・カテゴリーページ用ソートボタンのコードです。
3.1 Lightning用
ファイル名:main-archive.php
保存先:wp-content/themes/child-theme/g3/template-parts/main-archive.php
<?php
/**
* Archive main template
*
* @package Lightning G3
*/
/* =========================================
ソートボタン(新着順・古い順)
検索ページでは非表示
========================================= */
// 現在の順序取得
$order = isset($_GET['order']) ? $_GET['order'] : 'DESC';
?>
<div class="category-sort-buttons">
<a href="<?php echo esc_url( add_query_arg( 'order', 'DESC' ) ); ?>" class="sort-btn">新着順</a>
<a href="<?php echo esc_url( add_query_arg( 'order', 'ASC' ) ); ?>" class="sort-btn">古い順</a>
</div>
<?php
/* =========================================
アーカイブタイトルと説明文
========================================= */
if ( ! is_search() ) {
$post_top_info = VK_Helpers::get_post_top_info();
// タイトル表示
if ( $post_top_info['use'] || get_post_type() !== 'post' ) {
if ( is_year() || is_month() || is_day() || is_tag() || is_tax() || is_category() ) {
$archive_title = get_the_archive_title();
$archive_header_html = '<header class="archive-header"><h1 class="archive-header-title">'
. esc_html( $archive_title ) .
'</h1></header>';
echo wp_kses_post( apply_filters( 'lightning_archive_header', $archive_header_html ) );
}
}
// 説明文表示
if ( is_category() || is_tax() || is_tag() ) {
$archive_description = term_description();
if ( ! empty( $archive_description ) && 0 === get_query_var( 'paged', 0 ) ) {
$archive_description_html = '<div class="archive-description">' . wp_kses_post( $archive_description ) . '</div>';
echo wp_kses_post( apply_filters( 'lightning_archive_description', $archive_description_html ) );
}
}
}
/* =========================================
投稿ループ開始
========================================= */
$post_type_info = VK_Helpers::get_post_type_info();
do_action( 'lightning_loop_before' );
if ( have_posts() ) :
if ( apply_filters( 'lightning_is_extend_loop', false ) ) :
do_action( 'lightning_extend_loop' );
else :
$post_list_class = 'post-list vk_posts vk_posts-mainSection';
echo '<div class="' . esc_attr( $post_list_class ) . '">';
global $lightning_loop_item_count;
$lightning_loop_item_count = 0;
while ( have_posts() ) :
the_post();
// ループアイテムを読み込む
lightning_get_template_part( 'template-parts/loop-item', $post_type_info['slug'] );
$lightning_loop_item_count++;
do_action( 'lightning_loop_item_after' );
endwhile;
echo '</div> <!-- /.post-list -->';
endif;
// ページネーション
$pagination_args = array(
'mid_size' => 1,
'prev_text' => '≪',
'next_text' => '≫',
'type' => 'list',
'before_page_number' => '<span class="meta-nav screen-reader-text">' . __( 'Page', 'lightning' ) . ' </span>',
);
the_posts_pagination( apply_filters( 'lightning_pagenation_array', $pagination_args ) );
else :
echo '<div class="main-section-no-posts"><p>' . wp_kses_post( lightning_get_no_post_text() ) . '</p></div>';
endif;
do_action( 'lightning_loop_after' );
?>
3.2 ディレクトリ構造
- child-theme/
- g3/
- template-parts/
- main-archive.php
- tmp/
- category-content.php
- archive.php
- category.php
- functions.php
- footer.php
- header.php
- style.css
- js/
- category-sort.js
- images/
- logo.png
- g3/
3.3 Cocoon用
ファイル名:category-content.php
保存先:wp-content/themes/child-theme/tmp/category-content.php
<?php
/**
* Cocoon WordPress Theme
* category.php カスタマイズ版
*
* カテゴリーページにソートボタンを追加し、
* ボタン用のスタイルを同じファイル内に記述。
*
* - 新着順 / 古い順 のボタンを表示
* - 検索ページでは非表示
* - 管理画面でも見やすいようにコード整理済み
*/
if ( ! defined( 'ABSPATH' ) ) exit;
/* =========================================
ソートボタン(新着順・古い順)
※検索結果ページでは非表示
========================================= */
if ( ! is_search() ) : ?>
<!-- ソートボタン用のスタイル -->
<style>
.sort-buttons {
display: flex;
flex-wrap: wrap;
gap: 10px;
margin: 1.5em 0;
justify-content: center;
}
.sort-buttons .sort-button {
background: #f5f5f5;
border: 2px solid #ddd;
border-radius: 30px;
padding: 10px 18px;
font-size: 15px;
font-weight: 600;
color: #333;
cursor: pointer;
transition: all 0.25s ease;
min-width: 110px;
text-align: center;
}
.sort-buttons .sort-button:hover {
background: #0073aa;
color: #fff;
border-color: #0073aa;
transform: translateY(-2px);
box-shadow: 0 3px 6px rgba(0,0,0,0.15);
}
.sort-buttons .sort-button.active {
background: #ff6f61;
border-color: #ff6f61;
color: #fff;
}
@media (max-width: 600px) {
.sort-buttons { gap: 8px; }
.sort-buttons .sort-button {
flex: 1 1 100px;
padding: 12px 10px;
font-size: 14px;
}
}
</style>
<!-- ソートボタン本体 -->
<div class="sort-buttons">
<a href="<?php echo esc_url( add_query_arg( 'order', 'DESC' ) ); ?>" class="sort-button">新着順</a>
<a href="<?php echo esc_url( add_query_arg( 'order', 'ASC' ) ); ?>" class="sort-button">古い順</a>
</div>
<?php endif; ?>
<?php
/* =========================================
カテゴリーアイキャッチ・説明文の表示
========================================= */
$cat_id = get_query_var('cat');
$eye_catch_url = get_the_category_eye_catch_url($cat_id);
$content = get_the_category_content($cat_id);
if ( $eye_catch_url || $content ) : ?>
<article class="category-content article<?php echo esc_attr(get_additional_entry_content_classes()); ?>">
<header class="article-header category-header">
<!-- カテゴリータイトル -->
<?php cocoon_template_part('tmp/list-title'); ?>
<?php if ( $eye_catch_url ) :
$display_none = is_eyecatch_visible() ? '' : ' display-none';
$caption = get_caption_from_image_url($eye_catch_url);
?>
<div class="eye-catch-wrap<?php echo esc_attr($display_none); ?>">
<figure class="eye-catch">
<img src="<?php echo esc_url($eye_catch_url); ?>"
class="eye-catch-image wp-category-image"
alt="<?php echo esc_attr(get_the_category_title($cat_id)); ?>">
<?php if ( is_eyecatch_label_visible() && apply_filters('is_eyecatch_category_label_visible', true) ) : ?>
<span class="cat-label cat-label-<?php echo esc_attr($cat_id); ?>">
<?php single_cat_title( '', true ); ?>
</span>
<?php endif; ?>
<?php if ( is_eyecatch_caption_visible() && $caption ) : ?>
<figcaption class="eye-catch-caption">
<?php echo esc_html($caption); ?>
</figcaption>
<?php endif; ?>
</figure>
</div>
<?php do_action('category_eye_catch_after'); ?>
<?php endif; ?>
<!-- カテゴリーシェアボタン -->
<?php cocoon_template_part('tmp/category-sns-share-top'); ?>
<?php if ( is_large_pr_labels_visible() ) generate_large_pr_label_tag(); ?>
</header>
<?php if ( $content ) : ?>
<div class="category-page-content entry-content">
<?php echo $content; ?>
</div>
<?php endif; ?>
</article>
<?php else : ?>
<!-- アイキャッチ・説明が無い場合 -->
<?php cocoon_template_part('tmp/list-title'); ?>
<?php cocoon_template_part('tmp/category-sns-share-top'); ?>
<?php if ( is_large_pr_labels_visible() ) generate_large_pr_label_tag(); ?>
<?php endif; ?>
3.2 ディレクトリ構造
- child-theme/
- g3/
- tmp/
- category-content.php
- archive.php
- category.php
- functions.php
- footer.php
- header.php
- style.css
- js/
- category-sort.js
- images/
- logo.png
4 JavaScript にコードを追加
ソートボタンをクリックするとページをリロードしてソートを反映します。
ファイル名:category-sort.js
保存先:wp-content/themes/child-theme/js/category-sort.js
document.addEventListener('DOMContentLoaded', function() {
document.querySelectorAll('.sort-button').forEach(function(btn) {
btn.addEventListener('click', function() {
const sort = this.dataset.sort;
const url = new URL(window.location.href);
url.searchParams.set('sort', sort);
window.location.href = url.toString();
});
});
});
3.2 ディレクトリ構造
- child-theme/
- g3/
- template-parts/
- main-archive.php
- tmp/
- category-content.php
- archive.php
- category.php
- functions.php
- footer.php
- header.php
- style.css
- js/
- category-sort.js
- images/
- logo.png
- g3/
5 汎用CSS
/* -----------------------------
* カテゴリーソートボタン
* ----------------------------- */
/* ソートボタン全体の配置 */
.category-sort-buttons {
margin: 20px 0; /* 上下の余白 */
text-align: center; /* 中央揃え */
}
/* 各ソートボタン */
.category-sort-buttons .sort-btn {
display: inline-block; /* 横並び可能にする */
padding: 8px 15px; /* 上下8px、左右15pxの内側余白 */
margin: 5px; /* ボタン間の隙間 */
border: 1px solid #0073aa; /* 青の枠線 */
border-radius: 5px; /* 角丸5px */
background: #f7f7f7; /* 薄いグレー背景 */
color: #0073aa; /* 文字色 青 */
cursor: pointer; /* ホバー時に手の形に */
transition: 0.3s; /* ホバー時の変化を0.3秒で */
font-size: 14px; /* 文字サイズ */
}
/* ホバー時 */
.category-sort-buttons .sort-btn:hover {
background: #0073aa; /* 背景色を青に変更 */
color: #fff; /* 文字色を白に変更 */
}
6 Cocoon用
CocoonのCSSは、category-content.phpに直書きしてます。
7 完成イメージ
7.1 汎用CSS

7.2 Cocoon

8 代用プラグイン
コード編集が難しい場合は「Content Views」や「WP Grid Builder」などのプラグインを使って、
カテゴリーページにソート機能を実装することも可能です。
9 まとめ
- カテゴリーページにソートボタンを追加することで、ユーザーが見たい順に記事を並べ替えることができ、回遊率アップやユーザビリティ向上につながります。ぜひ自分のテーマに合わせてカスタマイズしてみてください。
- カテゴリ・タグページのクエリパラメータやページ分割での重複を防ぐコードを追加します。詳しくは、▶ カテゴリ・タグページのクエリパラメータやページ分割での重複を防ぐ方法をご覧ください。


