Liquid、JavaScriptなどに関する質問
【質問】全商品を表示させる方法をお伺いします。
コレクションの中に、商品のカテゴリーをいくつか作っているのですが、その一項目に「全商品を表示」という項目を作りたいのですが、どうしても全商品を表示させることができません。
ショップページを見るとどうしても次のページを見るように矢印をクリックしなければならないのですが、そうではなく1ページに全商品(500品ほど)を表示させる方法はありますでしょうか?下にスクロールしていけば次々と商品が見えるようにしたいという意味です。
当方、ウェブサイト知識は簡単なHTML程度を理解している程度ですので、なるだけわかりやすくおしえていただければ助かります。どうぞよろしくお願いいたします。
解決済! ベストソリューションを見る。
成功
かなり古い投稿ですので、すでに解決しておられるかもしれませんが。
コミュニティの活性化のためにも回答させていただきます。
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以降はすべてレイジーロードにするとかするなどしてパフォーマンスを考慮しないといけないとおもいます。
成功
Twitterのフロント部分はReactを使ったSPAですね。最初投稿は3件くらいしか生成されていませんが、スクロールするとDOMツリーがどんどん生成されていくタイプです。
レイジーロードはもう少し単純なもので、HTTPリクエストが発生しそうなものをすべて一旦別の要素で置き換えます。
例えば 最も重たいのは画像ですよね。
通常 <img src="画像のURL"> となっているはずですが
<img src="" data-src="画像のURL"> のようにして、いったんリクエストされない形にしておきます。
でスクロールしていって当該の要素がウィンドウに近づいたら data-srcの中身を srcに移し替えて画像をリクエストします。
こうすることで一気に大量のリクエストが送られずに、徐々に表示されるため、体感スピードが大幅に向上します。
自身で書かなくても、class を当てるだけでいい ライブラリもいくつか存在します。
liquidはバックエンド言語だと思うので、APIがないとこういったリアルタイムな通信はできないんじゃないでしょうか。
なのでテーマ編集のみで実装するのであれば、ファーストビュー分を除く全てのDOMを上記のようにlazy対応しておいて
JSでスクロール監視→src書き換え とするしかないかな~と思います。
成功
かなり古い投稿ですので、すでに解決しておられるかもしれませんが。
コミュニティの活性化のためにも回答させていただきます。
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以降はすべてレイジーロードにするとかするなどしてパフォーマンスを考慮しないといけないとおもいます。
コミュニティ活性のためのご回答ありがとうございます!
参考になりました。
僕もoffsetを使ったこの方法がよいと思います。
レイジーロードとは、Twitterなどのスクロールのように、次にスクロールした段階で、続きのoffsetからデータを描画するということですよね?
成功
Twitterのフロント部分はReactを使ったSPAですね。最初投稿は3件くらいしか生成されていませんが、スクロールするとDOMツリーがどんどん生成されていくタイプです。
レイジーロードはもう少し単純なもので、HTTPリクエストが発生しそうなものをすべて一旦別の要素で置き換えます。
例えば 最も重たいのは画像ですよね。
通常 <img src="画像のURL"> となっているはずですが
<img src="" data-src="画像のURL"> のようにして、いったんリクエストされない形にしておきます。
でスクロールしていって当該の要素がウィンドウに近づいたら data-srcの中身を srcに移し替えて画像をリクエストします。
こうすることで一気に大量のリクエストが送られずに、徐々に表示されるため、体感スピードが大幅に向上します。
自身で書かなくても、class を当てるだけでいい ライブラリもいくつか存在します。
liquidはバックエンド言語だと思うので、APIがないとこういったリアルタイムな通信はできないんじゃないでしょうか。
なのでテーマ編集のみで実装するのであれば、ファーストビュー分を除く全てのDOMを上記のようにlazy対応しておいて
JSでスクロール監視→src書き換え とするしかないかな~と思います。
なるほど。ご回答ありがとうございます。
> liquidはバックエンド言語だと思うので、APIがないとこういったリアルタイムな通信はできないんじゃないでしょうか。
そうですね、liquidのデータは最初の描画時に全てデータを保持してるはずなので、リアルタイムで追加データを参照することはできないと思います。
こちらに回答させていただいた 1ページに大量の商品を表示させる方法ですが、
実際には 50商品以上出力されないことが確認できました。
なのでこちらの回答は使えないコードなので参考になさらないようにお願いいたします。
Shopifyの仕様で、同一ページ内に、1つのcollectionオブジェクトから取得可能なproductは50まででした。
これは一つのforループという縛りではなく、forを分割したり、別の変数にオブジェクトを定義しなおして新たにforループを作成しても同じです。
1ページに50以上productを表示可能な方法は異なるcollectionオブジェクト同士の場合のみでした。
フォローアップありがとうございます。
こちらにも書いてありますね。 https://help.shopify.com/en/themes/liquid/objects/collection
なお、このドキュメントに collection.next_product collection.previous_product というオブジェクトがありますが、これでiterationした場合はどうでしょうか? nil になるまでループし続けたら、50件以上表示できたりしないですかね?
ご返信ありがとうございます。
たしかに書いてありました(汗)
どう曲解したのか、当時の私は一回の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アイテムが上限?っぽいのでどのみち弊社のボリュームでは使用できず、
今はとりあえず諦めてコレクションを大量生成して商品タイプにキーワードを含ませて検索させてるようにしました。。。根本的な解決にはなりませんが。。。
なるほど。検証ありがとうございます。大変助かります。
Shopify アカデミーの学習パスと認定スキルバッジExpanding Your Shopify Business Internationallyを活用して、国際的にビジネ...
By Shopify Feb 7, 2025Shopify アカデミーの学習パスB2B on Shopify:立ち上げとカスタマイズで卸売販売に進出しましょう。これら3つの無料コースは、ShopifyストアでB2B機能...
By Shopify Jan 31, 2025サポートの選択肢が増えていく中、最適となる選択の判断が難しくなっているかと存じます。今回は問題の解決に最適となるサポートの選択方法を、紹介させて頂きます。 選択肢のご紹介...
By Mirai Oct 6, 2024