Shopify Flow에서 Liquid 변수 사용

Liquid 변수는 워크플로가 실행될 때 GraphQL Admin API의 값으로 대체되는 Liquid에 정의된 플레이스 홀더입니다. 변수는 주문 번호, 주문 가격 또는 고객 이름과 같이 워크플로와 관련된 고객, 주문 및 제품의 특성을 설명할 수 있습니다. 변수는 조건에서 워크플로의 논리를 제어하거나 작업에서 데이터를 출력하는 데 사용할 수 있습니다.

Liquid를 사용하여 워크플로에 변수 추가

변수 추가 링크가 포함된 모든 텍스트 필드에 Liquid를 사용하여 변수를 추가할 수 있습니다. 관련 필드 아래의 변수 추가 링크를 클릭한 다음 목록에서 변수를 선택하십시오.

내부 이메일 보내기 작업의 구성 패널 이미지, 제목 필드 아래의 '변수 추가' 옵션이 강조 표시됨.

변수 추가 목록의 변수는 필터링되므로 트리거와 같이 현재 단계 이전 단계에서 반환되는 변수만 사용할 수 있습니다. 예를 들어 주문 생성됨 트리거는 변수로 삽입할 수 있는 Admin API의 주문 및 상점 리소스를 제공합니다. 목록에서 변수를 선택하면 올바른 형식의 Liquid로 텍스트 상자에 추가됩니다.

텍스트 필드에 Liquid를 직접 작성할 수도 있습니다. 예를 들어 {{ order.name }} 변수를 사용하여 order-123과 같은 Shopify 관리자의 주문 문자열을 표시할 수 있습니다.

Flow는 Admin API를 사용하여 Liquid에 사용되는 데이터를 검색하므로 변수 구문은 카멜 케이스를 사용합니다. 카멜 케이스 변수는 첫 단어가 소문자로 시작하고 다음 단어는 firstName 또는 canMarkAsPaid와 같이 대문자로 시작합니다. 예를 들어 제품이 생성된 날짜에 액세스하려면 {{ product.createdAt }}을(를) 입력합니다. 카멜 케이스를 사용하지 않는 Shopify 테마에서 Liquid 구문을 사용하는 경우 {{ product.created_at }}을(를) 입력합니다.

조건부 및 반복 Liquid 태그

Liquid 태그는 변수와 함께 사용하여 다음 기능을 수행할 수 있습니다.

  • 주문 총액이 100달러보다 큰지 확인하는 등 조건문을 작성합니다.
  • 주문의 각 품목에 대한 데이터를 출력하는 등 개체 목록을 반복합니다.

Liquid 태그를 사용하여 이러한 문을 작성하고 개체를 반복할 수 있습니다.

예를 들어, 다음 Liquid는 주문 총액이 100달러보다 큰 경우 주문 번호를 표시합니다.

{% if order.totalPriceSet.shopMoney.amount > 100 %}
  Order number: {{ order.name }}
{% endif %}

for 루프를 사용하여 주문의 품목과 같은 개체 목록을 반복할 수도 있습니다. 예를 들어, 다음 Liquid는 주문에 있는 각 품목의 이름을 표시합니다.

{% for li in order.lineItems %}
  {{ li.title }}
{% endfor %}

Flow는 다음 Liquid 조건부(또는 제어 흐름) 태그를 지원합니다.

Flow는 다음 Liquid 반복 태그도 지원합니다.

변수에 필터 적용

필터를 사용하여 Liquid에서 변수 데이터를 변환할 수 있습니다. Flow는 모든 오픈 소스 Liquid 필터를 지원합니다.

예를 들어 다음 Liquid는 주문 이름에서 접두사를 제거하고 남은 부분을 출력합니다. {{ order.name | remove: "Order-" }}

필터에서 Liquid 변수 사용 시 고려 사항

