FROM CACHE - jp_header
解決済

全商品表示方法について

Shopifylion
訪問者
1 0 0

【質問】全商品を表示させる方法をお伺いします。

 

コレクションの中に、商品のカテゴリーをいくつか作っているのですが、その一項目に「全商品を表示」という項目を作りたいのですが、どうしても全商品を表示させることができません。

 

ショップページを見るとどうしても次のページを見るように矢印をクリックしなければならないのですが、そうではなく1ページに全商品(500品ほど)を表示させる方法はありますでしょうか?下にスクロールしていけば次々と商品が見えるようにしたいという意味です。

 

当方、ウェブサイト知識は簡単なHTML程度を理解している程度ですので、なるだけわかりやすくおしえていただければ助かります。どうぞよろしくお願いいたします。

 

2 件の受理された解決策

WEBUILD
Shopify Partner
39 11 41

成功

かなり古い投稿ですので、すでに解決しておられるかもしれませんが。
コミュニティの活性化のためにも回答させていただきます。

HTMLのみの知識ということですと実装はかなりハードルが高そうですが・・・

通常collectionに含まれるプロダクトは50商品が表示限界になっているようです。

ただしこれは一回のループ内で・・・という縛りっぽいです。
当方がまだ構築中で50にも商品数が届いていなにので
まだ確実なテストできておりませんが。
collection.products のループを数カ所作った結果、同じプロダクトの情報ではありますが50を超える

プロダクトの出力が可能でした。これが実際、すべて異なるプロダクトの数が50個までという謎仕様出ない限り

複数個のcollection.products のループを設置で実現できるかもしれません。

{%- assign maxpage = collection.all_products_count | divided_by: 10 | ceil -%}
{% for i in (0..maxpage) %}
	{%- assign offset = i | times: 10 -%}
	{%- assign offset_limit = i | plus: 1 | times: 10 | minus: 1 -%}
	{% for product in collection.products offset: offset limit: 10 %}
                <!-- ここにアイテムカードをincludeする -->
  	{% endfor %}
{% endfor %}

こんな感じのコードですかね~
これは10件ずつループで回しています。
たぶんソートも効くはずです。

ただこのままもし本当に500商品とか表示すると重くて仕方がないと思うので
最初の10以降はすべてレイジーロードにするとかするなどしてパフォーマンスを考慮しないといけないとおもいます。

 

元の投稿で解決策を見る

WEBUILD
Shopify Partner
39 11 41

成功

Twitterのフロント部分はReactを使ったSPAですね。最初投稿は3件くらいしか生成されていませんが、スクロールするとDOMツリーがどんどん生成されていくタイプです。

レイジーロードはもう少し単純なもので、HTTPリクエストが発生しそうなものをすべて一旦別の要素で置き換えます。
例えば 最も重たいのは画像ですよね。
通常 <img src="画像のURL">  となっているはずですが
<img src="" data-src="画像のURL">  のようにして、いったんリクエストされない形にしておきます。

でスクロールしていって当該の要素がウィンドウに近づいたら data-srcの中身を srcに移し替えて画像をリクエストします。

こうすることで一気に大量のリクエストが送られずに、徐々に表示されるため、体感スピードが大幅に向上します。

 

自身で書かなくても、class を当てるだけでいい ライブラリもいくつか存在します。

liquidはバックエンド言語だと思うので、APIがないとこういったリアルタイムな通信はできないんじゃないでしょうか。
なのでテーマ編集のみで実装するのであれば、ファーストビュー分を除く全てのDOMを上記のようにlazy対応しておいて
JSでスクロール監視→src書き換え とするしかないかな~と思います。

元の投稿で解決策を見る

8件の返信8

WEBUILD
Shopify Partner
39 11 41

成功

かなり古い投稿ですので、すでに解決しておられるかもしれませんが。
コミュニティの活性化のためにも回答させていただきます。

HTMLのみの知識ということですと実装はかなりハードルが高そうですが・・・

通常collectionに含まれるプロダクトは50商品が表示限界になっているようです。

ただしこれは一回のループ内で・・・という縛りっぽいです。
当方がまだ構築中で50にも商品数が届いていなにので
まだ確実なテストできておりませんが。
collection.products のループを数カ所作った結果、同じプロダクトの情報ではありますが50を超える

プロダクトの出力が可能でした。これが実際、すべて異なるプロダクトの数が50個までという謎仕様出ない限り

複数個のcollection.products のループを設置で実現できるかもしれません。

{%- assign maxpage = collection.all_products_count | divided_by: 10 | ceil -%}
{% for i in (0..maxpage) %}
	{%- assign offset = i | times: 10 -%}
	{%- assign offset_limit = i | plus: 1 | times: 10 | minus: 1 -%}
	{% for product in collection.products offset: offset limit: 10 %}
                <!-- ここにアイテムカードをincludeする -->
  	{% endfor %}
{% endfor %}

こんな感じのコードですかね~
これは10件ずつループで回しています。
たぶんソートも効くはずです。

