ショップガイドを「実際のサイトのように作りたい」というご要望に応え、テンプレートを作成する方法をご紹介します。
サイトエディターがベータ版ではなくなったため、テンプレートの編集をノーコードで行えるブロックテーマを使います。従来のテーマではカスタマイズのためにコーディングが必要でしたが、ブロックテーマのサイトエディター機能を使えば、ブロックを配置するだけで簡単に編集できます。
ノーコードで編集できるとはいえ、テンプレートの作成を最小限に抑えるために、PHPやJavaScriptも活用します。これらの技術をどこで使うのか考えながら、読み進めてみてください。
完成イメージ
テンプレート階層
テンプレートを作成するにあたり、まずは基本的なポイントをしっかり押さえておきましょう。
WordPressは、一致するテンプレートファイルが見つかるまで、テンプレート階層を検索します。現在のテーマのディレクトリ内を検索し、階層で指定された最初に一致するテンプレートファイルを使用します。見つからない場合は、テーマのindex.phpファイルが使用されます。
例えば、課題サイトが「https://example.com/kadai/」にあり、「shopcategory」というタクソノミーを作成し、「fashion」というタームを追加したとします。この場合、https://example.com/kadai/shopcategory/fashion/ をクリックすると、WordPressは以下の順でテンプレートを検索します。
- taxonomy-shopcategory-fashion.php
- taxonomy-shopcategory.php
- taxonomy.php
- archive.php
- index.php
詳しくは、Custom Taxonomies(カスタム タクソノミー)を参照してください。
カスタムタクソノミー
勘のいい方は、私がカスタムタクソノミーを利用してテンプレートを作成しようとしていることに気づいたかもしれません。これは、新規に追加するテンプレートを少なくするためです。
ピンとこない方は、通常のタクソノミー(カテゴリーとタグ)で試してみてください。Template Hierarchyを参照しながら、積極的に試行錯誤することで、得られるものがあります。
カスタムタクソノミーは、Custom Post Type UIプラグインを使うと簡単に追加できます。
ショップガイドに必要なカスタムタクソノミーは、「カテゴリー」「頭文字」「フロア」です。各タクソノミーに「Fashion」から「Services」、「あ行」から「Z」、「B2」から「RF」、といったタームを追加します。
また、「ショップ」というカスタム投稿タイプを作成し、この投稿タイプを利用して、各ショップの投稿を作成します。
テンプレート
サイトエディターを使ってテンプレートを編集します。つまり、ブロックを使ってテンプレートを編集します。
- [外観|エディター]を開く
- [テンプレート]をクリック
- 新規テンプレートの追加や既存のテンプレートの編集をする
「フルサイト編集を使わないなんてもったいないです!」で、ベータ版のサイトエディターについて説明したので、ここでは省略します。WordPress.comのGetting Startedというコースでもサイトエディターについて学べます。
すべてに精通している必要はありません。機能を使えば使うほど理解が深まり、知れば知るほど使いやすくなります。課題用のサイトであれば、壊れても問題ありません。アグレッシブに試していきましょう!
テンプレートパーツ
テンプレートパーツは、複数のテンプレート内に配置できる再利用可能な同期されたブロックパターンです。テンプレートパーツを変更すると、それを使用しているすべての場所で更新されます。
ページのタイトルや投稿の表示などの共通部分は、テンプレートパーツで作成すると便利です。
- [外観|エディター]を開く
- [パターン]をクリック
- [テンプレートパーツ一覧]をクリック
- 新規パターンの追加や既存のパターンの編集をする
編集画面からテンプレートパーツの作成や解除もできます。ブロックを選択し、3つの点が縦に並んだアイコンをクリックしてみてください。
テンプレートの作成例
この画像は、カスタムタクソノミーを表示するためのテンプレート作成例です。