필터를 사용하여 변수를 변환하기 전에 다음 고려 사항을 검토하십시오.

  • Flow는 일부 필터에서 사용할 수 있는 점 표기법을 지원하지 않습니다. 예를 들어 Flow는 {{ order.lineItems | size }}은(는) 지원하지만 {{ order.lineItems.size }}은(는) 지원하지 않습니다.
  • Flow는 메타 필드에 대한 점 표기법을 지원하지 않습니다. 예를 들어 {{ order.metafields.custom.hold_note }}을(를) 사용할 수 없습니다. 대신 예에 설명된 대로 메타 필드를 반복해야 합니다.
  • Flow는 인덱스를 사용하여 목록의 품목에 액세스하는 것을 지원하지 않습니다. 예를 들어 {{ order.lineItems[0].title }}을(를) 사용할 수 없습니다. 대신 예에 설명된 대로 품목을 반복해야 합니다.

날짜 필터

표준 Liquid 필터 외에도 Flow는 예약된 시간 트리거 및 데이터 가져오기 기능을 지원하기 위해 다른 날짜를 기준으로 날짜를 가져오는 날짜 필터를 제공합니다. 이러한 필터는 date_minusdate_plus입니다. 예:

  • 미래의 날짜를 하루 반환하려면: {{ "now" | date_plus: "1 day" }}
  • 과거의 날짜를 하루 반환하려면: {{ "now" | date_minus: "1 day" }}

이 필터는 단수(예: second) 및 복수(예: seconds) 형식 모두에서 기간 단위로 second, minute, day, week, month, year를 허용합니다. 다음 유형의 사용자 지정 가능 단위도 제공할 수 있습니다.

  • 초 수를 나타내는 정수: {{ "now" | date_minus: 3600 }}, 여기서 3600은 1시간과 같습니다.
  • ISO8601 기간 문자열: {{ "now" | date_minus: "P1Y2D" }}, 여기서 P1Y2D는 1년 2일을 의미합니다.

암호화 필터

Flow는 해싱해시 기반 메시지 인증 코드(HMAC) 생성을 위한 암호화 필터를 제공합니다. 이러한 필터는 고유 식별자, 체크섬을 생성하거나 특정 해시 형식이 필요한 타사 시스템과 통합하는 데 유용합니다.

해싱 필터

Shopify Flow는 다음과 같은 유형의 해싱 필터를 지원합니다.

  • blake3 - BLAKE3 해시를 생성합니다(일반적인 사용에 권장됨).
  • sha256 - SHA-256 해시를 생성합니다.
  • sha1 - SHA-1 해시를 생성합니다.
  • md5 - MD5 해시를 생성합니다.

일반적인 해싱 용도 및 새로운 구현에는 이전 알고리즘에 비해 성능과 보안이 우수한 blake3를 사용해야 합니다. 하지만 sha256, sha1, md5는 타사 시스템과의 호환성을 위해 사용할 수 있습니다.

사용 예: {{ "hello world" | blake3 }}는 “hello world”의 BLAKE3 해시를 반환합니다.

HMAC 필터

비밀 키로 HMAC를 생성하려면 다음 지원 필터 중 하나를 사용하십시오.

사용 예:

  • 기본: {{ "message" | hmac_sha256: "secret_key" }}
  • 비밀 사용(권장): {{ "message" | hmac_sha256: secrets.api_key }}

Shopify Flow에서 Liquid로 변수를 사용하는 예

Liquid 변수 사용 방법을 더 잘 이해하려면 다음 예를 참조하십시오.

리소스의 URL 출력

워크플로와 관련된 고객, 주문, 제품의 URL을 출력하려고 합니다.

# Output the base Admin URL for your store
https://admin.shopify.com/store/{{ shop.myShopifyDomain | replace: ".myshopify.com", "" }}

# Assign the base Admin url to a variable named base_url:
{%- capture base_url -%}https://admin.shopify.com/store/{{ shop.myShopifyDomain | replace: ".myshopify.com", "" }}{%- endcapture -%}

# Customer from a Customer trigger:
{{ base_url }}/customers/{{ customer.legacyResourceId }}

