はじめに このカスタマイズ方法は現在の日付から「◯日後」や「締め時間」で分岐させるシンプルな仕様です。 また、出力結果は土日や祝日を除くことはできますが、臨時休業や平日の定休日には対応しておりませんので、長期休暇案内セクションを実装や営業日カレンダーを実装と併用してご利用いただくか、さらにカスタマイズしてご利用ください。 リクエストにお応えして連休対応版に改良しました。2024年11月以前にこのカスタマイズをご利用されている方は、コードを差し替えていただくことで、さらに便利にご利用いただけます。 スニペットファイルを追加 「新しいスニペットを追加する」より「product-shipping-date.liquid」を作成し以下のコードを順番にコピペしてください。 Liquidコード {% liquid assign day = 86400 assign now = 'now' | date: '%s' assign now_time = 'now' | date: '%k' | abs assign date_format = block.settings.date_format assign set_days = block.settings.shipping_day assign shipping_days = set_days | times: day assign shipping_close_time = block.settings.shipping_close_time assign show_weekday = block.settings.show_weekday assign exclude_weekend = block.settings.exclude_weekend assign set_date = now | plus: shipping_days assign now_week = now | date: '%a' assign weekend = '' if exclude_weekend assign weekend = 'Sat,Sun' | split: ',' endif unless shipping_days == 0 and weekend contains now_week if now_time >= shipping_close_time assign set_date = set_date | plus: day assign set_days = set_days | plus: 1 endif endunless if exclude_weekend capture weeks for number in (0..set_days) assign days = day | times: number echo now | plus: days | date: '%a' unless forloop.last echo ',' endunless endfor endcapture assign weeks_array = weeks | split: ',' assign plus_days = 0 for week in weeks_array case week when 'Sat', 'Sun' assign plus_days = plus_days | plus: 1 endcase endfor capture weeks_2nd assign set_days_2nd = set_days | plus: plus_days for number in (0..set_days_2nd) assign days = day | times: number echo now | plus: days | date: '%a' unless forloop.last echo ',' endunless endfor endcapture assign weeks_2nd_array = weeks_2nd | remove: weeks | split: ',' for week in weeks_2nd_array case week when 'Sat', 'Sun' assign plus_days = plus_days | plus: 1 endcase endfor assign plus_day = day | times: plus_days assign set_date = set_date | plus: plus_day endif capture shipping_date assign weekday = set_date | date: '%a' if show_weekday capture weekday_jp case weekday when 'Sun' echo '日曜日' when 'Mon' echo '月曜日' when 'Tue' echo '火曜日' when 'Wed' echo '水曜日' when 'Thu' echo '木曜日' when 'Fri' echo '金曜日' when 'Sat' echo '土曜日' endcase endcapture endif echo set_date | date: date_format | append: weekday_jp endcapture assign data_shipping_date = set_date | date: '%Y-%m-%d' assign set_days = set_date | minus: now | divided_by: day %} 順に説明します。 2行目の「day」で1日を秒数としたもの、3行目で現在の日付をUNIX時間、4行目の「now_time」で現在の時刻を定義しています。 5〜10行目はそれぞれブロック設定を割り当てており、「shipping_days」は「日数×86400」で出荷日までの日数を秒に変換しています。 12〜23行目は締め時間の分岐で、現在の時刻が締め時間を超えた場合に1日追加される仕組みです。また「週末を除外」設定が有効な場合は、加算日を調整しております。 25〜937行目にて、出力される日付を定義しています。「週末を除外」設定が有効な場合は、本日から締め時間分岐で算出された日付の曜日をweeks_arrayとして配列化し、土日を含む場合にそれぞれ+1日が加算されます。また、加算された日付までをさらにweeks_2nd_arrayとして配列化し最初の配列分を削除、残った曜日配列から土日を含んでる場合にそれぞれ+1日を加算します。オプションとして曜日が日本語で出力されるようになっています。 ※連休や長期期間に対応させるため改良しました。 HTMLコード <div class="shipping-date-box"> {%- capture date_format -%} <strong id="ShippingDate" class="shipping-date" data-shipping-date="{{ data_shipping_date }}" data-exclude-weekend="{{ exclude_weekend }}">{{ shipping_date }}</strong> {%- endcapture -%} <p>{{ block.settings.label | replace: 'date', date_format }}</p> </div> 「date_format」にて算出した日付を定義します。ブロック設定で「発送予定日: date」とした場合、「date」部分を日付と置換されるようになっています。また、「data-shipping-date」属性として「YYYY-MM-DD」形式で発送日が出力され、「data-exclude-weekend」属性として「週末を除外」設定の真偽値を出力します。 HTML構造はお好みで編集してください。 Javascriptコード {%- if block.settings.holiday -%} {% liquid capture days for number in (0..set_days) assign days = day | times: number echo now | plus: days | date: '%Y-%m-%d' unless forloop.last echo ',' endunless endfor endcapture assign days_array = days | split: ',' %} <script> const shippingDateElement = document.getElementById('ShippingDate'); const shippingDateData = new Date(shippingDateElement.dataset.shippingDate); const holidaysApiUrl = 'https://holidays-jp.github.io/api/v1/date.json'; const excludeWeekend = shippingDateElement.dataset.excludeWeekend === "true"; const daysArray = {{ days_array | json }}; const formatOptions = { year: 'numeric', month: 'long', day: 'numeric', {% if show_weekday %}weekday: 'long',{% endif %} }; const isWeekend = date => date.getDay() === 0 || date.getDay() === 6; const fetchHolidays = async () => { try { const response = await fetch(holidaysApiUrl); const holidaysData = await response.json(); const holidays = new Set(Object.keys(holidaysData)); let shippingDate = new Date(shippingDateData); const plusDays = daysArray.reduce((count, day) => { if (holidays.has(day)) { const holidayDate = new Date(day); if (!(excludeWeekend && isWeekend(holidayDate))) { count += 1; } } return count; }, 0); shippingDate.setDate(shippingDate.getDate() + plusDays); while (holidays.has(shippingDate.toISOString().split('T')[0])) { shippingDate.setDate(shippingDate.getDate() + 1); } shippingDateElement.textContent = new Intl.DateTimeFormat('ja-JP', formatOptions).format(shippingDate); shippingDateElement.dataset.shippingDate = shippingDate.toISOString().split('T')[0]; } catch (error) { console.error('Failed to fetch holidays:', error); } }; fetchHolidays(); </script> {%- endif -%} これは祝日に発送しない場合「祝日を除外」設定が有効な場合のみ出力されます。 Liquidコードだけでは日本の祝日に対応しないため、「Holidays JP API」という日本の祝日を出力するAPIを使用して、祝日を判定し配送予定日を加算するコードです。 元々は「data-shipping-date」属性の値が祝日だった場合に翌日に書き換えるというシンプル設計でしたが、連休や振替休日などにも対応させるために改良しました。 仕様は以下の通りです。 99-108行目のLiquidコードにて、週末判定後の配送期間の日付をdays_arrayとして配列化します。 そしてHolidays JP APIより配列化した祝日の日付と一致する場合は+1日を加算し、「週末を除外」設定が有効な場合で祝日が土日の場合は加算しないようにしています。 加算した結果が祝日だった場合は、次の平日がセットされるようにしてあります。 何度も検証したのでよほど大丈夫だとは思いますが、エラーや改善点などありましたが、ご連絡いただけると幸いです。 以上で、スニペットファイルは完了です。 セクションファイルを編集 商品ページを出力するファイルを開きます。Dawnの場合は「sections/main-product.liquid」が該当します。 スキーマにブロックを追加 {% schema %}内の「blocks」に以下のブロックを追加します。 { "type": "shipping_date", "name": "発送予定日", "limit": 1, "settings": [ { "type": "text", "id": "label", "label": "出力テキスト", "default": "発送予定日: date", "info": "dateで日付を出力" }, { "type": "text", "id": "date_format", "label": "日付フォーマット", "default": "%Y年%-m月%-d日", "info": "[Rubyドキュメント](https://ruby-doc.org/core-3.1.1/Time.html#method-i-strftime)または[strftimeリファレンスとサンドボックス](https://www.strfti.me/)を参照してください。" }, { "type": "range", "id": "shipping_day", "label": "発送日", "min": 0, "max": 14, "step": 1, "unit": "日後", "default": 2, "info": "「0」で締め時間までは当日発送" }, { "type": "range", "id": "shipping_close_time", "label": "締め時間", "min": 0, "max": 23, "step": 1, "unit": "時", "default": 12 }, { "type": "checkbox", "id": "show_weekday", "label": "曜日を表示", "default": true }, { "type": "checkbox", "id": "exclude_weekend", "label": "週末を除外", "default": true, "info": "土日を発送日から除外し翌営業日を出力します。" }, { "type": "checkbox", "id": "holiday", "label": "祝日を除外", "default": true, "info": "[Holidays JP API](https://holidays-jp.github.io/)より日本の祝日情報を取得します。" } ] } ブロック設定の詳細に関しては、後ほど「設定」にてご説明します。 「発送日」は14日後まで設定できるようになっていますが、それ以上の日数を設定する場合は「max」の値を編集してください。 2.0に未対応のテーマに実装する場合は、ブロック設定をセクション設定に置き換えるなどしてください。 スニペットファイルを読み込む {% case block.type %}〜{% endcase %}内の最後の方に以下のコードをコピペしてください。 {%- when 'shipping_date' -%} {% render 'product-shipping-date' block: block %} 2.0に未対応のテーマをご利用の際は{% when %}以外の2行を、購入ボタン付近に分岐などして実装してください。 以上でテーマの編集は終わりです。 設定 カスタマイザーより商品ページを開き、「ブロックを追加」で「発送予定日」ブロックを追加し、お好きな位置にドラッグしてください。 2.0に未対応のテーマをご利用の際は不要です。 各設定について上から順に説明します。 「出力テキスト」では実際に出力するテキストを設定できます。「発送予定日: date」とした場合は「発送予定日: YYYY年MM月DD日」と出力されます。「date」部分が日付に置換されますので、「YYYY年MM月DD日に発送」といった感じでも出力できます。 「日付フォーマット」はサイトに合わせて好きなフォーマットで出力できます。「%Y-%m-%d」とすれば「YYYY-MM-DD」、「%Y/%m/%d」で「YYYY/MM/DD」と出力されます。 「発送日」は何日後に発送するのかを設定します。当日出荷の場合は「0」日で設定してください。 「締め時間」では受付の締め切り時間を設定できます。特に設定しない場合は定時などを設定してください。 「曜日を表示」にチェックで日付の末尾に曜日を出力できます。曜日は「○曜日」と日本語表記となりますが「(月)」などカッコ書きを希望の場合は、2-1のLiquidコードを編集してください。 「週末を除外」にチェックで土日を出力結果から除外し、除外分が配送日に加算されます。 「祝日を除外」にチェックで祝日を出力結果から除外し、除外分が配送日に加算されます。