theme-check 1.11.0 → 1.12.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (60) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +3 -0
  3. data/CHANGELOG.md +7 -0
  4. data/CONTRIBUTING.md +82 -0
  5. data/README.md +4 -0
  6. data/Rakefile +7 -0
  7. data/TROUBLESHOOTING.md +65 -0
  8. data/data/shopify_liquid/built_in_liquid_objects.json +60 -0
  9. data/data/shopify_liquid/documentation/filters.json +5528 -0
  10. data/data/shopify_liquid/documentation/latest.json +1 -0
  11. data/data/shopify_liquid/documentation/objects.json +19272 -0
  12. data/data/shopify_liquid/documentation/tags.json +1252 -0
  13. data/lib/theme_check/checks/undefined_object.rb +4 -0
  14. data/lib/theme_check/language_server/completion_context.rb +52 -0
  15. data/lib/theme_check/language_server/completion_engine.rb +15 -21
  16. data/lib/theme_check/language_server/completion_provider.rb +16 -1
  17. data/lib/theme_check/language_server/completion_providers/assignments_completion_provider.rb +36 -0
  18. data/lib/theme_check/language_server/completion_providers/filter_completion_provider.rb +49 -6
  19. data/lib/theme_check/language_server/completion_providers/object_attribute_completion_provider.rb +47 -0
  20. data/lib/theme_check/language_server/completion_providers/object_completion_provider.rb +10 -7
  21. data/lib/theme_check/language_server/completion_providers/render_snippet_completion_provider.rb +5 -1
  22. data/lib/theme_check/language_server/completion_providers/tag_completion_provider.rb +8 -1
  23. data/lib/theme_check/language_server/handler.rb +3 -1
  24. data/lib/theme_check/language_server/protocol.rb +9 -0
  25. data/lib/theme_check/language_server/type_helper.rb +22 -0
  26. data/lib/theme_check/language_server/variable_lookup_finder/assignments_finder/node_handler.rb +63 -0
  27. data/lib/theme_check/language_server/variable_lookup_finder/assignments_finder/scope.rb +57 -0
  28. data/lib/theme_check/language_server/variable_lookup_finder/assignments_finder/scope_visitor.rb +42 -0
  29. data/lib/theme_check/language_server/variable_lookup_finder/assignments_finder.rb +76 -0
  30. data/lib/theme_check/language_server/variable_lookup_finder/constants.rb +43 -0
  31. data/lib/theme_check/language_server/variable_lookup_finder/liquid_fixer.rb +103 -0
  32. data/lib/theme_check/language_server/variable_lookup_finder/potential_lookup.rb +10 -0
  33. data/lib/theme_check/language_server/variable_lookup_finder/tolerant_parser.rb +94 -0
  34. data/lib/theme_check/language_server/variable_lookup_finder.rb +60 -100
  35. data/lib/theme_check/language_server/variable_lookup_traverser.rb +70 -0
  36. data/lib/theme_check/language_server.rb +12 -0
  37. data/lib/theme_check/remote_asset_file.rb +13 -7
  38. data/lib/theme_check/shopify_liquid/documentation/markdown_template.rb +51 -0
  39. data/lib/theme_check/shopify_liquid/documentation.rb +44 -0
  40. data/lib/theme_check/shopify_liquid/filter.rb +4 -0
  41. data/lib/theme_check/shopify_liquid/object.rb +4 -0
  42. data/lib/theme_check/shopify_liquid/source_index/base_entry.rb +60 -0
  43. data/lib/theme_check/shopify_liquid/source_index/base_state.rb +23 -0
  44. data/lib/theme_check/shopify_liquid/source_index/filter_entry.rb +18 -0
  45. data/lib/theme_check/shopify_liquid/source_index/filter_state.rb +11 -0
  46. data/lib/theme_check/shopify_liquid/source_index/object_entry.rb +14 -0
  47. data/lib/theme_check/shopify_liquid/source_index/object_state.rb +11 -0
  48. data/lib/theme_check/shopify_liquid/source_index/parameter_entry.rb +21 -0
  49. data/lib/theme_check/shopify_liquid/source_index/property_entry.rb +9 -0
  50. data/lib/theme_check/shopify_liquid/source_index/return_type_entry.rb +37 -0
  51. data/lib/theme_check/shopify_liquid/source_index/tag_entry.rb +20 -0
  52. data/lib/theme_check/shopify_liquid/source_index/tag_state.rb +11 -0
  53. data/lib/theme_check/shopify_liquid/source_index.rb +56 -0
  54. data/lib/theme_check/shopify_liquid/source_manager.rb +111 -0
  55. data/lib/theme_check/shopify_liquid/tag.rb +4 -0
  56. data/lib/theme_check/shopify_liquid.rb +17 -1
  57. data/lib/theme_check/version.rb +1 -1
  58. data/shipit.rubygems.yml +3 -0
  59. data/theme-check.gemspec +3 -1
  60. metadata +37 -2