# Customer without the base_url:
https://admin.shopify.com/store/{{ shop.myShopifyDomain | replace: ".myshopify.com", "" }}/customers/{{ customer.legacyResourceId }}

# Customer from an Order trigger:
{{ base_url }}/customers/{{ order.customer.legacyResourceId }}

# Order:
{{ base_url }}/orders/{{ order.legacyResourceId }}

# Product:
{{ base_url }}/products/{{ product.legacyResourceId }}

# Product Variant:
{{ base_url }}/products/{{ product.legacyResourceId }}/variants/{{ productVariant.legacyResourceId }}

# Example showing a clickable link in HTML, making use of the URL:
<a href="{{ base_url }}/products/{{ product.legacyResourceId }}">{{ product.title }}</a>

태그 목록을 메타 필드로 전환

태그 세트를 단일 행 텍스트 필드 목록인 메타 필드로 전환하려고 합니다. **스토어에 제품 추가됨** 트리거를 사용하여 워크플로를 생성하고 **제품 메타 필드 업데이트** 작업을 사용합니다. **제품 메타 필드 업데이트** 작업의 **값** 섹션에 다음 Liquid 코드를 추가합니다. 이 예에서는 제품이 생성될 때 값을 한 번만 설정하면 되며, 제품에 color:redcolor:orange라는 두 개의 관련 태그가 있다고 가정합니다.

단일 행 텍스트 필드 목록을 설정하는 Liquid 예.
입력출력
{% capture mf_value %}
{%- for tags_item in product.tags -%}
  {%- if tags_item contains "color:" -%}
    "{{- tags_item | remove_first: "color:" | strip -}}",
  {%- endif -%}
{%- endfor -%}
{% endcapture -%}
[{{mf_value | remove_last: ","}}]
      
["red","orange"]

주문에 대한 동적 이메일 메시지 작성

고객이 주문에 $500 이상을 지출하면 직원에게 이메일을 보내는 워크플로를 생성하려고 합니다. **주문 생성됨** 트리거를 사용하여 워크플로를 생성하고, 주문 총액이 $500를 초과하는 경우에 true가 되는 조건을 설정하고, **내부 이메일 보내기** 작업을 사용합니다. **내부 이메일 보내기** 작업의 **메시지** 섹션에서 다음 변수를 사용합니다.

고객 세부 정보를 제공하기 위한 변수 사용 예.
입력출력
Please send a personal thank you note to {{ order.customer.firstName }} {{ order.customer.lastName }}({{ order.customer.email }}) for placing an order for $ {{ order.totalPriceSet.shopMoney.amount }}.
$763.42 주문에 대해 Jeanne Dupont(jeanne@example.com)에게 개인적인 감사 메모를 보내주세요.

재고가 부족한 제품에 대한 동적 이메일 메시지 작성

제품 재고가 부족해지고 재고를 추가로 주문해야 할 때 직원에게 알려야 합니다. **재고 수량 변경됨** 트리거로 시작하는 워크플로를 생성하고, 이전 재고 수량이 10 이하인 경우에 true가 되는 조건을 설정합니다. **내부 이메일 보내기** 작업의 **메시지** 섹션에서 다음 변수를 사용합니다.

품목 세부 정보를 제공하기 위한 변수 사용 예.
입력출력
Please reorder {{ product.title }}. Email owner@store.com to verify that they've received the purchase order.
하이 웨이스트 레깅스 - 검정색을 재주문하십시오. 구매 주문을 받았는지 확인하려면 owner@example.com으로 이메일을 보내십시오.

사기 주문에 대해 직원에게 알리는 동적 이메일 메시지 작성

위험 수준이 높은 주문을 취소하려고 하지만 직원이 수동으로 주문을 취소하는 것을 선호합니다. **주문 생성됨** 트리거로 시작하는 워크플로를 생성하고, 주문의 위험 수준이 높음과 같으면 true가 되는 조건을 설정합니다. **내부 이메일 보내기** 작업의 **메시지** 섹션에서 다음 변수를 사용합니다.

