Shopifyでカテゴリ別のFAQコンテンツ(記事URLあり)を作る

Shopifyでカテゴリ別のFAQコンテンツ(記事URLあり)を作る

ShopifyのテーマにもともとFAQ(よくあるご質問)用のセクションが用意されていたり、カスタマイズのサンプルで作り方を取り上げているケースをよく見かけますが、ダイナミックソースに直接QAを入力してアコーディオンで表示するだけ、というシンプルなものが多いです。
QAひとつひとつに独立した記事URLを持たせたり、質問のカテゴリで絞り込みをしたりするようなコンテンツを作りたい場合、ブログとタグを活用すれば実現できます。

実現したいゴール

FAQに、擬似的に下記のようなカテゴリ階層を作りたいと思います。

  • ご注文について
    • 配送・納期について
    • お支払いについて
    • 返品・交換について
  • 商品について
    • ハードウェアについて
    • ゲームソフトについて

上記はすべてタグとして登録します。
たとえば、お支払いについての質問であれば、タグには親階層となる「ご注文について」と、「お支払いについて」の2つのタグを設定しておきます。

今回の記事ではブログの作り方は省略します。
ブログとブログ記事、それぞれに任意のFAQ用テンプレートファイルを指定しましょう。

中身のブログ記事自体は、資料ダウンロードコンテンツを作ったときと同様に、ブログのテンプレートファイルを用意して作成します。

擬似カテゴリをタグで運用する以上、自動的に階層化して一覧を表示するということができません。
それぞれのタグの親子関係を指定するための方法は2つあります。

ひとつは、サイドメニューを作ったときのように、FAQ階層用のメニューを作成して、タグページのリンクリストを作って対応する方法です。

この場合のやりかたは上記の記事で紹介しているので、割愛します。

今回は、もうひとつの方法、動的セクションを使用します。
メニューで一気に管理できたほうがいい、という人もいるかもしれませんが、動的セクションには別のメリットがあります。

カテゴリ(タグ)を指定するためのセクションとブロックを用意する

まず、ブログの一覧画面に表示するFAQのカテゴリを、テーマカスタマイズから直接選べるように、動的セクションを作ります。
ここではsectionsディレクトリにblog-posts-faq.liquidというファイルを作って、スキーマを書いていきます。

blog-posts-faq.liquidのスキーマ

セクションひとつにつき、メインカテゴリを指定し、その中に複数のサブカテゴリを指定できるようにします。

{% schema %}
  {
    "name": "FAQカテゴリ",
    "tag": "section",
    "settings": [
      {
        "type": "text",
        "id": "faq-category",
        "label": "FAQメインカテゴリタグ"
      }
    ],
    "blocks": [
      {
        "name": "FAQサブカテゴリタグ",
        "type": "faq-subcategory",
        "settings": [
          {
            "id": "faq-subcategory-tag",
            "type": "text",
            "label": "タグ"
          }
        ]
      }
    ],
    "presets": [
      {
        "name": "faq-archive"
      }
    ]
  }
{% endschema %}

このfaq-categoryセクションを、実際にブログのテンプレートに挿入しておきます。

セクション自体のsettingsではメインカテゴリのタグを、

ブロックのsettingsではサブカテゴリのタグを指定します。

先ほど動的セクションにメリットがあると書きましたが、この動的セクションを作ることで、FAQブログ以外のページでも、特定のタグを指定して、関連するFAQを表示することができるようになります。
たとえば、ストアのご利用ガイドのようなご案内ページのテンプレートでは決済や配送に関するFAQを表示し、商品ページのテンプレートでは商品に関するFAQを表示する、といった使い方ができます。
「いや、それもメニューでできるじゃん」と思われるかもしれませんが、FAQを掲載したいテンプレートごとにいちいちメニューを作っていくと煩雑になりますし、各テンプレート内で好きな組み合わせを作って設定できるほうが、汎用性が高いかなと考えました。

blog-posts-faq.liquidのマークアップ

次に、指定されたタグをループしてリストを表示していくコードをblog-posts-faq.liquidに追記していきます。
ブログなので単体URLも持っていますが、一覧でもすぐに内容を確認することができるように、summary要素とdetails要素を使ってアコーディオン風にしています。