@@ -0,0 +1,1252 @@
1
+ [
2
+ {
3
+ "category": "html",
4
+ "deprecated": false,
5
+ "deprecation_reason": "",
6
+ "description": "Because there are many different form types available in Shopify themes, the `form` tag requires a type. Depending on the\nform type, an additional parameter might be required. You can specify the following form types:\n\n- [`activate_customer_password`](/api/liquid/tags/form#form-activate_customer_password)\n- [`cart`](/api/liquid/tags/form#form-cart)\n- [`contact`](/api/liquid/tags/form#form-contact)\n- [`create_customer`](/api/liquid/tags/form#form-create_customer)\n- [`currency`](/api/liquid/tags/form#form-currency)\n- [`customer`](/api/liquid/tags/form#form-customer)\n- [`customer_address`](/api/liquid/tags/form#form-customer_address)\n- [`customer_login`](/api/liquid/tags/form#form-customer_login)\n- [`guest_login`](/api/liquid/tags/form#form-guest_login)\n- [`localization`](/api/liquid/tags/form#form-localization)\n- [`new_comment`](/api/liquid/tags/form#form-new_comment)\n- [`product`](/api/liquid/tags/form#form-product)\n- [`recover_customer_password`](/api/liquid/tags/form#form-recover_customer_password)\n- [`reset_customer_password`](/api/liquid/tags/form#form-reset_customer_password)\n- [`storefront_password`](/api/liquid/tags/form#form-storefront_password)",
7
+ "parameters": [
8
+ {
9
+ "description": "The desired URL to redirect to when the form submits.",
10
+ "name": "return_to",
11
+ "required": false,
12
+ "types": [
13
+ "string"
14
+ ]
15
+ }
16
+ ],
17
+ "summary": "Generates an HTML `<form>` tag, including any required `<input>` tags to submit the form to a specific endpoint.",
18
+ "name": "form",
19
+ "syntax": "{% form 'form_type' %}\n content\n{% endform %}",
20
+ "syntax_keywords": [
21
+ {
22
+ "keyword": "form_type",
23
+ "description": "The name of the desired form type"
24
+ },
25
+ {
26
+ "keyword": "content",
27
+ "description": "The form contents"
28
+ }
29
+ ],
30
+ "examples": [
31
+ {
32
+ "name": "activate_customer_password",
33
+ "description": "Generates a form for activating a customer account.\nTo learn more about using this form, and its contents, refer to the [`customers/activate_account` template](/themes/architecture/templates/customers-activate-account#content).\n",
34
+ "syntax": "{% form 'activate_customer_password', article %}\n form_content\n{% endform %}\n",
35
+ "path": "/",
36
+ "raw_liquid": "{% form 'activate_customer_password' %}\n <!-- form content -->\n{% endform %}",
37
+ "parameter": false,
38
+ "display_type": "text",
39
+ "show_data_tab": true
40
+ },
41
+ {
42
+ "name": "cart",
43
+ "description": "Generates a form for creating a checkout based on the items currently in the cart. The `cart` form requires a [`cart` object](/api/liquid/objects/cart) as a parameter.\nTo learn more about using the cart form in your theme, refer to the [`cart` template](/themes/architecture/templates/cart#proceed-to-checkout).\n",
44
+ "syntax": "{% form 'cart', cart %}\n form_content\n{% endform %}\n",
45
+ "path": "/",
46
+ "raw_liquid": "{% form 'cart', cart %}\n <!-- form content -->\n{% endform %}",
47
+ "parameter": false,
48
+ "display_type": "text",
49
+ "show_data_tab": true
50
+ },
51
+ {
52
+ "name": "contact",
53
+ "description": "Generates a form for submitting an email to the merchant. To learn more about using this form in your theme, refer to [Add a contact form to your theme](/themes/customer-engagement/add-contact-form).\n\n> Tip:\n> To learn more about the merchant experience of receiving submissions, refer to [the Shopify Help Center](https://help.shopify.com/manual/online-store/themes/customizing-themes/add-contact-page#view-contact-form-submissions).\n",
54
+ "syntax": "{% form 'contact' %}\n form_content\n{% endform %}\n",
55
+ "path": "/",
56
+ "raw_liquid": "{% form 'contact' %}\n <!-- form content -->\n{% endform %}",
57
+ "parameter": false,
58
+ "display_type": "text",
59
+ "show_data_tab": true
60
+ },
61
+ {
62
+ "name": "create_customer",
63
+ "description": "Generates a form for creating a new customer account.\nTo learn more about using this form, and its contents, refer to the [`customers/register` template](/themes/architecture/templates/customers-register#content).\n",
64
+ "syntax": "{% form 'create_customer' %}\n form_content\n{% endform %}\n",
65
+ "path": "/",
66
+ "raw_liquid": "{% form 'create_customer' %}\n <!-- form content -->\n{% endform %}",
67
+ "parameter": false,
68
+ "display_type": "text",
69
+ "show_data_tab": true
70
+ },
71
+ {
72
+ "name": "currency",
73
+ "description": "> Deprecated:\n> The `currency` form is deprecated and has been replaced by the [`localization` form](/api/liquid/tags/form#form-localization).\n\nGenerates a form for customers to select their preferred currency.\n\n> Tip:\n> Use the [`currency_selector` filter](/api/liquid/filters/currency_selector) to include a currency selector inside the form.\n",
74
+ "syntax": "{% form 'currency' %}\n form_content\n{% endform %}\n",
75
+ "path": "/",
76
+ "raw_liquid": "{% form 'currency' %}\n {{ form | currency_selector }}\n{% endform %}",
77
+ "parameter": false,
78
+ "display_type": "text",
79
+ "show_data_tab": true
80
+ },
81
+ {
82
+ "name": "customer",
83
+ "description": "Generates a form for creating a new customer without registering a new account. This form is useful for collecting customer information when you don't want customers to log in to your store, such as building a list of emails from a newsletter signup.\n\n> Tip:\n> To generate a form that registers a customer account, use the [`create_customer` form](/api/liquid/tags/form#form-create_customer).\n\nTo learn more about using this form, and its contents, refer to [Email consent](/themes/customer-engagement/email-consent#newsletter-sign-up-form).\n",
84
+ "syntax": "{% form 'customer' %}\n form_content\n{% endform %}\n",
85
+ "path": "/",
86
+ "raw_liquid": "{% form 'customer' %}\n <!-- form content -->\n{% endform %}",
87
+ "parameter": false,
88
+ "display_type": "text",
89
+ "show_data_tab": true
90
+ },
91
+ {
92
+ "name": "customer_address",
93
+ "description": "Generates a form for creating a new address on a customer account, or editing an existing one. The `customer_address` form requires a specific parameter, depending on whether a new address is being created or an existing one is being edited:\n\n| Parameter value | Use-case |\n| --- | --- |\n| `customer.new_address` | When a new address is being created. |\n| `address` | When an existing address is being edited. |\n\nTo learn more about using this form, and its contents, refer to the [`customers/addresses` template](/themes/architecture/templates/customers-addresses#content).\n",
94
+ "syntax": "{% form 'customer_address', address_type %}\n form_content\n{% endform %}\n",
95
+ "path": "/",
96
+ "raw_liquid": "{% form 'customer_address', customer.new_address %}\n <!-- form content -->\n{% endform %}",
97
+ "parameter": false,
98
+ "display_type": "text",
99
+ "show_data_tab": false
100
+ },
101
+ {
102
+ "name": "customer_login",
103
+ "description": "Generates a form for logging into a customer account.\nTo learn more about using this form, and its contents, refer to the [`customers/login` template](/themes/architecture/templates/customers-login#the-customer-login-form).\n",
104
+ "syntax": "{% form 'customer_login' %}\n form_content\n{% endform %}\n",
105
+ "path": "/",
106
+ "raw_liquid": "{% form 'customer_login' %}\n <!-- form content -->\n{% endform %}",
107
+ "parameter": false,
108
+ "display_type": "text",
109
+ "show_data_tab": true
110
+ },
111
+ {
112
+ "name": "guest_login",
113
+ "description": "Generates a form, for use in the [`customers/login` template](/themes/architecture/templates/customers-login), that directs customers back to their checkout session as a guest instead of logging in to an account.\nTo learn more about using this form, and its contents, refer to [Offer guest checkout](/themes/architecture/templates/customers-login#offer-guest-checkout).\n",
114
+ "syntax": "{% form 'guest_login' %}\n form_content\n{% endform %}\n",
115
+ "path": "/",
116
+ "raw_liquid": "{% form 'guest_login' %}\n <!-- form content -->\n{% endform %}",
117
+ "parameter": false,
118
+ "display_type": "text",
119
+ "show_data_tab": true
120
+ },
121
+ {
122
+ "name": "localization",
123
+ "description": "Generates a form for customers to select their preferred country so that they're shown the appropriate language and currency. The `localization` form can contain one of two selectors:\n\n- A country selector\n- A language selector\n\n> Note:\n> The `localization` form replaces the deprecated [`currency` form](/api/liquid/tags/form#form-currency).\n\nTo learn more about using this form, and its contents, refer to [Support multiple currencies and languages](/themes/internationalization/multiple-currencies-languages).\n",
124
+ "syntax": "{% form 'localization' %}\n form_content\n{% endform %}\n",
125
+ "path": "/",
126
+ "raw_liquid": "{% form 'localization' %}\n <!-- form content -->\n{% endform %}",
127
+ "parameter": false,
128
+ "display_type": "text",
129
+ "show_data_tab": true
130
+ },
131
+ {
132
+ "name": "new_comment",
133
+ "description": "Generates a form for creating a new comment on an article. The `new_comment` form requires an [`article` object](/api/liquid/objects/article) as a parameter.\nTo learn more about using this form, and its contents, refer to the [`article` template](/themes/architecture/templates/article#the-comment-form).\n",
134
+ "syntax": "{% form 'new_comment', article %}\n form_content\n{% endform %}\n",
135
+ "path": "/blogs/potion-notions/how-to-tell-if-you-have-run-out-of-invisibility-potion",
136
+ "raw_liquid": "{% form 'new_comment', article %}\n <!-- form content -->\n{% endform %}",
137
+ "parameter": false,
138
+ "display_type": "text",
139
+ "show_data_tab": true
140
+ },
141
+ {
142
+ "name": "product",
143
+ "description": "Generates a form for adding a product variant to the cart. The `product` form requires a [`product` object](/api/liquid/objects/product) as a parameter.\nTo learn more about using this form, and its contents, refer to the [`product` template](/themes/architecture/templates/product#the-product-form).\n",
144
+ "syntax": "{% form 'product', product %}\n form_content\n{% endform %}\n",
145
+ "path": "/products/health-potion",
146
+ "raw_liquid": "{% form 'product', product %}\n <!-- form content -->\n{% endform %}",
147
+ "parameter": false,
148
+ "display_type": "text",
149
+ "show_data_tab": true
150
+ },
151
+ {
152
+ "name": "recover_customer_password",
153
+ "description": "Generates a form, for use in the [`customers/login` template](/themes/architecture/templates/customers-login), for a customer to recover a lost or forgotten password.\nTo learn more about using this form, and its contents, refer to [Provide a \"Forgot your password\" option](/themes/architecture/templates/customers-login#provide-a-forgot-your-password-option).\n",
154
+ "syntax": "{% form 'recover_customer_password' %}\n form_content\n{% endform %}\n",
155
+ "path": "/",
156
+ "raw_liquid": "{% form 'recover_customer_password' %}\n <!-- form content -->\n{% endform %}",
157
+ "parameter": false,
158
+ "display_type": "text",
159
+ "show_data_tab": true
160
+ },
161
+ {
162
+ "name": "reset_customer_password",
163
+ "description": "Generates a form for a customer to reset their password.\nTo learn more about using this form, and its contents, refer to the [`customers/reset_password` template](/themes/architecture/templates/customers-reset-password#content).\n",
164
+ "syntax": "{% form 'reset_customer_password' %}\n form_content\n{% endform %}\n",
165
+ "path": "/",
166
+ "raw_liquid": "{% form 'reset_customer_password' %}\n <!-- form content -->\n{% endform %}",
167
+ "parameter": false,
168
+ "display_type": "text",
169
+ "show_data_tab": true
170
+ },
171
+ {
172
+ "name": "storefront_password",
173
+ "description": "Generates a form for entering a password protected storefront.\nTo learn more about using this form, and its contents, refer to the [`password` template](/themes/architecture/templates/password#the-password-form).\n",
174
+ "syntax": "{% form 'storefront_password' %}\n form_content\n{% endform %}\n",
175
+ "path": "/",
176
+ "raw_liquid": "{% form 'storefront_password' %}\n <!-- form content -->\n{% endform %}",
177
+ "parameter": false,
178
+ "display_type": "text",
179
+ "show_data_tab": true
180
+ },
181
+ {
182
+ "name": "return_to",
183
+ "description": "By default, each form type redirects customers to a specific page after the form submits. For example, the `product` form redirects to the cart page.\n\nThe `return_to` parameter allows you to specify a URL to redirect to. This can be done with the following values:\n\n| Value | Description |\n| --- | --- |\n| `back` | Redirect back to the same page that the customer was on before submitting the form. |\n| A relative path | A specific URL path. For example `/collections/all`. |\n| A [`routes` attribute](/api/liquid/objects/routes) | For example, `routes.root_url` |\n",
184
+ "syntax": "{% form 'form_type', return_to: string %}\n content\n{% endform %}\n",
185
+ "path": "/",
186
+ "raw_liquid": "{% form 'customer_login', return_to: routes.root_url %}\n <!-- form content -->\n{% endform %}",
187
+ "parameter": true,
188
+ "display_type": "text",
189
+ "show_data_tab": true
190
+ },
191
+ {
192
+ "name": "HTML attributes",
193
+ "description": "You can specify [HTML attributes](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe#attributes) by adding a parameter that matches the attribute name with `data-` prepended, and the desired value.\n",
194
+ "syntax": "{% form 'form_type', attribute: string %}\n content\n{% endform %}\n",
195
+ "path": "/products/health-potion",
196
+ "raw_liquid": "{% form \"product\", product, id: 'custom-id', class: 'custom-class', data-example: '100' %}\n <!-- form content -->\n{% endform %}",
197
+ "parameter": true,
198
+ "display_type": "text",
199
+ "show_data_tab": true
200
+ }
201
+ ]
202
+ },
203
+ {
204
+ "category": "theme",
205
+ "deprecated": false,
206
+ "deprecation_reason": "",
207
+ "description": "",
208
+ "parameters": [
209
+
210
+ ],
211
+ "summary": "Specify which [layout](/themes/architecture/layouts) to use.",
212
+ "name": "layout",
213
+ "syntax": "{% layout name %}",
214
+ "syntax_keywords": [
215
+ {
216
+ "keyword": "name",
217
+ "description": "The name of the layout file you want to use, wrapped in quotes, or `none` for no layout."
218
+ }
219
+ ],
220
+ "examples": [
221
+ {
222
+ "name": "",
223
+ "description": "By default, the `theme.liquid` layout is used. The `layout` tag allows you to specify an alternate layout, or use no layout.\n\n```liquid\n{% layout 'full-width' %}\n{% layout none %}\n```\n",
224
+ "syntax": "",
225
+ "path": "",
226
+ "raw_liquid": "",
227
+ "parameter": false,
228
+ "display_type": "text",
229
+ "show_data_tab": true
230
+ }
231
+ ]
232
+ },
233
+ {
234
+ "category": "variable",
235
+ "deprecated": false,
236
+ "deprecation_reason": "",
237
+ "description": "You can create variables of any [basic type](/api/liquid/basics#types), [object](/api/liquid/objects), or object property.",
238
+ "parameters": [
239
+
240
+ ],
241
+ "summary": "Creates a new variable.",
242
+ "name": "assign",
243
+ "syntax": "{% assign variable_name = value %}",
244
+ "syntax_keywords": [
245
+ {
246
+ "keyword": "variable_name",
247
+ "description": "The name of the variable being created."
248
+ },
249
+ {
250
+ "keyword": "value",
251
+ "description": "The value you want to assign to the variable."
252
+ }
253
+ ],
254
+ "examples": [
255
+ {
256
+ "name": "",
257
+ "description": "",
258
+ "syntax": "",
259
+ "path": "/products/health-potion",
260
+ "raw_liquid": "{%- assign product_title = product.title | upcase -%}\n\n{{ product_title }}",
261
+ "parameter": false,
262
+ "display_type": "text",
263
+ "show_data_tab": true
264
+ }
265
+ ]
266
+ },
267
+ {
268
+ "category": "iteration",
269
+ "deprecated": false,
270
+ "deprecation_reason": "",
271
+ "description": "",
272
+ "parameters": [
273
+
274
+ ],
275
+ "summary": "Stops a [`for` loop](/api/liquid/tags/for) from iterating.",
276
+ "name": "break",
277
+ "syntax": "{% break %}",
278
+ "syntax_keywords": [
279
+
280
+ ],
281
+ "examples": [
282
+ {
283
+ "name": "",
284
+ "description": "",
285
+ "syntax": "",
286
+ "path": "/",
287
+ "raw_liquid": "{% for i in (1..5) -%}\n {%- if i == 4 -%}\n {% break %}\n {%- else -%}\n {{ i }}\n {%- endif -%}\n{%- endfor %}",
288
+ "parameter": false,
289
+ "display_type": "text",
290
+ "show_data_tab": true
291
+ }
292
+ ]
293
+ },
294
+ {
295
+ "category": "variable",
296
+ "deprecated": false,
297
+ "deprecation_reason": "",
298
+ "description": "You can create complex strings with Liquid logic and variables.",
299
+ "parameters": [
300
+
301
+ ],
302
+ "summary": "Creates a new variable with a string value.",
303
+ "name": "capture",
304
+ "syntax": "{% capture variable %}\n value\n{% endcapture %}",
305
+ "syntax_keywords": [
306
+ {
307
+ "keyword": "variable",
308
+ "description": "The name of the variable being created."
309
+ },
310
+ {
311
+ "keyword": "value",
312
+ "description": "The value you want to assign to the variable."
313
+ }
314
+ ],
315
+ "examples": [
316
+ {
317
+ "name": "",
318
+ "description": "",
319
+ "syntax": "",
320
+ "path": "/products/health-potion",
321
+ "raw_liquid": "{%- assign up_title = product.title | upcase -%}\n{%- assign down_title = product.title | downcase -%}\n{%- assign show_up_title = true -%}\n\n{%- capture title -%}\n {% if show_up_title -%}\n Upcase title: {{ up_title }}\n {%- else -%}\n Downcase title: {{ down_title }}\n {%- endif %}\n{%- endcapture %}\n\n{{ title }}",
322
+ "parameter": false,
323
+ "display_type": "text",
324
+ "show_data_tab": true
325
+ }
326
+ ]
327
+ },
328
+ {
329
+ "category": "conditional",
330
+ "deprecated": false,
331
+ "deprecation_reason": "",
332
+ "description": "",
333
+ "parameters": [
334
+
335
+ ],
336
+ "summary": "Renders a specific expression depending on the value of a specific variable.",
337
+ "name": "case",
338
+ "syntax": "{% case variable %}\n {% when first_value %}\n first_expression\n {% when second_value %}\n second_expression\n {% else %}\n third_expression\n{% endcase %}",
339
+ "syntax_keywords": [
340
+ {
341
+ "keyword": "variable",
342
+ "description": "The name of the variable you want to base your case statement on."
343
+ },
344
+ {
345
+ "keyword": "first_value",
346
+ "description": "A specific value to check for."
347
+ },
348
+ {
349
+ "keyword": "second_value",
350
+ "description": "A specific value to check for."
351
+ },
352
+ {
353
+ "keyword": "first_expression",
354
+ "description": "An expression to be rendered when the variable's value matches `first_value`."
355
+ },
356
+ {
357
+ "keyword": "second_expression",
358
+ "description": "An expression to be rendered when the variable's value matches `second_value`."
359
+ },
360
+ {
361
+ "keyword": "third_expression",
362
+ "description": "An expression to be rendered when the variable's value has no match."
363
+ }
364
+ ],
365
+ "examples": [
366
+ {
367
+ "name": "",
368
+ "description": "",
369
+ "syntax": "",
370
+ "path": "/products/health-potion",
371
+ "raw_liquid": "{% case product.type %}\n {% when 'Health' %}\n This is a health potion.\n {% when 'Love' %}\n This is a love potion.\n {% else %}\n This is a potion.\n{% endcase %}",
372
+ "parameter": false,
373
+ "display_type": "text",
374
+ "show_data_tab": true
375
+ },
376
+ {
377
+ "name": "Multiple values",
378
+ "description": "A `when` tag can accept multiple values. When multiple values are provided, the expression is returned when the variable matches any of the values inside of the tag.\nProvide the values as a comma-separated list, or separate them using an `or` operator.\n",
379
+ "syntax": "{% case variable %}\n {% when first_value or second_value or third_value %}\n first_expression\n {% when fourth_value, fifth_value, sixth_value %}\n second_expression\n {% else %}\n third_expression\n{% endcase %}\n",
380
+ "path": "/products/health-potion",
381
+ "raw_liquid": "{% case product.tags %}\n {% when 'Love' or 'Luck' %}\n This is a love or luck potion.\n {% when 'Strength','Health' %}\n This is a strength or health potion.\n {% else %}\n This is a potion.\n{% endcase %}",
382
+ "parameter": false,
383
+ "display_type": "text",
384
+ "show_data_tab": true
385
+ }
386
+ ]
387
+ },
388
+ {
389
+ "category": "syntax",
390
+ "deprecated": false,
391
+ "deprecation_reason": "",
392
+ "description": "Any text inside `comment` tags won't be output, and any Liquid code will be parsed, but not executed.",
393
+ "parameters": [
394
+
395
+ ],
396
+ "summary": "Prevents an expression from being rendered or output.",
397
+ "name": "comment",
398
+ "syntax": "{% comment %}\n content\n{% endcomment %}",
399
+ "syntax_keywords": [
400
+ {
401
+ "keyword": "content",
402
+ "description": "The content of the comment."
403
+ }
404
+ ],
405
+ "examples": [
406
+ {
407
+ "name": "Inline comments",
408
+ "description": "Inline comments prevent an expression inside of a tag `{% %}` from being rendered or output.\n\nYou can use inline comment tags to annotate your code, or to temporarily prevent logic in your code from executing.\n\nYou can create multi-line inline comments. However, each line in the tag must begin with a `#`, or a syntax error will occur.\n",
409
+ "syntax": "{% # content %}",
410
+ "path": "/",
411
+ "raw_liquid": "{% # this is a comment %}\n\n{% # for i in (1..3) -%}\n {{ i }}\n{% # endfor %}\n\n{%\n ###############################\n # This is a comment\n # across multiple lines\n ###############################\n%}",
412
+ "parameter": false,
413
+ "display_type": "text",
414
+ "show_data_tab": true
415
+ },
416
+ {
417
+ "name": "Inline comments inside `liquid` tags",
418
+ "description": "You can use inline comment tags inside [`liquid` tags](/api/liquid/tags/liquid). The tag must be used for each line that you want to comment.\n",
419
+ "syntax": "",
420
+ "path": "/",
421
+ "raw_liquid": "{% liquid\n # this is a comment\n assign topic = 'Learning about comments!'\n echo topic\n%}",
422
+ "parameter": false,
423
+ "display_type": "text",
424
+ "show_data_tab": true
425
+ }
426
+ ]
427
+ },
428
+ {
429
+ "category": "iteration",
430
+ "deprecated": false,
431
+ "deprecation_reason": "",
432
+ "description": "",
433
+ "parameters": [
434
+
435
+ ],
436
+ "summary": "Causes a [`for` loop](/api/liquid/tags/for) to skip to the next iteration.",
437
+ "name": "continue",
438
+ "syntax": "{% continue %}",
439
+ "syntax_keywords": [
440
+
441
+ ],
442
+ "examples": [
443
+ {
444
+ "name": "",
445
+ "description": "",
446
+ "syntax": "",
447
+ "path": "/",
448
+ "raw_liquid": "{% for i in (1..5) -%}\n {%- if i == 4 -%}\n {% continue %}\n {%- else -%}\n {{ i }}\n {%- endif -%}\n{%- endfor %}",
449
+ "parameter": false,
450
+ "display_type": "text",
451
+ "show_data_tab": true
452
+ }
453
+ ]
454
+ },
455
+ {
456
+ "category": "iteration",
457
+ "deprecated": false,
458
+ "deprecation_reason": "",
459
+ "description": "The `cycle` tag must be used inside a `for` loop.\n\n> Tip:\n> Use the `cycle` tag to output text in a predictable pattern. For example, to apply odd/even classes to rows in a table.",
460
+ "parameters": [
461
+
462
+ ],
463
+ "summary": "Loops through a group of strings and outputs them one at a time for each iteration of a [`for` loop](/api/liquid/tags/for).",
464
+ "name": "cycle",
465
+ "syntax": "{% cycle string, string, ... %}",
466
+ "syntax_keywords": [
467
+
468
+ ],
469
+ "examples": [
470
+ {
471
+ "name": "",
472
+ "description": "",
473
+ "syntax": "",
474
+ "path": "/",
475
+ "raw_liquid": "{% for i in (1..4) -%}\n {% cycle 'one', 'two', 'three' %}\n{%- endfor %}",
476
+ "parameter": false,
477
+ "display_type": "text",
478
+ "show_data_tab": true
479
+ },
480
+ {
481
+ "name": "Create unique cycle groups",
482
+ "description": "If you include multiple `cycle` tags with the same parameters, in the same template, then each set of tags is treated as the same group. This means that it's possible for a `cycle` tag to output any of the provided strings, instead of always starting at the first string.\nTo account for this, you can specify a group name for each `cycle` tag.\n",
483
+ "syntax": "{% cycle string: string, string, ... %}",
484
+ "path": "/",
485
+ "raw_liquid": "<!-- Iteration 1 -->\n{% for i in (1..4) -%}\n {% cycle 'one', 'two', 'three' %}\n{%- endfor %}\n\n<!-- Iteration 2 -->\n{% for i in (1..4) -%}\n {% cycle 'one', 'two', 'three' %}\n{%- endfor %}\n\n<!-- Iteration 3 -->\n{% for i in (1..4) -%}\n {% cycle 'group_1': 'one', 'two', 'three' %}\n{%- endfor %}\n\n<!-- Iteration 4 -->\n{% for i in (1..4) -%}\n {% cycle 'group_2': 'one', 'two', 'three' %}\n{%- endfor %}",
486
+ "parameter": false,
487
+ "display_type": "text",
488
+ "show_data_tab": true
489
+ }
490
+ ]
491
+ },
492
+ {
493
+ "category": "variable",
494
+ "deprecated": false,
495
+ "deprecation_reason": "",
496
+ "description": "Variables that are declared with `decrement` are unique to the [layout](/themes/architecture/layouts), [template](/themes/architecture/templates),\nor [section](/themes/architecture/sections) file that they're created in. However, the variable is shared across\n[snippets](/themes/architecture#snippets) included in the file.\n\nSimilarly, variables that are created with `decrement` are independent from those created with [`assign`](/api/liquid/tags/assign)\nand [`capture`](/api/liquid/tags/capture). However, `decrement` and [`increment`](/api/liquid/tags/increment) share\nvariables.",
497
+ "parameters": [
498
+
499
+ ],
500
+ "summary": "Creates a new variable, with a default value of -1, that's decreased by 1 with each subsequent call.",
501
+ "name": "decrement",
502
+ "syntax": "{% decrement variable_name %}",
503
+ "syntax_keywords": [
504
+ {
505
+ "keyword": "variable_name",
506
+ "description": "The name of the variable being decremented."
507
+ }
508
+ ],
509
+ "examples": [
510
+ {
511
+ "name": "",
512
+ "description": "",
513
+ "syntax": "",
514
+ "path": "/",
515
+ "raw_liquid": "{% decrement variable %}\n{% decrement variable %}\n{% decrement variable %}",
516
+ "parameter": false,
517
+ "display_type": "text",
518
+ "show_data_tab": true
519
+ }
520
+ ]
521
+ },
522
+ {
523
+ "category": "syntax",
524
+ "deprecated": false,
525
+ "deprecation_reason": "",
526
+ "description": "Using the `echo` tag is the same as wrapping an expression in curly brackets (`{{` and `}}`). However, unlike the curly\nbracket method, you can use the `echo` tag inside [`liquid` tags](/api/liquid/tags/liquid).\n\n> Tip:\n> You can use [filters](/api/liquid/filters) on expressions inside `echo` tags.",
527
+ "parameters": [
528
+
529
+ ],
530
+ "summary": "Outputs an expression.",
531
+ "name": "echo",
532
+ "syntax": "{% liquid\n echo expression\n%}",
533
+ "syntax_keywords": [
534
+ {
535
+ "keyword": "expression",
536
+ "description": "The expression to be output."
537
+ }
538
+ ],
539
+ "examples": [
540
+ {
541
+ "name": "",
542
+ "description": "",
543
+ "syntax": "",
544
+ "path": "/products/health-potion",
545
+ "raw_liquid": "{% echo product.title %}\n\n{% liquid\n echo product.price | money\n%}",
546
+ "parameter": false,
547
+ "display_type": "text",
548
+ "show_data_tab": true
549
+ }
550
+ ]
551
+ },
552
+ {
553
+ "category": "iteration",
554
+ "deprecated": false,
555
+ "deprecation_reason": "",
556
+ "description": "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\n[`paginate` tag](/api/liquid/tags/paginate) to split the items over multiple pages.\n\n> Tip:\n> Every `for` loop has an associated [`forloop` object](/api/liquid/objects/forloop) with information about the loop.",
557
+ "parameters": [
558
+ {
559
+ "description": "The number of iterations to perform.",
560
+ "name": "limit",
561
+ "required": false,
562
+ "types": [
563
+ "number"
564
+ ]
565
+ },
566
+ {
567
+ "description": "The 1-based index to start iterating at.",
568
+ "name": "offset",
569
+ "required": false,
570
+ "types": [
571
+ "number"
572
+ ]
573
+ },
574
+ {
575
+ "description": "A custom numeric range to iterate over.",
576
+ "name": "range",
577
+ "required": false,
578
+ "types": [
579
+ "untyped"
580
+ ]
581
+ },
582
+ {
583
+ "description": "Iterate in reverse order.",
584
+ "name": "reversed",
585
+ "required": false,
586
+ "types": [
587
+ "untyped"
588
+ ]
589
+ }
590
+ ],
591
+ "summary": "Renders an expression for every item in an array.",
592
+ "name": "for",
593
+ "syntax": "{% for variable in array %}\n expression\n{% endfor %}",
594
+ "syntax_keywords": [
595
+ {
596
+ "keyword": "variable",
597
+ "description": "The current item in the array."
598
+ },
599
+ {
600
+ "keyword": "array",
601
+ "description": "The array to iterate over."
602
+ },
603
+ {
604
+ "keyword": "expression",
605
+ "description": "The expression to render for each iteration."
606
+ }
607
+ ],
608
+ "examples": [
609
+ {
610
+ "name": "",
611
+ "description": "",
612
+ "syntax": "",
613
+ "path": "/collections/sale-potions",
614
+ "raw_liquid": "{% for product in collection.products -%}\n {{ product.title }}\n{%- endfor %}",
615
+ "parameter": false,
616
+ "display_type": "text",
617
+ "show_data_tab": true
618
+ },
619
+ {
620
+ "name": "limit",
621
+ "description": "You can limit the number of iterations using the `limit` parameter.",
622
+ "syntax": "{% for variable in array limit: number %}\n expression\n{% endfor %}\n",
623
+ "path": "/collections/sale-potions",
624
+ "raw_liquid": "{% for product in collection.products limit: 2 -%}\n {{ product.title }}\n{%- endfor %}",
625
+ "parameter": true,
626
+ "display_type": "text",
627
+ "show_data_tab": true
628
+ },
629
+ {
630
+ "name": "offset",
631
+ "description": "You can specify a 1-based index to start iterating at using the `offset` parameter.",
632
+ "syntax": "{% for variable in array offset: number %}\n expression\n{% endfor %}\n",
633
+ "path": "/collections/sale-potions",
634
+ "raw_liquid": "{% for product in collection.products offset: 2 -%}\n {{ product.title }}\n{%- endfor %}",
635
+ "parameter": true,
636
+ "display_type": "text",
637
+ "show_data_tab": true
638
+ },
639
+ {
640
+ "name": "range",
641
+ "description": "Instead of iterating over specific items in an array, you can specify a numeric range to iterate over.\n\n> Note:\n> You can define the range using both literal and variable values.\n",
642
+ "syntax": "{% for variable in (number..number) %}\n expression\n{% endfor %}\n",
643
+ "path": "/collections/all",
644
+ "raw_liquid": "{% for i in (1..3) -%}\n {{ i }}\n{%- endfor %}\n\n{%- assign lower_limit = 2 -%}\n{%- assign upper_limit = 4 -%}\n\n{% for i in (lower_limit..upper_limit) -%}\n {{ i }}\n{%- endfor %}",
645
+ "parameter": true,
646
+ "display_type": "text",
647
+ "show_data_tab": true
648
+ },
649
+ {
650
+ "name": "reversed",
651
+ "description": "You can iterate in reverse order using the `reversed` parameter.",
652
+ "syntax": "{% for variable in array reversed %}\n expression\n{% endfor %}\n",
653
+ "path": "/collections/sale-potions",
654
+ "raw_liquid": "{% for product in collection.products reversed -%}\n {{ product.title }}\n{%- endfor %}",
655
+ "parameter": true,
656
+ "display_type": "text",
657
+ "show_data_tab": true
658
+ }
659
+ ]
660
+ },
661
+ {
662
+ "category": "conditional",
663
+ "deprecated": false,
664
+ "deprecation_reason": "",
665
+ "description": "",
666
+ "parameters": [
667
+
668
+ ],
669
+ "summary": "Renders an expression if a specific condition is `true`.",
670
+ "name": "if",
671
+ "syntax": "{% if condition %}\n expression\n{% endif %}",
672
+ "syntax_keywords": [
673
+ {
674
+ "keyword": "condition",
675
+ "description": "The condition to evaluate."
676
+ },
677
+ {
678
+ "keyword": "expression",
679
+ "description": "The expression to render if the condition is met."
680
+ }
681
+ ],
682
+ "examples": [
683
+ {
684
+ "name": "",
685
+ "description": "",
686
+ "syntax": "",
687
+ "path": "/products/glacier-ice",
688
+ "raw_liquid": "{% if product.compare_at_price > product.price %}\n This product is on sale!\n{% endif %}",
689
+ "parameter": false,
690
+ "display_type": "text",
691
+ "show_data_tab": true
692
+ },
693
+ {
694
+ "name": "elsif",
695
+ "description": "You can use the `elsif` tag to check for multiple conditions.",
696
+ "syntax": "",
697
+ "path": "/products/health-potion",
698
+ "raw_liquid": "{% if product.type == 'Love' %}\n This is a love potion!\n{% elsif product.type == 'Health' %}\n This is a health potion!\n{% endif %}",
699
+ "parameter": false,
700
+ "display_type": "text",
701
+ "show_data_tab": true
702
+ }
703
+ ]
704
+ },
705
+ {
706
+ "category": "theme",
707
+ "deprecated": true,
708
+ "deprecation_reason": "Deprecated because the way that variables are handled reduces performance and makes code harder to both read and maintain.\n\nThe `include` tag has been replaced by [`render`](/api/liquid/tags/render).",
709
+ "description": "Inside the snippet, you can access and alter variables that are [created](/api/liquid/tags/variable-tags) outside of the\nsnippet.",
710
+ "parameters": [
711
+
712
+ ],
713
+ "summary": "Renders a [snippet](/themes/architecture#snippets).",
714
+ "name": "include",
715
+ "syntax": "{% include 'filename' %}",
716
+ "syntax_keywords": [
717
+ {
718
+ "keyword": "filename",
719
+ "description": "The name of the snippet to render, without the `.liquid` extension."
720
+ }
721
+ ],
722
+ "examples": [
723
+
724
+ ]
725
+ },
726
+ {
727
+ "category": "variable",
728
+ "deprecated": false,
729
+ "deprecation_reason": "",
730
+ "description": "Variables that are declared with `increment` are unique to the [layout](/themes/architecture/layouts), [template](/themes/architecture/templates),\nor [section](/themes/architecture/sections) file that they're created in. However, the variable is shared across\n[snippets](/themes/architecture#snippets) included in the file.\n\nSimilarly, variables that are created with `increment` are independent from those created with [`assign`](/api/liquid/tags/assign)\nand [`capture`](/api/liquid/tags/capture). However, `increment` and [`decrement`](/api/liquid/tags/decrement) share\nvariables.",
731
+ "parameters": [
732
+
733
+ ],
734
+ "summary": "Creates a new variable, with a default value of 0, that's increased by 1 with each subsequent call.",
735
+ "name": "increment",
736
+ "syntax": "{% increment variable_name %}",
737
+ "syntax_keywords": [
738
+ {
739
+ "keyword": "variable_name",
740
+ "description": "The name of the variable being incremented."
741
+ }
742
+ ],
743
+ "examples": [
744
+ {
745
+ "name": "",
746
+ "description": "",
747
+ "syntax": "",
748
+ "path": "/",
749
+ "raw_liquid": "{% increment variable %}\n{% increment variable %}\n{% increment variable %}",
750
+ "parameter": false,
751
+ "display_type": "text",
752
+ "show_data_tab": true
753
+ }
754
+ ]
755
+ },
756
+ {
757
+ "category": "syntax",
758
+ "deprecated": false,
759
+ "deprecation_reason": "",
760
+ "description": "",
761
+ "parameters": [
762
+
763
+ ],
764
+ "summary": "Outputs any Liquid code as text instead of rendering it.",
765
+ "name": "raw",
766
+ "syntax": "{% raw %}\n expression\n{% endraw %}",
767
+ "syntax_keywords": [
768
+ {
769
+ "keyword": "expression",
770
+ "description": "The expression to be output without being rendered."
771
+ }
772
+ ],
773
+ "examples": [
774
+ {
775
+ "name": "",
776
+ "description": "",
777
+ "syntax": "",
778
+ "path": "/",
779
+ "raw_liquid": "{% raw %}\n{{ 2 | plus: 2 }} equals 4.\n{% endraw %}",
780
+ "parameter": false,
781
+ "display_type": "text",
782
+ "show_data_tab": true
783
+ }
784
+ ]
785
+ },
786
+ {
787
+ "category": "theme",
788
+ "deprecated": false,
789
+ "deprecation_reason": "",
790
+ "description": "Inside snippets and app blocks, you can't directly access variables that are [created](/api/liquid/tags/variable-tags) outside\nof the snippet or app block. However, you can [specify variables as parameters](/api/liquid/tags/render#render-passing-variables-to-a-snippet)\nto pass outside variables to snippets.\n\nWhile you can't directly access created variables, you can access global objects, as well as any objects that are\ndirectly accessible outside the snippet or app block. For example, a snippet or app block inside the [product template](/themes/architecture/templates/product)\ncan access the [`product` object](/api/liquid/objects/product), and a snippet or app block inside a [section](/themes/architecture/sections)\ncan access the [`section` object](/api/liquid/objects/section).\n\nOutside a snippet or app block, you can't access variables created inside the snippet or app block.\n\n> Note:\n> When you render a snippet using the `render` tag, you can't use the [`include` tag](/api/liquid/tags/include)\n> inside the snippet.",
791
+ "parameters": [
792
+
793
+ ],
794
+ "summary": "Renders a [snippet](/themes/architecture#snippets) or [app block](/themes/architecture/sections/section-schema#render-app-blocks).",
795
+ "name": "render",
796
+ "syntax": "{% render 'filename' %}",
797
+ "syntax_keywords": [
798
+ {
799
+ "keyword": "filename",
800
+ "description": "The name of the snippet to render, without the `.liquid` extension."
801
+ }
802
+ ],
803
+ "examples": [
804
+ {
805
+ "name": "for",
806
+ "description": "You can render a snippet for every item in an array using the `for` parameter. You can also supply an optional `as` parameter to be able to reference the current item in the iteration inside the snippet.\nAdditionally, you can access a [`forloop` object](/api/liquid/objects/forloop) for the loop inside the snippet.\n",
807
+ "syntax": "{% render 'filename' for array as item %}",
808
+ "path": "/",
809
+ "raw_liquid": "",
810
+ "parameter": true,
811
+ "display_type": "text",
812
+ "show_data_tab": true
813
+ },
814
+ {
815
+ "name": "Passing variables to a snippet",
816
+ "description": "Variables that have been [created](/api/liquid/tags/variable-tags) outside of a snippet can be passed to a snippet as parameters on the `render` tag.\n\n> Note:\n> Any changes that are made to a passed variable apply only within the snippet.\n",
817
+ "syntax": "{% render 'filename', variable: value %}",
818
+ "path": "/",
819
+ "raw_liquid": "",
820
+ "parameter": true,
821
+ "display_type": "text",
822
+ "show_data_tab": true
823
+ },
824
+ {
825
+ "name": "with",
826
+ "description": "You can pass a single object to a snippet using the `with` parameter. You can also supply an optional `as` parameter to specify a custom name to reference the object inside the snippet.\n",
827
+ "syntax": "{% render 'filename' with object as name %}",
828
+ "path": "/",
829
+ "raw_liquid": "",
830
+ "parameter": true,
831
+ "display_type": "text",
832
+ "show_data_tab": true
833
+ }
834
+ ]
835
+ },
836
+ {
837
+ "category": "iteration",
838
+ "deprecated": false,
839
+ "deprecation_reason": "",
840
+ "description": "The `tablerow` tag must be wrapped in HTML `<table>` and `</table>` tags.\n\n> Tip:\n> Every `tablerow` loop has an associated [`tablerowloop` object](/api/liquid/objects/tablerowloop) with information about the loop.",
841
+ "parameters": [
842
+ {
843
+ "description": "The number of columns that the table should have.",
844
+ "name": "cols",
845
+ "required": false,
846
+ "types": [
847
+ "number"
848
+ ]
849
+ },
850
+ {
851
+ "description": "The number of iterations to perform.",
852
+ "name": "limit",
853
+ "required": false,
854
+ "types": [
855
+ "number"
856
+ ]
857
+ },
858
+ {
859
+ "description": "The 1-based index to start iterating at.",
860
+ "name": "offset",
861
+ "required": false,
862
+ "types": [
863
+ "number"
864
+ ]
865
+ },
866
+ {
867
+ "description": "A custom numeric range to iterate over.",
868
+ "name": "range",
869
+ "required": false,
870
+ "types": [
871
+ "untyped"
872
+ ]
873
+ }
874
+ ],
875
+ "summary": "Generates HTML table rows for every item in an array.",
876
+ "name": "tablerow",
877
+ "syntax": "{% tablerow variable in array %}\n expression\n{% endtablerow %}",
878
+ "syntax_keywords": [
879
+ {
880
+ "keyword": "variable",
881
+ "description": "The current item in the array."
882
+ },
883
+ {
884
+ "keyword": "array",
885
+ "description": "The array to iterate over."
886
+ },
887
+ {
888
+ "keyword": "expression",
889
+ "description": "The expression to render."
890
+ }
891
+ ],
892
+ "examples": [
893
+ {
894
+ "name": "",
895
+ "description": "",
896
+ "syntax": "",
897
+ "path": "/collections/sale-potions",
898
+ "raw_liquid": "<table>\n {% tablerow product in collection.products %}\n {{ product.title }}\n {% endtablerow %}\n</table>",
899
+ "parameter": false,
900
+ "display_type": "text",
901
+ "show_data_tab": true
902
+ },
903
+ {
904
+ "name": "cols",
905
+ "description": "You can define how many columns the table should have using the `cols` parameter.",
906
+ "syntax": "{% tablerow variable in array cols: number %}\n expression\n{% endtablerow %}\n",
907
+ "path": "/collections/sale-potions",
908
+ "raw_liquid": "<table>\n {% tablerow product in collection.products cols: 2 %}\n {{ product.title }}\n {% endtablerow %}\n</table>",
909
+ "parameter": true,
910
+ "display_type": "text",
911
+ "show_data_tab": true
912
+ },
913
+ {
914
+ "name": "limit",
915
+ "description": "You can limit the number of iterations using the `limit` parameter.",
916
+ "syntax": "{% tablerow variable in array limit: number %}\n expression\n{% endtablerow %}\n",
917
+ "path": "/collections/sale-potions",
918
+ "raw_liquid": "<table>\n {% tablerow product in collection.products limit: 2 %}\n {{ product.title }}\n {% endtablerow %}\n</table>",
919
+ "parameter": true,
920
+ "display_type": "text",
921
+ "show_data_tab": true
922
+ },
923
+ {
924
+ "name": "offset",
925
+ "description": "You can specify a 1-based index to start iterating at using the `offset` parameter.",
926
+ "syntax": "{% tablerow variable in array offset: number %}\n expression\n{% endtablerow %}\n",
927
+ "path": "/collections/sale-potions",
928
+ "raw_liquid": "<table>\n {% tablerow product in collection.products offset: 2 %}\n {{ product.title }}\n {% endtablerow %}\n</table>",
929
+ "parameter": true,
930
+ "display_type": "text",
931
+ "show_data_tab": true
932
+ },
933
+ {
934
+ "name": "range",
935
+ "description": "Instead of iterating over specific items in an array, you can specify a numeric range to iterate over.\n\n> Note:\n> You can define the range using both literal and variable values.\n",
936
+ "syntax": "{% tablerow variable in (number..number) %}\n expression\n{% endtablerow %}\n",
937
+ "path": "/",
938
+ "raw_liquid": "<table>\n {% tablerow i in (1..3) %}\n {{ i }}\n {% endtablerow %}\n</table>\n\n{%- assign lower_limit = 2 -%}\n{%- assign upper_limit = 4 -%}\n\n<table>\n {% tablerow i in (lower_limit..upper_limit) %}\n {{ i }}\n {% endtablerow %}\n</table>",
939
+ "parameter": true,
940
+ "display_type": "text",
941
+ "show_data_tab": true
942
+ }
943
+ ]
944
+ },
945
+ {
946
+ "category": "conditional",
947
+ "deprecated": false,
948
+ "deprecation_reason": "",
949
+ "description": "> Tip:\n> Similar to the [`if` tag](/api/liquid/tags/if), you can use `elsif` to add more conditions to an `unless` tag.",
950
+ "parameters": [
951
+
952
+ ],
953
+ "summary": "Renders an expression unless a specific condition is `true`.",
954
+ "name": "unless",
955
+ "syntax": "{% unless condition %}\n expression\n{% endunless %}",
956
+ "syntax_keywords": [
957
+ {
958
+ "keyword": "condition",
959
+ "description": "The condition to evaluate."
960
+ },
961
+ {
962
+ "keyword": "expression",
963
+ "description": "The expression to render unless the condition is met."
964
+ }
965
+ ],
966
+ "examples": [
967
+ {
968
+ "name": "",
969
+ "description": "",
970
+ "syntax": "",
971
+ "path": "/products/health-potion",
972
+ "raw_liquid": "{% unless product.has_only_default_variant %}\n // Variant selection functionality\n{% endunless %}",
973
+ "parameter": false,
974
+ "display_type": "text",
975
+ "show_data_tab": true
976
+ }
977
+ ]
978
+ },
979
+ {
980
+ "category": "iteration",
981
+ "deprecated": false,
982
+ "deprecation_reason": "",
983
+ "description": "Because [`for` loops](/api/liquid/tags/for) are limited to 50 iterations per page, you need to use the `paginate` tag to\niterate over an array that has more than 50 items. The following arrays can be paginated:\n\n- [`all_products`](/api/liquid/objects/all_products)\n- [`article.comments`](/api/liquid/objects/article#article-comments)\n- [`blog.articles`](/api/liquid/objects/blog#blog-articles)\n- [`collections`](/api/liquid/objects/collections)\n- [`collection.products`](/api/liquid/objects/collection#collection-products)\n- [`customer.addresses`](/api/liquid/objects/customer#customer-addresses)\n- [`customer.orders`](/api/liquid/objects/customer#customer-orders)\n- [`pages`](/api/liquid/objects/pages)\n- [`search.results`](/api/liquid/objects/search#search-results)\n- [`collection_list` settings](/themes/architecture/settings/input-settings#collection_list)\n- [`product_list` settings](/themes/architecture/settings/input-settings#product_list)\n\nWithin the `paginate` tag, you have access to the [`paginate` object](/api/liquid/objects/paginate). You can use this\nobject, or the [`default_pagination` filter](/api/liquid/filters/default_pagination), to build page navigation.",
984
+ "parameters": [
985
+ {
986
+ "description": "The number of pages to display in the pagination.",
987
+ "name": "window_size",
988
+ "required": false,
989
+ "types": [
990
+ "string"
991
+ ]
992
+ }
993
+ ],
994
+ "summary": "Splits an array's items across multiple pages.",
995
+ "name": "paginate",
996
+ "syntax": "{% paginate array by page_size %}\n {% for item in array %}\n forloop_content\n {% endfor %}\n{% endpaginate %}",
997
+ "syntax_keywords": [
998
+ {
999
+ "keyword": "array",
1000
+ "description": "The array to be looped over."
1001
+ },
1002
+ {
1003
+ "keyword": "page_size",
1004
+ "description": "The number of array items to include per page, between 1 and 50."
1005
+ },
1006
+ {
1007
+ "keyword": "item",
1008
+ "description": "An item in the array being looped."
1009
+ },
1010
+ {
1011
+ "keyword": "forloop_content",
1012
+ "description": "Content for each loop iteration."
1013
+ }
1014
+ ],
1015
+ "examples": [
1016
+ {
1017
+ "name": "",
1018
+ "description": "",
1019
+ "syntax": "",
1020
+ "path": "/collections/all",
1021
+ "raw_liquid": "{% paginate collection.products by 5 %}\n {% for product in collection.products -%}\n {{ product.title }}\n {%- endfor %}\n\n {{- paginate | default_pagination }}\n{% endpaginate %}",
1022
+ "parameter": false,
1023
+ "display_type": "text",
1024
+ "show_data_tab": true
1025
+ },
1026
+ {
1027
+ "name": "Paginating setting arrays",
1028
+ "description": "To allow the pagination of `product_list` and `collection_list` settings to operate independently from other paginated lists on a page, these lists use a pagination query parameter with a unique key. The key is automatically assigned by the `paginate` tag, and you don't need to reference the key in your code. However, you can access the key using [`paginate.page_param`](/api/liquid/objects/paginate#paginate-page_param).\n\n> Tip:\n> To paginate two arrays independently without refreshing the entire page, you can use the [Section Rendering API](/api/section-rendering).\n",
1029
+ "syntax": "",
1030
+ "path": "/",
1031
+ "raw_liquid": "",
1032
+ "parameter": false,
1033
+ "display_type": "text",
1034
+ "show_data_tab": true
1035
+ },
1036
+ {
1037
+ "name": "window_size",
1038
+ "description": "Set the window size of the pagination. The window size is the number of pages that should be visible in the pagination navigation.\n",
1039
+ "syntax": "{% paginate collection.products by 3, window_size: '1' %}",
1040
+ "path": "/collections/all",
1041
+ "raw_liquid": "{% paginate collection.products by 3, window_size: '1' %}\n {% for product in collection.products -%}\n {{ product.title }}\n {%- endfor %}\n\n {{- paginate | default_pagination }}\n{% endpaginate %}",
1042
+ "parameter": true,
1043
+ "display_type": "text",
1044
+ "show_data_tab": true
1045
+ }
1046
+ ]
1047
+ },
1048
+ {
1049
+ "category": "theme",
1050
+ "deprecated": false,
1051
+ "deprecation_reason": "",
1052
+ "description": "You need to use these tags only if your section or app block is meant to be installed on multiple themes or stores. Otherwise, you should include the JavaScript that your section needs in your theme's [`assets`](/themes/architecture#assets) directory. Each section or app block can have only one `{% javascript %}` tag.\n\nTo learn more about how section-specific JavaScript is loaded and run, refer to the documentation for [sections](/themes/architecture/sections/section-assets#javascript).\n> Caution:\n> Liquid isn't rendered inside of `{% javascript %}` tags. Including Liquid code can cause syntax errors.",
1053
+ "parameters": [
1054
+
1055
+ ],
1056
+ "summary": "JavaScript code included in a [section](/themes/architecture/sections) file.",
1057
+ "name": "javascript",
1058
+ "syntax": "{% javascript %}\n javascript_code\n{% endjavascript %}",
1059
+ "syntax_keywords": [
1060
+ {
1061
+ "keyword": "javascript_code",
1062
+ "description": "The JavaScript code for the section."
1063
+ }
1064
+ ],
1065
+ "examples": [
1066
+
1067
+ ]
1068
+ },
1069
+ {
1070
+ "category": "theme",
1071
+ "deprecated": false,
1072
+ "deprecation_reason": "",
1073
+ "description": "Rendering a section with the `section` tag renders a section statically. To learn more about sections and how to use\nthem in your theme, refer to [Render a section](/themes/architecture/sections#render-a-section).",
1074
+ "parameters": [
1075
+
1076
+ ],
1077
+ "summary": "Renders a [section](/themes/architecture/sections).",
1078
+ "name": "section",
1079
+ "syntax": "{% section 'name' %}",
1080
+ "syntax_keywords": [
1081
+ {
1082
+ "keyword": "name",
1083
+ "description": "The name of the section file you want to render."
1084
+ }
1085
+ ],
1086
+ "examples": [
1087
+ {
1088
+ "name": "",
1089
+ "description": "",
1090
+ "syntax": "",
1091
+ "path": "/",
1092
+ "raw_liquid": "{% section 'header' %}",
1093
+ "parameter": false,
1094
+ "display_type": "text",
1095
+ "show_data_tab": true
1096
+ }
1097
+ ]
1098
+ },
1099
+ {
1100
+ "category": "theme",
1101
+ "deprecated": false,
1102
+ "deprecation_reason": "",
1103
+ "description": "You need to use these tags only if your section or app block is meant to be installed on multiple themes or stores. Otherwise, you should include the JavaScript that your section needs in your theme's [`assets`](/themes/architecture#assets) directory. Each section or app block can have only one `{% stylesheet %}` tag.\n\nTo learn more about how section-specific CSS is loaded and run, refer to the documentation for [sections](/themes/architecture/sections/section-assets#stylesheet).\n> Caution:\n> Liquid isn't rendered inside of `{% stylesheet %}` tags. Including Liquid code can cause syntax errors.",
1104
+ "parameters": [
1105
+
1106
+ ],
1107
+ "summary": "CSS styles included in a [section](/themes/architecture/sections) file.",
1108
+ "name": "stylesheet",
1109
+ "syntax": "{% stylesheet %}\n css_styles\n{% endstylesheet %}",
1110
+ "syntax_keywords": [
1111
+ {
1112
+ "keyword": "css_styles",
1113
+ "description": "The CSS styles for the section."
1114
+ }
1115
+ ],
1116
+ "examples": [
1117
+
1118
+ ]
1119
+ },
1120
+ {
1121
+ "category": "html",
1122
+ "deprecated": false,
1123
+ "deprecation_reason": "",
1124
+ "description": "> Note:\n> If you reference [color settings](/themes/architecture/settings/input-settings#color) inside `style` tags, then\n> the associated CSS rules will update as the setting is changed in the theme editor, without a page refresh.",
1125
+ "parameters": [
1126
+
1127
+ ],
1128
+ "summary": "Generates an HTML `<style>` tag with an attribute of `data-shopify`.",
1129
+ "name": "style",
1130
+ "syntax": "{% style %}\n CSS_rules\n{% endstyle %}",
1131
+ "syntax_keywords": [
1132
+ {
1133
+ "keyword": "CSS_rules",
1134
+ "description": "The desired CSS rules for the `<style>` tag."
1135
+ }
1136
+ ],
1137
+ "examples": [
1138
+ {
1139
+ "name": "",
1140
+ "description": "",
1141
+ "syntax": "",
1142
+ "path": "/",
1143
+ "raw_liquid": "{% style %}\n .h1 {\n color: {{ settings.colors_accent_1 }};\n }\n{% endstyle %}",
1144
+ "parameter": false,
1145
+ "display_type": "text",
1146
+ "show_data_tab": true
1147
+ }
1148
+ ]
1149
+ },
1150
+ {
1151
+ "category": "conditional",
1152
+ "deprecated": false,
1153
+ "deprecation_reason": "",
1154
+ "description": "You can use the `else` tag with the following tags:\n\n- [`case`](/api/liquid/tags/case)\n- [`if`](/api/liquid/tags/if)\n- [`unless`](/api/liquid/tags/unless)",
1155
+ "parameters": [
1156
+
1157
+ ],
1158
+ "summary": "Allows you to specify a default expression to execute when no other condition is met.",
1159
+ "name": "else",
1160
+ "syntax": "{% else %}\n expression",
1161
+ "syntax_keywords": [
1162
+ {
1163
+ "keyword": "expression",
1164
+ "description": "The expression to render if no other condition is met."
1165
+ }
1166
+ ],
1167
+ "examples": [
1168
+ {
1169
+ "name": "",
1170
+ "description": "",
1171
+ "syntax": "",
1172
+ "path": "/products/health-potion",
1173
+ "raw_liquid": "{% if product.available %}\n This product is available!\n{% else %}\n This product is sold out!\n{% endif %}",
1174
+ "parameter": false,
1175
+ "display_type": "text",
1176
+ "show_data_tab": true
1177
+ }
1178
+ ]
1179
+ },
1180
+ {
1181
+ "category": "iteration",
1182
+ "deprecated": false,
1183
+ "deprecation_reason": "",
1184
+ "description": "",
1185
+ "parameters": [
1186
+
1187
+ ],
1188
+ "summary": "Allows you to specify a default expression to execute when a [`for` loop](/api/liquid/tags/for) has zero length.",
1189
+ "name": "else",
1190
+ "syntax": "{% for variable in array %}\n first_expression\n{% else %}\n second_expression\n{% endfor %}",
1191
+ "syntax_keywords": [
1192
+ {
1193
+ "keyword": "variable",
1194
+ "description": "The current item in the array."
1195
+ },
1196
+ {
1197
+ "keyword": "array",
1198
+ "description": "The array to iterate over."
1199
+ },
1200
+ {
1201
+ "keyword": "first_expression",
1202
+ "description": "The expression to render for each iteration."
1203
+ },
1204
+ {
1205
+ "keyword": "second_expression",
1206
+ "description": "The expression to render if the loop has zero length."
1207
+ }
1208
+ ],
1209
+ "examples": [
1210
+ {
1211
+ "name": "",
1212
+ "description": "",
1213
+ "syntax": "",
1214
+ "path": "/collections/empty",
1215
+ "raw_liquid": "{% for product in collection.products %}\n {{ product.title }}<br>\n{% else %}\n There are no products in this collection.\n{% endfor %}",
1216
+ "parameter": false,
1217
+ "display_type": "text",
1218
+ "show_data_tab": true
1219
+ }
1220
+ ]
1221
+ },
1222
+ {
1223
+ "category": "syntax",
1224
+ "deprecated": false,
1225
+ "deprecation_reason": "",
1226
+ "description": "Because the tags don't have delimeters, each tag needs to be on its own line.\n\n> Tip:\n> Use the [`echo` tag](/api/liquid/tags/echo) to output an expression inside `liquid` tags.",
1227
+ "parameters": [
1228
+
1229
+ ],
1230
+ "summary": "Allows you to have a block of Liquid without delimeters on each tag.",
1231
+ "name": "liquid",
1232
+ "syntax": "{% liquid\n expression\n%}",
1233
+ "syntax_keywords": [
1234
+ {
1235
+ "keyword": "expression",
1236
+ "description": "The expression to be rendered inside the `liquid` tag."
1237
+ }
1238
+ ],
1239
+ "examples": [
1240
+ {
1241
+ "name": "",
1242
+ "description": "",
1243
+ "syntax": "",
1244
+ "path": "/products/health-potion",
1245
+ "raw_liquid": "{% liquid\n # Show a message that's customized to the product type\n\n assign product_type = product.type | downcase\n assign message = ''\n\n case product_type\n when 'health'\n assign message = 'This is a health potion!'\n when 'love'\n assign message = 'This is a love potion!'\n else\n assign message = 'This is a potion!'\n endcase\n\n echo message\n%}",
1246
+ "parameter": false,
1247
+ "display_type": "text",
1248
+ "show_data_tab": true
1249
+ }
1250
+ ]
1251
+ }
1252
+ ]