Korzystanie ze zmiennych Liquid w aplikacji Shopify Flow

Zmienne Liquid to zdefiniowane w języku Liquid symbole zastępcze, które podczas przebiegu przepływu pracy są zastępowane wartościami z interfejsu GraphQL Admin API. Zmienne mogą opisywać atrybuty klientów, zamówień i produktów, które biorą udział w przepływach pracy, takie jak numer zamówienia, cena zamówienia czy nazwa klienta. Zmiennych można używać w warunkach do kontrolowania logiki w przepływie pracy lub do wyprowadzania danych z akcji.

Dodawanie zmiennych w przepływach pracy za pomocą Liquid

Możesz dodawać zmienne za pomocą Liquid do dowolnego pola tekstowego, które zawiera link Dodaj zmienną. Kliknij link Dodaj zmienną pod odpowiednim polem, a następnie wybierz zmienną z listy.

Obraz panelu konfiguracyjnego akcji „Wyślij wewnętrzną wiadomość e-mail”, z zaznaczoną opcją „Dodaj zmienną” pod polem Temat.

Zmienne na liście Dodaj zmienną są filtrowane, dzięki czemu używasz tylko zmiennych zwracanych przez kroki poprzedzające bieżący krok, takie jak wyzwalacze. Na przykład wyzwalacz Utworzono zamówienie dostarcza zasoby zamówienia i sklepu z Admin API, które można wstawić jako zmienne. Po wybraniu zmiennej z listy jest ona dodawana do pola tekstowego jako poprawnie sformatowany kod Liquid.

Możesz również wpisać kod Liquid bezpośrednio w polu tekstowym. Na przykład możesz użyć zmiennej {{ order.name }}, aby wyświetlić ciąg znaków zamówienia z panelu administracyjnego Shopify, taki jak order-123.

Ponieważ aplikacja Flow używa Admin API do pobierania danych wykorzystywanych w Liquid, składnia zmiennych używa zapisu camel case. W przypadku zmiennych zapisywanych w camel case pierwsze słowo zaczyna się małą literą, a kolejne słowa wielką literą, np. firstName lub canMarkAsPaid. Na przykład, aby uzyskać dostęp do daty utworzenia produktu, wprowadź {{ product.createdAt }}. Jeśli używasz składni Liquid w szablonie Shopify, który nie używa zapisu camel case, należy wprowadzić {{ product.created_at }}.

Tagi warunkowe i iteracyjne Liquid

Tagów Liquid można używać ze zmiennymi do wykonywania następujących funkcji:

  • Pisanie instrukcji warunkowych, np. w celu ustalenia, czy łączna kwota zamówienia jest większa niż 100 USD.
  • Iterowanie przez listę obiektów, np. w celu wyprowadzenia danych dla każdej pozycji pojedynczej w zamówieniu.

Możesz użyć tagów Liquid, aby pisać te instrukcje i iterować przez obiekty.

Na przykład poniższy kod Liquid wyświetla numer zamówienia, jeśli łączna kwota zamówienia jest większa niż 100 USD:

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

Możesz również użyć pętli for do iterowania przez listę obiektów, takich jak pozycje pojedyncze w zamówieniu. Na przykład poniższy kod Liquid wyświetla nazwę każdej pozycji pojedynczej w zamówieniu:

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

Aplikacja Flow obsługuje następujące tagi warunkowe (lub sterujące przepływem) Liquid:

Aplikacja Flow obsługuje również następujące tagi iteracyjne Liquid:

Stosowanie filtrów do zmiennych

Możesz przekształcać dane zmiennych w Liquid za pomocą filtrów. Aplikacja Flow obsługuje wszystkie filtry Liquid typu open source.

Na przykład poniższy kod Liquid usuwa prefiks z nazwy zamówienia i zwraca pozostałą część: {{ order.name | remove: "Order-" }}

