カスタム投稿ページにリンクするとパンくずが迷子に?固定ページとアーカイブの問題を解決した方法
WordPressで「固定ページ」にクエリループブロックを使ってカスタム投稿を表示させたとき、困ったことがありました。
それは、カスタム投稿の個別ページを開くと、パンくずリストのリンク先が“固定ページ”ではなく“カスタム投稿のアーカイブページ”になってしまうこと。
固定ページからカスタム投稿ページへリンクしたページ
今回サンプルとして作成したページは 「店舗一覧」と言う固定ページです。この固定ページ内にはカスタム投稿の一覧をクエリーループで読み込んでいます。
カスタム投稿は「店舗一覧」というカスタム投稿タイプを作成し、その中にエリアを分けるためのタクソノミー「エリア」のなかに「尾張エリア」と「三河エリア」のタームがあります。このタクソノミーは固定ページにクエリーループで読み込む時の絞り込みに使います。

で、こちらでページを作るとこうなります。
まず、店舗一覧を見るための入り口のページを固定ページで作成します。各エリアへのリンクはクエリーループで読み込んだカスタム投稿のページタイトルです。(CSSでボタン風にデザインしてあります)

ここまでは問題ないのです。ここまでは……。
『一宮市店舗一覧』をクリックして一覧ページを開きます。カスタム投稿で作成したページにリンクします。
一見何の問題もないように見えますが、パンくずがカスタム投稿の構造で表示されています。

そしてこのパンくずの『店舗一覧』をクリックすると、元の固定ページの『店舗一覧』ではなくカスタム投稿のアーカイブページに戻ってしまいます。

ユーザーからすると、えっ?さっきと違うページに戻ってない?ってなります。
そう、ここは元の固定ページに戻りたいのです。
けれど、パンくずは自動でアーカイブに戻る仕様のため、思ったように制御できません。
今回はタクソノミーのなかにタームも使っていたので、さらにややこしいことに……。
カスタム投稿の構造になるとタームのアーカイブもできています。
図3の画像を見るとわかるのですが、パンくずのなかに『尾張エリア』と言うのができています。構造的には正しいのです。必要な時もあります。けれど、今回はこのパンくずはいらないのです。

この『尾張エリア』のパンくずをクリックすると、タクソノミーアカーブへ戻ります。

このページ、あっても良いのですが最初の設計の段階で作っていないページなのでいらないのです。最初の入り口の固定ページから行けるようにしていないし。(完全に制作者都合ですが……)
色々と試してみても上手く動かず、思いついたのは
最初は、functions.phpにパンくずリストのアーカイブを固定ページに書き換えるコードを追記してみたり、アーカイブを無効化するコードを追記してみたり、色々と試しましたが上手くいかず……。
最終的には、カスタム投稿アーカイブには固定ページを読み込んで解決できる。
問題はタクソノミーアーカイブ。
タクソノミーを使わない選択もありますが、使わないとクエリーループで読み込む時に絞り込めない。
パンクズの、このタクソノミーアーカイブのリンク、いらないんだよね……
いらない、そう、いらないなら非表示にすればいいんだ!
と思いつきました。
私が試したことと、最終的な解決法
1. パンくずリストの中身をJavaScriptで非表示にする
ここではタクソノミーアーカイブへのリンクはいらないので非表示にします。
※今回はパンくずの『尾張エリア』のリンクを非表示にしたいので、まずデベロッパーツールなどでリンク先のURLを確認しておきます。
該当部分の <a> のリンクURLに特定の文字列(例:link-a, link-b)が含まれているとき、その<li>ごと削除するようにしました。
パンくずの後に表示されている”/”はCSSだけで非表示にできなかったので、(特に親要素+擬似要素は制御できません)今回はjavascriptで消すことにしました。
<script>
document.addEventListener("DOMContentLoaded", function () {
const breadcrumbItems = document.querySelectorAll(".breadcrumb-list__item a[href*='a-owari']");
breadcrumbItems.forEach(function (link) {
const li = link.closest('li');
if (li) {
li.remove(); // 完全にDOMから削除
}
});
});
</script>
href
に a-owari
を含む <a>
タグを持つ <li>
を削除。<li>
が削除されるので、擬似要素 ::after
も表示されなくなります。
同じような処理をしたいカスタム投稿が2つ以上の場合はこちらでまとめて記述。selectors
配列に、削除したい条件を増やしていく形式です。
たとえば将来 tokai-link
も非表示にしたくなったら、配列に .breadcrumb-list__item a[href*='tokai-link']
を追加するだけです。
document.addEventListener("DOMContentLoaded", function () {
const selectors = [
".breadcrumb-list__item a[href*='a-owari']",
".breadcrumb-list__item a[href*='hp-link']"
];
selectors.forEach(selector => {
document.querySelectorAll(selector).forEach(link => {
const li = link.closest('li');
if (li) li.remove();
});
});
});
これで、不要なパンくずリストの項目を消すことができました。
このコードは子テーマの中のcustom.js に追記しました。
※ユーザ定義のjsを使用する場合はfunctions.phpで読み込みの処理が必要です。
2. アーカイブページに固定ページの内容を差し込む
元の固定ページに戻りたいのにカスタム投稿のアーカイブページ戻ってしまう問題は、アーカイブページに元の固定ページの内容を読み込むことで解決しました。URLは違いますが内容は同じなので許容範囲です。
これまではfunctions.phpに追記をして読み込んでいたのですが、今回はLightningテーマの「ループ前ウィジェット」を使って、そこに該当の固定ページの内容を表示することにしました。(この機能、いつからあったの?と気づかなかった私……)
デフォルトではこの機能はオフになっているので、
ダッシュボードの [ ExUnit ] - [ウィジェット機能 ] で「投稿ループ前ウィジェットエリア」にチェックを入れて有効化したら、[ 外観 ] - [ ウィジット ] で設定を行います。

「VK固定ページ本文」ブロックを使って、ウィジット内に固定ページの内容を読み込みます。

カスタム投稿アーカイブに固定ページの内容が読み込まれました。その下にはカスタム投稿のアーカイブのループブロックがのこっていますので、 これをCSSで非表示にします。
デベロッパーツールなどで、ターゲットになるクラスを調べます。今回は "div.vk_posts-postType-cp-test-b" が該当のブロックだったので、子テーマのCSSに以下のように記述。
div.vk_posts-postType-cp-test-b {
display: none;
}

これで、実質「固定ページ風のアーカイブページ」ができあがり、パンくずリストがアーカイブ構造で表示されても違和感がなくなりました!
力技ですが、プログラムが得意でない、苦手な場合はこれも一つの選択肢ではないかと思います。
たかがパンくず、されどパンくず……カスタム投稿を使う場合は、パンくずリストのことも考えて設計することが重要です。
今後の課題・メモ
- 一瞬だけパンくずが表示されてしまうのが気になるが、今のところ許容範囲。
- 以前はアーカイブページに直接PHPで固定ページを読み込んでいたが、コード管理が面倒なのでやめた。
- ブロックエディタ+CSS+少しのJavaScriptで対応できたのが今回の大きな収穫!
まとめ
パンくずリストってあまり注目されないけれど、実はUXの要。
カスタム投稿を固定ページでうまく扱おうとすると、意外と複雑な落とし穴があることを今回改めて実感しました。
技術力のある上級者の方なら、もっと上手なやり方でさくっと処理するかもしれません。
けれど、私はあまりプログラミングが得意ではないので、力技のようなやり方で何とかしていましました。
同じように「パンくずで迷子になる問題」で悩んでいる方の参考になればうれしいです!