今回は、どうしても面倒だった、Liquid data > jsへjsonで渡す > jsでHTMLテンプレートにデータを入れて出力 の工程で楽出来ないかと思い…試行錯誤した結果、上手くいったので共有したいと思います。
なぜ、この方法を考えたかと言うと、たまにある一覧データでのもっと見るボタン。
Liquidでの実装も可能だが、独自カスタムをした場合、jsを組み込む必要があるため、どうしても一旦は全データをjsへ渡す必要がある。
今までは、Liquidでjsonを作成し、それをjsで加工し、HTMLへ流し込むとやってはいたが…。jsがスパゲッティ化してしまう。
というか、条件に応じてどれだけでも存在するロジックを組み、コードを書くのが面倒くさかった。
理想としては、Liquidで判定 > Liqiud dataをHTMLに入れる > HTMLごとjsへ > jsは必要な分だけ出力。
こいつができたので、以下で説明していきます。
まずはコードの共有
今回は注文履歴一覧での、もっと見る実装だったのでcustomer.ordersで実装しています。
{% paginate customer.orders by 250 %}
<div id="container"></div>
{%- comment -%} jsに渡すためのデータを作成 {%- endcomment -%}
{%- assign order_array = "" -%}
{% for order in customer.orders by 250 %}
{% capture html %}
{%- comment -%} ここにrenderか直書きでカードHTMLを入れ込む {%- endcomment -%}
{%- render "order-list-card", order: order -%}
{% endcapture %}
{% capture one_order %}{"data": {{ html | json }}}{% endcapture %}
{% assign order_array = order_array | append: "," | append: one_order %}
{% endfor %}
{% assign order_array = order_array | remove_first: "," %}
{%- comment -%} オーダーJSON作成 {%- endcomment -%}
{% capture order_list_data %}[{{ order_array }}]{% endcapture %}
{% endpaginate %}
<script type='text/javascript'>
const ORDER_LIST_DATA = {{ order_list_data }};
let cards;
// ORDER_LIST_DATAを加工して必要なぶんだけ取り出した配列に変更してもOK
cards = ORDER_LIST_DATA.map(item => { return item.data });
cards = cards.join('');
document.getElementById('container').insertAdjacentHTML('beforeend', cards);
</script>
説明
{%- render "order-list-card", order: order -%} で読み込んでいるところがHTML本体になるところです。
ここは、renderを使って別ファイルを読み込んでもいいし、HTML直書きでもOKです。
一番大事なところが、{% capture one_order %}{"data": {{ html | json }}}{% endcapture %}で、この時点でHTMLをjsonで入力し、これ以降でLiquidオブジェクトをjson化しないことです。このタイミングでjsonにしてあげないと、jsに上手くオブジェクトとして伝わってくれません。
あとは、Liquidで作成した配列をjsへ渡し、必要な分だけcontainerの中に出力してあげればOKです。
まとめ
特定のデータの全取得からの表示…。今までとても面倒で嫌いでしたが、これで実装・管理しやすくなったと思います。
まだ試していませんが、これなら一度に取得する情報量も、Liquidのページネーションで制限し、もっとみるを押した時点で次のページのデータを取得するとかもいけそう…。
それもどこかで試していこうと思います。
あと…
ARCHETYPでは、Shopifyのテーマ開発やアプリ開発をやりたいエンジニアを募集しております!
気になった方はお気軽にエントリーをお待ちしております!
https://www.archetyp.jp/recruit/
(業務委託の方もお待ちしておりますー!)