star back image
people4
電飾 電飾
moon
astronaut

【shopify】パンくずをjsonで出し分ける

BLOG shopifyWEBログ
読了約:61分

shopifyはショッピングサイトなので、従来のホームページ制作のように自由にディレクトリーを増やして階層のある下層URLを作るような概念があまり無いようです。

shopifyではディレクトリは大きく以下のように分かれていますでしょうか。

/products/ ←商品のページ
/pages/ ←個別のページ
/blogs/ ←ブログのページ
/account/ ←アカウントのページ
/cart ←カートのページ

昔ながらの人だと、関連ページごとにURLを分けて、パンくずをガッチリと決め込みたい気持ちになりますよね。

それを捨てる。潔いなぁと思います。

逆にわかりやすいのかも?

え?それができないなら。せめて。
パンくずだけでもディレクトリーを表現したい。階層があるんだと、見せかけだって言われてもいい\(_’ω’)/ウオオオオオアアアーーーッ!

検索しました。すると、

スニペットで以下のように/snippets/breadcrumbs.liquidファイルを作成。

{% render 'breadcrumbs' %}

で呼び出す方法がたくさん出てきます。これがマストで正解でしょうか。

theme.liquid内でのsnippet呼び出し

<main id="MainContent" class="content-for-layout">
  {%- unless template == 'index' or template == '404' -%}
    {% render 'breadcrumbs' %}
  {%- endunless -%}
  
  {{ content_for_layout }}
</main>

パンクズの有無をURLの要素で出し分けを刻むならこんな感じでしょうか。

<main id="MainContent" class="content-for-layout">
  {%- liquid
    assign show_breadcrumbs = true
    if template == 'index'
      assign show_breadcrumbs = false
    elsif template contains 'product'
      if product.tags contains 'campaign'
        assign show_breadcrumbs = false
      endif
    elsif template == 'cart'
      assign show_breadcrumbs = false
    endif
  -%}
  
  {%- if show_breadcrumbs -%}
    {% render 'breadcrumbs' %}
  {%- endif -%}
  
  {{ content_for_layout }}
</main>

これで十分。

なぜjsonでやるのですか?

パンくずのあるない指示が入り乱れて、テンパったから。
どうしても整理したかったようです。

今はAIにも聞けます。

【共有】パンくずをjsonで出し分ける by shopify

スニペットの方法、それ意外にも色々と方法があると思います。もしかしたら余計なことをしているかもと今になって思っていますが、せっかくなので保管したいと思いました。

要件は以下です。

  • theme.lquidをシンプルに保ちたい ←最大の理由はこれ。
  • templatesのjsonで表示非表示を決めたい
  • breadcrumbs.liquidでパンクズの並びを指定(sectionに作成)

theme.lquid

<main id="MainContent" class="content-for-layout l-container {% if template == 'index' %}l-container--no-padding{% endif %}" role="main" tabindex="-1">
  {% if template == 'cart' %}
    <section id="main-cart-wrapper" class="l-section p-cart {% if cart == empty %} is-empty{% endif %}">
      <div class="p-cart__inner l-section__inner">
        <div class="p-cart__container">
          {{ content_for_layout }}
        </div>
      </div>
    </section>
  {% else %}
    {{ content_for_layout }}
  {% endif %}
</main>

theme.lquidでは、{{ content_for_layout }}だけの仕込みにしたいのです。

カートは違うデザインにしたかった形跡がありますね。

/templates/のjson

存在するページには専用のjsonが自動で作成されています。
パンくずを入れたいページのjsonにコードを追加します。

/*
 * ------------------------------------------------------------
 * IMPORTANT: The contents of this file are auto-generated.
 *
 * This file may be updated by the Shopify admin theme editor
 * or related systems. Please exercise caution as any changes
 * made to this file may be overwritten.
 * ------------------------------------------------------------
 */
{
  "sections": {
    "breadcrumbs": {
      "type": "breadcrumbs",
      "settings": {}
    }
    "product-grid": {
      "type": "main-collection-product-grid",
      "settings": {
        "products_per_page": 20,
        "enable_filtering": true
      }
    }
  },
  "order": [
    "breadcrumbs",
    "product-grid"
  ]
}