Kwestie do rozważenia przy używaniu zmiennych Liquid w filtrach

Przed przekształceniem zmiennych za pomocą filtrów zapoznaj się z następującymi kwestiami:

  • Aplikacja Flow nie obsługuje notacji kropkowej, która jest dostępna dla niektórych filtrów. Na przykład aplikacja Flow obsługuje zapis {{ order.lineItems | size }}, ale nie obsługuje zapisu {{ order.lineItems.size }}.
  • Aplikacja Flow nie obsługuje notacji kropkowej dla metapól. Na przykład nie można użyć zapisu {{ order.metafields.custom.hold_note }}. Zamiast tego należy użyć pętli dla metapól, jak pokazano w przykładach.
  • Aplikacja Flow nie obsługuje używania indeksów do uzyskiwania dostępu do pozycji na liście. Na przykład nie można użyć zapisu {{ order.lineItems[0].title }}. Zamiast tego należy użyć pętli dla pozycji pojedynczych, jak pokazano w przykładach.

Filtry dat

Oprócz standardowych filtrów Liquid aplikacja Flow udostępnia filtry daty, które umożliwiają uzyskanie daty względnej w stosunku do innej daty w celu obsługi wyzwalacza Zaplanowany czas i funkcji Pobierz dane. Filtry te to: date_minus i date_plus. Na przykład:

  • Aby zwrócić datę o jeden dzień w przyszłości: {{ "now" | date_plus: "1 day" }}
  • Aby zwrócić datę o jeden dzień w przeszłości: {{ "now" | date_minus: "1 day" }}

Filtry te akceptują second, minute, day, week, month i year jako jednostki czasu trwania, zarówno w liczbie pojedynczej (np. second), jak i mnogiej (np. seconds). Można również podać następujące typy jednostek niestandardowych:

  • Liczba całkowita reprezentująca liczbę sekund: {{ "now" | date_minus: 3600 }}, gdzie 3600 jest równoważne 1 godzinie.
  • Ciąg znaków czasu trwania ISO8601: {{ "now" | date_minus: "P1Y2D" }}, gdzie P1Y2D oznacza 1 rok i 2 dni.

Filtry kryptograficzne

Aplikacja Flow udostępnia filtry kryptograficzne do haszowania i tworzenia kodów uwierzytelniających wiadomości opartych na haszowaniu (HMAC). Filtry te są przydatne do tworzenia unikalnych identyfikatorów, sum kontrolnych lub integracji z systemami zewnętrznymi, które wymagają określonych formatów haszujących.

Filtry haszujące

Aplikacja Shopify Flow obsługuje następujące typy filtrów haszujących:

  • blake3 – tworzy skrót BLAKE3 (zalecany do ogólnego użytku).
  • sha256 – tworzy skrót SHA-256.
  • sha1 – tworzy skrót SHA-1.
  • md5 – tworzy skrót MD5.

Do ogólnych celów haszowania i nowych wdrożeń należy używać filtru blake3, ponieważ oferuje on lepszą wydajność i bezpieczeństwo w porównaniu ze starszymi algorytmami. Jednak filtry sha256, sha1 i md5 są dostępne w celu zapewnienia zgodności z systemami zewnętrznymi.

Przykład użycia: {{ "hello world" | blake3 }} zwraca skrót BLAKE3 dla „hello world”.

Filtry HMAC

Aby utworzyć kod HMAC za pomocą tajnego klucza, użyj jednego z następujących obsługiwanych filtrów:

Przykład użycia:

  • Podstawowy: {{ "message" | hmac_sha256: "secret_key" }}
  • Z danymi poufnymi (zalecane): {{ "message" | hmac_sha256: secrets.api_key }}

Przykłady użycia zmiennych z Liquid w Shopify Flow

Aby lepiej zrozumieć, jak używać zmiennych Liquid, zapoznaj się z następującymi przykładami:

Wyświetlanie adresów URL dla zasobów

