fbpx

メニュー

WordPressカテゴリーページをもっとカスタマイズしたい

高橋文樹 高橋文樹

この投稿は 12年 前に公開されました。いまではもう無効になった内容を含んでいるかもしれないことをご了承ください。

ぜったい需要あるし知りたいから書いてくれたしと言われたので書きます。最近、リクエストに答えてブログ書くのが楽だなーと感じる自堕落。

さて、WordPressをCMS的に使っていると、「カテゴリーアーカイブの情報を充実させたい」という需要がよくあると思います。

ケーススタディ

筋トレの情報サイトを作っているとしましょう。カテゴリー階層は大きく分けて3系統あります。

 

トレーニング方法
腕立て、スクワット、デッドリフトなど、トレーニング情報のジャンルがサブカテゴリーとしてぶら下がる
サプリメント
筋量を増やしたいとか、持久力を付けたいとか、体重を落としつつ筋肉をつけたいとか、そういった「サプリメント使用の目的」ごとにサブカテゴリーがわかれています。
トレーニングジム
サブカテゴリーとして地域がぶら下がっています。

 

図示するとこんな感じです。

カテゴリー
│
├トレーニング方法
│ ├腕立て
│ ├スクワット
│ └懸垂
│
├サプリメント
│ ├筋量肥大
│ ├ダイエット
│ └持久力
│
└トレーニングジム
  ├関東
  ├関西
  └中部

WordPressのカテゴリーは重複を許しますが、入力のルールとして「大カテゴリーをまたいだカテゴライズはしない」という制約があると仮定します。要するに、一つの投稿に対して「腕立て」と「関東」が両方つくということはないってことですね。

さて、WordPressのカテゴリーアーカイブページは基本的に「そのカテゴリーに属する投稿をずらっと並べたリスト」なのですが、このサイトでは大カテゴリー(トレーニング方法、サプリメント、トレージングジム)については、もうちょっとコンテンツを追加したいという要望があったとします。

ちょうど、Apple Storeにおける「Mac」のページのように、カテゴリーについて説明するある程度リッチなコンテンツがあり、それが定期的に更新されるという状況なわけですね。

AppleのMacページは新製品が出るとコンテンツが変わる
AppleのMacページは新製品が出るとコンテンツが変わる

WordPressのカテゴリーには、「説明」という項目があります。文章だけでちょろっと説明があればいいならそれを出力すれば済むのですが、画像を入れたりリンクをはったりとなると、物足りません。

カテゴリーにもちょろっと入力欄がある
カテゴリーにもちょろっと入力欄がある

で、こうした「カテゴリーアーカイブページに表示するリッチなコンテンツをWordPressの管理画面で楽々更新したい」という要望を叶えるためにどうすればいいかというお話です。

もうこの説明だけで疲れちゃいました……

ケース1: コンテンツ作成用の隠しカスタム投稿タイプを作る

さて、前述の要望を叶えるためにできる一つの案は、カスタム投稿タイプを作ることですが、これを隠しで作成します。カスタム投稿タイプはCustom Post Type UIとかで簡単に作れるのですが、ポイントはpublicをfalseにして、パーマリンクを与えないでおきながら、show_uiをtrueにして管理画面だけ作っておくという点です。今回の例では、投稿タイプをcategory-topとし、スラッグをカテゴリースラッグと一致させるようにしましょう。たとえば、トレーニング方法のカテゴリスラッグがtrainingだった場合、トレーニングトップはtrainingとする、というような感じです。

これで管理画面からトレーニングトップの編集画面でごちゃごちゃ入力し、公開します。で、category.phpをこんな風にします。

<?php
     $query = new WP_Query('post_type=category-top&name='.current(get_the_category())->slug);
     if($query->have_posts()): while($query->have_posts()): $query->the_post();
?>
     <?php the_content(); ?>
     ここはカテゴリートップで入力した情報が出力される
<?php endwhile; endif; wp_reset_query(); ?>

<?php if(have_posts()): while(have_posts()): the_post(); ?>
     ここはカテゴリーの一覧が出力されるループ
<?php endwhile; endif; ?>

これで、管理画面で入力した情報が表示されます。

ケース2: カテゴリートップを独立した別ページとして表示

さて、これはカスタム投稿タイプを作るまでは上と同じですが、投稿数が異様に多い場合はこっちのアプローチの方が良いかもしれません。

この方法では、カスタム投稿タイプを作るときにpublicをtrueにします。つまり、「トレーニングトップ」と「トレーニングカテゴリーのアーカイブページの1ページ目」はコンテンツとして異なるわけですね。これはAmazonを例にとるとわかりやすいのです。

Amazonの「本トップページ」と「本カテゴリーの一覧」は明確に役割が分かれています。前者は幾つかの特集的なコーナーがあり、後者は純粋なリストです。それぞれ用途も異なり、前者はAmazonの提示する序列を重視し、後者はユーザーの能動的な検索アクションを重視しています。

amazonの本トップページ
amazonの本トップページ
amazonの本カテゴリーページ
amazonの本カテゴリーページ

アーカイブにちょろっと何かを追加する程度であればケース1のやり方で問題ないと思いますが、ものすごく沢山コンテンツがあり、ユーザーに対して提供できる切り口がたくさんある場合はこちらのケース2のやり方がいいでしょう。こっちの方法では、single-category-top.phpを激しくカスタマイズすることになります。当然複数のループを書くことになるので、Codexのループページを熟読してください。

<?php
$cat_slug;
if(have_posts()): while(have_posts()): the_post(); ?>
     <?php
          //カテゴリースラッグを保存しておく
          $cat_slug = $post->post_name;
          //内容を出力
          the_content();
     ?>
<?php endwhile; endif; ?>
<?php
     //カテゴリースラッグからカテゴリーオブジェクトを取得
     $cat = get_category_by_slug($cat_slug);
     //子カテゴリーを全部取得
     $cat_children = get_categories("parent={$cat->term_id}");
     //リピート
     foreach($cat_children as $c):
?>
     <h3><?php echo $c->name; ?>の最新投稿</h2>
     <ul>
     <?php
          //子カテゴリーすべての最新5件を出力
          $query = new WP_Query("cat={$c->term_id}&posts_per_page=5");
          if($query->have_posts()): while($query->have_posts()): $query->the_posts();
     ?>
          <li><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></li>
     <?php endwhile; endif; ?>
     </ul>
<?php endforeach; ?>

というわけで、後半はめんどくさくなって端折ってしまいました。わからないことなどありましたらコメントください。

すべての投稿を見る

高橋文樹ニュースレター

高橋文樹が最近の活動報告、サイトでパブリックにできない情報などをお伝えするメーリングリストです。 滅多に送りませんので、ぜひご登録お願いいたします。 お得なダウンロードコンテンツなども計画中です。