「ショップカテゴリー」「ショップ名」「ショップフロア」の3つのテンプレートを作成しています。今回は、各フロアのショップを表示するためのテンプレートについて、編集内容の一部を解説します。
ボタンの塗りつぶし
現在のページのURLに基づいてボタンを塗りつぶすことで、どのタームに属する投稿が表示されているのかを直感的に把握しやすくします。
仕組み
たとえば、[B1]ボタンがクリックされると、そのリンク先が現在のページのURLと一致するため、[B1]ボタンが塗りつぶされる仕組みです。
リンク設定
たとえば、課題サイトが「https://example.com/kadai/」にあり、「shop_floor」というタクソノミーを作成し、「b1」というタームを追加している場合、[B1]のリンクは「/kadai/shop_floor/b1」と設定します。
JavaScriptコード
ボタンブロックの[追加CSSクラス]に「shop-guide-btns」を設定し、JavaScriptでHTML要素を取得できるようにします。
このコードは「カテゴリー」「頭文字」「フロア」の3つのテンプレートで共通して使用できるため、テンプレートパーツとして登録し、各テンプレートの末尾に追加すると管理しやすくなります。
コードは、カスタムHTMLブロックを使って記述します。
<script>
// ページ読み込み時に実行
document.addEventListener('DOMContentLoaded', () => {
// shop-guide-btnsクラス内のdiv要素を取得
const btns = document.querySelectorAll('.shop-guide-btns div');
// 取得した要素をループ処理する
btns.forEach(btn => {
// ボタン内のリンク要素を取得
const link = btn.querySelector('a');
// ボタンのリンク先が現在のページのURLと一致する場合の処理
if (link.href === location.href) {
// ボタンのスタイルを変更
btn.classList.remove('is-style-outline');
btn.classList.add('is-style-fill');
}
});
});
</script>
フロアマップの表示
各フロアのショップを表示する際に、該当するフロアマップも表示します。
前提条件
これから紹介するコードは、以下のタクソノミーとタームを作成している前提で書いています。
- タクソノミー:shop_floor
- shop_floorのターム:b2、b1、1f、2f、3f、4f、rf
タームと画像ID
各フロアのタームとフロアマップの画像IDが、以下のようになっているとします。
フロア | ターム | 画像ID |
---|---|---|
B2 | b2 | 1 |
B1 | b1 | 2 |
1F | 1f | 3 |
2F | 2f | 4 |
3F | 3f | 5 |
4F | 4f | 6 |
RF | rf | 7 |
画像IDは、[管理画面|メディア]を開き、対象の画像をマウスオーバーすると、確認できます。
画像のZOOMリンク
フロアマップ画像のZOOMリンクを追加し、クリックするとLightboxが開くようにします。Lightboxは、画像を別ウィンドウや新しいタブを開かずに、同じ画面上に拡大表示する機能です。
実際のサイトでは、PhotoSwipeが使われています。WordPressにPhotoSwipeを統合したLightbox with PhotoSwipeプラグインも利用できます。
PHPコード
shop_floorというタクソノミーに追加したタームに基づいて、該当するフロアマップを表示します。
コードは、Post Snippetsプラグインを使って記述し、Post Snippetsブロックを使ってテンプレートに追加します。
使用している関数については、WordPress Developer Resourcesの公式ドキュメントを参照してください。
<?php
// 各フロアのタームに対応する画像IDの配列を作成
$terms_to_attachments = array(
'b2' => 1,
'b1' => 2,
'1f' => 3,
'2f' => 4,
'3f' => 5,
'4f' => 6,
'rf' => 7,
);
// 画像IDを格納する変数の初期化
$attachment_id = null;
// タームと画像IDの配列をループ処理する
foreach ($terms_to_attachments as $term => $id) {
// 現在のタームが指定されたタクソノミー('shop_floor')に属しているか確認する
if (is_tax('shop_floor', $term)) {
// タームが一致した場合、画像IDを設定してループを終了する
$attachment_id = $id;
break;
}
}
// 画像IDが設定されている場合の処理
if ($attachment_id) {
// 画像を取得して出力
echo wp_get_attachment_image($attachment_id, 'large');
?>
<!-- 画像のZOOMリンクを出力 -->
<a href="<?php echo esc_url(wp_get_attachment_image_url($attachment_id)); ?>">ZOOM</a>
<?php
}
?>
カテゴリーで絞り込む
「実際のサイトと同じように実装したい」というリクエストに応えるため、JavaScriptを使って各フロアのショップをカテゴリーで絞り込みます。WordPressではPHPを使って投稿を絞り込む方が適切なため、この方法は非推奨です。
注意点
JavaScriptを使用する場合、投稿のHTML要素を取得してdisplayプロパティの値を変更することで、絞り込みを実現します。そのため、ページに表示されていない投稿は絞り込みの対象外になります。ページに表示される投稿数は、[設定|表示設定]の[1ページに表示する最大投稿数]に従うため、適切な値を設定する必要があります。
これらの理由から、投稿の絞り込みにはPHPを使う方が適切と考え、「絞り込み検索をプラグインで実装してみよう」ではVK Filter Searchプラグインを利用する方法を紹介しました。自分で実装したい方は、「絞り込み検索をPHPで実装してみよう」を参考にしてください。
前提条件
これから紹介するコードは、以下のタクソノミーとタームを作成している前提で書いています。
- タクソノミー:shop_category
- shop_categoryのターム:fashion、lifestyle、cosmetics、dining、food、services
チェックボックス
カスタムHTMLブロックを使ってチェックボックスを実装し、ショップのカテゴリーを選択できるようにします。
投稿のdisplayプロパティの値を変更する際に、inputタグのvalue属性の値を使用するため、開発者ツールで投稿のクラス名を確認し、適切な値を設定します。
<div id="shop-category-checkbox">
<label><input type="checkbox" value="shop_category-fashion">Fashion</label>
<label><input type="checkbox" value="shop_category-lifestyle">Lifestyle</label>
<label><input type="checkbox" value="shop_category-cosmetics">Cosmetics</label>
<label><input type="checkbox" value="shop_category-dining">Dining & Café</label>
<label><input type="checkbox" value="shop_category-food">Dining & Café</label>
<label><input type="checkbox" value="shop_category-services">Services</label>
</div>
ボタン
ボタンブロックで[絞り込む]ボタンを作成し、クリックされたらショップの絞り込みが実行されるよう、JavaScriptの実行トリガーとします。
ブロックの[HTMLアンカー]を利用して、「narrow-down-shop-category-btn」というID名を設定します。
クエリーループブロック
クエリーループブロック内に配置されている投稿テンプレートブロックの[追加CSS]に「shop-guide-query-loop-block」を設定し、投稿のHTML要素を取得できるようにします。
JavaScriptコード
[絞り込む]ボタンがクリックされたら、選択されたカテゴリーに基づいて投稿のdisplayプロパティを変更します。
コードは、カスタムHTMLブロックを使って記述します。
<script>
// "絞り込む"ボタンがクリックされた際の処理
document.querySelector('#narrow-down-shop-category-btn').addEventListener('click', (event) => {
// チェックされていないカテゴリーを取得
const categories = document.querySelectorAll('#shop-category-checkbox input:not(:checked)');
// 投稿のリストを取得
const posts = document.querySelectorAll('ul.shop-guide-query-loop-block li');
// 全ての投稿を表示する
posts.forEach(post => {
post.style.display = 'block';
});
// 選択されたカテゴリーが6未満の場合の処理
if(categories.length < 6) {
// チェックされたカテゴリーに属する投稿を非表示にする
categories.forEach(category => {
// 選択されたカテゴリーに対応する投稿を非表示にする
document.querySelectorAll(`ul.shop-guide-query-loop-block li.${category.value}`).forEach(list => {
list.style.display = 'none';
});
});
}
});
</script>
まとめ
みなさんはどのように作成しましたか?テンプレートの作成方法やコードの書き方はひとつではないので、改善の余地があると感じたら、コメントをください。一緒に成長していきましょう!