@augeo/smelt 1.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (152) hide show
  1. package/.claude/settings.json +11 -0
  2. package/.github/workflows/verify.yml +64 -0
  3. package/.gitmodules +3 -0
  4. package/.prettierignore +25 -0
  5. package/.prettierrc.cjs +9 -0
  6. package/.zed/settings.json +21 -0
  7. package/AGENTS.md +232 -0
  8. package/LICENSE +21 -0
  9. package/README.md +266 -0
  10. package/biome.json +58 -0
  11. package/dist/cli.d.mts +1 -0
  12. package/dist/cli.mjs +350 -0
  13. package/dist/schema.d.mts +265 -0
  14. package/dist/schema.mjs +21 -0
  15. package/docs/TESTING.md +293 -0
  16. package/docs/assets-plan.md +197 -0
  17. package/docs/build-spec.md +466 -0
  18. package/docs/library-conversion-plan.md +419 -0
  19. package/example/.gitattributes +7 -0
  20. package/example/.shopifyignore +28 -0
  21. package/example/.theme-check.yml +7 -0
  22. package/example/blocks/_built--sections--hero--blocks--feature.liquid +52 -0
  23. package/example/config/settings_schema.json +10 -0
  24. package/example/layout/theme.liquid +25 -0
  25. package/example/locales/en.default.json +1 -0
  26. package/example/package-lock.json +51 -0
  27. package/example/package.json +20 -0
  28. package/example/sections/built--sections--hero.liquid +83 -0
  29. package/example/snippets/built--components--button.liquid +38 -0
  30. package/example/snippets/built--components--card.liquid +33 -0
  31. package/example/src/components/button/button.css +13 -0
  32. package/example/src/components/card/card.css +16 -0
  33. package/example/src/components/card/card.liquid +9 -0
  34. package/example/src/sections/hero/blocks/feature/feature.css +11 -0
  35. package/example/src/sections/hero/blocks/feature/feature.liquid +9 -0
  36. package/example/src/sections/hero/blocks/feature/feature.schema.ts +14 -0
  37. package/example/src/sections/hero/hero.css +15 -0
  38. package/example/src/sections/hero/hero.liquid +16 -0
  39. package/example/src/sections/hero/hero.schema.ts +26 -0
  40. package/example/src/sections/hero/hero.test.ts +43 -0
  41. package/example/src/utilities/labels.ts +5 -0
  42. package/example/templates/index.liquid +1 -0
  43. package/example/tsconfig.json +10 -0
  44. package/example/vitest.config.ts +6 -0
  45. package/lib/build/build.test.ts +475 -0
  46. package/lib/build/build.ts +314 -0
  47. package/lib/build/command.ts +27 -0
  48. package/lib/build/index.ts +1 -0
  49. package/lib/cli.ts +17 -0
  50. package/lib/dev/command.ts +25 -0
  51. package/lib/dev/index.ts +1 -0
  52. package/lib/dev/watch.ts +52 -0
  53. package/lib/resolver.test.ts +275 -0
  54. package/lib/resolver.ts +156 -0
  55. package/lib/schema.ts +37 -0
  56. package/package.json +59 -0
  57. package/scripts/codegen-schema.ts +66 -0
  58. package/src/components/button/button.css +13 -0
  59. package/src/components/button/button.liquid +5 -0
  60. package/src/components/button/button.ts +5 -0
  61. package/src/tsconfig.json +10 -0
  62. package/tests/example.test.ts +101 -0
  63. package/tsconfig.json +20 -0
  64. package/tsdown.config.ts +14 -0
  65. package/vendor/theme-liquid-docs/.gitattributes +10 -0
  66. package/vendor/theme-liquid-docs/.github/CODEOWNERS +1 -0
  67. package/vendor/theme-liquid-docs/.github/CODE_OF_CONDUCT.md +73 -0
  68. package/vendor/theme-liquid-docs/.github/ISSUE_TEMPLATE/bug_report.md +17 -0
  69. package/vendor/theme-liquid-docs/.github/ISSUE_TEMPLATE/feature_request.md +17 -0
  70. package/vendor/theme-liquid-docs/.github/dependabot.yaml +6 -0
  71. package/vendor/theme-liquid-docs/.github/workflows/ci.yml +33 -0
  72. package/vendor/theme-liquid-docs/.github/workflows/cla.yml +27 -0
  73. package/vendor/theme-liquid-docs/.github/workflows/shopify-dev-preview-automation.yml +86 -0
  74. package/vendor/theme-liquid-docs/.github/workflows/update-latest.yml +56 -0
  75. package/vendor/theme-liquid-docs/.prettierrc.json +16 -0
  76. package/vendor/theme-liquid-docs/.vscode/settings.json +28 -0
  77. package/vendor/theme-liquid-docs/LICENSE.md +7 -0
  78. package/vendor/theme-liquid-docs/README.md +48 -0
  79. package/vendor/theme-liquid-docs/ai/claude/CLAUDE.md +1485 -0
  80. package/vendor/theme-liquid-docs/ai/cursor/rules/assets.mdc +15 -0
  81. package/vendor/theme-liquid-docs/ai/cursor/rules/blocks.mdc +339 -0
  82. package/vendor/theme-liquid-docs/ai/cursor/rules/examples/block-example-group.mdc +103 -0
  83. package/vendor/theme-liquid-docs/ai/cursor/rules/examples/block-example-text.mdc +59 -0
  84. package/vendor/theme-liquid-docs/ai/cursor/rules/examples/section-example.mdc +61 -0
  85. package/vendor/theme-liquid-docs/ai/cursor/rules/examples/snippet-example.mdc +72 -0
  86. package/vendor/theme-liquid-docs/ai/cursor/rules/liquid.mdc +837 -0
  87. package/vendor/theme-liquid-docs/ai/cursor/rules/locales.mdc +100 -0
  88. package/vendor/theme-liquid-docs/ai/cursor/rules/localization.mdc +67 -0
  89. package/vendor/theme-liquid-docs/ai/cursor/rules/mcp.mdc +2 -0
  90. package/vendor/theme-liquid-docs/ai/cursor/rules/schemas.mdc +184 -0
  91. package/vendor/theme-liquid-docs/ai/cursor/rules/sections.mdc +84 -0
  92. package/vendor/theme-liquid-docs/ai/cursor/rules/settings-schema.mdc +51 -0
  93. package/vendor/theme-liquid-docs/ai/cursor/rules/snippets.mdc +119 -0
  94. package/vendor/theme-liquid-docs/ai/github/copilot-instructions.md +1485 -0
  95. package/vendor/theme-liquid-docs/ai/liquid.mdc +638 -0
  96. package/vendor/theme-liquid-docs/data/filters.json +6148 -0
  97. package/vendor/theme-liquid-docs/data/latest.json +2 -0
  98. package/vendor/theme-liquid-docs/data/objects.json +20594 -0
  99. package/vendor/theme-liquid-docs/data/shopify_system_translations.json +2586 -0
  100. package/vendor/theme-liquid-docs/data/tags.json +1276 -0
  101. package/vendor/theme-liquid-docs/package.json +20 -0
  102. package/vendor/theme-liquid-docs/schemas/manifest_schema.json +31 -0
  103. package/vendor/theme-liquid-docs/schemas/manifest_theme.json +19 -0
  104. package/vendor/theme-liquid-docs/schemas/manifest_theme_app_extension.json +10 -0
  105. package/vendor/theme-liquid-docs/schemas/theme/app_block_entry.json +13 -0
  106. package/vendor/theme-liquid-docs/schemas/theme/default_setting_values.json +24 -0
  107. package/vendor/theme-liquid-docs/schemas/theme/local_block_entry.json +25 -0
  108. package/vendor/theme-liquid-docs/schemas/theme/preset.json +72 -0
  109. package/vendor/theme-liquid-docs/schemas/theme/preset_blocks.json +91 -0
  110. package/vendor/theme-liquid-docs/schemas/theme/section.json +208 -0
  111. package/vendor/theme-liquid-docs/schemas/theme/setting.json +1413 -0
  112. package/vendor/theme-liquid-docs/schemas/theme/settings.json +10 -0
  113. package/vendor/theme-liquid-docs/schemas/theme/targetted_block_entry.json +15 -0
  114. package/vendor/theme-liquid-docs/schemas/theme/theme_block.json +91 -0
  115. package/vendor/theme-liquid-docs/schemas/theme/theme_block_entry.json +14 -0
  116. package/vendor/theme-liquid-docs/schemas/theme/theme_settings.json +83 -0
  117. package/vendor/theme-liquid-docs/schemas/theme/translations.json +63 -0
  118. package/vendor/theme-liquid-docs/schemas/update/update_extension_schema_v1.json +186 -0
  119. package/vendor/theme-liquid-docs/tests/fixtures/section-nested-blocks.json +18 -0
  120. package/vendor/theme-liquid-docs/tests/fixtures/section-schema-1.json +90 -0
  121. package/vendor/theme-liquid-docs/tests/fixtures/section-schema-2.json +201 -0
  122. package/vendor/theme-liquid-docs/tests/fixtures/section-schema-3.json +29 -0
  123. package/vendor/theme-liquid-docs/tests/fixtures/section-schema-4.json +315 -0
  124. package/vendor/theme-liquid-docs/tests/fixtures/section-schema-5.json +114 -0
  125. package/vendor/theme-liquid-docs/tests/fixtures/section-schema-6.json +63 -0
  126. package/vendor/theme-liquid-docs/tests/fixtures/section-schema-conditional-settings.json +145 -0
  127. package/vendor/theme-liquid-docs/tests/fixtures/section-schema-preset-blocks-as-hash.json +60 -0
  128. package/vendor/theme-liquid-docs/tests/fixtures/section-schema-static-block-preset.json +76 -0
  129. package/vendor/theme-liquid-docs/tests/fixtures/section-settings.json +34 -0
  130. package/vendor/theme-liquid-docs/tests/fixtures/theme-block-1.json +234 -0
  131. package/vendor/theme-liquid-docs/tests/fixtures/theme-block-2.json +253 -0
  132. package/vendor/theme-liquid-docs/tests/fixtures/theme-block-basics.json +48 -0
  133. package/vendor/theme-liquid-docs/tests/fixtures/theme-block-conditional-settings.json +202 -0
  134. package/vendor/theme-liquid-docs/tests/fixtures/theme-block-presets-as-hash.json +50 -0
  135. package/vendor/theme-liquid-docs/tests/fixtures/theme-block-settings.json +34 -0
  136. package/vendor/theme-liquid-docs/tests/fixtures/theme-settings-all-settings.json +313 -0
  137. package/vendor/theme-liquid-docs/tests/fixtures/theme-settings-dawn.json +1469 -0
  138. package/vendor/theme-liquid-docs/tests/fixtures/theme-settings-metadata.json +10 -0
  139. package/vendor/theme-liquid-docs/tests/fixtures/translations-1.json +14 -0
  140. package/vendor/theme-liquid-docs/tests/section.spec.ts +367 -0
  141. package/vendor/theme-liquid-docs/tests/test-constants.ts +58 -0
  142. package/vendor/theme-liquid-docs/tests/test-helpers.ts +104 -0
  143. package/vendor/theme-liquid-docs/tests/theme-settings/color_palette.spec.ts +184 -0
  144. package/vendor/theme-liquid-docs/tests/theme-settings/color_scheme_group.spec.ts +143 -0
  145. package/vendor/theme-liquid-docs/tests/theme-settings/general.spec.ts +192 -0
  146. package/vendor/theme-liquid-docs/tests/theme-settings/metaobject.spec.ts +94 -0
  147. package/vendor/theme-liquid-docs/tests/theme-settings/resource_list.spec.ts +58 -0
  148. package/vendor/theme-liquid-docs/tests/theme-settings/theme-metadata.spec.ts +59 -0
  149. package/vendor/theme-liquid-docs/tests/theme_block.spec.ts +266 -0
  150. package/vendor/theme-liquid-docs/tests/translations_schema.spec.ts +31 -0
  151. package/vendor/theme-liquid-docs/yarn.lock +543 -0
  152. package/vitest.config.ts +7 -0
