Shopifyのコレクションリストで、コレクションの表示順を変更する
気温も下がり、秋の訪れどころか、冬の足音が至近距離で鳴り響き、体調を崩さないか不安なディレクターの田辺です。
さて、今回は表題の通り、「Shopifyのコレクションリストで、コレクションの表示順を変更する」方法を取り上げます。しかし、本記事で紹介する方法は、よく言えばハックなのですが、Shopify的には非推奨なのではないかと考えています。
そのため、本記事の内容をコピペするだけでの利用は避けていただいた方が良いです。
本記事の内容は、Shopifyが定めたLiquidのルールに従えば、こういうこともできる、という一種の実験であるとお考えください。
なお、本記事は、テーマ「Dawn 11.0.0」を前提としています。
はじめに
コレクションリストとは、ShopifyストアのURLで言うところの、/collections
のことです。下図のようなページです。
本記事では、このページのコレクション表示順を制御する方法を研究してみます。
早速、表示順を変更してみる
セクション > main-list-collections.liquid
を編集します。
23行目から30行目付近の下記にコードを追加します。
assign paginate_by = 28
endif
-%}
{%- paginate collections by paginate_by -%}
<ul
class="collection-list grid grid--{{ section.settings.columns_desktop }}-col-desktop grid--{{ section.settings.columns_mobile }}-col-tablet-down"
↓
assign paginate_by = 28
endif
-%}
{% assign collections = collections | sort: 'published_at' %}
{%- paginate collections by paginate_by -%}
<ul
class="collection-list grid grid--{{ section.settings.columns_desktop }}-col-desktop grid--{{ section.settings.columns_mobile }}-col-tablet-down"
{% assign collections = collections | sort: 'published_at' %}
を{%- paginate collectio...
の前に追加しました。
これで、コレクションの公開日順で並び変わります。
しかし、実は、この時点ですでに問題が発生しています。
1ページに表示されるコレクションの数を2に変更してページネーションを表示させてみます。
上図のように、ページネーションが表示されました。
全部で8個のコレクションがあるため、1ページに2つ表示するのであれば、4ページあるのは道理です。
しかし、そもそも、「1ページにコレクション2つ表示」ができておらず、全コレクションが表示されてしまっています。
この原因は明らかで、{% assign collections = collections | sort: 'published_at' %}
を追加したからです。
上記の追加コードではcollections
というオブジェクトを上書きしています。
なぜ、collections
というオブジェクトを上書きすると、ページネーションが正常に機能しなくなってしまうのかまでは分かりません。
分かっているのは、collections
を上書きするとページネーションが機能しなくなるという事実だけです。
collections
を上書きすることが問題なのであれば、他のオブジェクトを使えばいいのではないかというと、そういうわけにもいきません。
なぜなら、ページネーションに使用できるオブジェクトは予め決まっているからです。
参考: https://shopify.dev/docs/api/liquid/objects/paginate
上記参考ページに記載されたオブジェクト以外は、ページネーションさせようとするとエラーになってしまいます。
そして、私が試した限りでは、上記参考ページに記載されたcollections
以外のページネーション可能なオブジェクトを使用しても、ページネーションの不具合は解消されませんでした。
ページネーションの不具合に対応してみる
collections
を使用するしかない以上、ページネーションの不具合に何とかして対応する方法を考えてみます。
ページネーションの中には、for文があり、そのfor文でコレクションのリストを出力しています。このfor文を工夫すれば何とかなりそうです。
次のようにセクション > main-list-collections.liquid
コードを変更します。
28行目から38行目付近。
{% assign collections = collections | sort: 'published_at' %}
{%- paginate collections by paginate_by -%}
<ul
class="collection-list grid grid--{{ section.settings.columns_desktop }}-col-desktop grid--{{ section.settings.columns_mobile }}-col-tablet-down"
role="list"
>
{%- for collection in collections -%}
<li
class="collection-list__item grid__item{% if settings.animations_reveal_on_scroll %} scroll-trigger animate--slide-in{% endif %}"
{% if settings.animations_reveal_on_scroll %}
↓
{% assign collections = collections | sort: 'published_at' %}
{% assign tmp_collections = collections %}
{%- paginate collections by paginate_by -%}
<ul
class="collection-list grid grid--{{ section.settings.columns_desktop }}-col-desktop grid--{{ section.settings.columns_mobile }}-col-tablet-down"
role="list"
>
{% assign index = paginate.current_page | minus: 1 | times: paginate_by %}
{% assign collections = tmp_collections | sort: 'published_at' | slice: index, paginate_by %}
{%- for collection in collections -%}
<li
class="collection-list__item grid__item{% if settings.animations_reveal_on_scroll %} scroll-trigger animate--slide-in{% endif %}"
{% if settings.animations_reveal_on_scroll %}
{% assign collections = collections | sort: 'published_at' %}
の後に{% assign tmp_collections = collections %}
を追加し、{%for collectio...
の前に下記2行を追加しました。
{% assign index = paginate.current_page | minus: 1 | times: paginate_by %}
{% assign collections = tmp_collections | sort: 'published_at' | slice: index, paginate_by %}
すると、下図のようになります。
うまく動いていることを確認するために2ページ目も確認します。
どうやら、うまくいったようです。
追加したコードではざっくり下記を行いました。
- コレクションの配列を加工して要素が2つ(1ページに2つずつなので)だけの配列を作成し、それをfor文に渡す。
- コレクションの配列を加工する際、「現在のページ番号」の情報を利用して、配列の何番目の要素から2つの要素を取り出すかを制御する。
まとめ
コレクション配列の加工の仕方を工夫すれば、特定の条件に合致したコレクションだけをコレクションリストに表示する、という制御もできそうです。
しかし、繰り返しになりますが、かなり無理をした実装になっており、Shopify的には非推奨であろうと考えています。
そして、何を隠そう、実はテーマカスタマイズで表示順は変更できます。
上記で選択できるソート順以外でソートしたい時に役に立つかもしれませんが、Liquidでどうにかしようとするより、ストアフロント側でJavaScriptで制御したり、要件に合うアプリを探して導入したりした方が無難です。
あくまで、「こういうこともできる」という参考程度にお留めください。