ただこのままもし本当に500商品とか表示すると重くて仕方がないと思うので
最初の10以降はすべてレイジーロードにするとかするなどしてパフォーマンスを考慮しないといけないとおもいます。

 

junichiokamura
Community Manager
1200 280 506

コミュニティ活性のためのご回答ありがとうございます!

 

参考になりました。

 

僕もoffsetを使ったこの方法がよいと思います。

 

レイジーロードとは、Twitterなどのスクロールのように、次にスクロールした段階で、続きのoffsetからデータを描画するということですよね?

Senior Partner Solutions Engineer
WEBUILD
Shopify Partner
39 11 41

成功

Twitterのフロント部分はReactを使ったSPAですね。最初投稿は3件くらいしか生成されていませんが、スクロールするとDOMツリーがどんどん生成されていくタイプです。

レイジーロードはもう少し単純なもので、HTTPリクエストが発生しそうなものをすべて一旦別の要素で置き換えます。
例えば 最も重たいのは画像ですよね。
通常 <img src="画像のURL">  となっているはずですが
<img src="" data-src="画像のURL">  のようにして、いったんリクエストされない形にしておきます。

でスクロールしていって当該の要素がウィンドウに近づいたら data-srcの中身を srcに移し替えて画像をリクエストします。

こうすることで一気に大量のリクエストが送られずに、徐々に表示されるため、体感スピードが大幅に向上します。

 

自身で書かなくても、class を当てるだけでいい ライブラリもいくつか存在します。

liquidはバックエンド言語だと思うので、APIがないとこういったリアルタイムな通信はできないんじゃないでしょうか。
なのでテーマ編集のみで実装するのであれば、ファーストビュー分を除く全てのDOMを上記のようにlazy対応しておいて
JSでスクロール監視→src書き換え とするしかないかな~と思います。

junichiokamura
Community Manager
1200 280 506

なるほど。ご回答ありがとうございます。

 

>  liquidはバックエンド言語だと思うので、APIがないとこういったリアルタイムな通信はできないんじゃないでしょうか。


そうですね、liquidのデータは最初の描画時に全てデータを保持してるはずなので、リアルタイムで追加データを参照することはできないと思います。

 

 

Senior Partner Solutions Engineer
WEBUILD
Shopify Partner
39 11 41

こちらに回答させていただいた 1ページに大量の商品を表示させる方法ですが、

実際には 50商品以上出力されないことが確認できました。
なのでこちらの回答は使えないコードなので参考になさらないようにお願いいたします。

Shopifyの仕様で、同一ページ内に、1つのcollectionオブジェクトから取得可能なproductは50まででした。
これは一つのforループという縛りではなく、forを分割したり、別の変数にオブジェクトを定義しなおして新たにforループを作成しても同じです。

1ページに50以上productを表示可能な方法は異なるcollectionオブジェクト同士の場合のみでした。


junichiokamura
Community Manager
1200 280 506

フォローアップありがとうございます。

こちらにも書いてありますね。 https://help.shopify.com/en/themes/liquid/objects/collection

なお、このドキュメントに collection.next_product collection.previous_product というオブジェクトがありますが、これでiterationした場合はどうでしょうか? nil になるまでループし続けたら、50件以上表示できたりしないですかね?

Senior Partner Solutions Engineer
WEBUILD
Shopify Partner
39 11 41

ご返信ありがとうございます。

たしかに書いてありました(汗)
どう曲解したのか、当時の私は一回のforループの上限が50という思い込みをしたようです><

テストしたときは20商品ほどしか登録できていなかったため、同じプロダクトを何度もループで出力した場合、50以上出力できるのでそれで可能だと勘違いしてしまいました。。。

collection.next_product, collection.previous_product 
については早速テストさせていただきました。

結論から言いますと、コレクションページでは使用できず、いずれのコレクションでも必ずNilが返りました。

Productページであれば機能しました。
そのProductが所属するコレクション内の前後商品を取得する機能のようです。

Productページでたくさん商品を表示したい場合は有りかもしれません。
が結構それはレアケースかな・・・

私はコレクションのタグフィルターをANDではなくORで使用したかったので、
自前で擬似Collectionオブジェクトを作成しようと試行錯誤していたのですが、どうしても50商品以上出力できませんでした。。。
Paginateオブジェクトも純粋なcollectionオブジェクトしか受け取らないしで結構しばりがきついですね。。。


海外版を見てもやはりできないらしく、Shopifyの商品をDBをローカルに移してJSで表示する方法取られている方がいました。
かなり手間がかかるのでどうかなぁって感じですが。。。
APIも考慮しましたが、まだサラッと読んだだけですが250アイテムが上限?っぽいのでどのみち弊社のボリュームでは使用できず、
今はとりあえず諦めてコレクションを大量生成して商品タイプにキーワードを含ませて検索させてるようにしました。。。根本的な解決にはなりませんが。。。

junichiokamura
Community Manager
1200 280 506

なるほど。検証ありがとうございます。大変助かります。

Senior Partner Solutions Engineer