●条件
- テーマは、最新のDawn。
- 使いまわしたいセクションは共通のバナーリストで、画像、リンク先、テキストが設定できる
- 以降、そのセクション名は「test-bnrlist.liquid」とする
- theme.liquidの構成は、大がかりな変更を加えないとする。
- テンプレートファイルも変更せず、json形式のまま
■使いまわしセクション設定画面のイメージ
■theme.liquid 基本構成
<html>
<head></head>
<body>
{% sections 'header-group' %}
{{ content_for_layout }}
{% sections 'footer-group' %}
</body>
</html>
■テンプレートファイルの例(404.jsonの例)
{
"sections": {
"main": {
"type": "main-404",
"settings": {
}
}
},
"order": [
"main"
]
}
当然、静的レンダリングであれば、記述を繰り返すことで、同じ設定のセクションが表示されます。
{% section 'test-bnrlist' %}
{% section 'test-bnrlist' %}
ただし、今回はthemeの構成も大きく変えず、テンプレートもjson形式の動的レンダリングで、同一内容を出力させたいと考えています。
※以降、長めに状況説明が入りますが、伺いたいことは最後にまとめています。
■思いつく解決策 jsでのHTMLパース
単純な解決策としては、themeなどにセクション「test-bnrlist」を設置し、画像等を登録。
同セクションでは、一旦jsのオブジェクトを出力。
あとはコピー用のセクションなどで、上記オブジェクトを基にHTMLにパースする方法です。
もしかしたらこれしか方法が無いのではと思っています。
その他の方法を思案したものの、結局頓挫してしまいました。
–
■頓挫策① settings_data.jsonの参照
test-bnrlistの設定がsettings_data.jsonに保存されることを確認しました。
{
"current": {
"logo_width": 90,
(略)
"cart_drawer_collection": "",
"sections": {
"test-bnrlist": {
"type": "test-bnrlist",
"blocks": {
"951064a7-93aa-4153-97d5-b49ae72b783b": {
"type": "choose",
"settings": {
"image": "shopify:\/\/shop_images\/business-pug-working-on-laptop.jpg",
"url": "",
"text": ""
}
}
},
"block_order": [
"951064a7-93aa-4153-97d5-b49ae72b783b"
],
"settings": {
}
}
},
},
"presets": {
"Default": {
"logo_width": 90,
(略)
}
}
}
{{ settings | json }}を出力させてみた限り、上記jsonのcurrent直下の値は確認できました。
しかし、目的とする「test-bnrlist」の設定値があるsections以下は存在しないように思います。
いっそのこと、直接settings_data.jsonを取得できれば、今回の目的も達成できそうに思えました。
しかし頓挫したのは、格納先が分からなかったためです。
アセッツ内cssのURLが以下なので予想を立ててみたのですが…。
//cdn.shopify.com/s/files/1///****/t/**/assets/style.css
設定ファイルはこのような形式かと思いましたが、結局たどり着けませんでした。
//cdn.shopify.com/s/files/1////t/**/config/settings_data.json
//cdn.shopify.com/s/files/1////t/**/settings_data.json
設定ファイルが取得出来たら、liquidファイルで完結するのが利点ですね。
可能ならこちらの手段で実現できたらと思います。
■頓挫策② セクション出力結果を変数に格納
結論としては全て「Cannot render sections inside sections」のエラーが発生します。
以下記述なら、セクション内容を変数に格納し、その出力も出来るだろうかと試してみました。
{% capture get_bnrlist %}{% section "test-bnrlist" %}{% endcapture %}
{{ get_bnrlist }}
■構成1 スニペットでの変数出力
(A)セクションファイル
スニペットのレンダリングのみ
{% render 'test-bnrlist_detail' %}
(B)スニペットファイル
セクションを変数に格納して出力
{% capture get_bnrlist %}{% section "test-bnrlist" %}{% endcapture %}
{{ get_bnrlist }}
=>エラー
■構成2 セクションからスニペットへ変数を引き渡す
(A)セクションファイル
変数を定義してスニペットを呼び出す
{% capture get_bnrlist %}{% section "test-bnrlist" %}{% endcapture %}
{% render 'test-bnrlist_detail' , get_bnrlist: get_bnrlist %}
(B)スニペットファイル
その変数を出力
{% assign result = get_bnrlist %}
{{ result }}
=>エラー
※renderをincludeに変更しても同じ結果です
ファイル階層を簡単に記述するなら以下のようになると思います。
【theme > テンプレート > セクション > スニペット(セクションを呼び出す)】
=> エラー
結局エラーを回避するならば、themeからスニペットを直接レンダリングするなど、themeの構成変更が必要そうです。
【theme > スニペット1(セクションを呼び出す)+ スニペット2(同一セクションを呼び出す)】
仕様上、間に挟まるセクションや{{ content_for_layout }}に対し、引数の受け渡しは出来ないのでしょう。
よって、仮にthemeでグローバル風の変数を定義したところで、それを渡す手段がないですね。
また、セクションの設定は同セクション以下でのみ活用可能な設計かと思います。
セクションから別セクションの設定を参照すること自体、不可能なのでしょう。
一応これらの解決の糸口が、頓挫策①に当たるはずなのですが。
■頓挫策③ (セクション設定不使用)グローバルな要素を使用する
乱暴な方法なら実現可能ではあります。
- コレクションやページのディスクリプション欄に必要なHTML要素を登録。
- メタオブジェクトに文字情報で格納。
ただし要素の入れ替えなど細かい調整に難儀するため、この方法は使いたくないですね。
■頓挫策④ (セクション設定不使用)アプリ
アプリなら要件を満たせるの気になりました。
ただ、アプリは開発経験がないので、現状どこまで出来るか不明な状態です。
本文が長くなりましたので、要点のまとめです。
■質問
同一設定のセクションをページ内で使いまわす方法
■条件
- 動的レンダリングを用いる
- themeの構成は大きく変更しない
- セクションの内容は共通バナーリストで、設定には画像、URL、テキストが含まれる
■回答いただきたいこと(どれでも分かるものだけで結構です)
- settings_data.jsonを直接参照する方法
- settings_data.json格納先のURL
- アプリなら要件を満たせるのかどうか?
以上です。ご回答いただければさいわいです。