@@ -0,0 +1,837 @@
1
+ ---
2
+ description: Valid Liquid syntax reference (including filters, tags, and objects) for Shopify themes
3
+ globs: *.liquid
4
+ alwaysApply: false
5
+ ---
6
+ # Liquid syntax standards
7
+
8
+ ## Liquid
9
+
10
+ ### Liquid delimiters
11
+
12
+ - **`{{ ... }}`**: Output – prints a value.
13
+ - **`{{- ... -}}`**: Output, trims whitespace around the value.
14
+ - **`{% ... %}`**: Logic/control tag (if, for, assign, etc.), does not print anything, no whitespace trim.
15
+ - **`{%- ... -%}`**: Logic/control tag, trims whitespace around the tag.
16
+
17
+ **Tip:**
18
+ Adding a dash (`-`) after `{%`/`{{` or before `%}`/`}}` trims spaces or newlines next to the tag.
19
+
20
+ **Examples:**
21
+ - `{{- product.title -}}` → print value, remove surrounding spaces or lines.
22
+ - `{%- if available -%}In stock{%- endif -%}` → logic, removes extra spaces/lines.
23
+
24
+ ### Liquid operators
25
+
26
+ **Comparison operators:**
27
+ - ==
28
+ - !=
29
+ - >
30
+ - <
31
+ - >=
32
+ - <=
33
+
34
+ **Logical operators:**
35
+ - `or`
36
+ - `and`
37
+ - `contains` - checks if a string contains a substring, or if an array contains a string
38
+
39
+ #### Comparison and comparison tags
40
+
41
+ **Key condition principles:**
42
+ - For simplificity, ALWAYS use nested `if` conditions when the logic requires more than one logical operator
43
+ - Parentheses are not supported in Liquid
44
+ - Ternary conditionals are not supported in Liquid, so always use `{% if cond %}`
45
+
46
+ **Basic comparison example:**
47
+ ```liquid
48
+ {% if product.title == "Awesome Shoes" %}
49
+ These shoes are awesome!
50
+ {% endif %}
51
+ ```
52
+
53
+ **Multiple Conditions:**
54
+ ```liquid
55
+ {% if product.type == "Shirt" or product.type == "Shoes" %}
56
+ This is a shirt or a pair of shoes.
57
+ {% endif %}
58
+ ```
59
+
60
+ **Contains Usage:**
61
+ - For strings: `{% if product.title contains "Pack" %}`
62
+ - For arrays: `{% if product.tags contains "Hello" %}`
63
+ - Note: `contains` only works with strings, not objects in arrays
64
+
65
+ **{% elsif %} (used inside if/unless only)**
66
+ ```liquid
67
+ {% if a %}
68
+ ...
69
+ {% elsif b %}
70
+ ...
71
+ {% endif %}
72
+ ```
73
+
74
+ **{% unless %}**
75
+ ```liquid
76
+ {% unless condition %}
77
+ ...
78
+ {% endunless %}
79
+ ```
80
+
81
+ **{% case %}**
82
+ ```liquid
83
+ {% case variable %}
84
+ {% when 'a' %}
85
+ a
86
+ {% when 'b' %}
87
+ b
88
+ {% else %}
89
+ other
90
+ {% endcase %}
91
+ ```
92
+
93
+ **{% else %} (used inside if, unless, case, or for)**
94
+ ```liquid
95
+ {% if product.available %}
96
+ In stock
97
+ {% else %}
98
+ Sold out
99
+ {% endif %}
100
+ ```
101
+ _or inside a for loop:_
102
+ ```liquid
103
+ {% for item in collection.products %}
104
+ {{ item.title }}
105
+ {% else %}
106
+ No products found.
107
+ {% endfor %}
108
+ ```
109
+
110
+ #### Variables and variable tags
111
+
112
+ ```liquid
113
+ {% assign my_variable = 'value' %}
114
+
115
+ {% capture my_variable %}
116
+ Contents of variable
117
+ {% endcapture %}
118
+
119
+ {% increment counter %}
120
+ {% decrement counter %}
121
+ ```
122
+
123
+ ### Liquid filters
124
+
125
+ You can chain filters in Liquid, passing the result of one filter as the input to the next.
126
+
127
+ See these filters:
128
+
129
+ - `upcase`: `{{ string | upcase }}` returns a **string**
130
+ - `split`: `{{ string | split: string }}` returns an **array** (as we may notice in the docs, `split` receives a string as its argument)
131
+ - `last`: `{{ array | last }}` returns **untyped**
132
+
133
+ Each filter can pass its return value to the next filter as long as the types match.
134
+
135
+ For example, `upcase` returns a string, which is suitable input for `split`, which then produces an array for `last` to use.
136
+
137
+ Here's how the filters are executed step by step to eventually return `"WORLD"`:
138
+
139
+ ```liquid
140
+ {{ "hello world" | upcase | split: " " | last }}
141
+ ```
142
+
143
+ - First, `"hello world"` is converted to uppercase: `"HELLO WORLD"`, which is a string
144
+ - Next, `split` can act on strings, so it splits the value by space into an array: `["HELLO", "WORLD"]`
145
+ - Finally, the `last` filter work with array, so `"WORLD"` is returned
146
+
147
+ #### Array
148
+ - `compact`: `{{ array | compact }}` returns `array`
149
+ - `concat`: `{{ array | concat: array }}` returns `array`
150
+ - `find`: `{{ array | find: string, string }}` returns `untyped`
151
+ - `find_index`: `{{ array | find_index: string, string }}` returns `number`
152
+ - `first`: `{{ array | first }}` returns `untyped`
153
+ - `has`: `{{ array | has: string, string }}` returns `boolean`
154
+ - `join`: `{{ array | join }}` returns `string`
155
+ - `last`: `{{ array | last }}` returns `untyped`
156
+ - `map`: `{{ array | map: string }}` returns `array`
157
+ - `reject`: `{{ array | reject: string, string }}` returns `array`
158
+ - `reverse`: `{{ array | reverse }}` returns `array`
159
+ - `size`: `{{ variable | size }}` returns `number`
160
+ - `sort`: `{{ array | sort }}` returns `array`
161
+ - `sort_natural`: `{{ array | sort_natural }}` returns `array`
162
+ - `sum`: `{{ array | sum }}` returns `number`
163
+ - `uniq`: `{{ array | uniq }}` returns `array`
164
+ - `where`: `{{ array | where: string, string }}` returns `array`
165
+
166
+ #### Cart
167
+ - `item_count_for_variant`: `{{ cart | item_count_for_variant: {variant_id} }}` returns `number`
168
+ - `line_items_for`: `{{ cart | line_items_for: object }}` returns `array`
169
+
170
+ #### Collection
171
+ - `link_to_type`: `{{ string | link_to_type }}` returns `string`
172
+ - `link_to_vendor`: `{{ string | link_to_vendor }}` returns `string`
173
+ - `sort_by`: `{{ string | sort_by: string }}` returns `string`
174
+ - `url_for_type`: `{{ string | url_for_type }}` returns `string`
175
+ - `url_for_vendor`: `{{ string | url_for_vendor }}` returns `string`
176
+ - `within`: `{{ string | within: collection }}` returns `string`
177
+ - `highlight_active_tag`: `{{ string | highlight_active_tag }}` returns `string`
178
+
179
+ #### Color
180
+ - `brightness_difference`: `{{ string | brightness_difference: string }}` returns `number`
181
+ - `color_brightness`: `{{ string | color_brightness }}` returns `number`
182
+ - `color_contrast`: `{{ string | color_contrast: string }}` returns `number`
183
+ - `color_darken`: `{{ string | color_darken: number }}` returns `string`
184
+ - `color_desaturate`: `{{ string | color_desaturate: number }}` returns `string`
185
+ - `color_difference`: `{{ string | color_difference: string }}` returns `number`
186
+ - `color_extract`: `{{ string | color_extract: string }}` returns `number`
187
+ - `color_lighten`: `{{ string | color_lighten: number }}` returns `string`
188
+ - `color_mix`: `{{ string | color_mix: string, number }}` returns `string`
189
+ - `color_modify`: `{{ string | color_modify: string, number }}` returns `string`
190
+ - `color_saturate`: `{{ string | color_saturate: number }}` returns `string`
191
+ - `color_to_hex`: `{{ string | color_to_hex }}` returns `string`
192
+ - `color_to_hsl`: `{{ string | color_to_hsl }}` returns `string`
193
+ - `color_to_oklch`: `{{ string | color_to_oklch }}` returns `string`
194
+ - `color_to_rgb`: `{{ string | color_to_rgb }}` returns `string`
195
+ - `hex_to_rgba`: `{{ string | hex_to_rgba }}` returns `string`
196
+
197
+ #### Customer
198
+ - `customer_login_link`: `{{ string | customer_login_link }}` returns `string`
199
+ - `customer_logout_link`: `{{ string | customer_logout_link }}` returns `string`
200
+ - `customer_register_link`: `{{ string | customer_register_link }}` returns `string`
201
+ - `avatar`: `{{ customer | avatar }}` returns `string`
202
+ - `login_button`: `{{ shop | login_button }}` returns `string`
203
+
204
+ #### Date
205
+ - `date`: `{{ date | date: string }}` returns `string`
206
+
207
+ #### Default
208
+ - `default_errors`: `{{ string | default_errors }}` returns `string`
209
+ - `default`: `{{ variable | default: variable }}` returns `untyped`
210
+ - `default_pagination`: `{{ paginate | default_pagination }}` returns `string`
211
+
212
+ #### Font
213
+ - `font_face`: `{{ font | font_face }}` returns `string`
214
+ - `font_modify`: `{{ font | font_modify: string, string }}` returns `font`
215
+ - `font_url`: `{{ font | font_url }}` returns `string`
216
+
217
+ #### Format
218
+ - `date`: `{{ string | date: string }}` returns `string`
219
+ - `json`: `{{ variable | json }}` returns `string`
220
+ - `structured_data`: `{{ variable | structured_data }}` returns `string`
221
+ - `unit_price_with_measurement`: `{{ number | unit_price_with_measurement: unit_price_measurement }}` returns `string`
222
+ - `weight_with_unit`: `{{ number | weight_with_unit }}` returns `string`
223
+
224
+ #### Hosted_file
225
+ - `asset_img_url`: `{{ string | asset_img_url }}` returns `string`
226
+ - `asset_url`: `{{ string | asset_url }}` returns `string`
227
+ - `file_img_url`: `{{ string | file_img_url }}` returns `string`
228
+ - `file_url`: `{{ string | file_url }}` returns `string`
229
+ - `global_asset_url`: `{{ string | global_asset_url }}` returns `string`
230
+ - `shopify_asset_url`: `{{ string | shopify_asset_url }}` returns `string`
231
+
232
+ #### Html
233
+ - `time_tag`: `{{ string | time_tag: string }}` returns `string`
234
+ - `inline_asset_content`: `{{ asset_name | inline_asset_content }}` returns `string`
235
+ - `highlight`: `{{ string | highlight: string }}` returns `string`
236
+ - `link_to`: `{{ string | link_to: string }}` returns `string`
237
+ - `placeholder_svg_tag`: `{{ string | placeholder_svg_tag }}` returns `string`
238
+ - `preload_tag`: `{{ string | preload_tag: as: string }}` returns `string`
239
+ - `script_tag`: `{{ string | script_tag }}` returns `string`
240
+ - `stylesheet_tag`: `{{ string | stylesheet_tag }}` returns `string`
241
+
242
+ #### Localization
243
+ - `currency_selector`: `{{ form | currency_selector }}` returns `string`
244
+ - `translate`: `{{ string | t }}` returns `string`
245
+ - `format_address`: `{{ address | format_address }}` returns `string`
246
+
247
+ #### Math
248
+ - `abs`: `{{ number | abs }}` returns `number`
249
+ - `at_least`: `{{ number | at_least }}` returns `number`
250
+ - `at_most`: `{{ number | at_most }}` returns `number`
251
+ - `ceil`: `{{ number | ceil }}` returns `number`
252
+ - `divided_by`: `{{ number | divided_by: number }}` returns `number`
253
+ - `floor`: `{{ number | floor }}` returns `number`
254
+ - `minus`: `{{ number | minus: number }}` returns `number`
255
+ - `modulo`: `{{ number | modulo: number }}` returns `number`
256
+ - `plus`: `{{ number | plus: number }}` returns `number`
257
+ - `round`: `{{ number | round }}` returns `number`
258
+ - `times`: `{{ number | times: number }}` returns `number`
259
+
260
+ #### Media
261
+ - `external_video_tag`: `{{ variable | external_video_tag }}` returns `string`
262
+ - `external_video_url`: `{{ media | external_video_url: attribute: string }}` returns `string`
263
+ - `image_tag`: `{{ string | image_tag }}` returns `string`
264
+ - `media_tag`: `{{ media | media_tag }}` returns `string`
265
+ - `model_viewer_tag`: `{{ media | model_viewer_tag }}` returns `string`
266
+ - `video_tag`: `{{ media | video_tag }}` returns `string`
267
+ - `article_img_url`: `{{ variable | article_img_url }}` returns `string`
268
+ - `collection_img_url`: `{{ variable | collection_img_url }}` returns `string`
269
+ - `image_url`: `{{ variable | image_url: width: number, height: number }}` returns `string`
270
+ - `img_tag`: `{{ string | img_tag }}` returns `string`
271
+ - `img_url`: `{{ variable | img_url }}` returns `string`
272
+ - `product_img_url`: `{{ variable | product_img_url }}` returns `string`
273
+
274
+ #### Metafield
275
+ - `metafield_tag`: `{{ metafield | metafield_tag }}` returns `string`
276
+ - `metafield_text`: `{{ metafield | metafield_text }}` returns `string`
277
+
278
+ #### Money
279
+ - `money`: `{{ number | money }}` returns `string`
280
+ - `money_with_currency`: `{{ number | money_with_currency }}` returns `string`
281
+ - `money_without_currency`: `{{ number | money_without_currency }}` returns `string`
282
+ - `money_without_trailing_zeros`: `{{ number | money_without_trailing_zeros }}` returns `string`
283
+
284
+ #### Payment
285
+ - `payment_button`: `{{ form | payment_button }}` returns `string`
286
+ - `payment_terms`: `{{ form | payment_terms }}` returns `string`
287
+ - `payment_type_img_url`: `{{ string | payment_type_img_url }}` returns `string`
288
+ - `payment_type_svg_tag`: `{{ string | payment_type_svg_tag }}` returns `string`
289
+
290
+ #### String
291
+ - `blake3`: `{{ string | blake3 }}` returns `string`
292
+ - `hmac_sha1`: `{{ string | hmac_sha1: string }}` returns `string`
293
+ - `hmac_sha256`: `{{ string | hmac_sha256: string }}` returns `string`
294
+ - `md5`: `{{ string | md5 }}` returns `string`
295
+ - `sha1`: `{{ string | sha1: string }}` returns `string`
296
+ - `sha256`: `{{ string | sha256: string }}` returns `string`
297
+ - `append`: `{{ string | append: string }}` returns `string`
298
+ - `base64_decode`: `{{ string | base64_decode }}` returns `string`
299
+ - `base64_encode`: `{{ string | base64_encode }}` returns `string`
300
+ - `base64_url_safe_decode`: `{{ string | base64_url_safe_decode }}` returns `string`
301
+ - `base64_url_safe_encode`: `{{ string | base64_url_safe_encode }}` returns `string`
302
+ - `capitalize`: `{{ string | capitalize }}` returns `string`
303
+ - `downcase`: `{{ string | downcase }}` returns `string`
304
+ - `escape`: `{{ string | escape }}` returns `string`
305
+ - `escape_once`: `{{ string | escape_once }}` returns `string`
306
+ - `lstrip`: `{{ string | lstrip }}` returns `string`
307
+ - `newline_to_br`: `{{ string | newline_to_br }}` returns `string`
308
+ - `prepend`: `{{ string | prepend: string }}` returns `string`
309
+ - `remove`: `{{ string | remove: string }}` returns `string`
310
+ - `remove_first`: `{{ string | remove_first: string }}` returns `string`
311
+ - `remove_last`: `{{ string | remove_last: string }}` returns `string`
312
+ - `replace`: `{{ string | replace: string, string }}` returns `string`
313
+ - `replace_first`: `{{ string | replace_first: string, string }}` returns `string`
314
+ - `replace_last`: `{{ string | replace_last: string, string }}` returns `string`
315
+ - `rstrip`: `{{ string | rstrip }}` returns `string`
316
+ - `slice`: `{{ string | slice }}` returns `string`
317
+ - `split`: `{{ string | split: string }}` returns `array`
318
+ - `strip`: `{{ string | strip }}` returns `string`
319
+ - `strip_html`: `{{ string | strip_html }}` returns `string`
320
+ - `strip_newlines`: `{{ string | strip_newlines }}` returns `string`
321
+ - `truncate`: `{{ string | truncate: number }}` returns `string`
322
+ - `truncatewords`: `{{ string | truncatewords: number }}` returns `string`
323
+ - `upcase`: `{{ string | upcase }}` returns `string`
324
+ - `url_decode`: `{{ string | url_decode }}` returns `string`
325
+ - `url_encode`: `{{ string | url_encode }}` returns `string`
326
+ - `camelize`: `{{ string | camelize }}` returns `string`
327
+ - `handleize`: `{{ string | handleize }}` returns `string`
328
+ - `url_escape`: `{{ string | url_escape }}` returns `string`
329
+ - `url_param_escape`: `{{ string | url_param_escape }}` returns `string`
330
+ - `pluralize`: `{{ number | pluralize: string, string }}` returns `string`
331
+
332
+ #### Tag
333
+ - `link_to_add_tag`: `{{ string | link_to_add_tag }}` returns `string`
334
+ - `link_to_remove_tag`: `{{ string | link_to_remove_tag }}` returns `string`
335
+ - `link_to_tag`: `{{ string | link_to_tag }}` returns `string`
336
+
337
+ ### Liquid objects
338
+
339
+ #### Global objects
340
+ - `collections`
341
+ - `pages`
342
+ - `all_products`
343
+ - `articles`
344
+ - `blogs`
345
+ - `cart`
346
+ - `closest`
347
+ - `content_for_header`
348
+ - `customer`
349
+ - `images`
350
+ - `linklists`
351
+ - `localization`
352
+ - `metaobjects`
353
+ - `request`
354
+ - `routes`
355
+ - `shop`
356
+ - `theme`
357
+ - `settings`
358
+ - `template`
359
+ - `additional_checkout_buttons`
360
+ - `all_country_option_tags`
361
+ - `canonical_url`
362
+ - `content_for_additional_checkout_buttons`
363
+ - `content_for_index`
364
+ - `content_for_layout`
365
+ - `country_option_tags`
366
+ - `current_page`
367
+ - `handle`
368
+ - `page_description`
369
+ - `page_image`
370
+ - `page_title`
371
+ - `powered_by_link`
372
+ - `scripts`
373
+
374
+ #### `/article` page
375
+ - `article`
376
+ - `blog`
377
+
378
+ #### `/blog` page
379
+ - `blog`
380
+ - `current_tags`
381
+
382
+ #### `/cart` page
383
+ - `cart`
384
+
385
+ #### `/checkout` page
386
+ - `checkout`
387
+
388
+ #### `/collection` page
389
+ - `collection`
390
+ - `current_tags`
391
+
392
+ #### `/customers/account` page
393
+ - `customer`
394
+
395
+ #### `/customers/addresses` page
396
+ - `customer`
397
+
398
+ #### `/customers/order` page
399
+ - `customer`
400
+ - `order`
401
+
402
+ #### `/gift_card.liquid` page
403
+ - `gift_card`
404
+ - `recipient`
405
+
406
+ #### `/metaobject` page
407
+ - `metaobject`
408
+
409
+ #### `/page` page
410
+ - `page`
411
+
412
+ #### `/product` page
413
+ - `product`
414
+ - `remote_product`
415
+
416
+ #### `/robots.txt.liquid` page
417
+ - `robots`
418
+
419
+ #### `/search` page
420
+ - `search`
421
+ ### Liquid tags
422
+
423
+
424
+ #### content_for
425
+ The `content_for` tag requires a type parameter to differentiate between rendering a number of theme blocks (`'blocks'`) and a single static block (`'block'`).
426
+
427
+
428
+ Syntax:
429
+ ```
430
+ {% content_for 'blocks' %}
431
+ {% content_for 'block', type: "slide", id: "slide-1" %}
432
+ ```
433
+
434
+ #### form
435
+ Because there are many different form types available in Shopify themes, the `form` tag requires a type. Depending on the
436
+ form type, an additional parameter might be required. You can specify the following form types:
437
+
438
+ - [`activate_customer_password`](https://shopify.dev/docs/api/liquid/tags/form#form-activate_customer_password)
439
+ - [`cart`](https://shopify.dev/docs/api/liquid/tags/form#form-cart)
440
+ - [`contact`](https://shopify.dev/docs/api/liquid/tags/form#form-contact)
441
+ - [`create_customer`](https://shopify.dev/docs/api/liquid/tags/form#form-create_customer)
442
+ - [`currency`](https://shopify.dev/docs/api/liquid/tags/form#form-currency)
443
+ - [`customer`](https://shopify.dev/docs/api/liquid/tags/form#form-customer)
444
+ - [`customer_address`](https://shopify.dev/docs/api/liquid/tags/form#form-customer_address)
445
+ - [`customer_login`](https://shopify.dev/docs/api/liquid/tags/form#form-customer_login)
446
+ - [`guest_login`](https://shopify.dev/docs/api/liquid/tags/form#form-guest_login)
447
+ - [`localization`](https://shopify.dev/docs/api/liquid/tags/form#form-localization)
448
+ - [`new_comment`](https://shopify.dev/docs/api/liquid/tags/form#form-new_comment)
449
+ - [`product`](https://shopify.dev/docs/api/liquid/tags/form#form-product)
450
+ - [`recover_customer_password`](https://shopify.dev/docs/api/liquid/tags/form#form-recover_customer_password)
451
+ - [`reset_customer_password`](https://shopify.dev/docs/api/liquid/tags/form#form-reset_customer_password)
452
+ - [`storefront_password`](https://shopify.dev/docs/api/liquid/tags/form#form-storefront_password)
453
+
454
+
455
+ Syntax:
456
+ ```
457
+ {% form 'form_type' %}
458
+ content
459
+ {% endform %}
460
+ ```
461
+
462
+ #### layout
463
+
464
+ Syntax:
465
+ ```
466
+ {% layout name %}
467
+ ```
468
+
469
+ #### assign
470
+ You can create variables of any [basic type](https://shopify.dev/docs/api/liquid/basics#types), [object](https://shopify.dev/docs/api/liquid/objects), or object property.
471
+
472
+ > Caution:
473
+ > Predefined Liquid objects can be overridden by variables with the same name.
474
+ > To make sure that you can access all Liquid objects, make sure that your variable name doesn't match a predefined object's name.
475
+
476
+
477
+ Syntax:
478
+ ```
479
+ {% assign variable_name = value %}
480
+ ```
481
+
482
+ #### break
483
+
484
+ Syntax:
485
+ ```
486
+ {% break %}
487
+ ```
488
+
489
+ #### capture
490
+ You can create complex strings with Liquid logic and variables.
491
+
492
+ > Caution:
493
+ > Predefined Liquid objects can be overridden by variables with the same name.
494
+ > To make sure that you can access all Liquid objects, make sure that your variable name doesn't match a predefined object's name.
495
+
496
+
497
+ Syntax:
498
+ ```
499
+ {% capture variable %}
500
+ value
501
+ {% endcapture %}
502
+ ```
503
+
504
+ #### case
505
+
506
+ Syntax:
507
+ ```
508
+ {% case variable %}
509
+ {% when first_value %}
510
+ first_expression
511
+ {% when second_value %}
512
+ second_expression
513
+ {% else %}
514
+ third_expression
515
+ {% endcase %}
516
+ ```
517
+
518
+ #### comment
519
+ Any text inside `comment` tags won't be output, and any Liquid code will be parsed, but not executed.
520
+
521
+
522
+ Syntax:
523
+ ```
524
+ {% comment %}
525
+ content
526
+ {% endcomment %}
527
+ ```
528
+
529
+ #### continue
530
+
531
+ Syntax:
532
+ ```
533
+ {% continue %}
534
+ ```
535
+
536
+ #### cycle
537
+ The `cycle` tag must be used inside a `for` loop.
538
+
539
+ > Tip:
540
+ > Use the `cycle` tag to output text in a predictable pattern. For example, to apply odd/even classes to rows in a table.
541
+
542
+
543
+ Syntax:
544
+ ```
545
+ {% cycle string, string, ... %}
546
+ ```
547
+
548
+ #### decrement
549
+ Variables that are declared with `decrement` are unique to the [layout](/themes/architecture/layouts), [template](/themes/architecture/templates),
550
+ or [section](/themes/architecture/sections) file that they're created in. However, the variable is shared across
551
+ [snippets](/themes/architecture/snippets) included in the file.
552
+
553
+ Similarly, variables that are created with `decrement` are independent from those created with [`assign`](https://shopify.dev/docs/api/liquid/tags/assign)
554
+ and [`capture`](https://shopify.dev/docs/api/liquid/tags/capture). However, `decrement` and [`increment`](https://shopify.dev/docs/api/liquid/tags/increment) share
555
+ variables.
556
+
557
+
558
+ Syntax:
559
+ ```
560
+ {% decrement variable_name %}
561
+ ```
562
+
563
+ #### doc
564
+ The `doc` tag allows developers to include documentation within Liquid
565
+ templates. Any content inside `doc` tags is not rendered or outputted.
566
+ Liquid code inside will be parsed but not executed. This facilitates
567
+ tooling support for features like code completion, linting, and inline
568
+ documentation.
569
+
570
+ For detailed documentation syntax and examples, see the
571
+ [`LiquidDoc` reference](https://shopify.dev/docs/storefronts/themes/tools/liquid-doc).
572
+
573
+
574
+ Syntax:
575
+ ```
576
+ {% doc %}
577
+ Renders a message.
578
+
579
+ @param {string} foo - A string value.
580
+ @param {string} [bar] - An optional string value.
581
+
582
+ @example
583
+ {% render 'message', foo: 'Hello', bar: 'World' %}
584
+ {% enddoc %}
585
+ ```
586
+
587
+ #### echo
588
+ Using the `echo` tag is the same as wrapping an expression in curly brackets (`{{` and `}}`). However, unlike the curly
589
+ bracket method, you can use the `echo` tag inside [`liquid` tags](https://shopify.dev/docs/api/liquid/tags/liquid).
590
+
591
+ > Tip:
592
+ > You can use [filters](https://shopify.dev/docs/api/liquid/filters) on expressions inside `echo` tags.
593
+
594
+
595
+ Syntax:
596
+ ```
597
+ {% liquid
598
+ echo expression
599
+ %}
600
+ ```
601
+
602
+ #### for
603
+ You can do a maximum of 50 iterations with a `for` loop. If you need to iterate over more than 50 items, then use the
604
+ [`paginate` tag](https://shopify.dev/docs/api/liquid/tags/paginate) to split the items over multiple pages.
605
+
606
+ > Tip:
607
+ > Every `for` loop has an associated [`forloop` object](https://shopify.dev/docs/api/liquid/objects/forloop) with information about the loop.
608
+
609
+
610
+ Syntax:
611
+ ```
612
+ {% for variable in array %}
613
+ expression
614
+ {% endfor %}
615
+ ```
616
+
617
+ #### if
618
+
619
+ Syntax:
620
+ ```
621
+ {% if condition %}
622
+ expression
623
+ {% endif %}
624
+ ```
625
+
626
+ #### increment
627
+ Variables that are declared with `increment` are unique to the [layout](/themes/architecture/layouts), [template](/themes/architecture/templates),
628
+ or [section](/themes/architecture/sections) file that they're created in. However, the variable is shared across
629
+ [snippets](/themes/architecture/snippets) included in the file.
630
+
631
+ Similarly, variables that are created with `increment` are independent from those created with [`assign`](https://shopify.dev/docs/api/liquid/tags/assign)
632
+ and [`capture`](https://shopify.dev/docs/api/liquid/tags/capture). However, `increment` and [`decrement`](https://shopify.dev/docs/api/liquid/tags/decrement) share
633
+ variables.
634
+
635
+
636
+ Syntax:
637
+ ```
638
+ {% increment variable_name %}
639
+ ```
640
+
641
+ #### raw
642
+
643
+ Syntax:
644
+ ```
645
+ {% raw %}
646
+ expression
647
+ {% endraw %}
648
+ ```
649
+
650
+ #### render
651
+ Inside snippets and app blocks, you can't directly access variables that are [created](https://shopify.dev/docs/api/liquid/tags/variable-tags) outside
652
+ of the snippet or app block. However, you can [specify variables as parameters](https://shopify.dev/docs/api/liquid/tags/render#render-passing-variables-to-a-snippet)
653
+ to pass outside variables to snippets.
654
+
655
+ While you can't directly access created variables, you can access global objects, as well as any objects that are
656
+ directly accessible outside the snippet or app block. For example, a snippet or app block inside the [product template](/themes/architecture/templates/product)
657
+ can access the [`product` object](https://shopify.dev/docs/api/liquid/objects/product), and a snippet or app block inside a [section](/themes/architecture/sections)
658
+ can access the [`section` object](https://shopify.dev/docs/api/liquid/objects/section).
659
+
660
+ Outside a snippet or app block, you can't access variables created inside the snippet or app block.
661
+
662
+ > Note:
663
+ > When you render a snippet using the `render` tag, you can't use the [`include` tag](https://shopify.dev/docs/api/liquid/tags/include)
664
+ > inside the snippet.
665
+
666
+
667
+ Syntax:
668
+ ```
669
+ {% render 'filename' %}
670
+ ```
671
+
672
+ #### tablerow
673
+ The `tablerow` tag must be wrapped in HTML `<table>` and `</table>` tags.
674
+
675
+ > Tip:
676
+ > Every `tablerow` loop has an associated [`tablerowloop` object](https://shopify.dev/docs/api/liquid/objects/tablerowloop) with information about the loop.
677
+
678
+
679
+ Syntax:
680
+ ```
681
+ {% tablerow variable in array %}
682
+ expression
683
+ {% endtablerow %}
684
+ ```
685
+
686
+ #### unless
687
+ > Tip:
688
+ > Similar to the [`if` tag](https://shopify.dev/docs/api/liquid/tags/if), you can use `elsif` to add more conditions to an `unless` tag.
689
+
690
+
691
+ Syntax:
692
+ ```
693
+ {% unless condition %}
694
+ expression
695
+ {% endunless %}
696
+ ```
697
+
698
+ #### paginate
699
+ Because [`for` loops](https://shopify.dev/docs/api/liquid/tags/for) are limited to 50 iterations per page, you need to use the `paginate` tag to
700
+ iterate over an array that has more than 50 items. The following arrays can be paginated:
701
+
702
+ - [`article.comments`](https://shopify.dev/docs/api/liquid/objects/article#article-comments)
703
+ - [`blog.articles`](https://shopify.dev/docs/api/liquid/objects/blog#blog-articles)
704
+ - [`collections`](https://shopify.dev/docs/api/liquid/objects/collections)
705
+ - [`collection.products`](https://shopify.dev/docs/api/liquid/objects/collection#collection-products)
706
+ - [`customer.addresses`](https://shopify.dev/docs/api/liquid/objects/customer#customer-addresses)
707
+ - [`customer.orders`](https://shopify.dev/docs/api/liquid/objects/customer#customer-orders)
708
+ - [`metaobject_definition.values`](https://shopify.dev/docs/api/liquid/objects/metaobject_definition#metaobject_definition-values)
709
+ - [`pages`](https://shopify.dev/docs/api/liquid/objects/pages)
710
+ - [`product.variants`](https://shopify.dev/docs/api/liquid/objects/product#variants)
711
+ - [`search.results`](https://shopify.dev/docs/api/liquid/objects/search#search-results)
712
+ - [`article_list` settings](/themes/architecture/settings/input-settings#article_list)
713
+ - [`collection_list` settings](/themes/architecture/settings/input-settings#collection_list)
714
+ - [`product_list` settings](/themes/architecture/settings/input-settings#product_list)
715
+
716
+ Within the `paginate` tag, you have access to the [`paginate` object](https://shopify.dev/docs/api/liquid/objects/paginate). You can use this
717
+ object, or the [`default_pagination` filter](https://shopify.dev/docs/api/liquid/filters/default_pagination), to build page navigation.
718
+
719
+ > Note:
720
+ > The `paginate` tag allows the user to paginate to the 25,000th item in the array and no further. To reach items further in
721
+ > the array the array should be filtered further before paginating. See
722
+ > [Pagination Limits](/themes/best-practices/performance/platform#pagination-limits) for more information.
723
+
724
+
725
+ Syntax:
726
+ ```
727
+ {% paginate array by page_size %}
728
+ {% for item in array %}
729
+ forloop_content
730
+ {% endfor %}
731
+ {% endpaginate %}
732
+ ```
733
+
734
+ #### javascript
735
+ Each section, block or snippet can have only one `{% javascript %}` tag.
736
+
737
+ To learn more about how JavaScript that's defined between the `javascript` tags is loaded and run, refer to the documentation for [javascript tags](/storefronts/themes/best-practices/javascript-and-stylesheet-tags#javascript).
738
+ > Caution:
739
+ > Liquid isn't rendered inside of `{% javascript %}` tags. Including Liquid code can cause syntax errors.
740
+
741
+
742
+ Syntax:
743
+ ```
744
+ {% javascript %}
745
+ javascript_code
746
+ {% endjavascript %}
747
+ ```
748
+
749
+ #### section
750
+ Rendering a section with the `section` tag renders a section statically. To learn more about sections and how to use
751
+ them in your theme, refer to [Render a section](/themes/architecture/sections#render-a-section).
752
+
753
+
754
+ Syntax:
755
+ ```
756
+ {% section 'name' %}
757
+ ```
758
+
759
+ #### stylesheet
760
+ Each section, block or snippet can have only one `{% stylesheet %}` tag.
761
+
762
+ To learn more about how CSS that's defined between the `stylesheet` tags is loaded and run, refer to the documentation for [stylesheet tags](/storefronts/themes/best-practices/javascript-and-stylesheet-tags#stylesheet).
763
+ > Caution:
764
+ > Liquid isn't rendered inside of `{% stylesheet %}` tags. Including Liquid code can cause syntax errors.
765
+
766
+
767
+ Syntax:
768
+ ```
769
+ {% stylesheet %}
770
+ css_styles
771
+ {% endstylesheet %}
772
+ ```
773
+
774
+ #### sections
775
+ Use this tag to render section groups as part of the theme's [layout](/themes/architecture/layouts) content. Place the `sections` tag where you want to render it in the layout.
776
+
777
+ To learn more about section groups and how to use them in your theme, refer to [Section groups](/themes/architecture/section-groups#usage).
778
+
779
+
780
+ Syntax:
781
+ ```
782
+ {% sections 'name' %}
783
+ ```
784
+
785
+ #### style
786
+ > Note:
787
+ > If you reference [color settings](/themes/architecture/settings/input-settings#color) inside `style` tags, then
788
+ > the associated CSS rules will update as the setting is changed in the theme editor, without a page refresh.
789
+
790
+
791
+ Syntax:
792
+ ```
793
+ {% style %}
794
+ CSS_rules
795
+ {% endstyle %}
796
+ ```
797
+
798
+ #### else
799
+ You can use the `else` tag with the following tags:
800
+
801
+ - [`case`](https://shopify.dev/docs/api/liquid/tags/case)
802
+ - [`if`](https://shopify.dev/docs/api/liquid/tags/if)
803
+ - [`unless`](https://shopify.dev/docs/api/liquid/tags/unless)
804
+
805
+
806
+ Syntax:
807
+ ```
808
+ {% else %}
809
+ expression
810
+ ```
811
+
812
+ #### else
813
+
814
+ Syntax:
815
+ ```
816
+ {% for variable in array %}
817
+ first_expression
818
+ {% else %}
819
+ second_expression
820
+ {% endfor %}
821
+ ```
822
+
823
+ #### liquid
824
+ Because the tags don't have delimeters, each tag needs to be on its own line.
825
+
826
+ > Tip:
827
+ > Use the [`echo` tag](https://shopify.dev/docs/api/liquid/tags/echo) to output an expression inside `liquid` tags.
828
+
829
+
830
+ Syntax:
831
+ ```
832
+ {% liquid
833
+ expression
834
+ %}
835
+ ```
836
+
837
+