応用編課題のショップガイドを作ってみよう

応用編課題のショップガイドを「実際のサイトのように作りたい・見せたい」というご要望に応え、テンプレートを作成する方法をご紹介します。

サイトエディターがベータ版ではなくなったため、テンプレートの編集をノーコードでできるブロックテーマを使います。

従来のテーマでは、カスタマイズのためにコーディングが必要でした。しかし、ブロックテーマを使えば、サイトエディターで簡単に編集できます。

ノーコードで編集できるとはいえ、これは応用編の課題なので、PHPやJavaScriptも活用します。これらの技術をどこで使うのか考えながら、楽しみに読み進めてください。

テンプレート階層

まずは基本的な部分をおさえておきましょう。

WordPressは、一致するテンプレートファイルが見つかるまで、テンプレート階層を検索します。現在のテーマのディレクトリ内を検索し、階層で指定された最初に一致するテンプレートファイルを使用します。見つけられない場合は、テーマの index.php ファイルが使用されます。

課題サイトが「https://example.com/kadai/」にあり、「shopcategory」というタクソノミーを作成し、「fashion」というタームを追加したとします。

この場合、https://example.com/kadai/shopcategory/fashion/ をクリックすると、WordPressは以下の順でテンプレートを検索します。

  1. taxonomy-shopcategory-fashion.php
  2. taxonomy-shopcategory.php
  3. taxonomy.php
  4. archive.php
  5. index.php

詳しくは、Custom Taxonomies(カスタム タクソノミー)を参照してください。

カスタムタクソノミー

勘のいい方は、私がカスタムタクソノミーを利用してテンプレートを作成しようとしていることに気づいたかもしれません。これは、新規に追加するテンプレートを少なくするためです。

ピンとこない方は、通常のタクソノミー(カテゴリーとタグ)で試してみてください。Template Hierarchyを参照しながら、積極的に試行錯誤することで、得られるものがあります。

カスタムタクソノミーは、Custom Post Type UIプラグインを使うと簡単に追加できます。

ショップガイドに必要なタクソノミーは、「ショップカテゴリー」「頭文字」「フロア」です。各タクソノミーに「ファッション」から「ビューティー&サービス」、「あ行」から「Z」、「B2」から「RF」、といったタームを追加します。

テンプレート編集

サイトエディターを使ってテンプレートを編集します。

つまり、ブロックを使ってテンプレートを編集します。

  1. [外観|エディター]を開きます
  2. [テンプレート]をクリックします
  3. 新規テンプレートの追加や既存のテンプレートの編集をします

フルサイト編集を使わないなんてもったいないです!というブログ記事で、ベータ版のサイトエディターについて説明したので、ここでは省略します。WordPress.comのGetting Startedというコースでも学べます。

すべてに精通している必要はありません。機能を使えば使うほど理解が深まり、知れば知るほど使いやすくなります。課題用のサイトなので、壊れても問題ありません。アグレッシブに試していきましょう!

テンプレートパーツ

テンプレートパーツは、複数のテンプレート内に配置できる再利用可能な同期されたブロックパターンです。テンプレートパーツを変更すると、それを使用しているすべての場所で更新されます。

ページのタイトルや投稿の表示などの共通部分は、テンプレートパーツで作成すると便利です。

  1. [外観|エディター]を開きます
  2. [パターン]をクリックします
  3. [すべてのテンプレートパーツを表示]を選択します

編集画面からテンプレートパーツの作成や解除もできます。ブロックを選択し、3つの点が縦に並んだアイコンをクリックしてみてください。

JavaScriptとPHP

テンプレートの作成を最小限に抑えるために、JavaScriptとPHPを活用します。

JavaScriptコードはカスタムHTMLブロックに記述し、テンプレートの末尾に配置します。複数のテンプレートで使うものは、テンプレートパーツにするとよいでしょう。

PHPコードはサイトエディターに記述できないので、Post Snippetsプラグインを利用します。

ボタンの塗りつぶし

例えば、ショップカテゴリーのテンプレートに配置した以下のボタンを、現在のURLに基づいて塗りつぶします。これにより、どのカテゴリーに属する投稿が表示されているかがより分かりやすくなります。

このボタンブロックの追加 CSS クラスに「shop-guide-btns」を追加しています。

<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>

フロア画像の表示

「floor」というタクソノミーに追加したタームに基づいて、該当するフロアマップを表示するPHPコードをPost Snippetsに追加し、Post Snippetsブロックを使ってテンプレートに追加します。

各フロアのタームと画像IDが、次のようになっているとします。

フロアターム画像ID
B2b21
B1b12
1F1f3
2F2f4
3F3f5
4F4f6
RFrf7
// 各フロアのタームに対応する画像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
}

詳しくは、WordPress Developer Resources の記事を参照してください。

フロア画像のZOOMリンク

上記のPHPコードでは、ZOOMリンクを追加しています。このリンクをクリックすると、Lightboxが開きます。Lightboxは、フロア画像を別ウィンドウや新しいタブを開かずに、同じ画面上に拡大表示する機能です。

実際のサイトでは、PhotoSwipeが使われています。WordPressにPhotoSwipeを統合したLightbox with PhotoSwipeプラグインが利用できます。

カテゴリーで絞り込む

各フロアの投稿をカテゴリーで絞り込むためのコードを追加します。

HTML

カスタムHTMLブロックを使ってチェックボックスを実装します。

<div id="shop-category-checkbox">
    <label><input type="checkbox" value="shop_category-fashion">ファッション</label>
    <label><input type="checkbox" value="shop_category-fashion-goods">ファッショングッズ</label>
    <label><input type="checkbox" value="shop_category-lifestyle-goods-cosmetics">ライススタイルグッズ&コスメ</label>
    <label><input type="checkbox" value="shop_category-restaurant-cafe">レストラン&カフェ</label>
    <label><input type="checkbox" value="shop_category-sweets-foods">スイーツ&フード・フレッシュフード</label>
    <label><input type="checkbox" value="shop_category-beauty-service">ビューティ&サービス</label>
</div>

Contact Form 7プラグインを利用するとよいかもしれません。フォームタグを使えば、HTMLの記述を省略できます。また、このプラグインが見た目の調整も行ってくれます。

ボタンブロック

「絞り込む」ボタンをボタンブロックで作成し、「narrow-down-shop-category-btn」という追加のCSSクラスをこのブロックに追加します。

JavaScript

「絞り込む」ボタンがクリックされた際に、選択されたカテゴリーに基づいて投稿の表示プロパティを変更します。

<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>

このコードからも分かるように、HTML要素を取得し、displayプロパティの値を変更することで、絞り込みを実現しています。従って、ページに表示されていない投稿は絞り込みの対象になりません。ページに表示される投稿数は、[設定]>[表示設定]>[1ページに表示する最大投稿数]に従うので、適切な値を設定してください。

実際のサイトと同じように実装したいというリクエストに応じたコードであることに注意してください。PHPを使って投稿を絞り込む方が適切と考え、応用編課題の絞り込み検索を実装してみようのブログ記事ではVK Filter Searchプラグインを利用する方法を紹介しました。

まとめ

みなさんはどのように作成しましたか?

テンプレートの作成方法やコードの書き方は一つではないので、改善の余地があると感じたら、コメントをください。

一緒に成長していきましょう!

コメントする