Chcesz wyświetlić adresy URL klienta, zamówienia i produktu, które biorą udział w workflow.

# 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>

Konwertowanie listy tagów na metapole

Chcesz skonwertować zestaw tagów na metapole, które jest listą jednowierszowych pól tekstowych. Tworzysz workflow za pomocą wyzwalacza Produkt dodany do sklepu i używasz akcji Zaktualizuj metapole produktu. W sekcji Wartość akcji Zaktualizuj metapole produktu dodajesz następujący kod Liquid. Ten przykład zakłada, że musisz ustawić wartości tylko raz podczas tworzenia produktu i że produkt ma dwa odpowiednie tagi: color:red i color:orange.

Przykładowy kod Liquid do ustawienia listy jednowierszowego pola tekstowego.
Dane wejścioweDane wyjściowe
{% 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"]

Tworzenie dynamicznej wiadomości e-mail dotyczącej zamówienia

Chcesz utworzyć workflow, aby wysłać wiadomość e-mail do pracownika, gdy klient wyda na zamówienie więcej niż 500 USD. Tworzysz workflow za pomocą wyzwalacza Utworzono zamówienie, ustawiasz warunek, który jest prawdziwy, jeśli suma zamówienia przekracza 500 USD, i używasz akcji Wyślij wewnętrzną wiadomość e-mail. W sekcji Wiadomość akcji Wyślij wewnętrzną wiadomość e-mail używasz następujących zmiennych.

Przykład użycia zmiennej do podania szczegółów dotyczących klienta.
Dane wejścioweDane wyjściowe
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 }}.
Proszę wysłać osobistą notatkę z podziękowaniami do Jeanne Dupont (jeanne@example.com) za złożenie zamówienia na kwotę 763,42 USD.

Tworzenie dynamicznej wiadomości e-mail dla produktu o niskim stanie zapasów

Decydujesz, że chcesz poinformować pracownika, gdy ilość zapasów produktu będzie niska i będzie trzeba złożyć zamówienie na większą ilość zapasów. Tworzysz workflow, który rozpoczyna się od wyzwalacza Zmieniono ilość zapasów i ustawiasz warunek, który jest prawdziwy, jeśli wcześniejsza ilość zapasów jest mniejsza lub równa 10. W sekcji Wiadomość akcji Wyślij wewnętrzną wiadomość e-mail używasz następujących zmiennych.

Przykład użycia zmiennej do podania szczegółów pozycji.
Dane wejścioweDane wyjściowe
Please reorder {{ product.title }}. Email owner@store.com to verify that they've received the purchase order.
Zamów ponownie High Waist Leggings – Black. Wyślij e-mail na adres owner@example.com, aby sprawdzić, czy otrzymano zamówienie.

Tworzenie dynamicznej wiadomości e-mail w celu powiadomienia pracowników o fałszywym zamówieniu

Chcesz anulować zamówienia o wysokim poziomie ryzyka, ale wolisz, aby Twoi pracownicy anulowali zamówienie ręcznie. Tworzysz workflow, który rozpoczyna się od wyzwalacza Utworzono zamówienie i ustawiasz warunek, który jest prawdziwy, jeśli poziom ryzyka zamówienia jest równy „wysoki”. W sekcji Wiadomość akcji Wyślij wewnętrzną wiadomość e-mail używasz następujących zmiennych.

Przykład użycia zmiennej do podania informacji o fałszywym zamówieniu.
Dane wejścioweDane wyjściowe
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!
Nasz sklep Shopify otrzymał zamówienie z wysokim ryzykiem oszustwa. Chcielibyśmy anulować to zamówienie od razu, zanim zostanie wysłane do produkcji:

#1001
Dupont, Jeanne
jeanne@example.com

Proszę o potwierdzenie nowego statusu zamówienia. Dziękuję!

Wyświetlanie pozycji pojedynczych dla zamówienia za pomocą pętli for

