Read the data in Liquid
The namespace
Section titled “The namespace”Every key DiscountOS writes uses one app-owned namespace:
app--284350873601--discount_osThe number is the DiscountOS app’s ID. Put the namespace in one variable, or better in a theme setting, and use it everywhere:
{%- assign ns = 'app--284350873601--discount_os' -%}Where the data is
Section titled “Where the data is”| Place | What it holds |
|---|---|
product.metafields[ns] | Discounts that apply to this product. With Publish to collection products on, this includes discounts on the product’s collections. |
collection.metafields[ns] | Discounts that target this collection. |
shop.metafields[ns] | Every published discount, plus the sync state. Discounts that cover the whole store, the order or shipping live only here. |
The keys
Section titled “The keys”Each product and collection with at least one discount has these keys:
| Key | Type | What it is |
|---|---|---|
discounts | list of discount entries | Every published discount for this product or collection. |
max_reward_percent | decimal | The best percentage off among discounts every shopper gets. 0 when there is none. |
max_reward_cents | integer | The best fixed amount off among discounts every shopper gets, in the shop currency’s smallest unit (1500 is $15.00). 0 when there is none. |
max_reward_discount | one discount entry | The discount behind max_reward_percent. When no percentage discount qualifies, the discount behind max_reward_cents. Missing when neither has a winner. |
When a product or collection has no discounts, all four keys are removed.
The shop also has two keys about the sync itself:
| Key | Type | What it is |
|---|---|---|
sync_paused | true / false | true while Live sync is off. The data is not being updated. |
synced_at | date and time | When the data was last written. |
Reading an entry
Section titled “Reading an entry”Each item in discounts is a discount entry: a Shopify metaobject with one field per fact. Read
every field with .value:
{%- assign offers = product.metafields[ns].discounts.value -%}{%- for d in offers -%} <p>{{ d.discount_title.value }} ({{ d.discount_type.value }}, {{ d.method.value }})</p>{%- endfor -%}Things to know:
- The list is not sorted best first. Use
max_reward_discountfor the best offer. - Money is in the smallest unit of the shop currency.
1500means $15.00. Shopify’smoneyfilter divides by 100, which is right for two-decimal currencies. For a currency with no decimals (such as JPY) or three decimals (such as KWD), rescale first. - Decimals print with a point.
reward_valuesandmaximum_reward_valueprint as10.0. Use| roundfor whole numbers. - Lists of products or collections cannot be read by position. In Liquid,
d.reward_product_references.value[0]and.firstreturn nothing. Loop over the list, or turn it into names with| map: 'title'. - A
jsonfield that is empty is still truthy. Check for the key you need, not the field. - Identify an entry by its handle.
d.system.handleisdiscount-followed by the Shopify discount ID. It stays the same after a fresh write; the entry’s own ID does not.
Is the data fresh?
Section titled “Is the data fresh?”{%- if shop.metafields[ns].sync_paused.value -%} <p>Offer updates are paused. Prices at checkout are always current.</p>{%- else -%} <p>Offers as of {{ shop.metafields[ns].synced_at.value | date: '%b %-d, %H:%M' }}</p>{%- endif -%}