Initial commit
This commit is contained in:
873
skills/shopify-liquid/references/filters.md
Normal file
873
skills/shopify-liquid/references/filters.md
Normal file
@@ -0,0 +1,873 @@
|
||||
# Liquid Filters - Complete Reference
|
||||
|
||||
Filters modify output using pipe syntax: `{{ value | filter: parameter }}`
|
||||
|
||||
## String Filters
|
||||
|
||||
### upcase
|
||||
|
||||
Convert to uppercase:
|
||||
|
||||
```liquid
|
||||
{{ "hello world" | upcase }}
|
||||
{# Output: HELLO WORLD #}
|
||||
```
|
||||
|
||||
### downcase
|
||||
|
||||
Convert to lowercase:
|
||||
|
||||
```liquid
|
||||
{{ "HELLO WORLD" | downcase }}
|
||||
{# Output: hello world #}
|
||||
```
|
||||
|
||||
### capitalize
|
||||
|
||||
Capitalize first letter only:
|
||||
|
||||
```liquid
|
||||
{{ "hello world" | capitalize }}
|
||||
{# Output: Hello world #}
|
||||
```
|
||||
|
||||
### reverse
|
||||
|
||||
Reverse string or array:
|
||||
|
||||
```liquid
|
||||
{{ "hello" | reverse }}
|
||||
{# Output: olleh #}
|
||||
|
||||
{{ array | reverse }}
|
||||
{# Reverses array order #}
|
||||
```
|
||||
|
||||
### size
|
||||
|
||||
Get character count or array length:
|
||||
|
||||
```liquid
|
||||
{{ "hello" | size }}
|
||||
{# Output: 5 #}
|
||||
|
||||
{{ collection.products | size }}
|
||||
{# Output: number of products #}
|
||||
```
|
||||
|
||||
### remove
|
||||
|
||||
Remove all occurrences of substring:
|
||||
|
||||
```liquid
|
||||
{{ "hello world world" | remove: "world" }}
|
||||
{# Output: hello #}
|
||||
```
|
||||
|
||||
### remove_first
|
||||
|
||||
Remove first occurrence only:
|
||||
|
||||
```liquid
|
||||
{{ "hello world world" | remove_first: "world" }}
|
||||
{# Output: hello world #}
|
||||
```
|
||||
|
||||
### replace
|
||||
|
||||
Replace all occurrences:
|
||||
|
||||
```liquid
|
||||
{{ "hello" | replace: "l", "L" }}
|
||||
{# Output: heLLo #}
|
||||
```
|
||||
|
||||
### replace_first
|
||||
|
||||
Replace first occurrence only:
|
||||
|
||||
```liquid
|
||||
{{ "hello" | replace_first: "l", "L" }}
|
||||
{# Output: heLlo #}
|
||||
```
|
||||
|
||||
### split
|
||||
|
||||
Split string into array:
|
||||
|
||||
```liquid
|
||||
{{ "a,b,c,d" | split: "," }}
|
||||
{# Output: ["a", "b", "c", "d"] #}
|
||||
|
||||
{% assign tags = "sale,new,featured" | split: "," %}
|
||||
{% for tag in tags %}
|
||||
{{ tag }}
|
||||
{% endfor %}
|
||||
```
|
||||
|
||||
### strip
|
||||
|
||||
Remove leading and trailing whitespace:
|
||||
|
||||
```liquid
|
||||
{{ " hello " | strip }}
|
||||
{# Output: hello #}
|
||||
```
|
||||
|
||||
### lstrip
|
||||
|
||||
Remove leading whitespace only:
|
||||
|
||||
```liquid
|
||||
{{ " hello " | lstrip }}
|
||||
{# Output: hello #}
|
||||
```
|
||||
|
||||
### rstrip
|
||||
|
||||
Remove trailing whitespace only:
|
||||
|
||||
```liquid
|
||||
{{ " hello " | rstrip }}
|
||||
{# Output: hello #}
|
||||
```
|
||||
|
||||
### truncate
|
||||
|
||||
Limit string length with ellipsis:
|
||||
|
||||
```liquid
|
||||
{{ "hello world" | truncate: 8 }}
|
||||
{# Output: hello... #}
|
||||
|
||||
{{ "hello world" | truncate: 10, "!" }}
|
||||
{# Output: hello worl! #}
|
||||
|
||||
{{ "hello world" | truncate: 50 }}
|
||||
{# Output: hello world (no truncation if shorter) #}
|
||||
```
|
||||
|
||||
### truncatewords
|
||||
|
||||
Limit by word count:
|
||||
|
||||
```liquid
|
||||
{{ "hello world testing" | truncatewords: 2 }}
|
||||
{# Output: hello world... #}
|
||||
|
||||
{{ "hello world testing" | truncatewords: 2, "--" }}
|
||||
{# Output: hello world-- #}
|
||||
```
|
||||
|
||||
### append
|
||||
|
||||
Add string to end:
|
||||
|
||||
```liquid
|
||||
{{ "hello" | append: " world" }}
|
||||
{# Output: hello world #}
|
||||
|
||||
{% assign file_name = "image" | append: ".jpg" %}
|
||||
{# file_name: image.jpg #}
|
||||
```
|
||||
|
||||
### prepend
|
||||
|
||||
Add string to beginning:
|
||||
|
||||
```liquid
|
||||
{{ "world" | prepend: "hello " }}
|
||||
{# Output: hello world #}
|
||||
```
|
||||
|
||||
### newline_to_br
|
||||
|
||||
Convert newlines to `<br>` tags:
|
||||
|
||||
```liquid
|
||||
{{ product.description | newline_to_br }}
|
||||
{# Converts \n to <br> #}
|
||||
```
|
||||
|
||||
### strip_html
|
||||
|
||||
Remove all HTML tags:
|
||||
|
||||
```liquid
|
||||
{{ "<p>Hello <strong>world</strong></p>" | strip_html }}
|
||||
{# Output: Hello world #}
|
||||
```
|
||||
|
||||
### escape
|
||||
|
||||
Escape HTML special characters:
|
||||
|
||||
```liquid
|
||||
{{ "<div>Test</div>" | escape }}
|
||||
{# Output: <div>Test</div> #}
|
||||
```
|
||||
|
||||
### escape_once
|
||||
|
||||
Escape HTML but don't double-escape:
|
||||
|
||||
```liquid
|
||||
{{ "<div>" | escape_once }}
|
||||
{# Output: <div> (not double-escaped) #}
|
||||
```
|
||||
|
||||
### url_encode
|
||||
|
||||
URL-encode string:
|
||||
|
||||
```liquid
|
||||
{{ "hello world" | url_encode }}
|
||||
{# Output: hello+world #}
|
||||
|
||||
{{ "foo@bar.com" | url_encode }}
|
||||
{# Output: foo%40bar.com #}
|
||||
```
|
||||
|
||||
### url_decode
|
||||
|
||||
Decode URL-encoded string:
|
||||
|
||||
```liquid
|
||||
{{ "hello+world" | url_decode }}
|
||||
{# Output: hello world #}
|
||||
```
|
||||
|
||||
### base64_encode
|
||||
|
||||
Encode to base64:
|
||||
|
||||
```liquid
|
||||
{{ "hello" | base64_encode }}
|
||||
{# Output: aGVsbG8= #}
|
||||
```
|
||||
|
||||
### base64_decode
|
||||
|
||||
Decode from base64:
|
||||
|
||||
```liquid
|
||||
{{ "aGVsbG8=" | base64_decode }}
|
||||
{# Output: hello #}
|
||||
```
|
||||
|
||||
### slice
|
||||
|
||||
Extract substring or array slice:
|
||||
|
||||
```liquid
|
||||
{{ "hello" | slice: 0, 3 }}
|
||||
{# Output: hel #}
|
||||
|
||||
{{ "hello" | slice: -3, 3 }}
|
||||
{# Output: llo #}
|
||||
```
|
||||
|
||||
## Numeric Filters
|
||||
|
||||
### abs
|
||||
|
||||
Absolute value:
|
||||
|
||||
```liquid
|
||||
{{ -5 | abs }}
|
||||
{# Output: 5 #}
|
||||
|
||||
{{ 5 | abs }}
|
||||
{# Output: 5 #}
|
||||
```
|
||||
|
||||
### ceil
|
||||
|
||||
Round up to nearest integer:
|
||||
|
||||
```liquid
|
||||
{{ 1.2 | ceil }}
|
||||
{# Output: 2 #}
|
||||
|
||||
{{ 1.9 | ceil }}
|
||||
{# Output: 2 #}
|
||||
```
|
||||
|
||||
### floor
|
||||
|
||||
Round down to nearest integer:
|
||||
|
||||
```liquid
|
||||
{{ 1.9 | floor }}
|
||||
{# Output: 1 #}
|
||||
|
||||
{{ 1.1 | floor }}
|
||||
{# Output: 1 #}
|
||||
```
|
||||
|
||||
### round
|
||||
|
||||
Round to specified decimal places:
|
||||
|
||||
```liquid
|
||||
{{ 1.5 | round }}
|
||||
{# Output: 2 #}
|
||||
|
||||
{{ 1.567 | round: 2 }}
|
||||
{# Output: 1.57 #}
|
||||
|
||||
{{ 1.234 | round: 1 }}
|
||||
{# Output: 1.2 #}
|
||||
```
|
||||
|
||||
### plus
|
||||
|
||||
Addition:
|
||||
|
||||
```liquid
|
||||
{{ 5 | plus: 3 }}
|
||||
{# Output: 8 #}
|
||||
|
||||
{{ product.price | plus: 1000 }}
|
||||
{# Add $10.00 (prices in cents) #}
|
||||
```
|
||||
|
||||
### minus
|
||||
|
||||
Subtraction:
|
||||
|
||||
```liquid
|
||||
{{ 5 | minus: 3 }}
|
||||
{# Output: 2 #}
|
||||
```
|
||||
|
||||
### times
|
||||
|
||||
Multiplication:
|
||||
|
||||
```liquid
|
||||
{{ 5 | times: 3 }}
|
||||
{# Output: 15 #}
|
||||
|
||||
{{ product.price | times: 0.8 }}
|
||||
{# 20% discount #}
|
||||
```
|
||||
|
||||
### divided_by
|
||||
|
||||
Integer division:
|
||||
|
||||
```liquid
|
||||
{{ 10 | divided_by: 2 }}
|
||||
{# Output: 5 #}
|
||||
|
||||
{{ 10 | divided_by: 3 }}
|
||||
{# Output: 3 (integer division) #}
|
||||
|
||||
{{ 10.0 | divided_by: 3 }}
|
||||
{# Output: 3.33... (float division) #}
|
||||
```
|
||||
|
||||
### modulo
|
||||
|
||||
Get remainder:
|
||||
|
||||
```liquid
|
||||
{{ 10 | modulo: 3 }}
|
||||
{# Output: 1 #}
|
||||
|
||||
{# Check if even #}
|
||||
{% if forloop.index | modulo: 2 == 0 %}
|
||||
Even row
|
||||
{% endif %}
|
||||
```
|
||||
|
||||
### at_least
|
||||
|
||||
Ensure minimum value:
|
||||
|
||||
```liquid
|
||||
{{ 1 | at_least: 5 }}
|
||||
{# Output: 5 #}
|
||||
|
||||
{{ 10 | at_least: 5 }}
|
||||
{# Output: 10 #}
|
||||
```
|
||||
|
||||
### at_most
|
||||
|
||||
Ensure maximum value:
|
||||
|
||||
```liquid
|
||||
{{ 100 | at_most: 50 }}
|
||||
{# Output: 50 #}
|
||||
|
||||
{{ 10 | at_most: 50 }}
|
||||
{# Output: 10 #}
|
||||
```
|
||||
|
||||
## Array/Collection Filters
|
||||
|
||||
### first
|
||||
|
||||
Get first element:
|
||||
|
||||
```liquid
|
||||
{{ collection.products | first }}
|
||||
{# Returns first product #}
|
||||
|
||||
{{ "a,b,c" | split: "," | first }}
|
||||
{# Output: a #}
|
||||
```
|
||||
|
||||
### last
|
||||
|
||||
Get last element:
|
||||
|
||||
```liquid
|
||||
{{ collection.products | last }}
|
||||
{# Returns last product #}
|
||||
```
|
||||
|
||||
### join
|
||||
|
||||
Join array with separator:
|
||||
|
||||
```liquid
|
||||
{{ product.tags | join: ", " }}
|
||||
{# Output: sale, new, featured #}
|
||||
```
|
||||
|
||||
### map
|
||||
|
||||
Extract property from each object:
|
||||
|
||||
```liquid
|
||||
{{ collection.products | map: "title" }}
|
||||
{# Returns array of product titles #}
|
||||
|
||||
{{ collection.products | map: "title" | join: ", " }}
|
||||
{# Output: Product 1, Product 2, Product 3 #}
|
||||
```
|
||||
|
||||
### sort
|
||||
|
||||
Sort array by property:
|
||||
|
||||
```liquid
|
||||
{{ collection.products | sort: "price" }}
|
||||
{# Sort by price ascending #}
|
||||
|
||||
{{ collection.products | sort: "title" }}
|
||||
{# Sort alphabetically #}
|
||||
```
|
||||
|
||||
### sort_natural
|
||||
|
||||
Case-insensitive sort:
|
||||
|
||||
```liquid
|
||||
{{ collection.products | sort_natural: "title" }}
|
||||
{# Sorts: Apple, banana, Cherry (natural order) #}
|
||||
```
|
||||
|
||||
### where
|
||||
|
||||
Filter array by property value:
|
||||
|
||||
```liquid
|
||||
{{ collection.products | where: "vendor", "Nike" }}
|
||||
{# Only Nike products #}
|
||||
|
||||
{{ collection.products | where: "available", true }}
|
||||
{# Only available products #}
|
||||
|
||||
{{ collection.products | where: "type", "shoes" | map: "title" }}
|
||||
{# Combine with map #}
|
||||
```
|
||||
|
||||
### uniq
|
||||
|
||||
Remove duplicates:
|
||||
|
||||
```liquid
|
||||
{{ collection.all_vendors | uniq }}
|
||||
{# Unique vendor names #}
|
||||
```
|
||||
|
||||
### limit
|
||||
|
||||
Limit array to N items:
|
||||
|
||||
```liquid
|
||||
{{ collection.products | limit: 5 }}
|
||||
{# First 5 products #}
|
||||
```
|
||||
|
||||
### offset
|
||||
|
||||
Skip first N items:
|
||||
|
||||
```liquid
|
||||
{{ collection.products | offset: 10 }}
|
||||
{# Products from 11th onward #}
|
||||
```
|
||||
|
||||
### concat
|
||||
|
||||
Merge two arrays:
|
||||
|
||||
```liquid
|
||||
{% assign array1 = "a,b,c" | split: "," %}
|
||||
{% assign array2 = "d,e,f" | split: "," %}
|
||||
{{ array1 | concat: array2 | join: ", " }}
|
||||
{# Output: a, b, c, d, e, f #}
|
||||
```
|
||||
|
||||
### compact
|
||||
|
||||
Remove nil values from array:
|
||||
|
||||
```liquid
|
||||
{{ array | compact }}
|
||||
{# Removes nil/null elements #}
|
||||
```
|
||||
|
||||
## Shopify-Specific Filters
|
||||
|
||||
### money
|
||||
|
||||
Format as currency with symbol:
|
||||
|
||||
```liquid
|
||||
{{ 1000 | money }}
|
||||
{# Output: $10.00 #}
|
||||
|
||||
{{ 1599 | money }}
|
||||
{# Output: $15.99 #}
|
||||
```
|
||||
|
||||
### money_without_currency
|
||||
|
||||
Format without currency symbol:
|
||||
|
||||
```liquid
|
||||
{{ 1000 | money_without_currency }}
|
||||
{# Output: 10.00 #}
|
||||
```
|
||||
|
||||
### money_without_trailing_zeros
|
||||
|
||||
Remove unnecessary decimals:
|
||||
|
||||
```liquid
|
||||
{{ 1000 | money_without_trailing_zeros }}
|
||||
{# Output: $10 #}
|
||||
|
||||
{{ 1050 | money_without_trailing_zeros }}
|
||||
{# Output: $10.50 #}
|
||||
```
|
||||
|
||||
### weight_with_unit
|
||||
|
||||
Add weight unit:
|
||||
|
||||
```liquid
|
||||
{{ 500 | weight_with_unit }}
|
||||
{# Output: 500 g #}
|
||||
|
||||
{{ product.variants.first.weight | weight_with_unit }}
|
||||
```
|
||||
|
||||
### asset_url
|
||||
|
||||
Get theme asset CDN URL:
|
||||
|
||||
```liquid
|
||||
{{ 'logo.png' | asset_url }}
|
||||
{# Output: //cdn.shopify.com/s/files/1/0000/0000/t/1/assets/logo.png #}
|
||||
```
|
||||
|
||||
### img_url
|
||||
|
||||
Generate image URL with size:
|
||||
|
||||
```liquid
|
||||
{{ product.featured_image | img_url: '500x500' }}
|
||||
{# Resize to 500x500 #}
|
||||
|
||||
{{ product.featured_image | img_url: 'large' }}
|
||||
{# Named size: pico, icon, thumb, small, compact, medium, large, grande, 1024x1024, 2048x2048 #}
|
||||
|
||||
{{ product.featured_image | img_url: '500x500', crop: 'center' }}
|
||||
{# With crop #}
|
||||
```
|
||||
|
||||
### link_to_type
|
||||
|
||||
Create link to product type collection:
|
||||
|
||||
```liquid
|
||||
{{ product.type | link_to_type }}
|
||||
{# Output: <a href="/collections/types?q=Shoes">Shoes</a> #}
|
||||
```
|
||||
|
||||
### link_to_vendor
|
||||
|
||||
Create link to vendor collection:
|
||||
|
||||
```liquid
|
||||
{{ product.vendor | link_to_vendor }}
|
||||
{# Output: <a href="/collections/vendors?q=Nike">Nike</a> #}
|
||||
```
|
||||
|
||||
### link_to_tag
|
||||
|
||||
Create link to tag filter:
|
||||
|
||||
```liquid
|
||||
{{ tag | link_to_tag: tag }}
|
||||
{# Output: <a href="/collections/all/sale">sale</a> #}
|
||||
```
|
||||
|
||||
### highlight
|
||||
|
||||
Highlight search terms:
|
||||
|
||||
```liquid
|
||||
{{ product.title | highlight: search.terms }}
|
||||
{# Wraps search terms in <strong class="highlight"> tags #}
|
||||
```
|
||||
|
||||
### highlight_active_tag
|
||||
|
||||
Highlight current tag:
|
||||
|
||||
```liquid
|
||||
{{ tag | highlight_active_tag: tag }}
|
||||
{# Wraps current tag in <span class="active"> #}
|
||||
```
|
||||
|
||||
### payment_type_img_url
|
||||
|
||||
Get payment icon URL:
|
||||
|
||||
```liquid
|
||||
{{ 'visa' | payment_type_img_url }}
|
||||
{# Returns Shopify-hosted Visa icon URL #}
|
||||
```
|
||||
|
||||
### placeholder_svg_tag
|
||||
|
||||
Generate placeholder SVG:
|
||||
|
||||
```liquid
|
||||
{{ 'product-1' | placeholder_svg_tag }}
|
||||
{# Generates placeholder product image SVG #}
|
||||
|
||||
{{ 'collection-1' | placeholder_svg_tag: 'custom-class' }}
|
||||
{# With custom CSS class #}
|
||||
```
|
||||
|
||||
### color_to_rgb
|
||||
|
||||
Convert hex to RGB:
|
||||
|
||||
```liquid
|
||||
{{ '#ff0000' | color_to_rgb }}
|
||||
{# Output: rgb(255, 0, 0) #}
|
||||
```
|
||||
|
||||
### color_to_hsl
|
||||
|
||||
Convert hex to HSL:
|
||||
|
||||
```liquid
|
||||
{{ '#ff0000' | color_to_hsl }}
|
||||
{# Output: hsl(0, 100%, 50%) #}
|
||||
```
|
||||
|
||||
### color_extract
|
||||
|
||||
Extract color component:
|
||||
|
||||
```liquid
|
||||
{{ '#ff0000' | color_extract: 'red' }}
|
||||
{# Output: 255 #}
|
||||
```
|
||||
|
||||
### color_brightness
|
||||
|
||||
Calculate brightness:
|
||||
|
||||
```liquid
|
||||
{{ '#ff0000' | color_brightness }}
|
||||
{# Output: brightness value 0-255 #}
|
||||
```
|
||||
|
||||
### color_modify
|
||||
|
||||
Modify color properties:
|
||||
|
||||
```liquid
|
||||
{{ '#ff0000' | color_modify: 'alpha', 0.5 }}
|
||||
{# Adjust alpha channel #}
|
||||
```
|
||||
|
||||
## Date Filters
|
||||
|
||||
### date
|
||||
|
||||
Format date using strftime:
|
||||
|
||||
```liquid
|
||||
{{ order.created_at | date: '%B %d, %Y' }}
|
||||
{# Output: November 10, 2025 #}
|
||||
|
||||
{{ order.created_at | date: '%m/%d/%Y' }}
|
||||
{# Output: 11/10/2025 #}
|
||||
|
||||
{{ order.created_at | date: '%Y-%m-%d %H:%M:%S' }}
|
||||
{# Output: 2025-11-10 14:30:00 #}
|
||||
```
|
||||
|
||||
**Common format codes:**
|
||||
|
||||
- `%Y` - 4-digit year (2025)
|
||||
- `%y` - 2-digit year (25)
|
||||
- `%m` - Month number (11)
|
||||
- `%B` - Full month (November)
|
||||
- `%b` - Short month (Nov)
|
||||
- `%d` - Day of month (10)
|
||||
- `%e` - Day without leading zero (10)
|
||||
- `%A` - Full weekday (Monday)
|
||||
- `%a` - Short weekday (Mon)
|
||||
- `%H` - Hour 24-hour (14)
|
||||
- `%I` - Hour 12-hour (02)
|
||||
- `%M` - Minutes (30)
|
||||
- `%S` - Seconds (45)
|
||||
- `%p` - AM/PM
|
||||
- `%z` - Timezone offset (+0000)
|
||||
|
||||
**Examples:**
|
||||
|
||||
```liquid
|
||||
{{ "now" | date: "%Y-%m-%d" }}
|
||||
{# Current date: 2025-11-10 #}
|
||||
|
||||
{{ article.published_at | date: "%B %d, %Y at %I:%M %p" }}
|
||||
{# November 10, 2025 at 02:30 PM #}
|
||||
```
|
||||
|
||||
## URL Filters
|
||||
|
||||
### url_for_type
|
||||
|
||||
Get collection URL for product type:
|
||||
|
||||
```liquid
|
||||
{{ product.type | url_for_type }}
|
||||
{# Output: /collections/types?q=Shoes #}
|
||||
```
|
||||
|
||||
### url_for_vendor
|
||||
|
||||
Get collection URL for vendor:
|
||||
|
||||
```liquid
|
||||
{{ product.vendor | url_for_vendor }}
|
||||
{# Output: /collections/vendors?q=Nike #}
|
||||
```
|
||||
|
||||
### within
|
||||
|
||||
Scope URL within collection:
|
||||
|
||||
```liquid
|
||||
{{ product.url | within: collection }}
|
||||
{# Output: /collections/sale/products/product-handle #}
|
||||
```
|
||||
|
||||
### default_pagination
|
||||
|
||||
Generate pagination HTML:
|
||||
|
||||
```liquid
|
||||
{{ paginate | default_pagination }}
|
||||
{# Outputs complete pagination HTML #}
|
||||
```
|
||||
|
||||
## Utility Filters
|
||||
|
||||
### default
|
||||
|
||||
Provide fallback value:
|
||||
|
||||
```liquid
|
||||
{{ product.metafield | default: "N/A" }}
|
||||
{# If metafield is nil, outputs "N/A" #}
|
||||
|
||||
{{ variant.title | default: "Default" }}
|
||||
```
|
||||
|
||||
### json
|
||||
|
||||
Convert to JSON:
|
||||
|
||||
```liquid
|
||||
{{ product | json }}
|
||||
{# Outputs product object as JSON string #}
|
||||
|
||||
<script>
|
||||
var productData = {{ product | json }};
|
||||
</script>
|
||||
```
|
||||
|
||||
## Filter Chaining
|
||||
|
||||
Filters execute left-to-right and can be chained:
|
||||
|
||||
```liquid
|
||||
{{ "hello world" | upcase | replace: "WORLD", "SHOPIFY" }}
|
||||
{# Output: HELLO SHOPIFY #}
|
||||
|
||||
{{ collection.products | where: "available" | map: "title" | sort | join: ", " }}
|
||||
{# Filter → extract → sort → join #}
|
||||
|
||||
{{ product.price | times: 0.8 | round: 2 | money }}
|
||||
{# Calculate 20% discount, round, format as money #}
|
||||
|
||||
{{ product.description | strip_html | truncatewords: 50 | escape }}
|
||||
{# Strip HTML → truncate → escape for safety #}
|
||||
```
|
||||
|
||||
## Performance Tips
|
||||
|
||||
1. **Cache filtered results** if used multiple times:
|
||||
|
||||
```liquid
|
||||
{# ❌ Inefficient: #}
|
||||
{% for i in (1..10) %}
|
||||
{{ collection.products | where: "available" | size }}
|
||||
{% endfor %}
|
||||
|
||||
{# ✅ Efficient: #}
|
||||
{% assign available_products = collection.products | where: "available" %}
|
||||
{% for i in (1..10) %}
|
||||
{{ available_products.size }}
|
||||
{% endfor %}
|
||||
```
|
||||
|
||||
2. **Use `limit` and `offset` filters** instead of manual iteration control
|
||||
|
||||
3. **Combine filters intelligently** to reduce operations:
|
||||
|
||||
```liquid
|
||||
{# ❌ Less efficient: #}
|
||||
{% assign titles = collection.products | map: "title" %}
|
||||
{% assign sorted = titles | sort %}
|
||||
{% assign limited = sorted | limit: 5 %}
|
||||
|
||||
{# ✅ More efficient: #}
|
||||
{% assign limited_titles = collection.products | map: "title" | sort | limit: 5 %}
|
||||
```
|
||||
695
skills/shopify-liquid/references/objects.md
Normal file
695
skills/shopify-liquid/references/objects.md
Normal file
@@ -0,0 +1,695 @@
|
||||
# Liquid Objects - Complete Reference
|
||||
|
||||
## Global Objects (Available Everywhere)
|
||||
|
||||
### shop
|
||||
|
||||
Store-level information:
|
||||
|
||||
```liquid
|
||||
{{ shop.name }} {# Store name #}
|
||||
{{ shop.url }} {# Store URL (https://...) #}
|
||||
{{ shop.description }} {# Store tagline/description #}
|
||||
{{ shop.currency }} {# ISO currency code: USD, GBP, EUR #}
|
||||
{{ shop.money_format }} {# Money format string: ${{amount}} #}
|
||||
{{ shop.permanent_domain }} {# Domain: store.myshopify.com #}
|
||||
{{ shop.domain }} {# Primary domain #}
|
||||
{{ shop.email }} {# Support email #}
|
||||
{{ shop.phone }} {# Support phone #}
|
||||
{{ shop.address }} {# Store address object #}
|
||||
{{ shop.address.city }}
|
||||
{{ shop.address.province }}
|
||||
{{ shop.address.country }}
|
||||
{{ shop.address.zip }}
|
||||
{{ shop.enabled_payment_types }} {# Array of enabled payment methods #}
|
||||
{{ shop.checkout.privacy_policy_url }}
|
||||
{{ shop.checkout.terms_of_service_url }}
|
||||
{{ shop.checkout.refund_policy_url }}
|
||||
```
|
||||
|
||||
### request
|
||||
|
||||
Request context and routing:
|
||||
|
||||
```liquid
|
||||
{{ request.path }} {# Current URL path: /products/handle #}
|
||||
{{ request.host }} {# Current domain #}
|
||||
{{ request.origin }} {# Protocol + host #}
|
||||
{{ request.page_type }} {# "product", "collection", "index", etc. #}
|
||||
{{ request.locale.iso_code }} {# Language: "en", "fr", "es" #}
|
||||
{{ request.locale.root_url }} {# Root URL for locale #}
|
||||
{{ request.design_mode }} {# Boolean: theme editor active #}
|
||||
{{ request.visual_preview_mode }} {# Boolean: theme preview active #}
|
||||
|
||||
{# Query parameters #}
|
||||
{{ request.query_string }} {# Full query string #}
|
||||
|
||||
{# Build canonical URL #}
|
||||
{{ request.canonical_url }} {# Full canonical URL #}
|
||||
{{ request.path_with_query }} {# Path + query string #}
|
||||
```
|
||||
|
||||
### settings
|
||||
|
||||
Theme settings (from settings_schema.json):
|
||||
|
||||
```liquid
|
||||
{# Colors #}
|
||||
{{ settings.color_primary }}
|
||||
{{ settings.color_secondary }}
|
||||
{{ settings.color_body_bg }}
|
||||
|
||||
{# Typography #}
|
||||
{{ settings.type_header_font }}
|
||||
{{ settings.type_body_font }}
|
||||
|
||||
{# Layout #}
|
||||
{{ settings.layout_container_width }}
|
||||
{{ settings.layout_sidebar_enabled }}
|
||||
|
||||
{# Media #}
|
||||
{{ settings.logo }} {# Image object #}
|
||||
{{ settings.logo.src }}
|
||||
{{ settings.logo.width }}
|
||||
{{ settings.logo.height }}
|
||||
{{ settings.logo.alt }}
|
||||
|
||||
{# Text content #}
|
||||
{{ settings.announcement_text }}
|
||||
{{ settings.footer_text }}
|
||||
|
||||
{# Boolean settings #}
|
||||
{% if settings.show_breadcrumbs %}
|
||||
{# Render breadcrumbs #}
|
||||
{% endif %}
|
||||
|
||||
{# URL settings #}
|
||||
{{ settings.social_twitter_link }}
|
||||
{{ settings.social_facebook_link }}
|
||||
```
|
||||
|
||||
### routes
|
||||
|
||||
URL routes to standard pages:
|
||||
|
||||
```liquid
|
||||
{{ routes.root_url }} {# / #}
|
||||
{{ routes.account_url }} {# /account #}
|
||||
{{ routes.account_login_url }} {# /account/login #}
|
||||
{{ routes.account_logout_url }} {# /account/logout #}
|
||||
{{ routes.account_register_url }} {# /account/register #}
|
||||
{{ routes.account_addresses_url }} {# /account/addresses #}
|
||||
{{ routes.collections_url }} {# /collections #}
|
||||
{{ routes.all_products_collection_url }} {# /collections/all #}
|
||||
{{ routes.search_url }} {# /search #}
|
||||
{{ routes.cart_url }} {# /cart #}
|
||||
{{ routes.cart_add_url }} {# /cart/add #}
|
||||
{{ routes.cart_change_url }} {# /cart/change #}
|
||||
{{ routes.cart_clear_url }} {# /cart/clear #}
|
||||
{{ routes.cart_update_url }} {# /cart/update #}
|
||||
```
|
||||
|
||||
### section
|
||||
|
||||
Current section context (within sections):
|
||||
|
||||
```liquid
|
||||
{{ section.id }} {# Unique ID: "section-1234567890" #}
|
||||
{{ section.settings.title }} {# Section setting #}
|
||||
{{ section.settings.background_color }}
|
||||
{{ section.index }} {# Position on page #}
|
||||
{{ section.location }} {# Where section appears #}
|
||||
|
||||
{# Blocks #}
|
||||
{{ section.blocks }} {# Array of blocks #}
|
||||
{{ section.blocks.size }} {# Number of blocks #}
|
||||
|
||||
{% for block in section.blocks %}
|
||||
{{ block.id }}
|
||||
{{ block.type }}
|
||||
{{ block.settings.text }}
|
||||
{{ block.shopify_attributes }} {# Required for theme editor #}
|
||||
{% endfor %}
|
||||
|
||||
{# Blocks by type #}
|
||||
{{ section.blocks_by_type }} {# Organized by type #}
|
||||
```
|
||||
|
||||
### block
|
||||
|
||||
Current block context (within section blocks):
|
||||
|
||||
```liquid
|
||||
{{ block.id }} {# Unique ID: "block-9876543210" #}
|
||||
{{ block.type }} {# Block type name #}
|
||||
{{ block.settings.text }} {# Block setting #}
|
||||
{{ block.shopify_attributes }} {# Required for theme editor #}
|
||||
|
||||
{# Example usage in section #}
|
||||
{% for block in section.blocks %}
|
||||
<div {{ block.shopify_attributes }}>
|
||||
{% case block.type %}
|
||||
{% when 'heading' %}
|
||||
<h2>{{ block.settings.title }}</h2>
|
||||
{% when 'text' %}
|
||||
<p>{{ block.settings.content }}</p>
|
||||
{% endcase %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
```
|
||||
|
||||
## Page Context Objects
|
||||
|
||||
### product
|
||||
|
||||
Product object (on product pages):
|
||||
|
||||
```liquid
|
||||
{# Core properties #}
|
||||
{{ product.id }} {# Numeric ID #}
|
||||
{{ product.title }} {# Product name #}
|
||||
{{ product.handle }} {# URL slug #}
|
||||
{{ product.description }} {# Full HTML description #}
|
||||
{{ product.vendor }} {# Brand/manufacturer #}
|
||||
{{ product.type }} {# Category #}
|
||||
{{ product.url }} {# Product URL #}
|
||||
{{ product.available }} {# Boolean: any variant in stock #}
|
||||
{{ product.published_at }} {# Publication timestamp #}
|
||||
{{ product.created_at }} {# Creation timestamp #}
|
||||
{{ product.updated_at }} {# Last modified timestamp #}
|
||||
|
||||
{# Pricing (in cents) #}
|
||||
{{ product.price }} {# Current variant price #}
|
||||
{{ product.price_min }} {# Cheapest variant #}
|
||||
{{ product.price_max }} {# Most expensive variant #}
|
||||
{{ product.price_varies }} {# Boolean: different prices #}
|
||||
{{ product.compare_at_price }} {# Original price for sales #}
|
||||
{{ product.compare_at_price_min }}
|
||||
{{ product.compare_at_price_max }}
|
||||
{{ product.compare_at_price_varies }}
|
||||
|
||||
{# Images #}
|
||||
{{ product.featured_image }} {# Primary image object #}
|
||||
{{ product.featured_image.src }}
|
||||
{{ product.featured_image.width }}
|
||||
{{ product.featured_image.height }}
|
||||
{{ product.featured_image.alt }}
|
||||
{{ product.featured_image | img_url: '500x500' }}
|
||||
|
||||
{{ product.images }} {# Array of all images #}
|
||||
{{ product.images.size }} {# Image count #}
|
||||
|
||||
{% for image in product.images %}
|
||||
<img src="{{ image | img_url: '300x300' }}" alt="{{ image.alt }}">
|
||||
{% endfor %}
|
||||
|
||||
{{ product.media }} {# Array of all media (images, videos, 3D) #}
|
||||
|
||||
{# Variants #}
|
||||
{{ product.variants }} {# Array of variants #}
|
||||
{{ product.variants.size }} {# Variant count #}
|
||||
{{ product.selected_variant }} {# Currently selected variant #}
|
||||
{{ product.selected_or_first_available_variant }}
|
||||
{{ product.first_available_variant }}
|
||||
{{ product.has_only_default_variant }} {# Boolean: single variant #}
|
||||
|
||||
{# Options #}
|
||||
{{ product.options }} {# Array: ["Size", "Color"] #}
|
||||
{{ product.options_with_values }} {# Array of option objects #}
|
||||
|
||||
{% for option in product.options_with_values %}
|
||||
<label>{{ option.name }}</label>
|
||||
<select>
|
||||
{% for value in option.values %}
|
||||
<option>{{ value }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
{% endfor %}
|
||||
|
||||
{# Collections #}
|
||||
{{ product.collections }} {# Array of collections #}
|
||||
{{ product.collections.size }}
|
||||
|
||||
{# Tags #}
|
||||
{{ product.tags }} {# Array of tags #}
|
||||
{{ product.tags | join: ", " }}
|
||||
|
||||
{# Custom data #}
|
||||
{{ product.metafields.namespace.key }}
|
||||
{{ product.metafields.custom.field_name }}
|
||||
|
||||
{# Template #}
|
||||
{{ product.template_suffix }} {# Template variant: "alternate" #}
|
||||
```
|
||||
|
||||
### variant
|
||||
|
||||
Variant object (product.variants, product.selected_variant):
|
||||
|
||||
```liquid
|
||||
{{ variant.id }} {# Variant ID #}
|
||||
{{ variant.product_id }} {# Parent product ID #}
|
||||
{{ variant.title }} {# "Red / Medium" #}
|
||||
{{ variant.price }} {# Price in cents #}
|
||||
{{ variant.compare_at_price }} {# Original price #}
|
||||
{{ variant.sku }} {# SKU code #}
|
||||
{{ variant.barcode }} {# Barcode #}
|
||||
{{ variant.weight }} {# Weight in grams #}
|
||||
{{ variant.weight_unit }} {# "kg", "lb", etc. #}
|
||||
{{ variant.weight_in_unit }} {# Weight in configured unit #}
|
||||
|
||||
{# Availability #}
|
||||
{{ variant.available }} {# Boolean: in stock #}
|
||||
{{ variant.inventory_quantity }} {# Current stock level #}
|
||||
{{ variant.inventory_policy }} {# "continue" or "deny" #}
|
||||
{{ variant.inventory_management }} {# "shopify" or null #}
|
||||
|
||||
{# Options #}
|
||||
{{ variant.option1 }} {# First option value: "Red" #}
|
||||
{{ variant.option2 }} {# Second option value: "Medium" #}
|
||||
{{ variant.option3 }} {# Third option value #}
|
||||
{{ variant.options }} {# Array: ["Red", "Medium"] #}
|
||||
|
||||
{# Image #}
|
||||
{{ variant.featured_image }} {# Variant-specific image #}
|
||||
{{ variant.image }} {# Same as featured_image #}
|
||||
|
||||
{# URL #}
|
||||
{{ variant.url }} {# Product URL with variant param #}
|
||||
|
||||
{# Metafields #}
|
||||
{{ variant.metafields.namespace.key }}
|
||||
```
|
||||
|
||||
### collection
|
||||
|
||||
Collection object (on collection pages):
|
||||
|
||||
```liquid
|
||||
{# Core properties #}
|
||||
{{ collection.id }} {# Numeric ID #}
|
||||
{{ collection.title }} {# Collection name #}
|
||||
{{ collection.handle }} {# URL slug #}
|
||||
{{ collection.description }} {# HTML description #}
|
||||
{{ collection.url }} {# Collection URL #}
|
||||
{{ collection.published_at }} {# Publication date #}
|
||||
|
||||
{# Image #}
|
||||
{{ collection.image }} {# Featured image object #}
|
||||
{{ collection.image.src }}
|
||||
{{ collection.image | img_url: '1024x1024' }}
|
||||
|
||||
{# Products #}
|
||||
{{ collection.products }} {# Array of products #}
|
||||
{{ collection.products_count }} {# Current page count #}
|
||||
{{ collection.all_products_count }}{# Total count #}
|
||||
|
||||
{# Filtering & sorting #}
|
||||
{{ collection.all_tags }} {# All tags (max 1000) #}
|
||||
{{ collection.all_types }} {# All product types #}
|
||||
{{ collection.all_vendors }} {# All vendors #}
|
||||
{{ collection.current_type }} {# Active type filter #}
|
||||
{{ collection.current_vendor }} {# Active vendor filter #}
|
||||
{{ collection.sort_by }} {# Current sort method #}
|
||||
{{ collection.default_sort_by }} {# Default sort #}
|
||||
{{ collection.sort_options }} {# Available sort methods #}
|
||||
|
||||
{# Filters (Storefront Filtering) #}
|
||||
{{ collection.filters }} {# Array of filter objects #}
|
||||
|
||||
{% for filter in collection.filters %}
|
||||
{{ filter.label }} {# Filter name #}
|
||||
{{ filter.type }} {# "list", "price_range" #}
|
||||
{{ filter.active_values }} {# Currently active #}
|
||||
{{ filter.values }} {# Available values #}
|
||||
{% endfor %}
|
||||
|
||||
{# Navigation (on product pages within collection) #}
|
||||
{{ collection.next_product }} {# Next product in collection #}
|
||||
{{ collection.previous_product }} {# Previous product #}
|
||||
|
||||
{# Metafields #}
|
||||
{{ collection.metafields.namespace.key }}
|
||||
|
||||
{# Template #}
|
||||
{{ collection.template_suffix }}
|
||||
```
|
||||
|
||||
### cart
|
||||
|
||||
Cart object (global - always available):
|
||||
|
||||
```liquid
|
||||
{# Cart state #}
|
||||
{{ cart.item_count }} {# Total line items #}
|
||||
{{ cart.total_price }} {# Total in cents #}
|
||||
{{ cart.total_weight }} {# Weight sum #}
|
||||
{{ cart.empty? }} {# Boolean: is cart empty #}
|
||||
|
||||
{# Items #}
|
||||
{{ cart.items }} {# Array of line items #}
|
||||
{{ cart.items.size }} {# Number of line items #}
|
||||
|
||||
{% for item in cart.items %}
|
||||
{{ item.product_id }}
|
||||
{{ item.variant_id }}
|
||||
{{ item.title }}
|
||||
{{ item.quantity }}
|
||||
{{ item.price }}
|
||||
{{ item.line_price }} {# price × quantity #}
|
||||
{{ item.image }}
|
||||
{% endfor %}
|
||||
|
||||
{# Notes and attributes #}
|
||||
{{ cart.note }} {# Customer note #}
|
||||
{{ cart.attributes }} {# Custom cart attributes #}
|
||||
|
||||
{# Access specific attribute #}
|
||||
{% if cart.attributes.gift_wrap %}
|
||||
Gift wrap requested
|
||||
{% endif %}
|
||||
|
||||
{# Discounts #}
|
||||
{{ cart.cart_level_discount_applications }}
|
||||
{{ cart.total_discount }} {# Total discount amount #}
|
||||
|
||||
{# Checkout #}
|
||||
{{ cart.requires_shipping }} {# Boolean #}
|
||||
```
|
||||
|
||||
### line_item
|
||||
|
||||
Line item object (cart.items):
|
||||
|
||||
```liquid
|
||||
{% for item in cart.items %}
|
||||
{{ item.id }} {# Line item ID #}
|
||||
{{ item.key }} {# Unique key #}
|
||||
{{ item.product_id }} {# Product ID #}
|
||||
{{ item.variant_id }} {# Variant ID #}
|
||||
|
||||
{# Product info #}
|
||||
{{ item.product }} {# Product object #}
|
||||
{{ item.variant }} {# Variant object #}
|
||||
{{ item.title }} {# Product title #}
|
||||
{{ item.product_title }} {# Same as title #}
|
||||
{{ item.variant_title }} {# Variant options #}
|
||||
|
||||
{# Pricing #}
|
||||
{{ item.quantity }} {# Quantity ordered #}
|
||||
{{ item.price }} {# Price per unit (cents) #}
|
||||
{{ item.line_price }} {# Total: price × quantity #}
|
||||
{{ item.original_price }} {# Before discounts #}
|
||||
{{ item.original_line_price }}
|
||||
{{ item.final_price }} {# After discounts #}
|
||||
{{ item.final_line_price }}
|
||||
|
||||
{# Images #}
|
||||
{{ item.image }} {# Line item image #}
|
||||
{{ item.featured_image.src }}
|
||||
|
||||
{# URL #}
|
||||
{{ item.url }} {# Link to product #}
|
||||
|
||||
{# SKU #}
|
||||
{{ item.sku }} {# Variant SKU #}
|
||||
|
||||
{# Properties (custom line item data) #}
|
||||
{{ item.properties }} {# Hash of properties #}
|
||||
{% for property in item.properties %}
|
||||
{{ property.first }}: {{ property.last }}
|
||||
{% endfor %}
|
||||
|
||||
{# Discounts #}
|
||||
{{ item.discount_allocations }}
|
||||
{% for discount in item.discount_allocations %}
|
||||
{{ discount.amount }}
|
||||
{{ discount.discount_application.title }}
|
||||
{% endfor %}
|
||||
|
||||
{# Fulfillment #}
|
||||
{{ item.requires_shipping }} {# Boolean #}
|
||||
{{ item.taxable }} {# Boolean #}
|
||||
{% endfor %}
|
||||
```
|
||||
|
||||
### customer
|
||||
|
||||
Customer object (when logged in):
|
||||
|
||||
```liquid
|
||||
{% if customer %}
|
||||
{{ customer.id }} {# Numeric ID #}
|
||||
{{ customer.email }} {# Email address #}
|
||||
{{ customer.first_name }}
|
||||
{{ customer.last_name }}
|
||||
{{ customer.name }} {# Full name #}
|
||||
{{ customer.phone }}
|
||||
|
||||
{# Account status #}
|
||||
{{ customer.has_account }} {# Boolean: registered #}
|
||||
{{ customer.accepts_marketing }} {# Email marketing opt-in #}
|
||||
{{ customer.email_marketing_consent }}
|
||||
|
||||
{# Addresses #}
|
||||
{{ customer.addresses }} {# Array of addresses #}
|
||||
{{ customer.addresses_count }}
|
||||
{{ customer.default_address }} {# Primary address #}
|
||||
|
||||
{% for address in customer.addresses %}
|
||||
{{ address.first_name }}
|
||||
{{ address.last_name }}
|
||||
{{ address.address1 }}
|
||||
{{ address.address2 }}
|
||||
{{ address.city }}
|
||||
{{ address.province }}
|
||||
{{ address.province_code }} {# State/region code #}
|
||||
{{ address.country }}
|
||||
{{ address.country_code }} {# Country code: US, CA, etc. #}
|
||||
{{ address.zip }}
|
||||
{{ address.phone }}
|
||||
{{ address.company }}
|
||||
{% endfor %}
|
||||
|
||||
{# Orders #}
|
||||
{{ customer.orders }} {# Array of orders #}
|
||||
{{ customer.orders_count }} {# Total orders #}
|
||||
{{ customer.total_spent }} {# Lifetime value (cents) #}
|
||||
|
||||
{# Tags #}
|
||||
{{ customer.tags }} {# Array of customer tags #}
|
||||
|
||||
{# Metafields #}
|
||||
{{ customer.metafields.namespace.key }}
|
||||
{% endif %}
|
||||
```
|
||||
|
||||
### order
|
||||
|
||||
Order object (order confirmation, customer account):
|
||||
|
||||
```liquid
|
||||
{{ order.id }} {# Numeric ID #}
|
||||
{{ order.name }} {# Order name: "#1001" #}
|
||||
{{ order.order_number }} {# 1001 #}
|
||||
{{ order.confirmation_number }} {# Unique confirmation #}
|
||||
{{ order.email }} {# Customer email #}
|
||||
{{ order.phone }} {# Customer phone #}
|
||||
{{ order.customer_url }} {# Link to view order #}
|
||||
|
||||
{# Timestamps #}
|
||||
{{ order.created_at }} {# Order date/time #}
|
||||
{{ order.updated_at }}
|
||||
{{ order.cancelled_at }} {# If cancelled #}
|
||||
{{ order.processed_at }}
|
||||
|
||||
{# Customer #}
|
||||
{{ order.customer }} {# Customer object #}
|
||||
{{ order.customer.name }}
|
||||
|
||||
{# Items #}
|
||||
{{ order.line_items }} {# Array of line items #}
|
||||
{{ order.line_items_count }}
|
||||
|
||||
{% for item in order.line_items %}
|
||||
{{ item.title }}
|
||||
{{ item.quantity }}
|
||||
{{ item.price }}
|
||||
{{ item.line_price }}
|
||||
{% endfor %}
|
||||
|
||||
{# Pricing #}
|
||||
{{ order.subtotal_price }} {# Before tax/shipping #}
|
||||
{{ order.total_price }} {# Grand total #}
|
||||
{{ order.tax_price }} {# Total tax #}
|
||||
{{ order.shipping_price }} {# Shipping cost #}
|
||||
{{ order.total_discounts }} {# Discount amount #}
|
||||
|
||||
{# Status #}
|
||||
{{ order.financial_status }} {# "paid", "pending", "refunded" #}
|
||||
{{ order.fulfillment_status }} {# "fulfilled", "partial", null #}
|
||||
{{ order.cancelled }} {# Boolean #}
|
||||
{{ order.cancel_reason }}
|
||||
|
||||
{# Addresses #}
|
||||
{{ order.shipping_address }}
|
||||
{{ order.billing_address }}
|
||||
|
||||
{# Shipping #}
|
||||
{{ order.shipping_method.title }} {# Shipping method name #}
|
||||
{{ order.shipping_method.price }}
|
||||
|
||||
{# Discounts #}
|
||||
{{ order.discount_applications }}
|
||||
{% for discount in order.discount_applications %}
|
||||
{{ discount.title }}
|
||||
{{ discount.total_allocated_amount }}
|
||||
{% endfor %}
|
||||
|
||||
{# Notes #}
|
||||
{{ order.note }} {# Customer note #}
|
||||
{{ order.attributes }} {# Custom attributes #}
|
||||
|
||||
{# Tags #}
|
||||
{{ order.tags }}
|
||||
```
|
||||
|
||||
### article
|
||||
|
||||
Article object (blog post pages):
|
||||
|
||||
```liquid
|
||||
{{ article.id }} {# Numeric ID #}
|
||||
{{ article.title }} {# Article headline #}
|
||||
{{ article.handle }} {# URL slug #}
|
||||
{{ article.content }} {# Full HTML content #}
|
||||
{{ article.excerpt }} {# Summary/teaser #}
|
||||
{{ article.excerpt_or_content }} {# Excerpt if set, else content #}
|
||||
|
||||
{# Author #}
|
||||
{{ article.author }} {# Author name #}
|
||||
{{ article.author_url }} {# Author profile URL #}
|
||||
|
||||
{# Dates #}
|
||||
{{ article.published_at }} {# Publication date #}
|
||||
{{ article.created_at }}
|
||||
{{ article.updated_at }}
|
||||
|
||||
{# URL #}
|
||||
{{ article.url }} {# Article URL #}
|
||||
|
||||
{# Image #}
|
||||
{{ article.image }} {# Featured image #}
|
||||
{{ article.image.src }}
|
||||
{{ article.image | img_url: 'large' }}
|
||||
|
||||
{# Comments #}
|
||||
{{ article.comments }} {# Array of comments #}
|
||||
{{ article.comments_count }}
|
||||
{{ article.comments_enabled }} {# Boolean #}
|
||||
{{ article.moderated }} {# Comment moderation enabled #}
|
||||
|
||||
{# Tags #}
|
||||
{{ article.tags }} {# Array of tags #}
|
||||
|
||||
{# Blog reference #}
|
||||
{{ article.blog }} {# Parent blog object #}
|
||||
{{ article.blog.title }}
|
||||
|
||||
{# Metafields #}
|
||||
{{ article.metafields.namespace.key }}
|
||||
```
|
||||
|
||||
### blog
|
||||
|
||||
Blog object (blog listing page):
|
||||
|
||||
```liquid
|
||||
{{ blog.id }} {# Numeric ID #}
|
||||
{{ blog.title }} {# Blog name #}
|
||||
{{ blog.handle }} {# URL slug #}
|
||||
{{ blog.url }} {# Blog URL #}
|
||||
|
||||
{# Articles #}
|
||||
{{ blog.articles }} {# Array of articles #}
|
||||
{{ blog.articles_count }} {# Total articles #}
|
||||
|
||||
{# Tags #}
|
||||
{{ blog.all_tags }} {# All article tags #}
|
||||
|
||||
{# Metafields #}
|
||||
{{ blog.metafields.namespace.key }}
|
||||
```
|
||||
|
||||
### search
|
||||
|
||||
Search results object:
|
||||
|
||||
```liquid
|
||||
{{ search.performed }} {# Boolean: search executed #}
|
||||
{{ search.results }} {# Results array #}
|
||||
{{ search.results_count }} {# Number of results #}
|
||||
{{ search.terms }} {# Search query #}
|
||||
{{ search.types }} {# Resource types found #}
|
||||
|
||||
{% for item in search.results %}
|
||||
{% case item.object_type %}
|
||||
{% when 'product' %}
|
||||
{{ item.title }}
|
||||
{{ item.price | money }}
|
||||
{% when 'article' %}
|
||||
{{ item.title }}
|
||||
{{ item.excerpt }}
|
||||
{% when 'page' %}
|
||||
{{ item.title }}
|
||||
{{ item.content | strip_html | truncatewords: 50 }}
|
||||
{% endcase %}
|
||||
{% endfor %}
|
||||
```
|
||||
|
||||
## Metafields
|
||||
|
||||
Access custom data on any object:
|
||||
|
||||
```liquid
|
||||
{# Product metafields #}
|
||||
{{ product.metafields.namespace.key }}
|
||||
{{ product.metafields.custom.warranty_info }}
|
||||
{{ product.metafields.specifications.material }}
|
||||
|
||||
{# Collection metafields #}
|
||||
{{ collection.metafields.seo.custom_title }}
|
||||
|
||||
{# Customer metafields #}
|
||||
{{ customer.metafields.loyalty.points }}
|
||||
|
||||
{# Shop metafields #}
|
||||
{{ shop.metafields.global.announcement }}
|
||||
|
||||
{# Check for existence #}
|
||||
{% if product.metafields.custom.size_guide %}
|
||||
{{ product.metafields.custom.size_guide }}
|
||||
{% endif %}
|
||||
|
||||
{# Use default filter for safety #}
|
||||
{{ product.metafields.custom.field | default: "Not specified" }}
|
||||
```
|
||||
|
||||
## Metaobjects
|
||||
|
||||
Access metaobject definitions:
|
||||
|
||||
```liquid
|
||||
{# Access metaobject by handle #}
|
||||
{% assign testimonial = shop.metaobjects.testimonials['customer-review-1'] %}
|
||||
|
||||
{{ testimonial.name }}
|
||||
{{ testimonial.rating }}
|
||||
{{ testimonial.content }}
|
||||
|
||||
{# Loop through metaobjects #}
|
||||
{% for testimonial in shop.metaobjects.testimonials.values %}
|
||||
{{ testimonial.fields.author }}
|
||||
{{ testimonial.fields.quote }}
|
||||
{% endfor %}
|
||||
```
|
||||
551
skills/shopify-liquid/references/syntax.md
Normal file
551
skills/shopify-liquid/references/syntax.md
Normal file
@@ -0,0 +1,551 @@
|
||||
# Liquid Syntax - Complete Reference
|
||||
|
||||
## Tag Categories
|
||||
|
||||
### Control Flow Tags
|
||||
|
||||
#### if/elsif/else/endif
|
||||
|
||||
```liquid
|
||||
{% if product.available %}
|
||||
<button>Add to Cart</button>
|
||||
{% elsif product.coming_soon %}
|
||||
<p>Coming Soon</p>
|
||||
{% else %}
|
||||
<p>Sold Out</p>
|
||||
{% endif %}
|
||||
```
|
||||
|
||||
**Operators:**
|
||||
- `==` - equals
|
||||
- `!=` - not equals
|
||||
- `>` - greater than
|
||||
- `<` - less than
|
||||
- `>=` - greater than or equal
|
||||
- `<=` - less than or equal
|
||||
- `contains` - substring or array contains
|
||||
- `and` - logical AND
|
||||
- `or` - logical OR
|
||||
|
||||
**Examples:**
|
||||
```liquid
|
||||
{% if product.price > 100 and product.available %}
|
||||
Premium item in stock
|
||||
{% endif %}
|
||||
|
||||
{% if product.tags contains 'sale' or product.type == 'clearance' %}
|
||||
On sale!
|
||||
{% endif %}
|
||||
```
|
||||
|
||||
#### unless
|
||||
|
||||
Negated if statement:
|
||||
|
||||
```liquid
|
||||
{% unless customer.name == blank %}
|
||||
Hello, {{ customer.name }}
|
||||
{% endunless %}
|
||||
|
||||
{# Equivalent to: #}
|
||||
{% if customer.name != blank %}
|
||||
Hello, {{ customer.name }}
|
||||
{% endif %}
|
||||
```
|
||||
|
||||
#### case/when
|
||||
|
||||
Switch-case statement:
|
||||
|
||||
```liquid
|
||||
{% case product.type %}
|
||||
{% when 'shoes' %}
|
||||
<icon>👟</icon>
|
||||
{% when 'boots' %}
|
||||
<icon>👢</icon>
|
||||
{% when 'sneakers' %}
|
||||
<icon>👟</icon>
|
||||
{% else %}
|
||||
<icon>📦</icon>
|
||||
{% endcase %}
|
||||
```
|
||||
|
||||
### Iteration Tags
|
||||
|
||||
#### for loop
|
||||
|
||||
```liquid
|
||||
{% for product in collection.products %}
|
||||
{{ product.title }}
|
||||
{% endfor %}
|
||||
```
|
||||
|
||||
**Modifiers:**
|
||||
|
||||
```liquid
|
||||
{# Limit to first 5 #}
|
||||
{% for product in collection.products limit: 5 %}
|
||||
{{ product.title }}
|
||||
{% endfor %}
|
||||
|
||||
{# Skip first 10 #}
|
||||
{% for product in collection.products offset: 10 %}
|
||||
{{ product.title }}
|
||||
{% endfor %}
|
||||
|
||||
{# Reverse order #}
|
||||
{% for product in collection.products reversed %}
|
||||
{{ product.title }}
|
||||
{% endfor %}
|
||||
|
||||
{# Combine modifiers #}
|
||||
{% for product in collection.products limit: 5 offset: 10 %}
|
||||
{# Items 11-15 #}
|
||||
{% endfor %}
|
||||
```
|
||||
|
||||
**forloop object (available inside loops):**
|
||||
|
||||
```liquid
|
||||
{% for item in array %}
|
||||
{{ forloop.index }} {# 1-based: 1, 2, 3, ... #}
|
||||
{{ forloop.index0 }} {# 0-based: 0, 1, 2, ... #}
|
||||
{{ forloop.rindex }} {# Reverse 1-based: 3, 2, 1 #}
|
||||
{{ forloop.rindex0 }} {# Reverse 0-based: 2, 1, 0 #}
|
||||
{{ forloop.first }} {# true on first iteration #}
|
||||
{{ forloop.last }} {# true on last iteration #}
|
||||
{{ forloop.length }} {# Total number of items #}
|
||||
{% endfor %}
|
||||
```
|
||||
|
||||
**Example usage:**
|
||||
|
||||
```liquid
|
||||
{% for product in collection.products %}
|
||||
{% if forloop.first %}
|
||||
<h2>Featured Product</h2>
|
||||
{% endif %}
|
||||
|
||||
<div class="product-{{ forloop.index }}">
|
||||
{{ product.title }}
|
||||
</div>
|
||||
|
||||
{% if forloop.index == 3 %}
|
||||
<hr> {# Divider after 3rd item #}
|
||||
{% endif %}
|
||||
|
||||
{% if forloop.last %}
|
||||
<p>Showing {{ forloop.length }} products</p>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
```
|
||||
|
||||
#### break and continue
|
||||
|
||||
```liquid
|
||||
{% for product in collection.products %}
|
||||
{% if product.handle == 'target' %}
|
||||
{% break %} {# Exit loop entirely #}
|
||||
{% endif %}
|
||||
|
||||
{% if product.available == false %}
|
||||
{% continue %} {# Skip to next iteration #}
|
||||
{% endif %}
|
||||
|
||||
{{ product.title }}
|
||||
{% endfor %}
|
||||
```
|
||||
|
||||
#### tablerow
|
||||
|
||||
Creates HTML table rows:
|
||||
|
||||
```liquid
|
||||
{% tablerow product in collection.products cols: 3 %}
|
||||
{{ product.title }}
|
||||
{% endtablerow %}
|
||||
|
||||
{# Output: #}
|
||||
<table>
|
||||
<tr class="row1">
|
||||
<td class="col1">Product 1</td>
|
||||
<td class="col2">Product 2</td>
|
||||
<td class="col3">Product 3</td>
|
||||
</tr>
|
||||
<tr class="row2">
|
||||
<td class="col1">Product 4</td>
|
||||
...
|
||||
</tr>
|
||||
</table>
|
||||
```
|
||||
|
||||
**tablerow object:**
|
||||
|
||||
```liquid
|
||||
{% tablerow product in products cols: 3 limit: 12 %}
|
||||
{{ tablerow.col }} {# Current column (1-based) #}
|
||||
{{ tablerow.col0 }} {# Current column (0-based) #}
|
||||
{{ tablerow.row }} {# Current row (1-based) #}
|
||||
{{ tablerow.index }} {# Item index (1-based) #}
|
||||
{{ tablerow.first }} {# true on first item #}
|
||||
{{ tablerow.last }} {# true on last item #}
|
||||
{{ tablerow.col_first }} {# true on first column #}
|
||||
{{ tablerow.col_last }} {# true on last column #}
|
||||
{% endtablerow %}
|
||||
```
|
||||
|
||||
#### paginate
|
||||
|
||||
For paginating large collections:
|
||||
|
||||
```liquid
|
||||
{% paginate collection.products by 12 %}
|
||||
|
||||
{% for product in paginate.collection.products %}
|
||||
{% render 'product-card', product: product %}
|
||||
{% endfor %}
|
||||
|
||||
{# Pagination controls #}
|
||||
{% if paginate.pages > 1 %}
|
||||
{{ paginate | default_pagination }}
|
||||
{% endif %}
|
||||
|
||||
{% endpaginate %}
|
||||
```
|
||||
|
||||
**paginate object:**
|
||||
|
||||
```liquid
|
||||
{{ paginate.current_page }} {# Current page number #}
|
||||
{{ paginate.pages }} {# Total pages #}
|
||||
{{ paginate.items }} {# Total items #}
|
||||
{{ paginate.page_size }} {# Items per page #}
|
||||
|
||||
{{ paginate.previous.url }} {# Previous page URL (if exists) #}
|
||||
{{ paginate.previous.title }} {# Previous page title #}
|
||||
{{ paginate.previous.is_link }} {# Boolean #}
|
||||
|
||||
{{ paginate.next.url }} {# Next page URL (if exists) #}
|
||||
{{ paginate.next.title }} {# Next page title #}
|
||||
{{ paginate.next.is_link }} {# Boolean #}
|
||||
|
||||
{{ paginate.parts }} {# Array of page links #}
|
||||
```
|
||||
|
||||
**Custom pagination:**
|
||||
|
||||
```liquid
|
||||
{% paginate collection.products by 20 %}
|
||||
|
||||
<div class="pagination">
|
||||
{% if paginate.previous %}
|
||||
<a href="{{ paginate.previous.url }}">← Previous</a>
|
||||
{% endif %}
|
||||
|
||||
{% for part in paginate.parts %}
|
||||
{% if part.is_link %}
|
||||
<a href="{{ part.url }}">{{ part.title }}</a>
|
||||
{% else %}
|
||||
<span class="current">{{ part.title }}</span>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
{% if paginate.next %}
|
||||
<a href="{{ paginate.next.url }}">Next →</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
{% endpaginate %}
|
||||
```
|
||||
|
||||
### Variable Assignment
|
||||
|
||||
#### assign
|
||||
|
||||
Single-line variable assignment:
|
||||
|
||||
```liquid
|
||||
{% assign sale_price = product.price | times: 0.8 %}
|
||||
{% assign is_available = product.available %}
|
||||
{% assign product_count = collection.products.size %}
|
||||
{% assign full_name = customer.first_name | append: ' ' | append: customer.last_name %}
|
||||
```
|
||||
|
||||
#### capture
|
||||
|
||||
Multi-line content capture:
|
||||
|
||||
```liquid
|
||||
{% capture product_title %}
|
||||
{{ collection.title }} - {{ product.title }}
|
||||
{% endcapture %}
|
||||
|
||||
{{ product_title }} {# "Summer Sale - Blue T-Shirt" #}
|
||||
|
||||
{% capture greeting %}
|
||||
<h1>Welcome, {{ customer.name }}!</h1>
|
||||
<p>You have {{ customer.orders_count }} orders.</p>
|
||||
{% endcapture %}
|
||||
|
||||
{{ greeting }}
|
||||
```
|
||||
|
||||
#### liquid (multi-statement)
|
||||
|
||||
Cleaner syntax for multiple statements:
|
||||
|
||||
```liquid
|
||||
{% liquid
|
||||
assign product_type = product.type
|
||||
assign is_on_sale = product.on_sale
|
||||
assign sale_percentage = product.discount_percent
|
||||
|
||||
if is_on_sale
|
||||
assign status = 'SALE'
|
||||
else
|
||||
assign status = 'REGULAR'
|
||||
endif
|
||||
|
||||
echo status
|
||||
%}
|
||||
```
|
||||
|
||||
### Template Inclusion
|
||||
|
||||
#### render
|
||||
|
||||
Isolated scope (preferred method):
|
||||
|
||||
```liquid
|
||||
{# Basic usage #}
|
||||
{% render 'product-card', product: product %}
|
||||
|
||||
{# Multiple parameters #}
|
||||
{% render 'product-card',
|
||||
product: product,
|
||||
show_price: true,
|
||||
show_vendor: false,
|
||||
css_class: 'featured'
|
||||
%}
|
||||
|
||||
{# Render for each item #}
|
||||
{% render 'product-card' for collection.products as item %}
|
||||
|
||||
{# Pass arrays #}
|
||||
{% render 'gallery', images: product.images %}
|
||||
```
|
||||
|
||||
**Inside product-card.liquid:**
|
||||
|
||||
```liquid
|
||||
{# Only has access to passed parameters #}
|
||||
<div class="product {% if css_class %}{{ css_class }}{% endif %}">
|
||||
<h3>{{ product.title }}</h3>
|
||||
|
||||
{% if show_price %}
|
||||
<p>{{ product.price | money }}</p>
|
||||
{% endif %}
|
||||
|
||||
{% if show_vendor %}
|
||||
<p>{{ product.vendor }}</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
```
|
||||
|
||||
#### include
|
||||
|
||||
Shared scope (legacy, avoid in new code):
|
||||
|
||||
```liquid
|
||||
{% include 'product-details' %}
|
||||
|
||||
{# Can access all parent template variables #}
|
||||
{# Harder to debug and reason about #}
|
||||
```
|
||||
|
||||
#### section
|
||||
|
||||
Load dynamic sections:
|
||||
|
||||
```liquid
|
||||
{% section 'featured-product' %}
|
||||
{% section 'newsletter-signup' %}
|
||||
```
|
||||
|
||||
### Utility Tags
|
||||
|
||||
#### comment
|
||||
|
||||
Multi-line comments:
|
||||
|
||||
```liquid
|
||||
{% comment %}
|
||||
This entire block is ignored
|
||||
by the Liquid renderer.
|
||||
Use for documentation.
|
||||
{% endcomment %}
|
||||
|
||||
{# Single-line comment #}
|
||||
```
|
||||
|
||||
#### echo
|
||||
|
||||
Output shorthand (alternative to `{{ }}`):
|
||||
|
||||
```liquid
|
||||
{% echo product.title %}
|
||||
{# Equivalent to: {{ product.title }} #}
|
||||
```
|
||||
|
||||
#### raw
|
||||
|
||||
Output Liquid code without processing:
|
||||
|
||||
```liquid
|
||||
{% raw %}
|
||||
{{ This will be output as-is }}
|
||||
{% Liquid tags won't be processed %}
|
||||
{% endraw %}
|
||||
```
|
||||
|
||||
Useful for documentation or code examples.
|
||||
|
||||
## Whitespace Control
|
||||
|
||||
Strip whitespace using hyphens:
|
||||
|
||||
```liquid
|
||||
{%- if condition -%}
|
||||
Content (whitespace stripped on both sides)
|
||||
{%- endif -%}
|
||||
|
||||
{{ "hello" -}}world
|
||||
{# Output: helloworld (no space) #}
|
||||
|
||||
{{- product.title }}
|
||||
{# Strips whitespace before output #}
|
||||
|
||||
{{ product.title -}}
|
||||
{# Strips whitespace after output #}
|
||||
```
|
||||
|
||||
**Example:**
|
||||
|
||||
```liquid
|
||||
{# Without whitespace control: #}
|
||||
{% for item in array %}
|
||||
{{ item }}
|
||||
{% endfor %}
|
||||
|
||||
{# Output has newlines and indentation #}
|
||||
|
||||
{# With whitespace control: #}
|
||||
{%- for item in array -%}
|
||||
{{ item }}
|
||||
{%- endfor -%}
|
||||
|
||||
{# Output is compact #}
|
||||
```
|
||||
|
||||
## Operator Precedence
|
||||
|
||||
**Order of evaluation (right-to-left):**
|
||||
|
||||
```liquid
|
||||
{% if true or false and false %}
|
||||
{# Evaluates as: true or (false and false) = true #}
|
||||
{% endif %}
|
||||
```
|
||||
|
||||
**IMPORTANT:** No parentheses support in Liquid. Break complex conditions into variables:
|
||||
|
||||
```liquid
|
||||
{# ❌ DOESN'T WORK: #}
|
||||
{% if (x > 5 and y < 10) or z == 0 %}
|
||||
|
||||
{# ✅ WORKS: #}
|
||||
{% assign condition1 = false %}
|
||||
{% if x > 5 and y < 10 %}
|
||||
{% assign condition1 = true %}
|
||||
{% endif %}
|
||||
|
||||
{% if condition1 or z == 0 %}
|
||||
{# Logic here #}
|
||||
{% endif %}
|
||||
```
|
||||
|
||||
## Performance Tips
|
||||
|
||||
1. **Cache repeated calculations:**
|
||||
|
||||
```liquid
|
||||
{# ❌ Inefficient: #}
|
||||
{% for i in (1..10) %}
|
||||
{{ collection.products.size }} {# Calculated 10 times #}
|
||||
{% endfor %}
|
||||
|
||||
{# ✅ Efficient: #}
|
||||
{% assign product_count = collection.products.size %}
|
||||
{% for i in (1..10) %}
|
||||
{{ product_count }}
|
||||
{% endfor %}
|
||||
```
|
||||
|
||||
2. **Use `limit` and `offset` instead of iterating full arrays:**
|
||||
|
||||
```liquid
|
||||
{# ❌ Inefficient: #}
|
||||
{% for product in collection.products %}
|
||||
{% if forloop.index <= 5 %}
|
||||
{{ product.title }}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
{# ✅ Efficient: #}
|
||||
{% for product in collection.products limit: 5 %}
|
||||
{{ product.title }}
|
||||
{% endfor %}
|
||||
```
|
||||
|
||||
3. **Prefer `render` over `include`** for better performance and variable scoping
|
||||
|
||||
4. **Use `liquid` tag** for cleaner multi-statement blocks
|
||||
|
||||
## Common Gotchas
|
||||
|
||||
1. **No parentheses in conditions** - Use variables instead
|
||||
2. **Right-to-left evaluation** - Be careful with operator precedence
|
||||
3. **String concatenation** - Use `append` filter or `capture` tag
|
||||
4. **Array/object mutation** - Not possible; create new variables
|
||||
5. **Integer division** - `{{ 5 | divided_by: 2 }}` returns `2`, not `2.5`
|
||||
6. **Truthy/falsy values:**
|
||||
- `false` and `nil` are falsy
|
||||
- Everything else (including `0`, `""`, `[]`) is truthy
|
||||
|
||||
## Debugging Tips
|
||||
|
||||
1. **Output variable types:**
|
||||
|
||||
```liquid
|
||||
{{ product | json }} {# Output entire object as JSON #}
|
||||
{{ product.class }} {# Output object type #}
|
||||
{{ variable.size }} {# Check array/string length #}
|
||||
```
|
||||
|
||||
2. **Check for nil/existence:**
|
||||
|
||||
```liquid
|
||||
{% if product.metafield %}
|
||||
Metafield exists
|
||||
{% else %}
|
||||
Metafield is nil
|
||||
{% endif %}
|
||||
```
|
||||
|
||||
3. **Use default filter for safety:**
|
||||
|
||||
```liquid
|
||||
{{ product.metafield.value | default: "Not set" }}
|
||||
```
|
||||
|
||||
4. **Enable theme preview console** to see Liquid errors in real-time
|
||||
Reference in New Issue
Block a user