Po otrzymaniu zamówienia przydatne może być wysłanie wiadomości zawierającej zamówione produkty. Można to zrobić za pomocą pętli for loop, która wielokrotnie wykonuje blok kodu. Pola tekstowe obsługujące zmienne obsługują również pętle for i obiekt forloop.

Załóżmy na przykład, że chcesz utworzyć proces, który zwraca listę wszystkich numerów SKU i ilości w zamówieniu. W sekcji Wiadomość akcji Wyślij wewnętrzną wiadomość e-mail użyj następujących zmiennych.

Przykład użycia pętli „for” w celu podania informacji o zamówieniu.
Dane wejścioweDane wyjściowe
Order summary:
{% for a in order.lineItems %}
  {{a.sku}} ( {{a.quantity}} )
{% endfor %}
Podsumowanie zamówienia:
8987097979 (50)
8877778887 (3)
888998898B (1)

Wyświetlanie pozycji pojedynczych zamówienia za pomocą pętli „for” z dodatkowymi informacjami

Postanawiasz dodać do wiadomości e-mail więcej informacji, w tym nazwę produktu, numery SKU, cenę za pozycję i informacje o wysyłce do klienta. W sekcji Wiadomość akcji Wyślij wewnętrzną wiadomość e-mail użyj następujących zmiennych.

Przykład użycia pętli „for” w celu podania bardziej szczegółowych informacji o zamówieniu.
Dane wejścioweDane wyjściowe
Order summary:
{% for a in order.lineItems %}
  Product: {{a.title}}
  SKU: {{a.sku}}
  Price (per unit): ${{a.originalUnitPriceSet.shopMoney.amount}}
  Quantity: {{a.quantity}}
{% endfor %}
Podsumowanie zamówienia:
Produkt: Legginsy z wysokim stanem – czarne
SKU: 8987097979
Cena (za sztukę): 8,49 USD
Ilość: 5
Produkt: Skarpetki sportowe – niebieskie
SKU: 888998898B
Cena (za sztukę): 5,61 USD
Ilość: 2

Wyświetlanie niektórych pozycji pojedynczych przez połączenie pętli „for” z instrukcją „if”

Musisz śledzić pozycje sprzedane, które są dostarczane przez określonego dostawcę. W sekcji Wiadomość akcji Wyślij wewnętrzną wiadomość e-mail użyj następujących zmiennych i dołącz instrukcję if do pętli for.

Przykład użycia pętli „for” i instrukcji „if” w celu podania informacji o zamówieniu dla określonych dostawców.
Dane wejścioweDane wyjściowe
Acme product sold:
{% for x in order.lineItems %}
  {% if x.vendor == 'acme-vendor' %}
    Product name: {{x.title}}
    SKU: {{x.sku}}
  {% endif %}
{% endfor %}
Sprzedany produkt Acme:
Nazwa produktu: Legginsy z wysokim stanem – czarne
SKU: 8987097979

Złożone obiekty danych w Shopify Flow

Aplikacja Flow umożliwia dostęp do niemal wszystkich danych znajdujących się w GraphQL Admin API. Obejmuje to złożone obiekty danych, takie jak listy i obiekty. Istnieją jednak pewne ograniczenia dotyczące działań, jakie można wykonać na tych obiektach. W tej sekcji opisano te ograniczenia i podano przykłady pracy z nimi.

Zamiast bezpośrednio wywoływać listy i obiekty, należy zapętlić listę i uwzględnić tylko potrzebne pola.

Na przykład, zamiast bezpośrednio wywoływać {{ order.lineItems }}, użyj następującego formatu, aby wywołać określone pola. Te przykłady zawierają wszystkie pola, które zostałyby uwzględnione przez bezpośrednie wywołanie listy lub obiektu. Skopiuj i wklej potrzebne pola.

Tekst
{% 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 %}
]

}