사기 주문에 대한 정보를 제공하기 위한 변수 사용 예.
입력출력
Our Shopify store has received an order with a high risk of fraud. We would like to cancel this order right away, before it is sent to production:
{{ order.name }} {{ order.billingAddress.lastName }}, {{ order.billingAddress.firstName }} {{ order.email }}
Please confirm the new order status. Thanks!
Shopify 스토어에 사기 위험이 높은 주문이 접수되었습니다. 생산 단계로 넘어가기 전에 이 주문을 즉시 취소하고자 합니다.

#1001
Dupont, Jeanne
jeanne@example.com

새 주문 상태를 확인해 주십시오. 감사합니다.

for 루프를 사용하여 주문 품목 출력

주문이 접수되면 주문된 제품이 포함된 메시지를 보내는 것이 유용할 수 있습니다. 코드 블록을 반복적으로 실행하는 for 루프를 사용하여 이 작업을 수행할 수 있습니다. 변수를 지원하는 텍스트 필드는 for 루프와 forloop 개체도 지원합니다.

예를 들어, 주문의 모든 SKU와 수량 목록을 반환하는 워크플로를 생성하려는 경우 내부 이메일 보내기 작업의 메시지 섹션에서 다음 변수를 사용합니다.

for 루프를 사용하여 주문 정보를 제공하는 예시입니다.
입력출력
Order summary:
{% for a in order.lineItems %}
  {{a.sku}} ( {{a.quantity}} )
{% endfor %}
주문 요약:
8987097979 (50)
8877778887 (3)
888998898B (1)

for 루프를 사용하여 추가 정보와 함께 주문의 품목 출력

이메일에 제품 이름, SKU, 품목당 가격, 고객 배송 정보 등 더 많은 정보를 추가하려면 내부 이메일 보내기 작업의 메시지 섹션에서 다음 변수를 사용하세요.

for 루프를 사용하여 더 광범위한 주문 정보를 제공하는 예시입니다.
입력출력
Order summary:
{% for a in order.lineItems %}
  Product: {{a.title}}
  SKU: {{a.sku}}
  Price (per unit): ${{a.originalUnitPriceSet.shopMoney.amount}}
  Quantity: {{a.quantity}}
{% endfor %}
주문 요약:
제품: High Waist Leggings - Black
SKU: 8987097979
가격(단위당): $8.49
수량: 5
제품: Athletic Socks - Blue
SKU: 888998898B
가격(단위당): $5.61
수량: 2

for 루프와 if 문을 결합하여 일부 품목 출력

특정 공급업체에서 공급한 판매 품목을 추적해야 하는 경우 내부 이메일 보내기 작업의 메시지 섹션에서 다음 변수를 사용하고 for loopif 문을 포함합니다.

for 루프 및 if 문을 사용하여 특정 공급업체에 대한 주문 정보를 제공하는 예시입니다.
입력출력
Acme product sold:
{% for x in order.lineItems %}
  {% if x.vendor == 'acme-vendor' %}
    Product name: {{x.title}}
    SKU: {{x.sku}}
  {% endif %}
{% endfor %}
Acme 제품 판매됨:
제품 이름: High Waist Leggings - Black
SKU: 8987097979

Shopify Flow의 복잡한 데이터 객체

Flow를 사용하면 GraphQL Admin API에 있는 거의 모든 데이터에 액세스할 수 있습니다. 여기에는 목록 및 객체와 같은 복잡한 데이터 객체가 포함됩니다. 그러나 이러한 객체로 수행할 수 있는 작업에는 몇 가지 제한이 있습니다. 이 섹션에서는 이러한 제한 사항을 간략하게 설명하고 이를 사용하는 방법에 대한 예시를 제공합니다.

목록 및 객체를 직접 호출하는 대신, 목록을 순환하며 원하는 필드만 포함해야 합니다.