<section class="faq-archive top-spacing-normal">
  <h2>
    <a href="/blogs/faq/tagged/{{ section.settings.faq-category | replace: '・', '-' }}">
      <span>{{ section.settings.faq-category }}のご質問</span>
    </a>
  </h2>
  {%- for block in section.blocks -%}
    {%- case block.type -%}
      {%- when 'faq-subcategory' -%}
      {%- assign tag = block.settings.faq-subcategory-tag -%}
      <h3>
        <a href="/blogs/faq/tagged/{{ tag | replace: '・', '-' }}">
          <span>{{ tag }}のご質問</span>
        </a>
      </h3>
      <ul>
        {% for article in blogs['faq'].articles %}
          {% for article_tag in article.tags %}
            {% if article_tag == tag %}
              <li>
                <details>
                  <summary>
                    <i class="fa-solid fa-circle-question"></i>
                    <span>{{ article.title }}</span>
                  </summary>
                  <div class="details-content">
                    {{ article.content }}
                    {%- if article.tags.size > 0 -%}
                      {%- render 'tags', tags: article.tags -%}
                    {%- endif -%}
                    <div class="linkto-article-faq">
                      <a href="{{ article.url }}">この質問のページを表示</a>
                    </div>
                  </div>
                </details>
              </li>
            {%- endif -%}
          {%- endfor -%}
        {%- endfor -%}
      </ul>
    {%- endcase -%}
  {%- endfor -%}
</section>

タグUIのリストの作り方は、過去の記事を参照してください。

ブログインデックスのテンプレートを作成する

main-blog-faq.liquid

FAQブログのインデックスページのメインセクションとなるmain-blog-faq.liquidファイルにコードを書いていきます。

<h1 class="mt0 mb0">
  {%- unless current_tags -%}
    {{ blog.title | escape }}
  {%- else -%}
    "{{ current_tags.first | replace: '-', ' ' }}"のよくあるご質問一覧
  {%- endunless -%}
</h1>
{%- if request.path contains '/tagged/' -%}
  {%- paginate blog.articles by section.settings.post_limit -%}
    <div class="faq-archive top-spacing-small">
      <ul>
        {% for article in blog.articles %}
          <li>
            <details>
              <summary>
                <i class="fa-solid fa-circle-question"></i>
                <span>{{ article.title }}</span>
              </summary>
              <div class="details-content">
                {{ article.content }}
                {%- if article.tags.size > 0 -%}
                  {%- render 'tags', tags: article.tags -%}
                {%- endif -%}
                <div class="linkto-article-faq">
                  <a href="{{ article.url }}">この質問のページを表示</a>
                </div>
              </div>
            </details>
          </li>
        {%- endfor -%}
      </ul>
    </div>
    {%- if paginate.pages > 1 -%}
      {%- render 'pagination', paginate: paginate, aligment: section.settings.heading_aligment -%}
    {%- endif -%}

  {%- endpaginate -%}
{%- endif -%}

コードの補足

最初にやっていることは、まずh1要素(見出し)の条件分岐です。
現在表示しているのがタグページだった場合はタグを見出しに含めるようにしています。

<h1 class="mt0 mb0">
  {%- unless current_tags -%}
    {{ blog.title | escape }}
  {%- else -%}
    "{{ current_tags.first | replace: '-', ' ' }}"のよくあるご質問一覧
  {%- endunless -%}
</h1>

そのあと、タグページだった場合には、そのタグが紐づいたFAQの一覧をデフォルトで表示するために条件分岐しています。

{%- if request.path contains '/tagged/' -%}
〜略〜
{%- endif -%}

テンプレートのblog.faq.jsonファイルに、上記のmain-blog-faqセクションと、そのあとに動的セクションのfaq-categoryを含めるにしておけば、タグのページにいるときも、そのほかのタグの質問一覧を表示することができます。
逆に、そのほかのタグの質問を表示したくない場合は、タグページかどうかの判定をしてメインのセクションを表示しないようにしておけばOK。

おわり!

記事ページも、main-article.liquidを複製して専用のfaq-article.liquidテンプレートファイルを作り、自由にカスタマイズしてみてください。

いろいろなカスタマイズをやっていくと、過去にやったことにちょっと手を加えるアレンジでいろんなことができるようになってきて面白いですね!