これは/templates/collection.json(コレクション一覧ページ)のjsonでしょうか。

ブログの詳細ページなら。
/templates/article.json
ですかね。

2箇所、jsonのテキストを追加します。

出したいページのjsonに以下の2つ記述します。

↓ sectionsにbreadcrumbsを追加します。
{
"sections": {
"breadcrumbs": {
"type": "breadcrumbs",
"settings": {}
},


それとorderに表示順番を指定。
},
"order": [
"breadcrumbs",
"product-grid"
]
}

“sections”: {を使うから、以下のbreadcrumbs.liquidファイルを/section/で作成した形になります。

スニペットじゃなくて大丈夫ですか。

breadcrumbs.liquid(sectionにファイル作成)

<!-- パンくずリスト全体のコンテナ -->
<div class="breadcrumbs">
  <!-- Schema.org BreadcrumbListとして構造化データを定義 -->
  <ul class="breadcrumbs__list" itemscope itemtype="http://schema.org/BreadcrumbList">
    
    <!-- 1. ホームリンク(必ず表示) -->
    <li class="breadcrumbs__item" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem">
      <a itemprop="item" href="{{ routes.root_url }}" class="breadcrumbs__link">
        <span itemprop="name">{{ 'sections.breadcrumbs.home' | t }}</span>
      </a>
      <meta itemprop="position" content="1" />
    </li>
    
    <!-- 2. 商品ページの場合 -->
    {%- if template contains 'product' -%}
      <!-- コレクション情報がある場合:ホーム > コレクション > 商品 -->
      {%- if collection.url -%}
        <li class="breadcrumbs__item" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem">
          <a itemprop="item" href="{{ collection.url }}" class="breadcrumbs__link">
            <span itemprop="name">{{ collection.title }}</span>
          </a>
          <meta itemprop="position" content="2" />
        </li>
        <li class="breadcrumbs__item" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem">
          <span itemprop="name" class="breadcrumbs__current">{{ product.title }}</span>
          <meta itemprop="position" content="3" />
        </li>
      {%- else -%}
        <!-- コレクション情報がない場合:ホーム > 商品 -->
        <li class="breadcrumbs__item" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem">
          <span itemprop="name" class="breadcrumbs__current">{{ product.title }}</span>
          <meta itemprop="position" content="2" />
        </li>
      {%- endif -%}
    
    <!-- 3. コレクションページの場合:ホーム > コレクション名 -->
    {%- elsif template contains 'collection' -%}
      <li class="breadcrumbs__item" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem">
        <span itemprop="name" class="breadcrumbs__current">
      {% comment %}
          <!-- 廃止された実装:メタフィールドによる性別表示 -->
          {%- assign gender = collection.metafields.custom.gender -%}
          {%- if gender == 'WOMEN' -%}
            WOMEN
          {%- elsif gender == 'MEN' -%}
            MEN
          {%- else -%}
            {{ collection.title }}
          {%- endif -%}
      {% endcomment %}
          <!-- 現在の実装:allコレクションは特別表示 -->
          {% if collection.handle == 'all' %}
            ALL ITEMS
          {% else %}
            {{ collection.title }}
          {% endif %}
        </span>
        <meta itemprop="position" content="2" />
      </li>
    
    <!-- 4. ブログページの場合:ホーム > ブログ名 -->
    {%- elsif template contains 'blog' -%}
      <li class="breadcrumbs__item" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem">
        <span itemprop="name" class="breadcrumbs__current">{{ blog.title }}</span>
        <meta itemprop="position" content="2" />
      </li>
    
    <!-- 5. 記事ページの場合:ホーム > ブログ名 > 記事タイトル -->
    {%- elsif template contains 'article' -%}
      <li class="breadcrumbs__item" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem">
        <a itemprop="item" href="{{ blog.url }}" class="breadcrumbs__link">
          <span itemprop="name">{{ blog.title }}</span>
        </a>
        <meta itemprop="position" content="2" />
      </li>
      <li class="breadcrumbs__item" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem">
        <span itemprop="name" class="breadcrumbs__current">{{ article.title }}</span>
        <meta itemprop="position" content="3" />
      </li>
    
    <!-- 6. カートページの場合:ホーム > カート -->
    {%- elsif template contains 'cart' -%}
      <li class="breadcrumbs__item" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem">
        <span itemprop="name" class="breadcrumbs__current">{{ 'sections.cart.title' | t }}</span>
        <meta itemprop="position" content="2" />
      </li>
    
    <!-- 7. 顧客アカウント関連ページ -->
    {%- elsif template contains 'customers' -%}
      <!-- アカウントトップページ:ホーム > アカウント -->
      {%- if template contains 'account' -%}
        <li class="breadcrumbs__item" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem">
          <span itemprop="name" class="breadcrumbs__current">{{ 'customer.account.title' | t }}</span>
          <meta itemprop="position" content="2" />
        </li>
      <!-- 住所管理ページ:ホーム > アカウント > 住所管理 -->
      {%- elsif template contains 'addresses' -%}
        <li class="breadcrumbs__item" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem">
          <a itemprop="item" href="{{ routes.account_url }}" class="breadcrumbs__link">
            <span itemprop="name">{{ 'customer.account.title' | t }}</span>
          </a>
          <meta itemprop="position" content="2" />
        </li>
        <li class="breadcrumbs__item" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem">
          <span itemprop="name" class="breadcrumbs__current">{{ 'customer.addresses.title' | t }}</span>
          <meta itemprop="position" content="3" />
        </li>
      <!-- 注文履歴ページ:ホーム > アカウント > 注文履歴 -->
      {%- elsif template contains 'order' -%}
        <li class="breadcrumbs__item" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem">
          <a itemprop="item" href="{{ routes.account_url }}" class="breadcrumbs__link">
            <span itemprop="name">{{ 'customer.account.title' | t }}</span>
          </a>
          <meta itemprop="position" content="2" />
        </li>
        <li class="breadcrumbs__item" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem">
          <span itemprop="name" class="breadcrumbs__current">{{ 'customer.orders.pagetitle' | t }}</span>
          <meta itemprop="position" content="3" />
        </li>
      {%- endif -%}
    
    <!-- 8. メタオブジェクトページ(店舗情報など) -->
    {%- elsif template contains 'metaobject' -%}
      <!-- 店舗情報の場合:ホーム > STORE > 店舗名 -->
      {%- if template contains 'store' -%}
        <li class="breadcrumbs__item" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem">
          <a itemprop="item" href="{{ pages.store.url }}" class="breadcrumbs__link">
            <span itemprop="name">STORE</span>
          </a>
          <meta itemprop="position" content="2" />
        </li>
        <li class="breadcrumbs__item" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem">
          <span itemprop="name" class="breadcrumbs__current">{{ metaobject.name }}</span>
          <meta itemprop="position" content="3" />
        </li>
      {%- endif -%}
    {%- endif -%}

    <!-- 9. 固定ページ(詳細な分岐処理) -->
    
    <!-- ショッピングガイドトップ:ホーム > SHOPPING GUIDE -->
    {%- if template contains 'page' and page.handle == 'shopping-guide' -%}
      <li class="breadcrumbs__item" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem">
        <span itemprop="name" class="breadcrumbs__current">SHOPPING GUIDE</span>
        <meta itemprop="position" content="2" />
      </li>
    
    <!-- 注文関連ページ:ホーム > SHOPPING GUIDE > ページタイトル -->
    {%- elsif template contains 'page' and page.handle contains 'order-' -%}
      <li class="breadcrumbs__item" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem">
        <a itemprop="item" href="{{ page.url }}" class="breadcrumbs__link">
          <span itemprop="name">SHOPPING GUIDE</span>
        </a>
        <meta itemprop="position" content="2" />
      </li>
      <li class="breadcrumbs__item" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem">
        <span itemprop="name" class="breadcrumbs__current">{{ page.title }}</span>
        <meta itemprop="position" content="3" />
      </li>
    
    <!-- 商品関連ページ:ホーム > SHOPPING GUIDE > ページタイトル -->
    {%- elsif template contains 'page' and page.handle contains 'item-' -%}
      <li class="breadcrumbs__item" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem">
        <a itemprop="item" href="{{ page.url }}" class="breadcrumbs__link">
          <span itemprop="name">SHOPPING GUIDE</span>
        </a>
        <meta itemprop="position" content="2" />
      </li>
      <li class="breadcrumbs__item" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem">
        <span itemprop="name" class="breadcrumbs__current">{{ page.title }}</span>
        <meta itemprop="position" content="3" />
      </li>
    
    <!-- 保証関連ページ:ホーム > SHOPPING GUIDE > ページタイトル -->
    {%- elsif template contains 'page' and page.handle contains 'guarantee' -%}
      <li class="breadcrumbs__item" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem">
        <a itemprop="item" href="{{ page.url }}" class="breadcrumbs__link">
          <span itemprop="name">SHOPPING GUIDE</span>
        </a>
        <meta itemprop="position" content="2" />
      </li>
      <li class="breadcrumbs__item" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem">
        <span itemprop="name" class="breadcrumbs__current">{{ page.title }}</span>
        <meta itemprop="position" content="3" />
      </li>
    
    <!-- メンテナンス・裾上げページ:ホーム > SHOPPING GUIDE > ページタイトル -->
    {%- elsif template contains 'page' and page.handle contains 'mainte-hemming' -%}
      <li class="breadcrumbs__item" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem">
        <a itemprop="item" href="{{ page.url }}" class="breadcrumbs__link">
          <span itemprop="name">SHOPPING GUIDE</span>
        </a>
        <meta itemprop="position" content="2" />
      </li>
      <li class="breadcrumbs__item" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem">
        <span itemprop="name" class="breadcrumbs__current">{{ page.title }}</span>
        <meta itemprop="position" content="3" />
      </li>
    
    <!-- ケア・お手入れページ:ホーム > SHOPPING GUIDE > ページタイトル -->
    {%- elsif template contains 'page' and page.handle contains 'care' -%}
      <li class="breadcrumbs__item" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem">
        <a itemprop="item" href="{{ page.url }}" class="breadcrumbs__link">
          <span itemprop="name">SHOPPING GUIDE</span>
        </a>
        <meta itemprop="position" content="2" />
      </li>
      <li class="breadcrumbs__item" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem">
        <span itemprop="name" class="breadcrumbs__current">{{ page.title }}</span>
        <meta itemprop="position" content="3" />
      </li>
    
    <!-- 会員登録ページ:ホーム > SHOPPING GUIDE > ページタイトル -->
    {%- elsif template contains 'page' and page.handle contains 'membership-register' -%}
      <li class="breadcrumbs__item" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem">
        <a itemprop="item" href="{{ page.url }}" class="breadcrumbs__link">
          <span itemprop="name">SHOPPING GUIDE</span>
        </a>
        <meta itemprop="position" content="2" />
      </li>
      <li class="breadcrumbs__item" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem">
        <span itemprop="name" class="breadcrumbs__current">{{ page.title }}</span>
        <meta itemprop="position" content="3" />
      </li>
    
    <!-- 支払い方法ページ:ホーム > SHOPPING GUIDE > ページタイトル -->
    {%- elsif template contains 'page' and page.handle contains 'payment' -%}
      <li class="breadcrumbs__item" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem">
        <a itemprop="item" href="{{ page.url }}" class="breadcrumbs__link">
          <span itemprop="name">SHOPPING GUIDE</span>
        </a>
        <meta itemprop="position" content="2" />
      </li>
      <li class="breadcrumbs__item" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem">
        <span itemprop="name" class="breadcrumbs__current">{{ page.title }}</span>
        <meta itemprop="position" content="3" />
      </li>
    
    <!-- 配送方法ページ:ホーム > SHOPPING GUIDE > ページタイトル -->
    {%- elsif template contains 'page' and page.handle contains 'shipping' -%}
      <li class="breadcrumbs__item" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem">
        <a itemprop="item" href="{{ page.url }}" class="breadcrumbs__link">
          <span itemprop="name">SHOPPING GUIDE</span>
        </a>
        <meta itemprop="position" content="2" />
      </li>
      <li class="breadcrumbs__item" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem">
        <span itemprop="name" class="breadcrumbs__current">{{ page.title }}</span>
        <meta itemprop="position" content="3" />
      </li>
    
    <!-- 返品・交換ページ:ホーム > SHOPPING GUIDE > ページタイトル -->
    {%- elsif template contains 'page' and page.handle contains 're-' -%}
      <li class="breadcrumbs__item" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem">
        <a itemprop="item" href="{{ page.url }}" class="breadcrumbs__link">
          <span itemprop="name">SHOPPING GUIDE</span>
        </a>
        <meta itemprop="position" content="2" />
      </li>
      <li class="breadcrumbs__item" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem">
        <span itemprop="name" class="breadcrumbs__current">{{ page.title }}</span>
        <meta itemprop="position" content="3" />
      </li>
    
    <!-- その他ガイドページ:ホーム > SHOPPING GUIDE > ページタイトル -->
    {%- elsif template contains 'page' and page.handle contains 'other-' -%}
      <li class="breadcrumbs__item" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem">
        <a itemprop="item" href="{{ page.url }}" class="breadcrumbs__link">
          <span itemprop="name">SHOPPING GUIDE</span>
        </a>
        <meta itemprop="position" content="2" />
      </li>
      <li class="breadcrumbs__item" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem">
        <span itemprop="name" class="breadcrumbs__current">{{ page.title }}</span>
        <meta itemprop="position" content="3" />
      </li>
    
    <!-- 上記以外の固定ページ:ホーム > ページタイトル -->
    {%- elsif template contains 'page' -%}
      <li class="breadcrumbs__item" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem">
        <span itemprop="name" class="breadcrumbs__current">{{ page.title }}</span>
        <meta itemprop="position" content="2" />
      </li>
    {%- endif -%}
    
  </ul>
</div>

<!-- セクション設定(Shopify管理画面で編集可能) -->
{% schema %}
{
  "name": "パンくずリスト",
  "tag": "section",
  "class": "l-section p-breadcrumbs",
  "settings": [],
  "presets": [
    {
      "name": "パンくずリスト"
    }
  ]
}
{% endschema %}

見慣れないコードがいくつかありました。
調べたところ、勉強になりました。

<li class="breadcrumbs__item" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem">
の以下はなんでしょう。
・itemprop="itemListElement"
・itemscope
・itemtype="http://schema.org/ListItem"

調べたところこれはSchema.orgの構造化データ用の記述でした。
無くても見た目も変わらない。けど、SEO的には重要なのであった方が良いそうです。以下が期待できます。

・Googleがパンくずを理解しやすくなる
・検索結果でのリッチスニペット表示の可能性
・クロールの効率化

<meta itemprop="position" content="3" />
の数字は3番目にあるパンクくずであることを表しています。

shopifyだから必要なコードという訳ではなく。

でも階層なきshopifyだからこそ必要なのかな。。

以上です。

【AI】イラストを描いてもらった

今回の記事のキャッチ画像で使わせてもらいます「Google ImageFX」で作成した画像です。誰でもgoogleアカウントでログインして使えます。

この記事にピッタリなイラストのための考えたリクエストは、
「宇宙人が食べ残したパンのクズを宇宙船に住み着いている宇宙ネズミが拾って食べている。宇宙ネズミを大きく表示する画角。パンクズを右手には拾っている。左手には口にパンクズを運んでムシャムシャ食べている。後ろでは宇宙人がくつろいでいる。」です。

宇ちゅーネズミかわいいです。

宇宙船にネズミがいるなんて。。

星間旅路のメロディ

「宇宙の静けさに包まれながら、漂流する過去の音楽を捜し求め、銀河の奥底でその旋律に耳を傾ける。」

「この電波はどこの星からきたのだろうか。」

どこかで聞いたことがあるような。