예를 들어 {{ order.lineItems }}를 직접 호출하는 대신 다음 형식을 사용하여 특정 필드를 호출하세요. 이 예시에는 목록이나 객체를 직접 호출하면 포함되는 모든 필드가 포함됩니다. 필요한 필드를 복사하여 붙여넣으세요.

텍스트
{% for li in order.lineItems %}
    {% comment %}li.contract - omitted{% endcomment %}

{% for ca in li.customAttributes %}
    {{ ca.key }}
    {{ ca.value }}
{% endfor %}

{% for da in li.discountAllocations %}
    {{ da.allocatedAmountSet.presentmentMoney.amount }}
    {{ da.allocatedAmountSet.presentmentMoney.currencyCode }}
    {{ da.allocatedAmountSet.shopMoney.amount }}
    {{ da.allocatedAmountSet.shopMoney.currencyCode }}
{% endfor %}

{{ li.discountedTotalSet.presentmentMoney.amount }}
{{ li.discountedTotalSet.presentmentMoney.currencyCode }}
{{ li.discountedTotalSet.shopMoney.amount }}
{{ li.discountedTotalSet.shopMoney.currencyCode }}

{{ li.discountedUnitPriceSet.presentmentMoney.amount }}
{{ li.discountedUnitPriceSet.presentmentMoney.currencyCode }}
{{ li.discountedUnitPriceSet.shopMoney.amount }}
{{ li.discountedUnitPriceSet.shopMoney.currencyCode }}

{% comment %}li.duties - omitted {% endcomment %}

{{ li.fulfillableQuantity }}

{{ li.fulfillmentService.callbackUrl }}
{{ li.fulfillmentService.fulfillmentOrdersOptIn }}
{{ li.fulfillmentService.handle }}
{{ li.fulfillmentService.id }}
{{ li.fulfillmentService.inventoryManagement }}
{% comment %}rest of location omitted{% endcomment %}
{{ li.fulfillmentService.location.name }}
{{ li.fulfillmentService.productBased }}
{{ li.fulfillmentService.serviceName }}
{% for sm in li.fulfillmentService.shippingMethods %}
    {{ sm.code }}
    {{ sm.label }}
{% endfor %}
{{ li.fulfillmentService.type }}

{{ li.fulfillmentStatus }}
{{ li.id }}

{{ li.image.altText }}
{{ li.image.height }}
{{ li.image.id }}
{% comment %}li.image.metafield omitted{% endcomment %}
{% comment %}li.image.privateMetafield omitted{% endcomment %}
{{ li.image.width }}

{{ li.merchantEditable }}
{{ li.name }}
{{ li.nonFulfillableQuantity }}

{{ li.originalTotalSet.presentmentMoney.amount }}
{{ li.originalTotalSet.presentmentMoney.currencyCode }}
{{ li.originalTotalSet.shopMoney.amount }}
{{ li.originalTotalSet.shopMoney.currencyCode }}

{{ li.originalUnitPriceSet.presentmentMoney.amount }}
{{ li.originalUnitPriceSet.presentmentMoney.currencyCode }}
{{ li.originalUnitPriceSet.shopMoney.amount }}
{{ li.originalUnitPriceSet.shopMoney.currencyCode }}

{% comment %}rest of product omitted{% endcomment %}
{{ li.product.title }}

{{ li.quantity }}
{{ li.refundableQuantity }}
{{ li.requiresShipping }}
{{ li.restockable }}

{{ li.sellingPlan.name }}

{{ li.sku }}

{% for tl in li.taxLines %}
    {{ tl.priceSet.presentmentMoney.amount | json }}
    {{ tl.priceSet.presentmentMoney.currencyCode | json }}
    {{ tl.priceSet.shopMoney.amount | json }}
    {{ tl.priceSet.shopMoney.currencyCode | json }}
    {{ tl.rate | json }}
    {{ tl.ratePercentage | json }}
    {{ tl.title | json }}
{% endfor %}

{{ li.taxable }}
{{ li.title }}

{{ li.totalDiscountSet.presentmentMoney.amount }}
{{ li.totalDiscountSet.presentmentMoney.currencyCode }}
{{ li.totalDiscountSet.shopMoney.amount }}
{{ li.totalDiscountSet.shopMoney.currencyCode }}

