前置きが長いのでコードだけコピペしたい方は目次よりジャンプして下さい。
作ろうと思ったきっかけなど
※ベースとなるHTMLとCSSはデイトラの「TF-30」というテーマを使用しています。別テーマを使用されている方は適宜読み替えてください。ちなみにSWELLだと驚くほど簡単に同機能を実装できます。おすすめ。
きっかけはデイトラのカスタム3兄弟のくだりでカスタム投稿タイプを使用して制作実績のページを作るレッスンが出てきたことでした。元々は制作ジャンルがURLで切り替わるようにできていたのですが、ここをAjax(って最近あんまり言わない)でサクサク切り替わるように実装できないかと。
URL版それはそれでSEO的にはあったほうがいいのかもですが人が見るのには軽い方がいいでしょ!ということで作ってみました。
思いついてから作り上げるまでにかなり時間と労力を使いましたが今の自分にちょうどいいレベル感で勉強になりました!…とはいえ8割方ChatGPTに書いてもらったのですが。笑 そのためわかる人が見ると「ん?ここ変じゃない?」というような箇所が散見されるかと思いますがとりあえず動くことを目標としたため悪しからず。
検索したワードなど
何か調べるのに、キーワードにたどり着くまでが第一の難関なんですよね。今回はWP_Queryとtax_query、foreachじゃないかと思います。
参考にしたページ
死ぬほど検索していろんなページを血眼になって見ましたが特に参考になったページをリンクしておきます。
いろんなサイトでこのページがかなり参考にされていて、10年経った今も代わりになるようなページが見当たらないことから、カテゴリー別ではなくターム別というのがマニアックなのか、はたまたそもそもやる人が少ないのか?
しかししつこく検索していると他にも似たような事にチャレンジしている方が何名か。
https://gatespace.jp/2012/05/14/view-posts-each-category/
こちらなんと11年前の記事!タブで切り替えたいというところまで同じです。
https://teratail.com/questions/96254
これもやりたい事としては近い。2017年の質問。
https://teratail.com/questions/215805
そうそう。似てる!2019年と比較的新し目で回答コードもありますが残念ながら動かず。しかし考え方は参考になりました。
枚挙にいとまがないのでこのあたりでやめます。
実際のコード
いいからコードはよ!という方お待たせしました。以下が完成コードです。archive-work.phpという名前でWPのテーマファイルに入れてあげることでタクソノミーのジャンル一覧ページのテンプレートとして動かしています。(例では制作実績一覧ページ)
<?php
/**
* Archive Work
*/
get_header();
?>
<div class="mainvisual">
<div class="inner">
<div class="mainvisual-content">
<div class="mainvisual-title">制作実績</div>
</div>
</div>
</div>
<?php if (function_exists('bcn_display')) : ?>
<div class="work-breadcrumb">
<div class="inner">
<div class="breadcrumb">
<?php bcn_display(); ?>
</div>
</div>
</div>
<?php endif; ?>
<div id="content" class="content-work">
<div class="inner">
<main id="primary">
<div class="genre-nav tab">
<?php
$tabs = array(
array('name' => 'Webサイト制作', 'slug' => 'web'),
array('name' => 'SEO支援', 'slug' => 'seo'),
array('name' => 'その他', 'slug' => 'other')
);
array_unshift($tabs, array('name' => 'すべて', 'slug' => 'all'));
?>
<?php foreach ($tabs as $tab) : ?>
<div class="genre-nav-link tab">
<a href="#<?php echo $tab['slug']; ?>" class="<?php echo ($tab['slug'] === 'all') ? 'is-active' : ''; ?>">
<?php echo $tab['name']; ?>
</a>
</div>
<?php endforeach; ?>
</div>
<?php foreach ($tabs as $tab) : ?>
<?php
if ($tab['slug'] === 'all') {
$args = array(
'post_type' => 'work',
'posts_per_page' => 6
);
} else {
$args = array(
'post_type' => 'work',
'posts_per_page' => 6,
'tax_query' => array(
array(
'taxonomy' => 'genre',
'field' => 'slug',
'terms' => $tab['slug']
),
)
);
}
$the_query = new WP_Query($args);
?>
<?php if ($the_query->have_posts()) : ?>
<div id="<?php echo $tab['slug']; ?>" class="tab_area <?php echo ($tab['slug'] === 'all') ? 'is-show' : ''; ?>">
<div class="entries entries-work">
<?php while ($the_query->have_posts()) : $the_query->the_post(); ?>
<a href="<?php the_permalink(); ?>" <?php post_class(array('entry-item', 'entry-item-horizontal')); ?>>
<!-- entry-item-img -->
<div class="entry-item-img">
<?php if (has_post_thumbnail()) {
the_post_thumbnail('my_thumbnail');
} else {
echo '<img src="' . esc_url(get_template_directory_uri()) . '/img/noimg.png" alt="">';
} ?>
</div><!-- /entry-item-img -->
<!-- entry-item-body -->
<div class="entry-item-body">
<div class="entry-item-meta">
<div class="entry-item-tag"><?php echo esc_html(get_the_terms(get_the_ID(), 'genre')[0]->name); ?></div><!-- /.entry-item-tag -->
</div><!-- /.entry-item-meta -->
<h2 class="entry-item-title"><?php the_title(); ?></h2><!-- /.entry-item-title -->
<div class="entry-item-excerpt">ここに抜粋が入ります</div><!-- /.entry-item-excerpt -->
</div><!-- /.entry-item-body -->
</a><!-- /.entry-item -->
<?php endwhile; ?>
</div><!-- /.entries -->
</div>
<?php endif; ?>
<?php wp_reset_postdata(); ?>
<?php endforeach; ?>
<?php if (paginate_links()) : ?>
<!-- pagenation -->
<div class="pagenation">
<?php
echo wp_kses_post(
paginate_links(
array(
'end_size' => 0,
'mid_size' => 1,
'prev_next' => true,
'prev_text' => '<i class="fas fa-angle-left"></i>',
'next_text' => '<i class="fas fa-angle-right"></i>',
)
)
);
?>
</div><!-- /.pagenation -->
<?php endif; ?>
</main><!-- /primary -->
</div><!-- /.inner -->
</div><!-- /.content -->
<?php get_footer(); ?>
タブ
基本的な仕組みについて
タブで作るページは大きく「タブ」と「パネル」という概念が出てくることを覚えておくといいかもしれないです。まずタブとはメニューの部分ですね。文房具のインデックスファイルに例えると「見出し山」の部分にあたります。パネルはファイルの部分に当たります、と言ったらわかりやすいですかね。
タブの仕組みについては以下のページがわかりやすかったです。
最初この概念(activeクラス付け外しで表示/非表示切り替え)が理解できず、jQueryの本に載っていたhideメソッドを使いましたが、子孫のクラスにdisplay: none;がかかってしまい表示されないとい事態に陥ったのでこちらの方がおすすめです。(入れ子になっていない場合ならhideメソッドでもいいかもしれないけど)
https://teratail.com/questions/43121
ちなみにこの方と同じ状況になりました。
all以外のスラッグをforeachで回す
ここではall以外のスラッグをforeachで回すのがポイントです。allも配列の中に含めてもいいようなもんですが、含めるとなぜか中身が出なかったです。allだけarray_unshiftという関数でくっつけてあげます。(このへんよく分かってません)
パネル
ここ今回の要ですね!まずslugがallの場合のみpost_typeで全て出力します。それ以外の場合はpost_typeと併せてtax_queryを使って出力します。
あとはWP_Queryを使ってサブループ⇨ループの内容を書いてあげる⇨最後にwp_reset_postdataでメインループに戻す
という流れで完成です!
jQueryのコード
内容としてはタブとパネルにis-active/is-showクラスをつけ外ししているだけです。これもChatGPT様のお世話になり、よくわからないけど動いたというレベルです。
/* tab */
jQuery(function () {
// 最初のタブをアクティブ状態にする
jQuery('.tab a:first').addClass('is-active');
// すべてのWorkを表示する
jQuery('.tab_area:first').addClass('is-show');
// クリックしたタブに対応するWorkを表示する
jQuery(".tab a").on("click", function (e) {
e.preventDefault();
var $this = jQuery(this);
var tab_area = $this.attr("href").substring(1);
jQuery(".tab a").removeClass("is-active");
$this.addClass("is-active");
jQuery('.tab_area').removeClass('is-show');
jQuery("#" + tab_area).addClass("is-show");
});
});
あとはクリックイベントがスムーススクロールとかぶってしまい、タブをクリックするとページの上に飛ぶという事態になったため、スムーススクロールのコードの一行目に.not(“.tab a”)を加えることでバッティング回避。
CSSのコード
とどのつまりこれだけで隠したり見せたりしてるだけという単純なカラクリなんですよね。しかし実装に時間かかった。
.tab_area {
display: none;
}
.tab_area.is-show {
display: block;
}
リンク集
表示形式は違うけどイメージを掴むのに参考になったページにリンクを貼っておきますね。
https://www.tipswork.net/wordpress/748/
https://deep-space.blue/web/1227
https://hirashimatakumi.com/blog/4147.html
https://gist.github.com/senooat/695603501ab7bc8306a1268ef45eb7b6
https://zxcvbnmnbvcxz.com/wp-taxonomy-term/index.html
https://qiita.com/39_isao/items/bda8cda119bcc87ff3cb
https://web.contempo.jp/weblog/tips/post-1338
https://www.nowte.net/wordpress/create-custom-taxonomy-template/
コメント