{{ li.unfulfilledDiscountedTotalSet.presentmentMoney.amount }}
{{ li.unfulfilledDiscountedTotalSet.presentmentMoney.currencyCode }}
{{ li.unfulfilledDiscountedTotalSet.shopMoney.amount }}
{{ li.unfulfilledDiscountedTotalSet.shopMoney.currencyCode }}

{{ li.unfulfilledOriginalTotalSet.presentmentMoney.amount }}
{{ li.unfulfilledOriginalTotalSet.presentmentMoney.currencyCode }}
{{ li.unfulfilledOriginalTotalSet.shopMoney.amount }}
{{ li.unfulfilledOriginalTotalSet.shopMoney.currencyCode }}

{{ li.unfulfilledQuantity }}

{% comment %}rest of variant omitted{% endcomment %}
{{ li.variant.title }}

{{ li.variantTitle }}
{{ li.vendor }}

{% endfor %}

json
{
    "lineItems": [
        {% for li in order.lineItems %}
            {% if forloop.first != true %},{% endif %}
        {
            "contract": {
                {% comment %}rest of contract omitted{% endcomment %}
                "id": {{ li.contract.id | json }}
            },
            "customAttributes": [
                {% for ca in li.customAttributes %}
                    {% if forloop.first != true %},{% endif %}
                    {
                        "key":{{ ca.key | json }},
                        "value":{{ ca.value | json }}
                    }
                {% endfor %}
            ],
&#x22;discountAllocations&#x22;: [
            {% for da in li.discountAllocations %}
                {% if forloop.first != true %},{% endif %}
                &#x22;allocatedAmountSet&#x22;: {
                    &#x22;presentmentMoney&#x22; : {
                        &#x22;amount&#x22;: {{ da.allocatedAmountSet.presentmentMoney.amount | json }},
                        &#x22;currencyCode&#x22;: {{ da.allocatedAmountSet.presentmentMoney.currencyCode | json }}
                    },
                    &#x22;shopMoney&#x22;: {
                        &#x22;amount&#x22;: {{ da.allocatedAmountSet.shopMoney.amount | json }},
                        &#x22;currencyCode&#x22;: {{ da.allocatedAmountSet.shopMoney.currencyCode | json }}
                    }
                }
            {% endfor %}
        ],

        &#x22;discountedTotalSet&#x22;: {
            &#x22;presentmentMoney&#x22; : {
                &#x22;amount&#x22;: {{ li.discountedTotalSet.presentmentMoney.amount | json }},
                &#x22;currencyCode&#x22;: {{ li.discountedTotalSet.presentmentMoney.currencyCode | json }}
            },
            &#x22;shopMoney&#x22;: {
                &#x22;amount&#x22;: {{ li.discountedTotalSet.shopMoney.amount | json }},
                &#x22;currencyCode&#x22;: {{ li.discountedTotalSet.shopMoney.currencyCode | json }}
            }
        },

        &#x22;discountedUnitPriceSet&#x22;: {
            &#x22;presentmentMoney&#x22; : {
                &#x22;amount&#x22;: {{ li.discountedUnitPriceSet.presentmentMoney.amount | json }},
                &#x22;currencyCode&#x22;: {{ li.discountedUnitPriceSet.presentmentMoney.currencyCode | json }}
            },
            &#x22;shopMoney&#x22;: {
                &#x22;amount&#x22;: {{ li.discountedUnitPriceSet.shopMoney.amount | json }},
                &#x22;currencyCode&#x22;: {{ li.discountedUnitPriceSet.shopMoney.currencyCode | json }}
            }
        },
        &#x22;duties&#x22;: [
            {% for duty li.duties %}
            {% if forloop.first != true %},{% endif %}
            {
                {% comment %}rest of duties omitted{% endcomment %}
                &#x22;id&#x22;: {{ duty.id | json }}
            }
            {% endfor %}
        ],
        &#x22;fulfillableQuantity&#x22;: {{ li.fulfillableQuantity | json }},

        &#x22;fulfillmentService&#x22;: {
            &#x22;callbackUrl&#x22;:{{ li.fulfillmentService.callbackUrl | json }},
            &#x22;fulfillmentOrdersOptIn&#x22;: {{ li.fulfillmentService.fulfillmentOrdersOptIn | json }},
            &#x22;handle&#x22;: {{ li.fulfillmentService.handle | json }},
            &#x22;id&#x22;: {{ li.fulfillmentService.id | json }},
            &#x22;inventoryManagement&#x22;: {{ li.fulfillmentService.inventoryManagement | json }},
            {% comment %}fulfillmentService.inventoryManagement - omitted {% endcomment %}
            &#x22;productBased&#x22;: {{ li.fulfillmentService.productBased | json }},
            &#x22;serviceName&#x22;: {{ li.fulfillmentService.serviceName | json }},
            &#x22;shippingMethods&#x22;: [
                {% for sm in li.fulfillmentService.shippingMethods %}
                    {% if forloop.first != true %},{% endif %}
                    {
                        &#x22;code&#x22;: {{ sm.code | json }},
                        &#x22;label&#x22;: {{ sm.label | json }}
                    }
                {% endfor %}
            ],
            &#x22;type&#x22;: {{ li.fulfillmentService.type | json }}

        },
        &#x22;fulfillmentStatus&#x22;: {{ li.fulfillmentStatus | json }},
        &#x22;id&#x22;: {{ li.id | json }},
        &#x22;image&#x22;: {
            &#x22;altText&#x22;: {{ li.image.altText | json }},
            &#x22;height&#x22;: {{ li.image.height | json }},
            &#x22;id&#x22;: {{ li.image.id | json }},
            {% comment %}li.image.metafield omitted{% endcomment %}
            {% comment %}li.image.privateMetafield omitted{% endcomment %}
            &#x22;width&#x22;:{{ li.image.width | json }}
        },
        &#x22;merchantEditable&#x22;: {{ li.merchantEditable | json }},
        &#x22;name&#x22;: {{ li.name | json }},
        &#x22;nonFulfillableQuantity&#x22;: {{ li.nonFulfillableQuantity | json }},

        &#x22;originalTotalSet&#x22;: {
            &#x22;presentmentMoney&#x22; : {
                &#x22;amount&#x22;: {{ li.originalTotalSet.presentmentMoney.amount | json }},
                &#x22;currencyCode&#x22;: {{ li.originalTotalSet.presentmentMoney.currencyCode | json }}
            },
            &#x22;shopMoney&#x22;: {
                &#x22;amount&#x22;: {{ li.originalTotalSet.shopMoney.amount | json }},
                &#x22;currencyCode&#x22;: {{ li.originalTotalSet.shopMoney.currencyCode | json }}
            }
        },

        &#x22;originalUnitPriceSet&#x22;: {
            &#x22;presentmentMoney&#x22; : {
                &#x22;amount&#x22;: {{ li.originalUnitPriceSet.presentmentMoney.amount | json }},
                &#x22;currencyCode&#x22;: {{ li.originalUnitPriceSet.presentmentMoney.currencyCode | json }}
            },
            &#x22;shopMoney&#x22;: {
                &#x22;amount&#x22;: {{ li.originalUnitPriceSet.shopMoney.amount | json }},
                &#x22;currencyCode&#x22;: {{ li.originalUnitPriceSet.shopMoney.currencyCode | json }}
            }
        },

        &#x22;product&#x22;: {
            {% comment %}rest of Product omitted{% endcomment %}
            &#x22;title&#x22;: {{ li.product.title | json }}
        },

        &#x22;quantity&#x22;: {{ li.quantity | json }},
        &#x22;refundableQuantity&#x22;: {{ li.refundableQuantity | json }},
        &#x22;requiresShipping&#x22;: {{ li.requiresShipping | json }},
        &#x22;restockable&#x22;: {{ li.restockable | json }},

        &#x22;sellingPlan&#x22;: {
            &#x22;name&#x22;: {{ li.sellingPlan.name | json }}
        },

        &#x22;sku&#x22;: {{ li.sku | json }},

        &#x22;taxLines&#x22;: [
            {% for tl in li.taxLines %}
                {% if forloop.first != true %},{% endif %}
                {
                    &#x22;priceSet&#x22;: {
                        &#x22;presentmentMoney&#x22; : {
                            &#x22;amount&#x22;: {{ tl.priceSet.presentmentMoney.amount | json }},
                            &#x22;currencyCode&#x22;: {{ tl.priceSet.presentmentMoney.currencyCode | json }}
                        },
                        &#x22;shopMoney&#x22;: {
                            &#x22;amount&#x22;: {{ tl.priceSet.shopMoney.amount | json }},
                            &#x22;currencyCode&#x22;: {{ tl.priceSet.shopMoney.currencyCode | json }}
                        }
                    },
                    &#x22;rate&#x22;: {{ tl.rate | json }},
                    &#x22;ratePercentage&#x22;: {{ tl.ratePercentage | json }},
                    &#x22;title&#x22;: {{ tl.title | json }}
                }
            {% endfor %}
        ],
        &#x22;taxable&#x22;:{{ li.taxable | json }},
        &#x22;title&#x22;:{{ li.title | json }},

        &#x22;totalDiscountSet&#x22;: {
            &#x22;presentmentMoney&#x22; : {
                &#x22;amount&#x22;: {{ li.totalDiscountSet.presentmentMoney.amount | json }},
                &#x22;currencyCode&#x22;: {{ li.totalDiscountSet.presentmentMoney.currencyCode | json }}
            },
            &#x22;shopMoney&#x22;: {
                &#x22;amount&#x22;: {{ li.totalDiscountSet.shopMoney.amount | json }},
                &#x22;currencyCode&#x22;: {{ li.totalDiscountSet.shopMoney.currencyCode | json }}
            }
        },

        &#x22;unfulfilledDiscountedTotalSet&#x22;: {
            &#x22;presentmentMoney&#x22; : {
                &#x22;amount&#x22;: {{ li.unfulfilledDiscountedTotalSet.presentmentMoney.amount | json }},
                &#x22;currencyCode&#x22;: {{ li.unfulfilledDiscountedTotalSet.presentmentMoney.currencyCode | json }}
            },
            &#x22;shopMoney&#x22;: {
                &#x22;amount&#x22;: {{ li.unfulfilledDiscountedTotalSet.shopMoney.amount | json }},
                &#x22;currencyCode&#x22;: {{ li.unfulfilledDiscountedTotalSet.shopMoney.currencyCode | json }}
            }
        },

        &#x22;unfulfilledOriginalTotalSet&#x22;: {
            &#x22;presentmentMoney&#x22; : {
                &#x22;amount&#x22;: {{ li.unfulfilledOriginalTotalSet.presentmentMoney.amount | json }},
                &#x22;currencyCode&#x22;: {{ li.unfulfilledOriginalTotalSet.presentmentMoney.currencyCode | json }}
            },
            &#x22;shopMoney&#x22;: {
                &#x22;amount&#x22;: {{ li.unfulfilledOriginalTotalSet.shopMoney.amount | json }},
                &#x22;currencyCode&#x22;: {{ li.unfulfilledOriginalTotalSet.shopMoney.currencyCode | json }}
            }
        },

        &#x22;unfulfilledQuantity&#x22;: {{ li.unfulfilledQuantity | json }},

        &#x22;variant&#x22;: {
            {% comment %}rest of variant omitted {% endcomment %}
            &#x22;title&#x22;: {{ li.variant.title | json }}
        },

        &#x22;variantTitle&#x22;: {{ li.variantTitle | json }},
        &#x22;vendor&#x22;: {{ li.vendor | json }}
    }
{% endfor %}
]

}