platformos-check 0.4.11 → 0.4.13

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/build_for_windows.yml +57 -0
  3. data/CHANGELOG.md +11 -0
  4. data/CONTRIBUTING.md +20 -18
  5. data/README.md +108 -57
  6. data/RELEASING.md +14 -7
  7. data/TROUBLESHOOTING.md +19 -10
  8. data/build/windows/build.sh +3 -2
  9. data/data/platformos_liquid/documentation/filters.json +1 -1
  10. data/data/platformos_liquid/documentation/latest.json +1 -1
  11. data/data/platformos_liquid/documentation/tags.json +1 -1
  12. data/docs/api/check.md +7 -6
  13. data/docs/api/html_check.md +12 -13
  14. data/docs/api/liquid_check.md +17 -21
  15. data/docs/api/yaml_check.md +3 -3
  16. data/docs/checks/TEMPLATE.md.erb +16 -11
  17. data/docs/checks/convert_include_to_render.md +29 -13
  18. data/docs/checks/deprecated_filter.md +5 -9
  19. data/docs/checks/form_action.md +12 -12
  20. data/docs/checks/form_authenticity_token.md +21 -15
  21. data/docs/checks/graphql_in_for_loop.md +15 -13
  22. data/docs/checks/html_parsing_error.md +12 -12
  23. data/docs/checks/img_lazy_loading.md +13 -11
  24. data/docs/checks/img_width_and_height.md +21 -23
  25. data/docs/checks/include_in_render.md +11 -11
  26. data/docs/checks/invalid_args.md +11 -11
  27. data/docs/checks/liquid_tag.md +12 -12
  28. data/docs/checks/missing_enable_comment.md +7 -7
  29. data/docs/checks/missing_template.md +14 -13
  30. data/docs/checks/parse_json_format.md +15 -14
  31. data/docs/checks/parser_blocking_javascript.md +19 -14
  32. data/docs/checks/required_layout_object.md +5 -7
  33. data/docs/checks/space_inside_braces.md +12 -12
  34. data/docs/checks/syntax_error.md +10 -10
  35. data/docs/checks/template_length.md +12 -12
  36. data/docs/checks/translation_files_match.md +10 -11
  37. data/docs/checks/translation_key_exists.md +10 -11
  38. data/docs/checks/undefined_object.md +11 -13
  39. data/docs/checks/unknown_filter.md +11 -11
  40. data/docs/checks/unreachable_code.md +11 -11
  41. data/docs/checks/unused_assign.md +11 -11
  42. data/docs/checks/unused_partial.md +7 -11
  43. data/docs/checks/valid_yaml.md +11 -11
  44. data/docs/language_server/how_to_correct_code_with_code_actions_and_execute_command.md +62 -70
  45. data/lib/platformos_check/language_server/completion_providers/filter_completion_provider.rb +1 -1
  46. data/lib/platformos_check/language_server/handler.rb +7 -6
  47. data/lib/platformos_check/language_server/variable_lookup_finder.rb +8 -10
  48. data/lib/platformos_check/platformos_liquid/documentation.rb +2 -2
  49. data/lib/platformos_check/version.rb +1 -1
  50. data/platformos-check.gemspec +1 -1
  51. metadata +6 -6
  52. data/build/windows/lsp.exe +0 -0
@@ -1,2 +1,2 @@
1
1
 
2
- {"revision":"b724c2c1372a98abd7bf03a146c88f8bc86a5f6b"}
2
+ {"revision":"f54926032237f368cd5f4737ddb64d8522474225"}
@@ -1,6 +1,6 @@
1
1
 
2
2
 
3
3
 
4
- [{"category":"variable","deprecated":false,"deprecation_reason":"","description":"You can create variables of any [basic type](/docs/api/liquid/basics#types), [object](/docs/api/liquid/objects), or object property.","parameters":[],"summary":"Creates a new variable.","name":"assign","syntax":"{% assign variable_name = value %}","syntax_keywords":[{"keyword":"variable_name","description":"The name of the variable being created."},{"keyword":"value","description":"The value you want to assign to the variable."}],"examples":[{"name":"","description":"","syntax":"","path":"/products/health-potion","raw_liquid":"{%- assign product_title = product.title | upcase -%}\n\n{{ product_title }}","parameter":false,"display_type":"text","show_data_tab":true}]},{"category":"platformOS","deprecated":false,"deprecation_reason":"","description":"Invokes code within the tag asynchronously, in the background.\nYou will only have access to variables you explicitly pass to the background tag. The context object is available by default, but with limitations - you need\nto explicitly pass page/layout metadata if you want to use it, as well as device and constants.","syntax":"Run background code from partial\nThe following code will run all the log queries in the background, not earlier than 0.5 minute (30 seconds) since the execution. You will only have access to variables\nexplicitly provided to the background tag: \"data\" and \"hey\". Note that you will not have access to the \"my_data\" variable. Also note\nthat the result of this background tag will not be rendered, and you will not have access to any variable inside the background tag.\n\n# app/views/partials/example_partial.liquid\n{% liquid\n log not_available_in_background # Will be null, as this variable was not passed to the background tag\n log data # You will see { \"hello\": \"world\" }, as it was provided to the background tag\n log hey # You will see \"hello\" as it was provided to the background tag\n log context # You will copy the current request context and make it available in the background\n assign not_available_outside = \"You will not see me\"\n\n%}\n\n# app/views/pages/test.liquid\n{% liquid\n assign my_data = null | hash_merge: hello: \"world\"\n assign not_available_in_job = \"You will not see me \"\n background job_id = 'example_partial', delay: 0.1, max_attempts: 3, source_name: 'custom_job', data: my_data, hey: 'hello'\n\n # This variable will be rendered in the background, meaning you won't see anything on the page\n echo not_available_outside\n%}","name":"background","parameters":[{"description":"Any variable provided to the background tag will become accessible in the code.","name":"options","required":false,"types":["untyped"]},{"description":"which defines the number of minutes to delay running code (defaults to 0, which means run code as soon as possible)","name":"options.delay","required":false,"types":["untyped"]},{"description":"low, default or high - see AsyncCallbackPriorityEnum GraphQL Object","name":"options.priority","required":false,"types":["untyped"]},{"description":"the number of time to re-try job upon failing. Default is 1, maximum is 5","name":"options.max_attempts","required":false,"types":["untyped"]},{"description":"your label of the job, which would help you identify it","name":"options.source_name","required":false,"types":["untyped"]}],"return_type":[],"examples":[{"name":"","description":"","syntax":"","path":"","raw_liquid":"Run background code from partial\nThe following code will run all the log queries in the background, not earlier than 0.5 minute (30 seconds) since the execution. You will only have access to variables\nexplicitly provided to the background tag: \"data\" and \"hey\". Note that you will not have access to the \"my_data\" variable. Also note\nthat the result of this background tag will not be rendered, and you will not have access to any variable inside the background tag.\n\n# app/views/partials/example_partial.liquid\n{% liquid\n log not_available_in_background # Will be null, as this variable was not passed to the background tag\n log data # You will see { \"hello\": \"world\" }, as it was provided to the background tag\n log hey # You will see \"hello\" as it was provided to the background tag\n log context # You will copy the current request context and make it available in the background\n assign not_available_outside = \"You will not see me\"\n\n%}\n\n# app/views/pages/test.liquid\n{% liquid\n assign my_data = null | hash_merge: hello: \"world\"\n assign not_available_in_job = \"You will not see me \"\n background job_id = 'example_partial', delay: 0.1, max_attempts: 3, source_name: 'custom_job', data: my_data, hey: 'hello'\n\n # This variable will be rendered in the background, meaning you won't see anything on the page\n echo not_available_outside\n%}","parameter":false,"display_type":"text","show_data_tab":true},{"name":"","description":"","syntax":"","path":"","raw_liquid":"Deprecated\nThe following code will run all the log queries in the background, not earlier than 0.5 minute (30 seconds) since the execution. You will only have access to variables\nexplicitly provided to the background tag: \"data\" and \"hey\". Note that you will not have access to the \"my_data\" variable. Also note\nthat the result of this background tag will not be rendered, and you will not have access to any variable inside the background tag.\n\n{% parse_json my_data %}{ \"hello\": \"world\" }{% endparse_json %}\n{% assign not_available_in_background = \"You will not see me\" %}\n{% background priority: 'low', delay: 0.5, max_attempts: 3, source_name: \"my custom job\", data: my_data, hey: 'hello' %}\n {% log not_available_in_background %} {% comment %}Will be null, as this variable was not passed to the background tag {% endcomment %}\n {% log data %} {% comment %}You will see { \"hello\": \"world\" }, as it was provided to the background tag{% endcomment %}\n {% log hey %} {% comment %}You will see \"hello\" as it was provided to the background tag{% endcomment %}\n {% log context %} {% comment %}You will copy the current request context and make it available in the background{% endcomment %}\n {% assign not_available_outside = \"You will not see me\" %}\n {{ not_available_outside }} {% comment %}This variable will be rendered in the background, meaning you won't see anything on the page{% endcomment %}\n{% endbackground %}\n{{ not_available_outside }} {% comment %}This will be blank, because the assign will happen in the background - you won't have access to it here{% endcomment %}","parameter":false,"display_type":"text","show_data_tab":true}]},{"category":"iteration","deprecated":false,"deprecation_reason":"","description":"","parameters":[],"summary":"Stops a [`for` loop](/docs/api/liquid/tags/for) from iterating.","name":"break","syntax":"{% break %}","syntax_keywords":[],"examples":[{"name":"","description":"","syntax":"","path":"/","raw_liquid":"{% for i in (1..5) -%}\n {%- if i == 4 -%}\n {% break %}\n {%- else -%}\n {{ i }}\n {%- endif -%}\n{%- endfor %}","parameter":false,"display_type":"text","show_data_tab":true}]},{"category":"platformOS","deprecated":false,"deprecation_reason":"","description":"Checks if there's string cached for the given key. If yes, it just returns the value without processing\nanything inside the cache tag, otherwise it executes code, stores the result in the cache.\nWhen you hit the page with such code for the first time, the code will be executed and hence it will iterate through the loop\nand generate random strings. However, then the result of the block will be cached and all the following requests within 20 seconds\nwould not invoke the code - instead, it would just take the value from the cache. The output will not change. When the cache expires,\nthe code will be evaluated again, producing another set of random string.\nCache is automatically invalidated if any changes are applied to any view/translation.","syntax":"{% cache 'this is my key', expire: 20 %}\n \u003cul\u003e\n {% for i in (1..100) %}\n \u003cli\u003e{{ 18 | random_string }}\u003c/li\u003e\n {% endfor %}\n \u003c/ul\u003e\n{% endcache %}","name":"cache","parameters":[{"description":"the key which should uniquely identify the cached fragment","name":"key","required":false,"types":["untyped"]},{"description":"optional. number of seconds since populating the cache to expiration","name":"expire","required":false,"types":["untyped"]}],"return_type":[],"examples":[{"name":"","description":"","syntax":"","path":"","raw_liquid":"{% cache 'this is my key', expire: 20 %}\n \u003cul\u003e\n {% for i in (1..100) %}\n \u003cli\u003e{{ 18 | random_string }}\u003c/li\u003e\n {% endfor %}\n \u003c/ul\u003e\n{% endcache %}","parameter":false,"display_type":"text","show_data_tab":true},{"name":"","description":"","syntax":"","path":"","raw_liquid":"{% parse_json pagesUpdatedAt %}\n {%- cache pagesUpdatedAtCache -%}\n {%- graphql g = 'pages_updated_at' | dig: 'admin_pages', 'results' -%}\n {{- g -}}\n {%- endcache -%}\n{% endparse_json %}\n{%- export pagesUpdatedAt, namespace: 'nav' -%}","parameter":false,"display_type":"text","show_data_tab":true}]},{"category":"variable","deprecated":false,"deprecation_reason":"","description":"You can create complex strings with Liquid logic and variables.","parameters":[],"summary":"Creates a new variable with a string value.","name":"capture","syntax":"{% capture variable %}\n value\n{% endcapture %}","syntax_keywords":[{"keyword":"variable","description":"The name of the variable being created."},{"keyword":"value","description":"The value you want to assign to the variable."}],"examples":[{"name":"","description":"","syntax":"","path":"/products/health-potion","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 }}","parameter":false,"display_type":"text","show_data_tab":true}]},{"category":"conditional","deprecated":false,"deprecation_reason":"","description":"","parameters":[],"summary":"Renders a specific expression depending on the value of a specific variable.","name":"case","syntax":"{% case variable %}\n {% when first_value %}\n first_expression\n {% when second_value %}\n second_expression\n {% else %}\n third_expression\n{% endcase %}","syntax_keywords":[{"keyword":"variable","description":"The name of the variable you want to base your case statement on."},{"keyword":"first_value","description":"A specific value to check for."},{"keyword":"second_value","description":"A specific value to check for."},{"keyword":"first_expression","description":"An expression to be rendered when the variable's value matches `first_value`."},{"keyword":"second_expression","description":"An expression to be rendered when the variable's value matches `second_value`."},{"keyword":"third_expression","description":"An expression to be rendered when the variable's value has no match."}],"examples":[{"name":"","description":"","syntax":"","path":"/products/health-potion","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 %}","parameter":false,"display_type":"text","show_data_tab":true},{"name":"Multiple values","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","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","path":"/products/health-potion","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 %}","parameter":false,"display_type":"text","show_data_tab":true}]},{"category":"syntax","deprecated":false,"deprecation_reason":"","description":"Any text inside `comment` tags won't be output, and any Liquid code will be parsed, but not executed.","parameters":[],"summary":"Prevents an expression from being rendered or output.","name":"comment","syntax":"{% comment %}\n content\n{% endcomment %}","syntax_keywords":[{"keyword":"content","description":"The content of the comment."}],"examples":[{"name":"Inline comments","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","syntax":"{% # content %}","path":"/","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%}","parameter":false,"display_type":"text","show_data_tab":true},{"name":"Inline comments inside `liquid` tags","description":"You can use inline comment tags inside [`liquid` tags](/docs/api/liquid/tags/liquid). The tag must be used for each line that you want to comment.\n","syntax":"","path":"/","raw_liquid":"{% liquid\n # this is a comment\n assign topic = 'Learning about comments!'\n echo topic\n%}","parameter":false,"display_type":"text","show_data_tab":true}]},{"category":"platformOS","deprecated":false,"deprecation_reason":"","description":"Stores a block of markup in an identifier for later use.\nRender it later with `yield` tag.","syntax":"{% content_for 'header' %}\n Hello world\n{% endcontent_for %}","name":"content_for","parameters":[{"description":"the markups will be stored under this name","name":"name","required":false,"types":["untyped"]},{"description":"optional. If the flush parameter is true content_for replaces the blocks it is given instead of appending content to the existing one","name":"flush","required":false,"types":["untyped"]}],"return_type":[],"examples":[{"name":"","description":"","syntax":"","path":"","raw_liquid":"{% content_for 'header' %}\n Hello world\n{% endcontent_for %}","parameter":false,"display_type":"text","show_data_tab":true}]},{"category":"platformOS","deprecated":false,"deprecation_reason":"","description":"Set locale in context to given language","syntax":"{% context language: 'de' %}","name":"context","parameters":[{"description":"language 2 letter","name":"language","required":false,"types":["untyped"]}],"return_type":[],"examples":[{"name":"","description":"","syntax":"","path":"","raw_liquid":"{% context language: 'de' %}","parameter":false,"display_type":"text","show_data_tab":true}]},{"category":"iteration","deprecated":false,"deprecation_reason":"","description":"","parameters":[],"summary":"Causes a [`for` loop](/docs/api/liquid/tags/for) to skip to the next iteration.","name":"continue","syntax":"{% continue %}","syntax_keywords":[],"examples":[{"name":"","description":"","syntax":"","path":"/","raw_liquid":"{% for i in (1..5) -%}\n {%- if i == 4 -%}\n {% continue %}\n {%- else -%}\n {{ i }}\n {%- endif -%}\n{%- endfor %}","parameter":false,"display_type":"text","show_data_tab":true}]},{"category":"iteration","deprecated":false,"deprecation_reason":"","description":"The `cycle` tag must be used inside a `for` loop.\n\n\u003e Tip:\n\u003e Use the `cycle` tag to output text in a predictable pattern. For example, to apply odd/even classes to rows in a table.","parameters":[],"summary":"Loops through a group of strings and outputs them one at a time for each iteration of a [`for` loop](/docs/api/liquid/tags/for).","name":"cycle","syntax":"{% cycle string, string, ... %}","syntax_keywords":[],"examples":[{"name":"","description":"","syntax":"","path":"/","raw_liquid":"{% for i in (1..4) -%}\n {% cycle 'one', 'two', 'three' %}\n{%- endfor %}","parameter":false,"display_type":"text","show_data_tab":true},{"name":"Create unique cycle groups","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","syntax":"{% cycle string: string, string, ... %}","path":"/","raw_liquid":"\u003c!-- Iteration 1 --\u003e\n{% for i in (1..4) -%}\n {% cycle 'one', 'two', 'three' %}\n{%- endfor %}\n\n\u003c!-- Iteration 2 --\u003e\n{% for i in (1..4) -%}\n {% cycle 'one', 'two', 'three' %}\n{%- endfor %}\n\n\u003c!-- Iteration 3 --\u003e\n{% for i in (1..4) -%}\n {% cycle 'group_1': 'one', 'two', 'three' %}\n{%- endfor %}\n\n\u003c!-- Iteration 4 --\u003e\n{% for i in (1..4) -%}\n {% cycle 'group_2': 'one', 'two', 'three' %}\n{%- endfor %}","parameter":false,"display_type":"text","show_data_tab":true}]},{"category":"variable","deprecated":false,"deprecation_reason":"","description":"Variables that are declared with `decrement` are unique to the [partial](/developer-guide/platformos-workflow/codebase#views-pages-layouts-and-partials), [template](/themes/architecture/templates),\nor [section](/themes/architecture/sections) file that they're created in. However, the variable is shared across\n[partial](/developer-guide/platformos-workflow/codebase#views-pages-layouts-and-partials) included in the file.\n\nSimilarly, variables that are created with `decrement` are independent from those created with [`assign`](/docs/api/liquid/tags/assign)\nand [`capture`](/docs/api/liquid/tags/capture). However, `decrement` and [`increment`](/docs/api/liquid/tags/increment) share\nvariables.","parameters":[],"summary":"Creates a new variable, with a default value of -1, that's decreased by 1 with each subsequent call.","name":"decrement","syntax":"{% decrement variable_name %}","syntax_keywords":[{"keyword":"variable_name","description":"The name of the variable being decremented."}],"examples":[{"name":"","description":"","syntax":"","path":"/","raw_liquid":"{% decrement variable %}\n{% decrement variable %}\n{% decrement variable %}","parameter":false,"display_type":"text","show_data_tab":true}]},{"category":"syntax","deprecated":false,"deprecation_reason":"","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](/docs/api/liquid/tags/liquid).\n\n\u003e Tip:\n\u003e You can use [filters](/docs/api/liquid/filters) on expressions inside `echo` tags.","parameters":[],"summary":"Outputs an expression.","name":"echo","syntax":"{% liquid\n echo expression\n%}","syntax_keywords":[{"keyword":"expression","description":"The expression to be output."}],"examples":[{"name":"","description":"","syntax":"","path":"/products/health-potion","raw_liquid":"{% echo product.title %}\n\n{% liquid\n echo product.price | money\n%}","parameter":false,"display_type":"text","show_data_tab":true}]},{"category":"conditional","deprecated":false,"deprecation_reason":"","description":"You can use the `else` tag with the following tags:\n\n- [`case`](/docs/api/liquid/tags/case)\n- [`if`](/docs/api/liquid/tags/if)\n- [`unless`](/docs/api/liquid/tags/unless)","parameters":[],"summary":"Allows you to specify a default expression to execute when no other condition is met.","name":"else","syntax":"{% else %}\n expression","syntax_keywords":[{"keyword":"expression","description":"The expression to render if no other condition is met."}],"examples":[{"name":"","description":"","syntax":"","path":"/products/health-potion","raw_liquid":"{% if product.available %}\n This product is available!\n{% else %}\n This product is sold out!\n{% endif %}","parameter":false,"display_type":"text","show_data_tab":true}]},{"category":"iteration","deprecated":false,"deprecation_reason":"","description":"","parameters":[],"summary":"Allows you to specify a default expression to execute when a [`for` loop](/docs/api/liquid/tags/for) has zero length.","name":"else","syntax":"{% for variable in array %}\n first_expression\n{% else %}\n second_expression\n{% endfor %}","syntax_keywords":[{"keyword":"variable","description":"The current item in the array."},{"keyword":"array","description":"The array to iterate over."},{"keyword":"first_expression","description":"The expression to render for each iteration."},{"keyword":"second_expression","description":"The expression to render if the loop has zero length."}],"examples":[{"name":"","description":"","syntax":"","path":"/collections/empty","raw_liquid":"{% for product in collection.products %}\n {{ product.title }}\u003cbr\u003e\n{% else %}\n There are no products in this collection.\n{% endfor %}","parameter":false,"display_type":"text","show_data_tab":true}]},{"category":"platformOS","deprecated":false,"deprecation_reason":"","description":"Makes variables defined inside partial accessible anywhere via context.exports.`namespace`","syntax":"{% liquid\n assign a = 'value for a'\n assign b = 'value for b'\n export a, b, namespace: 'my_hash'\n%}\n\n{{ context.exports.my_hash }} =\u003e { \"a\": \"value for a\", \"b\": \"value for b\" }\n{% parse_json company %}\n{\n \"name\": \"platformOS\",\n \"technologies\": [\"liquid\", \"graphql\"],\n \"countries\": { \"USA\": 5, \"Poland\": 5, \"Romania\": 2 }\n}\n{% endparse_json %}\n\n{% export company, namespace: 'data' %}\n\n{{ context.exports.data }} =\u003e\n {\"company\"=\u003e{\"name\"=\u003e\"platformOS\", \"technologies\"=\u003e[\"liquid\", \"graphql\"], \"countries\"=\u003e{\"USA\"=\u003e5, \"Poland\"=\u003e5, \"Romania\"=\u003e2}}}\n{{ context.exports.data.company.technologies }} =\u003e liquidgraphql\n{{ context.exports.data.company.name }} =\u003e platformOS","name":"export","parameters":[{"description":"variable to be stored inside the namespace","name":"variable","required":false,"types":["untyped"]},{"description":"namespace under which variable will be in context.exports","name":"namespace","required":false,"types":["untyped"]}],"return_type":[],"examples":[{"name":"","description":"","syntax":"","path":"","raw_liquid":"{% liquid\n assign a = 'value for a'\n assign b = 'value for b'\n export a, b, namespace: 'my_hash'\n%}\n\n{{ context.exports.my_hash }} =\u003e { \"a\": \"value for a\", \"b\": \"value for b\" }\n{% parse_json company %}\n{\n \"name\": \"platformOS\",\n \"technologies\": [\"liquid\", \"graphql\"],\n \"countries\": { \"USA\": 5, \"Poland\": 5, \"Romania\": 2 }\n}\n{% endparse_json %}\n\n{% export company, namespace: 'data' %}\n\n{{ context.exports.data }} =\u003e\n {\"company\"=\u003e{\"name\"=\u003e\"platformOS\", \"technologies\"=\u003e[\"liquid\", \"graphql\"], \"countries\"=\u003e{\"USA\"=\u003e5, \"Poland\"=\u003e5, \"Romania\"=\u003e2}}}\n{{ context.exports.data.company.technologies }} =\u003e liquidgraphql\n{{ context.exports.data.company.name }} =\u003e platformOS","parameter":false,"display_type":"text","show_data_tab":true}]},{"category":"iteration","deprecated":false,"deprecation_reason":"","description":"Every `for` loop has an associated [`forloop` object](/api-reference/liquid/loops#helper-variables) with information about the loop.","parameters":[{"description":"The number of iterations to perform.","name":"limit","required":false,"types":["number"]},{"description":"The 1-based index to start iterating at.","name":"offset","required":false,"types":["number"]},{"description":"A custom numeric range to iterate over.","name":"range","required":false,"types":["untyped"]},{"description":"Iterate in reverse order.","name":"reversed","required":false,"types":["untyped"]}],"summary":"Renders an expression for every item in an array.","name":"for","syntax":"{% for variable in array %}\n expression\n{% endfor %}","syntax_keywords":[{"keyword":"variable","description":"The current item in the array."},{"keyword":"array","description":"The array to iterate over."},{"keyword":"expression","description":"The expression to render for each iteration."}],"examples":[{"name":"","description":"","syntax":"","path":"/collections/sale-potions","raw_liquid":"{% for product in collection.products -%}\n {{ product.title }}\n{%- endfor %}","parameter":false,"display_type":"text","show_data_tab":true},{"name":"limit","description":"You can limit the number of iterations using the `limit` parameter.","syntax":"{% for variable in array limit: number %}\n expression\n{% endfor %}\n","path":"/collections/sale-potions","raw_liquid":"{% for product in collection.products limit: 2 -%}\n {{ product.title }}\n{%- endfor %}","parameter":true,"display_type":"text","show_data_tab":true},{"name":"offset","description":"You can specify a 1-based index to start iterating at using the `offset` parameter.","syntax":"{% for variable in array offset: number %}\n expression\n{% endfor %}\n","path":"/collections/sale-potions","raw_liquid":"{% for product in collection.products offset: 2 -%}\n {{ product.title }}\n{%- endfor %}","parameter":true,"display_type":"text","show_data_tab":true},{"name":"range","description":"Instead of iterating over specific items in an array, you can specify a numeric range to iterate over.\n\n\u003e Note:\n\u003e You can define the range using both literal and variable values.\n","syntax":"{% for variable in (number..number) %}\n expression\n{% endfor %}\n","path":"/collections/all","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 %}","parameter":true,"display_type":"text","show_data_tab":true},{"name":"reversed","description":"You can iterate in reverse order using the `reversed` parameter.","syntax":"{% for variable in array reversed %}\n expression\n{% endfor %}\n","path":"/collections/sale-potions","raw_liquid":"{% for product in collection.products reversed -%}\n {{ product.title }}\n{%- endfor %}","parameter":true,"display_type":"text","show_data_tab":true}]},{"category":"platformOS","deprecated":false,"deprecation_reason":"","description":"Used to generate a html form element for a resource. Use within `form configuration`.\nInside the tag you can use `form_builder` variable.","syntax":"{% form %}\n {{ form_builder }}\n{% endform %}","name":"form","parameters":[{"description":"set id attribute in `\u003cform id=\"\"\u003e` element","name":"html-id","required":false,"types":["untyped"]},{"description":"add `novalidate` attribute to `\u003cform novalidate\u003e` element","name":"html-novalidate","required":false,"types":["untyped"]},{"description":"add css class `\u003cform class=\"\"\u003e` element","name":"html-class","required":false,"types":["untyped"]},{"description":"add `enctype=\"multipart/form-data\"` attribute to `\u003cform enctype=\"multipart/form-data\"\u003e` element.\nMultipart is enabled by default","name":"html-multipart","required":false,"types":["untyped"]},{"description":"[String] add data attribute to `\u003cform data-[attr]=\"\"\u003e` element","name":"html-data-","required":false,"types":["untyped"]}],"return_type":[],"examples":[{"name":"","description":"","syntax":"","path":"","raw_liquid":"{% form %}\n {{ form_builder }}\n{% endform %}","parameter":false,"display_type":"text","show_data_tab":true},{"name":"","description":"","syntax":"","path":"","raw_liquid":"{% form html-id: 'someid', html-novalidate: true, html-class: 'big-form green-form', html-data-user-id: '12345', html-multipart: false %}\n{% endform %}","parameter":false,"display_type":"text","show_data_tab":true}]},{"category":"platformOS","deprecated":false,"deprecation_reason":"","description":"Allows to store a variable returned by a partial. Partial needs to return data with `return` tag.\nAll variables needs to be passed explicitly to function. Variables from upper scope are not visible in function.\n*Note:* `context` is not available inside the function partial unless explicitly passed as a variable.","syntax":"{% function res = 'path/to/my/partial', arg1: 'hello' %}","name":"function","parameters":[],"return_type":[],"examples":[{"name":"","description":"","syntax":"","path":"","raw_liquid":"{% function res = 'path/to/my/partial', arg1: 'hello' %}","parameter":false,"display_type":"text","show_data_tab":true},{"name":"","description":"","syntax":"","path":"","raw_liquid":"# path/to/my/partial\n{% liquid\n assign res = 'hello' | append: foo | append: ' ' | append: context.location.host\n return res\n%}\n# path/to/my/partial\n\n{% liquid\n assign foo = 'hello'\n function res = 'path/to/my/partial', foo: foo, context: context\n%}","parameter":false,"display_type":"text","show_data_tab":true}]},{"category":"platformOS","deprecated":false,"deprecation_reason":"","description":"Used to execute GraphQL query stored in a file or invoke GraphQL query inline. All arguments provided to the tag will be passed to GraphQL.\nIt returns a hash with the data or the errors that occurred (for example, variable type mismatch, required variable not provided,\nsyntax error) etc.","syntax":"Invoke query \"get_models\" and store the result in variable \"g\":\n{% graphql g = \"get_models\", model_id: context.params.slug2 %}","name":"graphql","parameters":[{"description":"name of the GraphQL query. For get_users.graphql file name of the query is get_users","name":"query_name","required":false,"types":["untyped"]},{"description":"optional. key:value pair(s) which will be passed to GraphQL query. For example, if\nyour query looks like `query my_query($email: String!)`, then you can provide `email: \"my-email@example.com\"`","name":"arguments","required":false,"types":["untyped"]},{"description":"optional. Either a Hash or a String) of the arguments which will be passed to GraphQL query. See examples below.","name":"args","required":false,"types":["untyped"]}],"return_type":[],"examples":[{"name":"","description":"","syntax":"","path":"","raw_liquid":"Invoke query \"get_models\" and store the result in variable \"g\":\n{% graphql g = \"get_models\", model_id: context.params.slug2 %}","parameter":false,"display_type":"text","show_data_tab":true},{"name":"","description":"","syntax":"","path":"","raw_liquid":"Chain filters to extract results in one line:\n{% graphql g = \"get_models\", model_id: context.params.slug2 | fetch: 'models' | fetch: 'results' %}","parameter":false,"display_type":"text","show_data_tab":true},{"name":"","description":"","syntax":"","path":"","raw_liquid":"Pass all arguments at once as a hash to have graphql tag in one line and/or compose arguments hash dynamically:\n{% parse_json arguments %}\n {\n \"model_id\": {{ context.params.slug2 | json }},\n \"user_id\": {{ context.params.user_id | json }}\n }\n{% endparse_json %}\n\n{% graphql g = \"get_models\", args: arguments %}","parameter":false,"display_type":"text","show_data_tab":true},{"name":"","description":"","syntax":"","path":"","raw_liquid":"Pass all arguments at once as a JSON string:\n\n{% capture arguments %}\n{\n \"per_page\": 20,\n \"page\": 2\n}\n{% endcapture %}\n\n{% graphql g = \"get_models\", args: arguments %}","parameter":false,"display_type":"text","show_data_tab":true},{"name":"","description":"","syntax":"","path":"","raw_liquid":"Invoke inline query and store the result in variable \"g\". This is recommended for one-time used queries.\n\n{% graphql g, id: context.params.slug2, message: \"new message\" %}\n mutation set_message($id: ID!, $message: String!) {\n model_update(\n id: $id\n model: {\n properties: [{ name: \"message\", value: $message }]\n }\n ) {\n id\n message: property(name: \"message\")\n }\n }\n{% endgraphql %}","parameter":false,"display_type":"text","show_data_tab":true}]},{"category":"platformOS","deprecated":false,"deprecation_reason":"","description":"Allows to easily modify a Hash with a syntax same as assign tag.","syntax":"{% parse_json my_hash %}{ \"a\": { \"b\": { \"c\": \"12\", \"d\": \"hello\" } } }{% endparse_json %}\n{% hash_assign my_hash[\"a\"][\"e\"] = \"assign\" | upcase %}\n{{ my_hash }} =\u003e {\"a\":{\"b\":{\"c\":\"12\",\"d\":\"hello\"},\"e\":\"ASSIGN\"}}","name":"hash_assign","parameters":[],"return_type":[],"examples":[{"name":"","description":"","syntax":"","path":"","raw_liquid":"{% parse_json my_hash %}{ \"a\": { \"b\": { \"c\": \"12\", \"d\": \"hello\" } } }{% endparse_json %}\n{% hash_assign my_hash[\"a\"][\"e\"] = \"assign\" | upcase %}\n{{ my_hash }} =\u003e {\"a\":{\"b\":{\"c\":\"12\",\"d\":\"hello\"},\"e\":\"ASSIGN\"}}","parameter":false,"display_type":"text","show_data_tab":true},{"name":"","description":"","syntax":"","path":"","raw_liquid":"{% parse_json my_hash %}{ \"a\": { \"b\": { \"c\": \"12\", \"d\": \"hello\" } } }{% endparse_json %}\n{% hash_assign my_hash[\"a\"][\"b\"][\"d\"] = \"bye\" | upcase %}\n{{ my_hash }} =\u003e {\"a\":{\"b\":{\"c\":\"12\",\"d\":\"BYE\"}}}","parameter":false,"display_type":"text","show_data_tab":true},{"name":"","description":"","syntax":"","path":"","raw_liquid":"{% parse_json my_hash %}{ \"a\": { \"b\": { \"c\": \"12\", \"d\": \"hello\" } } }{% endparse_json %}\n{% hash_assign my_hash[\"a\"][\"b\"] = null %}\n{{ my_hash }} =\u003e {\"a\":{\"b\":null}}","parameter":false,"display_type":"text","show_data_tab":true},{"name":"","description":"","syntax":"","path":"","raw_liquid":"{% parse_json my_hash %}{ \"a\": { \"b\": { \"c\": \"12\", \"d\": \"hello\" } } }{% endparse_json %}\n{% hash_assign my_hash[\"a\"][\"b\"][\"c\"][\"e\"] = \"bye\" | upcase %}) =\u003e HashAssignTagError: Liquid error: my_hash[a][b][c] is 12, expected Hash","parameter":false,"display_type":"text","show_data_tab":true}]},{"category":"conditional","deprecated":false,"deprecation_reason":"","description":"","parameters":[],"summary":"Renders an expression if a specific condition is `true`.","name":"if","syntax":"{% if condition %}\n expression\n{% endif %}","syntax_keywords":[{"keyword":"condition","description":"The condition to evaluate."},{"keyword":"expression","description":"The expression to render if the condition is met."}],"examples":[{"name":"","description":"","syntax":"","path":"/products/glacier-ice","raw_liquid":"{% if product.compare_at_price \u003e product.price %}\n This product is on sale!\n{% endif %}","parameter":false,"display_type":"text","show_data_tab":true},{"name":"elsif","description":"You can use the `elsif` tag to check for multiple conditions.","syntax":"","path":"/products/health-potion","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 %}","parameter":false,"display_type":"text","show_data_tab":true}]},{"category":"theme","deprecated":true,"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`](/docs/api/liquid/tags/render).","description":"Inside the partial, you can access and alter variables that are [created](/docs/api/liquid/tags/variable-tags) outside of the\npartial.","parameters":[],"summary":"Renders a [partial](/developer-guide/platformos-workflow/codebase#views-pages-layouts-and-partials).","name":"include","syntax":"{% include 'filename' %}","syntax_keywords":[{"keyword":"filename","description":"The name of the partial to render, without the `.liquid` extension."}],"examples":[]},{"category":"platformOS","deprecated":false,"deprecation_reason":"","description":"This tag should be used to render forms defined in forms directory","syntax":"{% include_form 'signup_form' %}","name":"include_form","parameters":[{"description":"name of the form configuration from forms directory","name":"form_name","required":false,"types":["untyped"]},{"description":"id of the resource you want to edit","name":"id","required":false,"types":["untyped"]},{"description":"name of the resource type, f.e. name of custom_model_type, transactable_type, user_profile_type","name":"parent_resource_id","required":false,"types":["untyped"]}],"return_type":[],"examples":[{"name":"","description":"","syntax":"","path":"","raw_liquid":"{% include_form 'signup_form' %}","parameter":false,"display_type":"text","show_data_tab":true},{"name":"","description":"","syntax":"","path":"","raw_liquid":"{% include_form 'edit_user', id: user.id %}","parameter":false,"display_type":"text","show_data_tab":true},{"name":"","description":"","syntax":"","path":"","raw_liquid":"{% include_form 'manager_invite_to_interview', parent_resource_id: 'invitation', user: g.user %}","parameter":false,"display_type":"text","show_data_tab":true}]},{"category":"variable","deprecated":false,"deprecation_reason":"","description":"Variables that are declared with `increment` are unique to the [partial](/developer-guide/platformos-workflow/codebase#views-pages-layouts-and-partials), [template](/themes/architecture/templates),\nor [section](/themes/architecture/sections) file that they're created in. However, the variable is shared across\n[partial](/developer-guide/platformos-workflow/codebase#views-pages-layouts-and-partials) included in the file.\n\nSimilarly, variables that are created with `increment` are independent from those created with [`assign`](/docs/api/liquid/tags/assign)\nand [`capture`](/docs/api/liquid/tags/capture). However, `increment` and [`decrement`](/docs/api/liquid/tags/decrement) share\nvariables.","parameters":[],"summary":"Creates a new variable, with a default value of 0, that's increased by 1 with each subsequent call.","name":"increment","syntax":"{% increment variable_name %}","syntax_keywords":[{"keyword":"variable_name","description":"The name of the variable being incremented."}],"examples":[{"name":"","description":"","syntax":"","path":"/","raw_liquid":"{% increment variable %}\n{% increment variable %}\n{% increment variable %}","parameter":false,"display_type":"text","show_data_tab":true}]},{"category":"syntax","deprecated":false,"deprecation_reason":"","description":"Because the tags don't have delimeters, each tag needs to be on its own line.\n\n\u003e Tip:\n\u003e Use the [`echo` tag](/docs/api/liquid/tags/echo) to output an expression inside `liquid` tags.","parameters":[],"summary":"Allows you to have a block of Liquid without delimeters on each tag.","name":"liquid","syntax":"{% liquid\n expression\n%}","syntax_keywords":[{"keyword":"expression","description":"The expression to be rendered inside the `liquid` tag."}],"examples":[{"name":"","description":"","syntax":"","path":"/products/health-potion","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%}","parameter":false,"display_type":"text","show_data_tab":true}]},{"category":"platformOS","deprecated":false,"deprecation_reason":"","description":"Print information to environment logs. To view logs run `pos-cli gui serve \u003cenvironment\u003e` in your application directory and go to `http://localhost:3333/Logs`. If you prefer seeing logs in the terminal, run `pos-cli gui logs \u003cenvironment\u003e`","syntax":"{% log 'hello world' %}","name":"log","parameters":[{"description":"Any object that can be printed","name":"message","required":false,"types":["untyped"]},{"description":"type of log entry. Use it to tag your logs to make it easier to differentiate logs. If you set it to 'error' pos-cli will also notify your OS about it if your OS supports it.","name":"type","required":false,"types":["untyped"]},{"description":"environment where the entry should be created; can be any of 'all', 'staging', 'production'. Default: 'all'","name":"env","required":false,"types":["untyped"]}],"return_type":[],"examples":[{"name":"","description":"","syntax":"","path":"","raw_liquid":"{% log 'hello world' %}","parameter":false,"display_type":"text","show_data_tab":true},{"name":"","description":"","syntax":"","path":"","raw_liquid":"{% log params, type: 'request-params' %}","parameter":false,"display_type":"text","show_data_tab":true},{"name":"","description":"","syntax":"","path":"","raw_liquid":"{% log user.id, type: 'debug' %}","parameter":false,"display_type":"text","show_data_tab":true},{"name":"","description":"","syntax":"","path":"","raw_liquid":"{% log context.current_user, type: 'error' %}","parameter":false,"display_type":"text","show_data_tab":true},{"name":"","description":"","syntax":"","path":"","raw_liquid":"{% log context.current_user, type: 'error', env: 'staging' %}","parameter":false,"display_type":"text","show_data_tab":true}]},{"category":"platformOS","deprecated":false,"deprecation_reason":"","description":"Captures and parses the JSON string inside of the opening and closing tags and assigns it to a variable.","syntax":"{% parse_json car %}\n { \"type\": \"SUV\", \"gearbox\": \"AT\" }\n{% endparse_json %}\n\n{{ car }} =\u003e {\"type\"=\u003e\"SUV\", \"gearbox\"=\u003e\"AT\"}\n{{ car.type }} =\u003e SUV","name":"parse_json","parameters":[{"description":"variable name that will be used to assign contents after it is parsed","name":"variable_name","required":false,"types":["untyped"]},{"description":"valid JSON string to be assigned","name":"content","required":false,"types":["untyped"]}],"return_type":[],"examples":[{"name":"","description":"","syntax":"","path":"","raw_liquid":"{% parse_json car %}\n { \"type\": \"SUV\", \"gearbox\": \"AT\" }\n{% endparse_json %}\n\n{{ car }} =\u003e {\"type\"=\u003e\"SUV\", \"gearbox\"=\u003e\"AT\"}\n{{ car.type }} =\u003e SUV","parameter":false,"display_type":"text","show_data_tab":true},{"name":"","description":"","syntax":"","path":"","raw_liquid":"{% parse_json cars %}\n [\n { \"maker\": \"Honda\", \"model\": \"CRX\" },\n { \"maker\": \"Subaru\", \"model\": \"Forester\"},\n { \"maker\": \"Lexus\", \"model\": \"LFA\" }\n ]\n{% endparse_json %}\n\n{{ cars }} =\u003e {\"maker\"=\u003e\"Honda\", \"model\"=\u003e\"CRX\"}{\"maker\"=\u003e\"Subaru\", \"model\"=\u003e\"Forester\"}{\"maker\"=\u003e\"Lexus\", \"model\"=\u003e\"LFA\"}","parameter":false,"display_type":"text","show_data_tab":true},{"name":"","description":"","syntax":"","path":"","raw_liquid":"In order to create JSON object from exsting values print them using `json` filter.\nThis is required only for strings and will escape properly `\"` and `'` characters.\nOther types will be handled automatically.\n\n{% parse_json nested %}\n {\n \"price\": 100\n }\n{% endparse_json %}\n{% assign color = \"red\" %}\n{% assign car = 'Mazda \"5\"' %}\n{% parse_json data %}\n {\n \"color\": {{ color | json }},\n \"car\": {{ car | json }},\n \"nested\": {{ nested }}\n }\n{% endparse_json %}\n\n{{ data }} =\u003e {\"color\":\"red\",\"car\":\"Mazda \\\"5\\\"\",\"nested\":{\"price\":100}}","parameter":false,"display_type":"text","show_data_tab":true}]},{"category":"platformOS","deprecated":false,"deprecation_reason":"","description":"Print variable, skipping any additional sanitization. It provides a way to display a variable which consists of both safe and unsafe html.\nWarning: Do not use it with data entered by users as it is gonna cause XSS.","syntax":"{% liquid\n assign invokable_script = \"\u003cscript\u003ealert('I will be executed')\u003c/script\u003e\"\n assign malicious_script = \"\u003cscript\u003ealert('I should be escaped')\u003c/script\u003e\"\n%}\n{% capture result %}\n {{ malicious_script }}{{ invokable_script | html_safe }}\n{% endcapture %}\n{% print result %}","name":"print","parameters":[{"description":"Variable containing safe and potentially unsafe HTML","name":"variable","required":false,"types":["untyped"]}],"return_type":[],"examples":[{"name":"","description":"","syntax":"","path":"","raw_liquid":"{% liquid\n assign invokable_script = \"\u003cscript\u003ealert('I will be executed')\u003c/script\u003e\"\n assign malicious_script = \"\u003cscript\u003ealert('I should be escaped')\u003c/script\u003e\"\n%}\n{% capture result %}\n {{ malicious_script }}{{ invokable_script | html_safe }}\n{% endcapture %}\n{% print result %}","parameter":false,"display_type":"text","show_data_tab":true}]},{"category":"syntax","deprecated":false,"deprecation_reason":"","description":"","parameters":[],"summary":"Outputs any Liquid code as text instead of rendering it.","name":"raw","syntax":"{% raw %}\n expression\n{ % endraw %}","syntax_keywords":[{"keyword":"expression","description":"The expression to be output without being rendered."}],"examples":[{"name":"","description":"","syntax":"","path":"/","raw_liquid":"{% raw %}\n{{ 2 | plus: 2 }} equals 4.\n{ % endraw %}","parameter":false,"display_type":"text","show_data_tab":true}]},{"category":"platformOS","deprecated":false,"deprecation_reason":"","description":"Redirects browser to target","syntax":"{% redirect_to '/dashboard' %}","name":"redirect_to","parameters":[{"description":"path or url","name":"target","required":false,"types":["untyped"]},{"description":"3xx HTTP code, default 302","name":"status","required":false,"types":["untyped"]}],"return_type":[],"examples":[{"name":"","description":"","syntax":"","path":"","raw_liquid":"{% redirect_to '/dashboard' %}","parameter":false,"display_type":"text","show_data_tab":true},{"name":"","description":"","syntax":"","path":"","raw_liquid":"{% redirect_to 'https://example.com/signup' %}","parameter":false,"display_type":"text","show_data_tab":true},{"name":"","description":"","syntax":"","path":"","raw_liquid":"{% redirect_to '/dashboard', status: 301 %}","parameter":false,"display_type":"text","show_data_tab":true}]},{"category":"theme","deprecated":false,"deprecation_reason":"","description":"Inside partial, you can't directly access variables that are [created](/docs/api/liquid/tags/variable-tags) outside\nof the partial. However, you can specify variables as parameters\nto pass outside variables to partials.\n\nWhile you can't directly access created variables, you can access global objects like `context`.\n\nOutside a partial, you can't access variables created inside it.\n\n\u003e Note:\n\u003e When you render a partial using the `render` tag, you can't use the [`include` tag](/docs/api/liquid/tags/include)\n\u003e inside the partial.","parameters":[],"summary":"Renders a [partial](/developer-guide/platformos-workflow/codebase#views-pages-layouts-and-partials).","name":"render","syntax":"{% render 'filename' %}","syntax_keywords":[{"keyword":"filename","description":"The name of the partial to render, without the `.liquid` extension and `views/partials` or `lib` prefix."}],"examples":[{"name":"for","description":"You can render a partial 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 partial.\nAdditionally, you can access a [`forloop` object](/docs/api/liquid/objects/forloop) for the loop inside the partial.\n","syntax":"{% render 'filename' for array as item %}","path":"/","raw_liquid":"{% render 'filename' for array as item %}","parameter":true,"display_type":"text","show_data_tab":true},{"name":"Passing variables to a partial","description":"Variables that have been [created](/docs/api/liquid/tags/variable-tags) outside of a partial can be passed to a partial as parameters on the `render` tag.\n\n\u003e Note:\n\u003e Any changes that are made to a passed variable apply only within the partial, unless it is an array or hash.\n","syntax":"{% render 'filename', variable: value %}","path":"/","raw_liquid":"{% render 'filename', variable: value %}","parameter":true,"display_type":"text","show_data_tab":true},{"name":"with","description":"You can pass a single object to a partial using the `with` parameter. You can also supply an optional `as` parameter to specify a custom name to reference the object inside the partial.\n","syntax":"{% render 'filename' with object as name %}","path":"/","raw_liquid":"{% render 'filename' with object as name %}","parameter":true,"display_type":"text","show_data_tab":true}]},{"category":"platformOS","deprecated":false,"deprecation_reason":"","description":"Allows you to set additional HTTP headers for the response.","syntax":"{% response_headers '{\"foo\": \"bar\"}' %}","name":"response_headers","parameters":[{"description":"headers as JSON string, default {}","name":"headers","required":false,"types":["untyped"]}],"return_type":[],"examples":[{"name":"","description":"","syntax":"","path":"","raw_liquid":"{% response_headers '{\"foo\": \"bar\"}' %}","parameter":false,"display_type":"text","show_data_tab":true},{"name":"","description":"","syntax":"","path":"","raw_liquid":"{% response_headers '{\"Content-Type\": \"application/json\", \"X-Frame-Options\": \"somevalue\" }' %}","parameter":false,"display_type":"text","show_data_tab":true}]},{"category":"platformOS","deprecated":false,"deprecation_reason":"","description":"Allows you to set HTTP status for the response. Default 200.","syntax":"{% response_status 204 %}","name":"response_status","parameters":[{"description":"HTTP status, default 200","name":"status","required":false,"types":["untyped"]}],"return_type":[],"examples":[{"name":"","description":"","syntax":"","path":"","raw_liquid":"{% response_status 204 %}","parameter":false,"display_type":"text","show_data_tab":true},{"name":"","description":"","syntax":"","path":"","raw_liquid":"{% response_status 404 %}","parameter":false,"display_type":"text","show_data_tab":true}]},{"category":"platformOS","deprecated":false,"deprecation_reason":"","description":"Used inside a partial invoked by a function tag to return a variable","syntax":"{% liquid\n assign result = 1 | plus: 3\n return result\n%}","name":"return","parameters":[],"return_type":[],"examples":[{"name":"","description":"","syntax":"","path":"","raw_liquid":"{% liquid\n assign result = 1 | plus: 3\n return result\n%}","parameter":false,"display_type":"text","show_data_tab":true}]},{"category":"platformOS","deprecated":false,"deprecation_reason":"","description":"Stores data during user's session\nSets field of given name to given value in context.session","syntax":"{% session foo = 'bar' %}\n{{ context.session | json }} =\u003e { \"foo\": \"bar\" }","name":"session","parameters":[],"return_type":[],"examples":[{"name":"","description":"","syntax":"","path":"","raw_liquid":"{% session foo = 'bar' %}\n{{ context.session | json }} =\u003e { \"foo\": \"bar\" }","parameter":false,"display_type":"text","show_data_tab":true},{"name":"","description":"","syntax":"","path":"","raw_liquid":"{% assign bar = \"42\" }\n{% session foo = bar %}\n{{ context.session | json }} =\u003e { \"foo\": \"42\" }","parameter":false,"display_type":"text","show_data_tab":true},{"name":"","description":"","syntax":"","path":"","raw_liquid":"{% session foo = null %}\n{{ context.session | json }} =\u003e {}","parameter":false,"display_type":"text","show_data_tab":true},{"name":"","description":"","syntax":"","path":"","raw_liquid":"{% session foo = blank %}\n{{ context.session | json }} =\u003e {}","parameter":false,"display_type":"text","show_data_tab":true}]},{"category":"platformOS","deprecated":false,"deprecation_reason":"","description":"Sign in user","syntax":"{% sign_in user_id: '12345' %}","name":"sign_in","parameters":[{"description":"id of the user you want to sign in","name":"user_id","required":false,"types":["untyped"]},{"description":"number of minutes after user will be log out","name":"timeout_in_minutes","required":false,"types":["untyped"]}],"return_type":[],"examples":[{"name":"","description":"","syntax":"","path":"","raw_liquid":"{% sign_in user_id: '12345' %}","parameter":false,"display_type":"text","show_data_tab":true},{"name":"","description":"","syntax":"","path":"","raw_liquid":"{% sign_in user_id: '12345', timeout_in_minutes: 15 %}","parameter":false,"display_type":"text","show_data_tab":true}]},{"category":"platformOS","deprecated":false,"deprecation_reason":"","description":"Generates html for spam protection. Supports Google reCAPTCHA strategies: recaptcha_v2, recaptcha_v3 and hcaptcha","syntax":"{% form %}\n {% spam_protection \"recaptcha_v2\" %}\n{% endform %}","name":"spam_protection","parameters":[{"description":"name of protection strategy. Default is recaptcha_v2","name":"strategy","required":false,"types":["untyped"]},{"description":"action name for reCAPTCHA V3, action may only contain alphanumeric characters and slashes","name":"action","required":false,"types":["untyped"]}],"return_type":[],"examples":[{"name":"","description":"","syntax":"","path":"","raw_liquid":"{% form %}\n {% spam_protection \"recaptcha_v2\" %}\n{% endform %}","parameter":false,"display_type":"text","show_data_tab":true},{"name":"","description":"","syntax":"","path":"","raw_liquid":"{% form %}\n {% spam_protection \"recaptcha_v3\", action: \"signup\" %}\n{% endform %}","parameter":false,"display_type":"text","show_data_tab":true},{"name":"","description":"","syntax":"","path":"","raw_liquid":"{% form %}\n {% spam_protection \"hcaptcha\" %}\n{% endform %}","parameter":false,"display_type":"text","show_data_tab":true}]},{"category":"iteration","deprecated":false,"deprecation_reason":"","description":"The `tablerow` tag must be wrapped in HTML `\u003ctable\u003e` and `\u003c/table\u003e` tags.\n\n\u003e Tip:\n\u003e Every `tablerow` loop has an associated [`tablerowloop` object](/docs/api/liquid/objects/tablerowloop) with information about the loop.","parameters":[{"description":"The number of columns that the table should have.","name":"cols","required":false,"types":["number"]},{"description":"The number of iterations to perform.","name":"limit","required":false,"types":["number"]},{"description":"The 1-based index to start iterating at.","name":"offset","required":false,"types":["number"]},{"description":"A custom numeric range to iterate over.","name":"range","required":false,"types":["untyped"]}],"summary":"Generates HTML table rows for every item in an array.","name":"tablerow","syntax":"{% tablerow variable in array %}\n expression\n{% endtablerow %}","syntax_keywords":[{"keyword":"variable","description":"The current item in the array."},{"keyword":"array","description":"The array to iterate over."},{"keyword":"expression","description":"The expression to render."}],"examples":[{"name":"","description":"","syntax":"","path":"/collections/sale-potions","raw_liquid":"\u003ctable\u003e\n {% tablerow product in collection.products %}\n {{ product.title }}\n {% endtablerow %}\n\u003c/table\u003e","parameter":false,"display_type":"text","show_data_tab":true},{"name":"cols","description":"You can define how many columns the table should have using the `cols` parameter.","syntax":"{% tablerow variable in array cols: number %}\n expression\n{% endtablerow %}\n","path":"/collections/sale-potions","raw_liquid":"\u003ctable\u003e\n {% tablerow product in collection.products cols: 2 %}\n {{ product.title }}\n {% endtablerow %}\n\u003c/table\u003e","parameter":true,"display_type":"text","show_data_tab":true},{"name":"limit","description":"You can limit the number of iterations using the `limit` parameter.","syntax":"{% tablerow variable in array limit: number %}\n expression\n{% endtablerow %}\n","path":"/collections/sale-potions","raw_liquid":"\u003ctable\u003e\n {% tablerow product in collection.products limit: 2 %}\n {{ product.title }}\n {% endtablerow %}\n\u003c/table\u003e","parameter":true,"display_type":"text","show_data_tab":true},{"name":"offset","description":"You can specify a 1-based index to start iterating at using the `offset` parameter.","syntax":"{% tablerow variable in array offset: number %}\n expression\n{% endtablerow %}\n","path":"/collections/sale-potions","raw_liquid":"\u003ctable\u003e\n {% tablerow product in collection.products offset: 2 %}\n {{ product.title }}\n {% endtablerow %}\n\u003c/table\u003e","parameter":true,"display_type":"text","show_data_tab":true},{"name":"range","description":"Instead of iterating over specific items in an array, you can specify a numeric range to iterate over.\n\n\u003e Note:\n\u003e You can define the range using both literal and variable values.\n","syntax":"{% tablerow variable in (number..number) %}\n expression\n{% endtablerow %}\n","path":"/","raw_liquid":"\u003ctable\u003e\n {% tablerow i in (1..3) %}\n {{ i }}\n {% endtablerow %}\n\u003c/table\u003e\n\n{%- assign lower_limit = 2 -%}\n{%- assign upper_limit = 4 -%}\n\n\u003ctable\u003e\n {% tablerow i in (lower_limit..upper_limit) %}\n {{ i }}\n {% endtablerow %}\n\u003c/table\u003e","parameter":true,"display_type":"text","show_data_tab":true}]},{"category":"platformOS","deprecated":false,"deprecation_reason":"","description":"Allows to specify search paths for theme partials via app/config.yml property \"theme_render_paths\"\n\nAssuming app/config.yml looks like this:\n\ntheme_search_paths :\n- theme/{{ context.constants.MY_THEME | default: \"custom\" }}\n- theme/simple","syntax":"\nWhen you render a partial using theme_render\n\n{% theme_render_rc 'product' %}\n\nThe system will try to render theme/custom/product, and if it does not exist, it will fallback to theme/simple/product (if it also does not exist, the missing partial error is raised)","name":"theme_render_rc","parameters":[],"return_type":[],"examples":[{"name":"","description":"","syntax":"","path":"","raw_liquid":"\nWhen you render a partial using theme_render\n\n{% theme_render_rc 'product' %}\n\nThe system will try to render theme/custom/product, and if it does not exist, it will fallback to theme/simple/product (if it also does not exist, the missing partial error is raised)","parameter":false,"display_type":"text","show_data_tab":true}]},{"category":"platformOS","deprecated":false,"deprecation_reason":"","description":"Allows to catch errors, especially useful with `liquid_raise_mode: true` setting in app/config.yml.","syntax":"{% liquid\n try\n include template_path\n catch err\n unless err.message contains \"can't find partial\"\n log err, type: 'error when including template file'\n endunless\n include fallback_template_path\n endtry\n%}","name":"try","parameters":[],"return_type":[],"examples":[{"name":"","description":"","syntax":"","path":"","raw_liquid":"{% liquid\n try\n include template_path\n catch err\n unless err.message contains \"can't find partial\"\n log err, type: 'error when including template file'\n endunless\n include fallback_template_path\n endtry\n%}","parameter":false,"display_type":"text","show_data_tab":true}]},{"category":"conditional","deprecated":false,"deprecation_reason":"","description":"\u003e Tip:\n\u003e Similar to the [`if` tag](/docs/api/liquid/tags/if), you can use `elsif` to add more conditions to an `unless` tag.","parameters":[],"summary":"Renders an expression unless a specific condition is `true`.","name":"unless","syntax":"{% unless condition %}\n expression\n{% endunless %}","syntax_keywords":[{"keyword":"condition","description":"The condition to evaluate."},{"keyword":"expression","description":"The expression to render unless the condition is met."}],"examples":[{"name":"","description":"","syntax":"","path":"/products/health-potion","raw_liquid":"{% unless product.has_only_default_variant %}\n // Variant selection functionality\n{% endunless %}","parameter":false,"display_type":"text","show_data_tab":true}]},{"category":"platformOS","deprecated":false,"deprecation_reason":"","description":"Execute code wrapped inside content_for","syntax":"Use this in a liquid view first. Then you can use yield inside the layout (for example) or another subsequently rendered view, like below:\n{% content_for 'greeting' %}Hello world{% endcontent_for %}\n\n# another_file.liquid\n{% yield 'greeting' %}","name":"yield","parameters":[{"description":"name of content_for block","name":"name","required":false,"types":["untyped"]}],"return_type":[],"examples":[{"name":"","description":"","syntax":"","path":"","raw_liquid":"Use this in a liquid view first. Then you can use yield inside the layout (for example) or another subsequently rendered view, like below:\n{% content_for 'greeting' %}Hello world{% endcontent_for %}\n\n# another_file.liquid\n{% yield 'greeting' %}","parameter":false,"display_type":"text","show_data_tab":true}]}]
4
+ [{"category":"variable","deprecated":false,"deprecation_reason":"","description":"You can create variables of any [basic type](/docs/api/liquid/basics#types), [object](/docs/api/liquid/objects), or object property.","parameters":[],"summary":"Creates a new variable.","name":"assign","syntax":"{% assign variable_name = value %}","syntax_keywords":[{"keyword":"variable_name","description":"The name of the variable being created."},{"keyword":"value","description":"The value you want to assign to the variable."}],"examples":[{"name":"","description":"","syntax":"","path":"/products/health-potion","raw_liquid":"{%- assign product_title = product.title | upcase -%}\n\n{{ product_title }}","parameter":false,"display_type":"text","show_data_tab":true}]},{"category":"platformOS","deprecated":false,"deprecation_reason":"","description":"Invokes code within the tag asynchronously, in the background.\nYou will only have access to variables you explicitly pass to the background tag. The context object is available by default, but with limitations - you need\nto explicitly pass page/layout metadata if you want to use it, as well as device and constants.","syntax":"Run background code from partial\nThe following code will run all the log queries in the background, not earlier than 0.5 minute (30 seconds) since the execution. You will only have access to variables\nexplicitly provided to the background tag: \"data\" and \"hey\". Note that you will not have access to the \"my_data\" variable. Also note\nthat the result of this background tag will not be rendered, and you will not have access to any variable inside the background tag.\n\n# app/views/partials/example_partial.liquid\n{% liquid\n log not_available_in_background # Will be null, as this variable was not passed to the background tag\n log data # You will see { \"hello\": \"world\" }, as it was provided to the background tag\n log hey # You will see \"hello\" as it was provided to the background tag\n log context # You will copy the current request context and make it available in the background\n assign not_available_outside = \"You will not see me\"\n\n%}\n\n# app/views/pages/test.liquid\n{% liquid\n assign my_data = null | hash_merge: hello: \"world\"\n assign not_available_in_job = \"You will not see me \"\n background job_id = 'example_partial', delay: 0.1, max_attempts: 3, source_name: 'custom_job', data: my_data, hey: 'hello'\n\n # This variable will be rendered in the background, meaning you won't see anything on the page\n echo not_available_outside\n%}","name":"background","parameters":[{"description":"Any variable provided to the background tag will become accessible in the code.","name":"options","required":false,"types":["untyped"]},{"description":"which defines the number of minutes to delay running code (defaults to 0, which means run code as soon as possible)","name":"options.delay","required":false,"types":["untyped"]},{"description":"low, default or high - see AsyncCallbackPriorityEnum GraphQL Object","name":"options.priority","required":false,"types":["untyped"]},{"description":"the number of time to re-try job upon failing. Default is 1, maximum is 5","name":"options.max_attempts","required":false,"types":["untyped"]},{"description":"your label of the job, which would help you identify it","name":"options.source_name","required":false,"types":["untyped"]}],"return_type":[],"examples":[{"name":"","description":"","syntax":"","path":"","raw_liquid":"Run background code from partial\nThe following code will run all the log queries in the background, not earlier than 0.5 minute (30 seconds) since the execution. You will only have access to variables\nexplicitly provided to the background tag: \"data\" and \"hey\". Note that you will not have access to the \"my_data\" variable. Also note\nthat the result of this background tag will not be rendered, and you will not have access to any variable inside the background tag.\n\n# app/views/partials/example_partial.liquid\n{% liquid\n log not_available_in_background # Will be null, as this variable was not passed to the background tag\n log data # You will see { \"hello\": \"world\" }, as it was provided to the background tag\n log hey # You will see \"hello\" as it was provided to the background tag\n log context # You will copy the current request context and make it available in the background\n assign not_available_outside = \"You will not see me\"\n\n%}\n\n# app/views/pages/test.liquid\n{% liquid\n assign my_data = null | hash_merge: hello: \"world\"\n assign not_available_in_job = \"You will not see me \"\n background job_id = 'example_partial', delay: 0.1, max_attempts: 3, source_name: 'custom_job', data: my_data, hey: 'hello'\n\n # This variable will be rendered in the background, meaning you won't see anything on the page\n echo not_available_outside\n%}","parameter":false,"display_type":"text","show_data_tab":true},{"name":"","description":"","syntax":"","path":"","raw_liquid":"Deprecated\nThe following code will run all the log queries in the background, not earlier than 0.5 minute (30 seconds) since the execution. You will only have access to variables\nexplicitly provided to the background tag: \"data\" and \"hey\". Note that you will not have access to the \"my_data\" variable. Also note\nthat the result of this background tag will not be rendered, and you will not have access to any variable inside the background tag.\n\n{% parse_json my_data %}{ \"hello\": \"world\" }{% endparse_json %}\n{% assign not_available_in_background = \"You will not see me\" %}\n{% background priority: 'low', delay: 0.5, max_attempts: 3, source_name: \"my custom job\", data: my_data, hey: 'hello' %}\n {% log not_available_in_background %} {% comment %}Will be null, as this variable was not passed to the background tag {% endcomment %}\n {% log data %} {% comment %}You will see { \"hello\": \"world\" }, as it was provided to the background tag{% endcomment %}\n {% log hey %} {% comment %}You will see \"hello\" as it was provided to the background tag{% endcomment %}\n {% log context %} {% comment %}You will copy the current request context and make it available in the background{% endcomment %}\n {% assign not_available_outside = \"You will not see me\" %}\n {{ not_available_outside }} {% comment %}This variable will be rendered in the background, meaning you won't see anything on the page{% endcomment %}\n{% endbackground %}\n{{ not_available_outside }} {% comment %}This will be blank, because the assign will happen in the background - you won't have access to it here{% endcomment %}","parameter":false,"display_type":"text","show_data_tab":true}]},{"category":"iteration","deprecated":false,"deprecation_reason":"","description":"","parameters":[],"summary":"Stops a [`for` loop](/docs/api/liquid/tags/for) from iterating.","name":"break","syntax":"{% break %}","syntax_keywords":[],"examples":[{"name":"","description":"","syntax":"","path":"/","raw_liquid":"{% for i in (1..5) -%}\n {%- if i == 4 -%}\n {% break %}\n {%- else -%}\n {{ i }}\n {%- endif -%}\n{%- endfor %}","parameter":false,"display_type":"text","show_data_tab":true}]},{"category":"platformOS","deprecated":false,"deprecation_reason":"","description":"Checks if there's string cached for the given key. If yes, it just returns the value without processing\nanything inside the cache tag, otherwise it executes code, stores the result in the cache.\nWhen you hit the page with such code for the first time, the code will be executed and hence it will iterate through the loop\nand generate random strings. However, then the result of the block will be cached and all the following requests within 20 seconds\nwould not invoke the code - instead, it would just take the value from the cache. The output will not change. When the cache expires,\nthe code will be evaluated again, producing another set of random string.\nCache is automatically invalidated if any changes are applied to any view/translation.","syntax":"{% cache 'this is my key', expire: 20 %}\n \u003cul\u003e\n {% for i in (1..100) %}\n \u003cli\u003e{{ 18 | random_string }}\u003c/li\u003e\n {% endfor %}\n \u003c/ul\u003e\n{% endcache %}","name":"cache","parameters":[{"description":"the key which should uniquely identify the cached fragment","name":"key","required":false,"types":["untyped"]},{"description":"optional. number of seconds since populating the cache to expiration","name":"expire","required":false,"types":["untyped"]}],"return_type":[],"examples":[{"name":"","description":"","syntax":"","path":"","raw_liquid":"{% cache 'this is my key', expire: 20 %}\n \u003cul\u003e\n {% for i in (1..100) %}\n \u003cli\u003e{{ 18 | random_string }}\u003c/li\u003e\n {% endfor %}\n \u003c/ul\u003e\n{% endcache %}","parameter":false,"display_type":"text","show_data_tab":true},{"name":"","description":"","syntax":"","path":"","raw_liquid":"{% parse_json pagesUpdatedAt %}\n {%- cache pagesUpdatedAtCache -%}\n {%- graphql g = 'pages_updated_at' | dig: 'admin_pages', 'results' -%}\n {{- g -}}\n {%- endcache -%}\n{% endparse_json %}\n{%- export pagesUpdatedAt, namespace: 'nav' -%}","parameter":false,"display_type":"text","show_data_tab":true}]},{"category":"variable","deprecated":false,"deprecation_reason":"","description":"You can create complex strings with Liquid logic and variables.","parameters":[],"summary":"Creates a new variable with a string value.","name":"capture","syntax":"{% capture variable %}\n value\n{% endcapture %}","syntax_keywords":[{"keyword":"variable","description":"The name of the variable being created."},{"keyword":"value","description":"The value you want to assign to the variable."}],"examples":[{"name":"","description":"","syntax":"","path":"/products/health-potion","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 }}","parameter":false,"display_type":"text","show_data_tab":true}]},{"category":"conditional","deprecated":false,"deprecation_reason":"","description":"","parameters":[],"summary":"Renders a specific expression depending on the value of a specific variable.","name":"case","syntax":"{% case variable %}\n {% when first_value %}\n first_expression\n {% when second_value %}\n second_expression\n {% else %}\n third_expression\n{% endcase %}","syntax_keywords":[{"keyword":"variable","description":"The name of the variable you want to base your case statement on."},{"keyword":"first_value","description":"A specific value to check for."},{"keyword":"second_value","description":"A specific value to check for."},{"keyword":"first_expression","description":"An expression to be rendered when the variable's value matches `first_value`."},{"keyword":"second_expression","description":"An expression to be rendered when the variable's value matches `second_value`."},{"keyword":"third_expression","description":"An expression to be rendered when the variable's value has no match."}],"examples":[{"name":"","description":"","syntax":"","path":"/products/health-potion","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 %}","parameter":false,"display_type":"text","show_data_tab":true},{"name":"Multiple values","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","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","path":"/products/health-potion","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 %}","parameter":false,"display_type":"text","show_data_tab":true}]},{"category":"syntax","deprecated":false,"deprecation_reason":"","description":"Any text inside `comment` tags won't be output, and any Liquid code will be parsed, but not executed.","parameters":[],"summary":"Prevents an expression from being rendered or output.","name":"comment","syntax":"{% comment %}\n content\n{% endcomment %}","syntax_keywords":[{"keyword":"content","description":"The content of the comment."}],"examples":[{"name":"Inline comments","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","syntax":"{% # content %}","path":"/","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%}","parameter":false,"display_type":"text","show_data_tab":true},{"name":"Inline comments inside `liquid` tags","description":"You can use inline comment tags inside [`liquid` tags](/docs/api/liquid/tags/liquid). The tag must be used for each line that you want to comment.\n","syntax":"","path":"/","raw_liquid":"{% liquid\n # this is a comment\n assign topic = 'Learning about comments!'\n echo topic\n%}","parameter":false,"display_type":"text","show_data_tab":true}]},{"category":"platformOS","deprecated":false,"deprecation_reason":"","description":"Stores a block of markup in an identifier for later use.\nRender it later with `yield` tag.","syntax":"{% content_for 'header' %}\n Hello world\n{% endcontent_for %}","name":"content_for","parameters":[{"description":"the markups will be stored under this name","name":"name","required":false,"types":["untyped"]},{"description":"optional. If the flush parameter is true content_for replaces the blocks it is given instead of appending content to the existing one","name":"flush","required":false,"types":["untyped"]}],"return_type":[],"examples":[{"name":"","description":"","syntax":"","path":"","raw_liquid":"{% content_for 'header' %}\n Hello world\n{% endcontent_for %}","parameter":false,"display_type":"text","show_data_tab":true}]},{"category":"platformOS","deprecated":false,"deprecation_reason":"","description":"Set locale in context to given language","syntax":"{% context language: 'de' %}","name":"context","parameters":[{"description":"language 2 letter","name":"language","required":false,"types":["untyped"]}],"return_type":[],"examples":[{"name":"","description":"","syntax":"","path":"","raw_liquid":"{% context language: 'de' %}","parameter":false,"display_type":"text","show_data_tab":true}]},{"category":"iteration","deprecated":false,"deprecation_reason":"","description":"","parameters":[],"summary":"Causes a [`for` loop](/docs/api/liquid/tags/for) to skip to the next iteration.","name":"continue","syntax":"{% continue %}","syntax_keywords":[],"examples":[{"name":"","description":"","syntax":"","path":"/","raw_liquid":"{% for i in (1..5) -%}\n {%- if i == 4 -%}\n {% continue %}\n {%- else -%}\n {{ i }}\n {%- endif -%}\n{%- endfor %}","parameter":false,"display_type":"text","show_data_tab":true}]},{"category":"iteration","deprecated":false,"deprecation_reason":"","description":"The `cycle` tag must be used inside a `for` loop.\n\n\u003e Tip:\n\u003e Use the `cycle` tag to output text in a predictable pattern. For example, to apply odd/even classes to rows in a table.","parameters":[],"summary":"Loops through a group of strings and outputs them one at a time for each iteration of a [`for` loop](/docs/api/liquid/tags/for).","name":"cycle","syntax":"{% cycle string, string, ... %}","syntax_keywords":[],"examples":[{"name":"","description":"","syntax":"","path":"/","raw_liquid":"{% for i in (1..4) -%}\n {% cycle 'one', 'two', 'three' %}\n{%- endfor %}","parameter":false,"display_type":"text","show_data_tab":true},{"name":"Create unique cycle groups","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","syntax":"{% cycle string: string, string, ... %}","path":"/","raw_liquid":"\u003c!-- Iteration 1 --\u003e\n{% for i in (1..4) -%}\n {% cycle 'one', 'two', 'three' %}\n{%- endfor %}\n\n\u003c!-- Iteration 2 --\u003e\n{% for i in (1..4) -%}\n {% cycle 'one', 'two', 'three' %}\n{%- endfor %}\n\n\u003c!-- Iteration 3 --\u003e\n{% for i in (1..4) -%}\n {% cycle 'group_1': 'one', 'two', 'three' %}\n{%- endfor %}\n\n\u003c!-- Iteration 4 --\u003e\n{% for i in (1..4) -%}\n {% cycle 'group_2': 'one', 'two', 'three' %}\n{%- endfor %}","parameter":false,"display_type":"text","show_data_tab":true}]},{"category":"variable","deprecated":false,"deprecation_reason":"","description":"Variables that are declared with `decrement` are unique to the [partial](/developer-guide/platformos-workflow/directory-structure#views-pages-layouts-and-partials), [template](/themes/architecture/templates),\nor [section](/themes/architecture/sections) file that they're created in. However, the variable is shared across\n[partial](/developer-guide/platformos-workflow/codebase#views-pages-layouts-and-partials) included in the file.\n\nSimilarly, variables that are created with `decrement` are independent from those created with [`assign`](/docs/api/liquid/tags/assign)\nand [`capture`](/docs/api/liquid/tags/capture). However, `decrement` and [`increment`](/docs/api/liquid/tags/increment) share\nvariables.","parameters":[],"summary":"Creates a new variable, with a default value of -1, that's decreased by 1 with each subsequent call.","name":"decrement","syntax":"{% decrement variable_name %}","syntax_keywords":[{"keyword":"variable_name","description":"The name of the variable being decremented."}],"examples":[{"name":"","description":"","syntax":"","path":"/","raw_liquid":"{% decrement variable %}\n{% decrement variable %}\n{% decrement variable %}","parameter":false,"display_type":"text","show_data_tab":true}]},{"category":"syntax","deprecated":false,"deprecation_reason":"","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](/docs/api/liquid/tags/liquid).\n\n\u003e Tip:\n\u003e You can use [filters](/docs/api/liquid/filters) on expressions inside `echo` tags.","parameters":[],"summary":"Outputs an expression.","name":"echo","syntax":"{% liquid\n echo expression\n%}","syntax_keywords":[{"keyword":"expression","description":"The expression to be output."}],"examples":[{"name":"","description":"","syntax":"","path":"/products/health-potion","raw_liquid":"{% echo product.title %}\n\n{% liquid\n echo product.price | money\n%}","parameter":false,"display_type":"text","show_data_tab":true}]},{"category":"conditional","deprecated":false,"deprecation_reason":"","description":"You can use the `else` tag with the following tags:\n\n- [`case`](/docs/api/liquid/tags/case)\n- [`if`](/docs/api/liquid/tags/if)\n- [`unless`](/docs/api/liquid/tags/unless)","parameters":[],"summary":"Allows you to specify a default expression to execute when no other condition is met.","name":"else","syntax":"{% else %}\n expression","syntax_keywords":[{"keyword":"expression","description":"The expression to render if no other condition is met."}],"examples":[{"name":"","description":"","syntax":"","path":"/products/health-potion","raw_liquid":"{% if product.available %}\n This product is available!\n{% else %}\n This product is sold out!\n{% endif %}","parameter":false,"display_type":"text","show_data_tab":true}]},{"category":"iteration","deprecated":false,"deprecation_reason":"","description":"","parameters":[],"summary":"Allows you to specify a default expression to execute when a [`for` loop](/docs/api/liquid/tags/for) has zero length.","name":"else","syntax":"{% for variable in array %}\n first_expression\n{% else %}\n second_expression\n{% endfor %}","syntax_keywords":[{"keyword":"variable","description":"The current item in the array."},{"keyword":"array","description":"The array to iterate over."},{"keyword":"first_expression","description":"The expression to render for each iteration."},{"keyword":"second_expression","description":"The expression to render if the loop has zero length."}],"examples":[{"name":"","description":"","syntax":"","path":"/collections/empty","raw_liquid":"{% for product in collection.products %}\n {{ product.title }}\u003cbr\u003e\n{% else %}\n There are no products in this collection.\n{% endfor %}","parameter":false,"display_type":"text","show_data_tab":true}]},{"category":"platformOS","deprecated":false,"deprecation_reason":"","description":"Makes variables defined inside partial accessible anywhere via context.exports.`namespace`","syntax":"{% liquid\n assign a = 'value for a'\n assign b = 'value for b'\n export a, b, namespace: 'my_hash'\n%}\n\n{{ context.exports.my_hash }} =\u003e { \"a\": \"value for a\", \"b\": \"value for b\" }\n{% parse_json company %}\n{\n \"name\": \"platformOS\",\n \"technologies\": [\"liquid\", \"graphql\"],\n \"countries\": { \"USA\": 5, \"Poland\": 5, \"Romania\": 2 }\n}\n{% endparse_json %}\n\n{% export company, namespace: 'data' %}\n\n{{ context.exports.data }} =\u003e\n {\"company\"=\u003e{\"name\"=\u003e\"platformOS\", \"technologies\"=\u003e[\"liquid\", \"graphql\"], \"countries\"=\u003e{\"USA\"=\u003e5, \"Poland\"=\u003e5, \"Romania\"=\u003e2}}}\n{{ context.exports.data.company.technologies }} =\u003e liquidgraphql\n{{ context.exports.data.company.name }} =\u003e platformOS","name":"export","parameters":[{"description":"variable to be stored inside the namespace","name":"variable","required":false,"types":["untyped"]},{"description":"namespace under which variable will be in context.exports","name":"namespace","required":false,"types":["untyped"]}],"return_type":[],"examples":[{"name":"","description":"","syntax":"","path":"","raw_liquid":"{% liquid\n assign a = 'value for a'\n assign b = 'value for b'\n export a, b, namespace: 'my_hash'\n%}\n\n{{ context.exports.my_hash }} =\u003e { \"a\": \"value for a\", \"b\": \"value for b\" }\n{% parse_json company %}\n{\n \"name\": \"platformOS\",\n \"technologies\": [\"liquid\", \"graphql\"],\n \"countries\": { \"USA\": 5, \"Poland\": 5, \"Romania\": 2 }\n}\n{% endparse_json %}\n\n{% export company, namespace: 'data' %}\n\n{{ context.exports.data }} =\u003e\n {\"company\"=\u003e{\"name\"=\u003e\"platformOS\", \"technologies\"=\u003e[\"liquid\", \"graphql\"], \"countries\"=\u003e{\"USA\"=\u003e5, \"Poland\"=\u003e5, \"Romania\"=\u003e2}}}\n{{ context.exports.data.company.technologies }} =\u003e liquidgraphql\n{{ context.exports.data.company.name }} =\u003e platformOS","parameter":false,"display_type":"text","show_data_tab":true}]},{"category":"iteration","deprecated":false,"deprecation_reason":"","description":"Every `for` loop has an associated [`forloop` object](/api-reference/liquid/loops#helper-variables) with information about the loop.","parameters":[{"description":"The number of iterations to perform.","name":"limit","required":false,"types":["number"]},{"description":"The 1-based index to start iterating at.","name":"offset","required":false,"types":["number"]},{"description":"A custom numeric range to iterate over.","name":"range","required":false,"types":["untyped"]},{"description":"Iterate in reverse order.","name":"reversed","required":false,"types":["untyped"]}],"summary":"Renders an expression for every item in an array.","name":"for","syntax":"{% for variable in array %}\n expression\n{% endfor %}","syntax_keywords":[{"keyword":"variable","description":"The current item in the array."},{"keyword":"array","description":"The array to iterate over."},{"keyword":"expression","description":"The expression to render for each iteration."}],"examples":[{"name":"","description":"","syntax":"","path":"/collections/sale-potions","raw_liquid":"{% for product in collection.products -%}\n {{ product.title }}\n{%- endfor %}","parameter":false,"display_type":"text","show_data_tab":true},{"name":"limit","description":"You can limit the number of iterations using the `limit` parameter.","syntax":"{% for variable in array limit: number %}\n expression\n{% endfor %}\n","path":"/collections/sale-potions","raw_liquid":"{% for product in collection.products limit: 2 -%}\n {{ product.title }}\n{%- endfor %}","parameter":true,"display_type":"text","show_data_tab":true},{"name":"offset","description":"You can specify a 1-based index to start iterating at using the `offset` parameter.","syntax":"{% for variable in array offset: number %}\n expression\n{% endfor %}\n","path":"/collections/sale-potions","raw_liquid":"{% for product in collection.products offset: 2 -%}\n {{ product.title }}\n{%- endfor %}","parameter":true,"display_type":"text","show_data_tab":true},{"name":"range","description":"Instead of iterating over specific items in an array, you can specify a numeric range to iterate over.\n\n\u003e Note:\n\u003e You can define the range using both literal and variable values.\n","syntax":"{% for variable in (number..number) %}\n expression\n{% endfor %}\n","path":"/collections/all","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 %}","parameter":true,"display_type":"text","show_data_tab":true},{"name":"reversed","description":"You can iterate in reverse order using the `reversed` parameter.","syntax":"{% for variable in array reversed %}\n expression\n{% endfor %}\n","path":"/collections/sale-potions","raw_liquid":"{% for product in collection.products reversed -%}\n {{ product.title }}\n{%- endfor %}","parameter":true,"display_type":"text","show_data_tab":true}]},{"category":"platformOS","deprecated":false,"deprecation_reason":"","description":"Used to generate a html form element for a resource. Use within `form configuration`.\nInside the tag you can use `form_builder` variable.","syntax":"{% form %}\n {{ form_builder }}\n{% endform %}","name":"form","parameters":[{"description":"set id attribute in `\u003cform id=\"\"\u003e` element","name":"html-id","required":false,"types":["untyped"]},{"description":"add `novalidate` attribute to `\u003cform novalidate\u003e` element","name":"html-novalidate","required":false,"types":["untyped"]},{"description":"add css class `\u003cform class=\"\"\u003e` element","name":"html-class","required":false,"types":["untyped"]},{"description":"add `enctype=\"multipart/form-data\"` attribute to `\u003cform enctype=\"multipart/form-data\"\u003e` element.\nMultipart is enabled by default","name":"html-multipart","required":false,"types":["untyped"]},{"description":"[String] add data attribute to `\u003cform data-[attr]=\"\"\u003e` element","name":"html-data-","required":false,"types":["untyped"]}],"return_type":[],"examples":[{"name":"","description":"","syntax":"","path":"","raw_liquid":"{% form %}\n {{ form_builder }}\n{% endform %}","parameter":false,"display_type":"text","show_data_tab":true},{"name":"","description":"","syntax":"","path":"","raw_liquid":"{% form html-id: 'someid', html-novalidate: true, html-class: 'big-form green-form', html-data-user-id: '12345', html-multipart: false %}\n{% endform %}","parameter":false,"display_type":"text","show_data_tab":true}]},{"category":"platformOS","deprecated":false,"deprecation_reason":"","description":"Allows to store a variable returned by a partial. Partial needs to return data with `return` tag.\nAll variables needs to be passed explicitly to function. Variables from upper scope are not visible in function.\n*Note:* `context` is not available inside the function partial unless explicitly passed as a variable.","syntax":"{% function res = 'path/to/my/partial', arg1: 'hello' %}","name":"function","parameters":[],"return_type":[],"examples":[{"name":"","description":"","syntax":"","path":"","raw_liquid":"{% function res = 'path/to/my/partial', arg1: 'hello' %}","parameter":false,"display_type":"text","show_data_tab":true},{"name":"","description":"","syntax":"","path":"","raw_liquid":"# path/to/my/partial\n{% liquid\n assign res = 'hello' | append: foo | append: ' ' | append: context.location.host\n return res\n%}\n# path/to/my/partial\n\n{% liquid\n assign foo = 'hello'\n function res = 'path/to/my/partial', foo: foo, context: context\n%}","parameter":false,"display_type":"text","show_data_tab":true}]},{"category":"platformOS","deprecated":false,"deprecation_reason":"","description":"Used to execute GraphQL query stored in a file or invoke GraphQL query inline. All arguments provided to the tag will be passed to GraphQL.\nIt returns a hash with the data or the errors that occurred (for example, variable type mismatch, required variable not provided,\nsyntax error) etc.","syntax":"Invoke query \"get_models\" and store the result in variable \"g\":\n{% graphql g = \"get_models\", model_id: context.params.slug2 %}","name":"graphql","parameters":[{"description":"name of the GraphQL query. For get_users.graphql file name of the query is get_users","name":"query_name","required":false,"types":["untyped"]},{"description":"optional. key:value pair(s) which will be passed to GraphQL query. For example, if\nyour query looks like `query my_query($email: String!)`, then you can provide `email: \"my-email@example.com\"`","name":"arguments","required":false,"types":["untyped"]},{"description":"optional. Either a Hash or a String) of the arguments which will be passed to GraphQL query. See examples below.","name":"args","required":false,"types":["untyped"]}],"return_type":[],"examples":[{"name":"","description":"","syntax":"","path":"","raw_liquid":"Invoke query \"get_models\" and store the result in variable \"g\":\n{% graphql g = \"get_models\", model_id: context.params.slug2 %}","parameter":false,"display_type":"text","show_data_tab":true},{"name":"","description":"","syntax":"","path":"","raw_liquid":"Chain filters to extract results in one line:\n{% graphql g = \"get_models\", model_id: context.params.slug2 | fetch: 'models' | fetch: 'results' %}","parameter":false,"display_type":"text","show_data_tab":true},{"name":"","description":"","syntax":"","path":"","raw_liquid":"Pass all arguments at once as a hash to have graphql tag in one line and/or compose arguments hash dynamically:\n{% parse_json arguments %}\n {\n \"model_id\": {{ context.params.slug2 | json }},\n \"user_id\": {{ context.params.user_id | json }}\n }\n{% endparse_json %}\n\n{% graphql g = \"get_models\", args: arguments %}","parameter":false,"display_type":"text","show_data_tab":true},{"name":"","description":"","syntax":"","path":"","raw_liquid":"Pass all arguments at once as a JSON string:\n\n{% capture arguments %}\n{\n \"per_page\": 20,\n \"page\": 2\n}\n{% endcapture %}\n\n{% graphql g = \"get_models\", args: arguments %}","parameter":false,"display_type":"text","show_data_tab":true},{"name":"","description":"","syntax":"","path":"","raw_liquid":"Invoke inline query and store the result in variable \"g\". This is recommended for one-time used queries.\n\n{% graphql g, id: context.params.slug2, message: \"new message\" %}\n mutation set_message($id: ID!, $message: String!) {\n model_update(\n id: $id\n model: {\n properties: [{ name: \"message\", value: $message }]\n }\n ) {\n id\n message: property(name: \"message\")\n }\n }\n{% endgraphql %}","parameter":false,"display_type":"text","show_data_tab":true}]},{"category":"platformOS","deprecated":false,"deprecation_reason":"","description":"Allows to easily modify a Hash with a syntax same as assign tag.","syntax":"{% parse_json my_hash %}{ \"a\": { \"b\": { \"c\": \"12\", \"d\": \"hello\" } } }{% endparse_json %}\n{% hash_assign my_hash[\"a\"][\"e\"] = \"assign\" | upcase %}\n{{ my_hash }} =\u003e {\"a\":{\"b\":{\"c\":\"12\",\"d\":\"hello\"},\"e\":\"ASSIGN\"}}","name":"hash_assign","parameters":[],"return_type":[],"examples":[{"name":"","description":"","syntax":"","path":"","raw_liquid":"{% parse_json my_hash %}{ \"a\": { \"b\": { \"c\": \"12\", \"d\": \"hello\" } } }{% endparse_json %}\n{% hash_assign my_hash[\"a\"][\"e\"] = \"assign\" | upcase %}\n{{ my_hash }} =\u003e {\"a\":{\"b\":{\"c\":\"12\",\"d\":\"hello\"},\"e\":\"ASSIGN\"}}","parameter":false,"display_type":"text","show_data_tab":true},{"name":"","description":"","syntax":"","path":"","raw_liquid":"{% parse_json my_hash %}{ \"a\": { \"b\": { \"c\": \"12\", \"d\": \"hello\" } } }{% endparse_json %}\n{% hash_assign my_hash[\"a\"][\"b\"][\"d\"] = \"bye\" | upcase %}\n{{ my_hash }} =\u003e {\"a\":{\"b\":{\"c\":\"12\",\"d\":\"BYE\"}}}","parameter":false,"display_type":"text","show_data_tab":true},{"name":"","description":"","syntax":"","path":"","raw_liquid":"{% parse_json my_hash %}{ \"a\": { \"b\": { \"c\": \"12\", \"d\": \"hello\" } } }{% endparse_json %}\n{% hash_assign my_hash[\"a\"][\"b\"] = null %}\n{{ my_hash }} =\u003e {\"a\":{\"b\":null}}","parameter":false,"display_type":"text","show_data_tab":true},{"name":"","description":"","syntax":"","path":"","raw_liquid":"{% parse_json my_hash %}{ \"a\": { \"b\": { \"c\": \"12\", \"d\": \"hello\" } } }{% endparse_json %}\n{% hash_assign my_hash[\"a\"][\"b\"][\"c\"][\"e\"] = \"bye\" | upcase %}) =\u003e HashAssignTagError: Liquid error: my_hash[a][b][c] is 12, expected Hash","parameter":false,"display_type":"text","show_data_tab":true}]},{"category":"conditional","deprecated":false,"deprecation_reason":"","description":"","parameters":[],"summary":"Renders an expression if a specific condition is `true`.","name":"if","syntax":"{% if condition %}\n expression\n{% endif %}","syntax_keywords":[{"keyword":"condition","description":"The condition to evaluate."},{"keyword":"expression","description":"The expression to render if the condition is met."}],"examples":[{"name":"","description":"","syntax":"","path":"/products/glacier-ice","raw_liquid":"{% if product.compare_at_price \u003e product.price %}\n This product is on sale!\n{% endif %}","parameter":false,"display_type":"text","show_data_tab":true},{"name":"elsif","description":"You can use the `elsif` tag to check for multiple conditions.","syntax":"","path":"/products/health-potion","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 %}","parameter":false,"display_type":"text","show_data_tab":true}]},{"category":"theme","deprecated":true,"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`](/docs/api/liquid/tags/render).","description":"Inside the partial, you can access and alter variables that are [created](/docs/api/liquid/tags/variable-tags) outside of the\npartial.","parameters":[],"summary":"Renders a [partial](/developer-guide/platformos-workflow/directory-structure#views-pages-layouts-and-partials).","name":"include","syntax":"{% include 'filename' %}","syntax_keywords":[{"keyword":"filename","description":"The name of the partial to render, without the `.liquid` extension."}],"examples":[]},{"category":"platformOS","deprecated":false,"deprecation_reason":"","description":"This tag should be used to render forms defined in forms directory","syntax":"{% include_form 'signup_form' %}","name":"include_form","parameters":[{"description":"name of the form configuration from forms directory","name":"form_name","required":false,"types":["untyped"]},{"description":"id of the resource you want to edit","name":"id","required":false,"types":["untyped"]},{"description":"name of the resource type, f.e. name of custom_model_type, transactable_type, user_profile_type","name":"parent_resource_id","required":false,"types":["untyped"]}],"return_type":[],"examples":[{"name":"","description":"","syntax":"","path":"","raw_liquid":"{% include_form 'signup_form' %}","parameter":false,"display_type":"text","show_data_tab":true},{"name":"","description":"","syntax":"","path":"","raw_liquid":"{% include_form 'edit_user', id: user.id %}","parameter":false,"display_type":"text","show_data_tab":true},{"name":"","description":"","syntax":"","path":"","raw_liquid":"{% include_form 'manager_invite_to_interview', parent_resource_id: 'invitation', user: g.user %}","parameter":false,"display_type":"text","show_data_tab":true}]},{"category":"variable","deprecated":false,"deprecation_reason":"","description":"Variables that are declared with `increment` are unique to the [partial](/developer-guide/platformos-workflow/directory-structure#views-pages-layouts-and-partials), [template](/themes/architecture/templates),\nor [section](/themes/architecture/sections) file that they're created in. However, the variable is shared across\n[partial](/developer-guide/platformos-workflow/codebase#views-pages-layouts-and-partials) included in the file.\n\nSimilarly, variables that are created with `increment` are independent from those created with [`assign`](/docs/api/liquid/tags/assign)\nand [`capture`](/docs/api/liquid/tags/capture). However, `increment` and [`decrement`](/docs/api/liquid/tags/decrement) share\nvariables.","parameters":[],"summary":"Creates a new variable, with a default value of 0, that's increased by 1 with each subsequent call.","name":"increment","syntax":"{% increment variable_name %}","syntax_keywords":[{"keyword":"variable_name","description":"The name of the variable being incremented."}],"examples":[{"name":"","description":"","syntax":"","path":"/","raw_liquid":"{% increment variable %}\n{% increment variable %}\n{% increment variable %}","parameter":false,"display_type":"text","show_data_tab":true}]},{"category":"syntax","deprecated":false,"deprecation_reason":"","description":"Because the tags don't have delimeters, each tag needs to be on its own line.\n\n\u003e Tip:\n\u003e Use the [`echo` tag](/docs/api/liquid/tags/echo) to output an expression inside `liquid` tags.","parameters":[],"summary":"Allows you to have a block of Liquid without delimeters on each tag.","name":"liquid","syntax":"{% liquid\n expression\n%}","syntax_keywords":[{"keyword":"expression","description":"The expression to be rendered inside the `liquid` tag."}],"examples":[{"name":"","description":"","syntax":"","path":"/products/health-potion","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%}","parameter":false,"display_type":"text","show_data_tab":true}]},{"category":"platformOS","deprecated":false,"deprecation_reason":"","description":"Print information to environment logs. To view logs run `pos-cli gui serve \u003cenvironment\u003e` in your application directory and go to `http://localhost:3333/Logs`. If you prefer seeing logs in the terminal, run `pos-cli gui logs \u003cenvironment\u003e`","syntax":"{% log 'hello world' %}","name":"log","parameters":[{"description":"Any object that can be printed","name":"message","required":false,"types":["untyped"]},{"description":"type of log entry. Use it to tag your logs to make it easier to differentiate logs. If you set it to 'error' pos-cli will also notify your OS about it if your OS supports it.","name":"type","required":false,"types":["untyped"]},{"description":"environment where the entry should be created; can be any of 'all', 'staging', 'production'. Default: 'all'","name":"env","required":false,"types":["untyped"]}],"return_type":[],"examples":[{"name":"","description":"","syntax":"","path":"","raw_liquid":"{% log 'hello world' %}","parameter":false,"display_type":"text","show_data_tab":true},{"name":"","description":"","syntax":"","path":"","raw_liquid":"{% log params, type: 'request-params' %}","parameter":false,"display_type":"text","show_data_tab":true},{"name":"","description":"","syntax":"","path":"","raw_liquid":"{% log user.id, type: 'debug' %}","parameter":false,"display_type":"text","show_data_tab":true},{"name":"","description":"","syntax":"","path":"","raw_liquid":"{% log context.current_user, type: 'error' %}","parameter":false,"display_type":"text","show_data_tab":true},{"name":"","description":"","syntax":"","path":"","raw_liquid":"{% log context.current_user, type: 'error', env: 'staging' %}","parameter":false,"display_type":"text","show_data_tab":true}]},{"category":"platformOS","deprecated":false,"deprecation_reason":"","description":"Captures and parses the JSON string inside of the opening and closing tags and assigns it to a variable.","syntax":"{% parse_json car %}\n { \"type\": \"SUV\", \"gearbox\": \"AT\" }\n{% endparse_json %}\n\n{{ car }} =\u003e {\"type\"=\u003e\"SUV\", \"gearbox\"=\u003e\"AT\"}\n{{ car.type }} =\u003e SUV","name":"parse_json","parameters":[{"description":"variable name that will be used to assign contents after it is parsed","name":"variable_name","required":false,"types":["untyped"]},{"description":"valid JSON string to be assigned","name":"content","required":false,"types":["untyped"]}],"return_type":[],"examples":[{"name":"","description":"","syntax":"","path":"","raw_liquid":"{% parse_json car %}\n { \"type\": \"SUV\", \"gearbox\": \"AT\" }\n{% endparse_json %}\n\n{{ car }} =\u003e {\"type\"=\u003e\"SUV\", \"gearbox\"=\u003e\"AT\"}\n{{ car.type }} =\u003e SUV","parameter":false,"display_type":"text","show_data_tab":true},{"name":"","description":"","syntax":"","path":"","raw_liquid":"{% parse_json cars %}\n [\n { \"maker\": \"Honda\", \"model\": \"CRX\" },\n { \"maker\": \"Subaru\", \"model\": \"Forester\"},\n { \"maker\": \"Lexus\", \"model\": \"LFA\" }\n ]\n{% endparse_json %}\n\n{{ cars }} =\u003e {\"maker\"=\u003e\"Honda\", \"model\"=\u003e\"CRX\"}{\"maker\"=\u003e\"Subaru\", \"model\"=\u003e\"Forester\"}{\"maker\"=\u003e\"Lexus\", \"model\"=\u003e\"LFA\"}","parameter":false,"display_type":"text","show_data_tab":true},{"name":"","description":"","syntax":"","path":"","raw_liquid":"In order to create JSON object from exsting values print them using `json` filter.\nThis is required only for strings and will escape properly `\"` and `'` characters.\nOther types will be handled automatically.\n\n{% parse_json nested %}\n {\n \"price\": 100\n }\n{% endparse_json %}\n{% assign color = \"red\" %}\n{% assign car = 'Mazda \"5\"' %}\n{% parse_json data %}\n {\n \"color\": {{ color | json }},\n \"car\": {{ car | json }},\n \"nested\": {{ nested }}\n }\n{% endparse_json %}\n\n{{ data }} =\u003e {\"color\":\"red\",\"car\":\"Mazda \\\"5\\\"\",\"nested\":{\"price\":100}}","parameter":false,"display_type":"text","show_data_tab":true}]},{"category":"platformOS","deprecated":false,"deprecation_reason":"","description":"Print variable, skipping any additional sanitization. It provides a way to display a variable which consists of both safe and unsafe html.\nWarning: Do not use it with data entered by users as it is gonna cause XSS.","syntax":"{% liquid\n assign invokable_script = \"\u003cscript\u003ealert('I will be executed')\u003c/script\u003e\"\n assign malicious_script = \"\u003cscript\u003ealert('I should be escaped')\u003c/script\u003e\"\n%}\n{% capture result %}\n {{ malicious_script }}{{ invokable_script | html_safe }}\n{% endcapture %}\n{% print result %}","name":"print","parameters":[{"description":"Variable containing safe and potentially unsafe HTML","name":"variable","required":false,"types":["untyped"]}],"return_type":[],"examples":[{"name":"","description":"","syntax":"","path":"","raw_liquid":"{% liquid\n assign invokable_script = \"\u003cscript\u003ealert('I will be executed')\u003c/script\u003e\"\n assign malicious_script = \"\u003cscript\u003ealert('I should be escaped')\u003c/script\u003e\"\n%}\n{% capture result %}\n {{ malicious_script }}{{ invokable_script | html_safe }}\n{% endcapture %}\n{% print result %}","parameter":false,"display_type":"text","show_data_tab":true}]},{"category":"syntax","deprecated":false,"deprecation_reason":"","description":"","parameters":[],"summary":"Outputs any Liquid code as text instead of rendering it.","name":"raw","syntax":"{% raw %}\n expression\n{ % endraw %}","syntax_keywords":[{"keyword":"expression","description":"The expression to be output without being rendered."}],"examples":[{"name":"","description":"","syntax":"","path":"/","raw_liquid":"{% raw %}\n{{ 2 | plus: 2 }} equals 4.\n{ % endraw %}","parameter":false,"display_type":"text","show_data_tab":true}]},{"category":"platformOS","deprecated":false,"deprecation_reason":"","description":"Redirects browser to target","syntax":"{% redirect_to '/dashboard' %}","name":"redirect_to","parameters":[{"description":"path or url","name":"target","required":false,"types":["untyped"]},{"description":"3xx HTTP code, default 302","name":"status","required":false,"types":["untyped"]}],"return_type":[],"examples":[{"name":"","description":"","syntax":"","path":"","raw_liquid":"{% redirect_to '/dashboard' %}","parameter":false,"display_type":"text","show_data_tab":true},{"name":"","description":"","syntax":"","path":"","raw_liquid":"{% redirect_to 'https://example.com/signup' %}","parameter":false,"display_type":"text","show_data_tab":true},{"name":"","description":"","syntax":"","path":"","raw_liquid":"{% redirect_to '/dashboard', status: 301 %}","parameter":false,"display_type":"text","show_data_tab":true}]},{"category":"theme","deprecated":false,"deprecation_reason":"","description":"Inside partial, you can't directly access variables that are [created](/docs/api/liquid/tags/variable-tags) outside\nof the partial. However, you can specify variables as parameters\nto pass outside variables to partials.\n\nWhile you can't directly access created variables, you can access global objects like `context`.\n\nOutside a partial, you can't access variables created inside it.\n\n\u003e Note:\n\u003e When you render a partial using the `render` tag, you can't use the [`include` tag](/docs/api/liquid/tags/include)\n\u003e inside the partial.","parameters":[],"summary":"Renders a [partial](/developer-guide/platformos-workflow/directory-structure#views-pages-layouts-and-partials).","name":"render","syntax":"{% render 'filename' %}","syntax_keywords":[{"keyword":"filename","description":"The name of the partial to render, without the `.liquid` extension and `views/partials` or `lib` prefix."}],"examples":[{"name":"for","description":"You can render a partial 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 partial.\nAdditionally, you can access a [`forloop` object](/docs/api/liquid/objects/forloop) for the loop inside the partial.\n","syntax":"{% render 'filename' for array as item %}","path":"/","raw_liquid":"{% render 'filename' for array as item %}","parameter":true,"display_type":"text","show_data_tab":true},{"name":"Passing variables to a partial","description":"Variables that have been [created](/docs/api/liquid/tags/variable-tags) outside of a partial can be passed to a partial as parameters on the `render` tag.\n\n\u003e Note:\n\u003e Any changes that are made to a passed variable apply only within the partial, unless it is an array or hash.\n","syntax":"{% render 'filename', variable: value %}","path":"/","raw_liquid":"{% render 'filename', variable: value %}","parameter":true,"display_type":"text","show_data_tab":true},{"name":"with","description":"You can pass a single object to a partial using the `with` parameter. You can also supply an optional `as` parameter to specify a custom name to reference the object inside the partial.\n","syntax":"{% render 'filename' with object as name %}","path":"/","raw_liquid":"{% render 'filename' with object as name %}","parameter":true,"display_type":"text","show_data_tab":true}]},{"category":"platformOS","deprecated":false,"deprecation_reason":"","description":"Allows you to set additional HTTP headers for the response.","syntax":"{% response_headers '{\"foo\": \"bar\"}' %}","name":"response_headers","parameters":[{"description":"headers as JSON string, default {}","name":"headers","required":false,"types":["untyped"]}],"return_type":[],"examples":[{"name":"","description":"","syntax":"","path":"","raw_liquid":"{% response_headers '{\"foo\": \"bar\"}' %}","parameter":false,"display_type":"text","show_data_tab":true},{"name":"","description":"","syntax":"","path":"","raw_liquid":"{% response_headers '{\"Content-Type\": \"application/json\", \"X-Frame-Options\": \"somevalue\" }' %}","parameter":false,"display_type":"text","show_data_tab":true}]},{"category":"platformOS","deprecated":false,"deprecation_reason":"","description":"Allows you to set HTTP status for the response. Default 200.","syntax":"{% response_status 204 %}","name":"response_status","parameters":[{"description":"HTTP status, default 200","name":"status","required":false,"types":["untyped"]}],"return_type":[],"examples":[{"name":"","description":"","syntax":"","path":"","raw_liquid":"{% response_status 204 %}","parameter":false,"display_type":"text","show_data_tab":true},{"name":"","description":"","syntax":"","path":"","raw_liquid":"{% response_status 404 %}","parameter":false,"display_type":"text","show_data_tab":true}]},{"category":"platformOS","deprecated":false,"deprecation_reason":"","description":"Used inside a partial invoked by a function tag to return a variable","syntax":"{% liquid\n assign result = 1 | plus: 3\n return result\n%}","name":"return","parameters":[],"return_type":[],"examples":[{"name":"","description":"","syntax":"","path":"","raw_liquid":"{% liquid\n assign result = 1 | plus: 3\n return result\n%}","parameter":false,"display_type":"text","show_data_tab":true}]},{"category":"platformOS","deprecated":false,"deprecation_reason":"","description":"Stores data during user's session\nSets field of given name to given value in context.session","syntax":"{% session foo = 'bar' %}\n{{ context.session | json }} =\u003e { \"foo\": \"bar\" }","name":"session","parameters":[],"return_type":[],"examples":[{"name":"","description":"","syntax":"","path":"","raw_liquid":"{% session foo = 'bar' %}\n{{ context.session | json }} =\u003e { \"foo\": \"bar\" }","parameter":false,"display_type":"text","show_data_tab":true},{"name":"","description":"","syntax":"","path":"","raw_liquid":"{% assign bar = \"42\" }\n{% session foo = bar %}\n{{ context.session | json }} =\u003e { \"foo\": \"42\" }","parameter":false,"display_type":"text","show_data_tab":true},{"name":"","description":"","syntax":"","path":"","raw_liquid":"{% session foo = null %}\n{{ context.session | json }} =\u003e {}","parameter":false,"display_type":"text","show_data_tab":true},{"name":"","description":"","syntax":"","path":"","raw_liquid":"{% session foo = blank %}\n{{ context.session | json }} =\u003e {}","parameter":false,"display_type":"text","show_data_tab":true}]},{"category":"platformOS","deprecated":false,"deprecation_reason":"","description":"Sign in user","syntax":"{% sign_in user_id: '12345' %}","name":"sign_in","parameters":[{"description":"id of the user you want to sign in","name":"user_id","required":false,"types":["untyped"]},{"description":"number of minutes after user will be log out","name":"timeout_in_minutes","required":false,"types":["untyped"]}],"return_type":[],"examples":[{"name":"","description":"","syntax":"","path":"","raw_liquid":"{% sign_in user_id: '12345' %}","parameter":false,"display_type":"text","show_data_tab":true},{"name":"","description":"","syntax":"","path":"","raw_liquid":"{% sign_in user_id: '12345', timeout_in_minutes: 15 %}","parameter":false,"display_type":"text","show_data_tab":true}]},{"category":"platformOS","deprecated":false,"deprecation_reason":"","description":"Generates html for spam protection. Supports Google reCAPTCHA strategies: recaptcha_v2, recaptcha_v3 and hcaptcha","syntax":"{% form %}\n {% spam_protection \"recaptcha_v2\" %}\n{% endform %}","name":"spam_protection","parameters":[{"description":"name of protection strategy. Default is recaptcha_v2","name":"strategy","required":false,"types":["untyped"]},{"description":"action name for reCAPTCHA V3, action may only contain alphanumeric characters and slashes","name":"action","required":false,"types":["untyped"]}],"return_type":[],"examples":[{"name":"","description":"","syntax":"","path":"","raw_liquid":"{% form %}\n {% spam_protection \"recaptcha_v2\" %}\n{% endform %}","parameter":false,"display_type":"text","show_data_tab":true},{"name":"","description":"","syntax":"","path":"","raw_liquid":"{% form %}\n {% spam_protection \"recaptcha_v3\", action: \"signup\" %}\n{% endform %}","parameter":false,"display_type":"text","show_data_tab":true},{"name":"","description":"","syntax":"","path":"","raw_liquid":"{% form %}\n {% spam_protection \"hcaptcha\" %}\n{% endform %}","parameter":false,"display_type":"text","show_data_tab":true}]},{"category":"iteration","deprecated":false,"deprecation_reason":"","description":"The `tablerow` tag must be wrapped in HTML `\u003ctable\u003e` and `\u003c/table\u003e` tags.\n\n\u003e Tip:\n\u003e Every `tablerow` loop has an associated [`tablerowloop` object](/docs/api/liquid/objects/tablerowloop) with information about the loop.","parameters":[{"description":"The number of columns that the table should have.","name":"cols","required":false,"types":["number"]},{"description":"The number of iterations to perform.","name":"limit","required":false,"types":["number"]},{"description":"The 1-based index to start iterating at.","name":"offset","required":false,"types":["number"]},{"description":"A custom numeric range to iterate over.","name":"range","required":false,"types":["untyped"]}],"summary":"Generates HTML table rows for every item in an array.","name":"tablerow","syntax":"{% tablerow variable in array %}\n expression\n{% endtablerow %}","syntax_keywords":[{"keyword":"variable","description":"The current item in the array."},{"keyword":"array","description":"The array to iterate over."},{"keyword":"expression","description":"The expression to render."}],"examples":[{"name":"","description":"","syntax":"","path":"/collections/sale-potions","raw_liquid":"\u003ctable\u003e\n {% tablerow product in collection.products %}\n {{ product.title }}\n {% endtablerow %}\n\u003c/table\u003e","parameter":false,"display_type":"text","show_data_tab":true},{"name":"cols","description":"You can define how many columns the table should have using the `cols` parameter.","syntax":"{% tablerow variable in array cols: number %}\n expression\n{% endtablerow %}\n","path":"/collections/sale-potions","raw_liquid":"\u003ctable\u003e\n {% tablerow product in collection.products cols: 2 %}\n {{ product.title }}\n {% endtablerow %}\n\u003c/table\u003e","parameter":true,"display_type":"text","show_data_tab":true},{"name":"limit","description":"You can limit the number of iterations using the `limit` parameter.","syntax":"{% tablerow variable in array limit: number %}\n expression\n{% endtablerow %}\n","path":"/collections/sale-potions","raw_liquid":"\u003ctable\u003e\n {% tablerow product in collection.products limit: 2 %}\n {{ product.title }}\n {% endtablerow %}\n\u003c/table\u003e","parameter":true,"display_type":"text","show_data_tab":true},{"name":"offset","description":"You can specify a 1-based index to start iterating at using the `offset` parameter.","syntax":"{% tablerow variable in array offset: number %}\n expression\n{% endtablerow %}\n","path":"/collections/sale-potions","raw_liquid":"\u003ctable\u003e\n {% tablerow product in collection.products offset: 2 %}\n {{ product.title }}\n {% endtablerow %}\n\u003c/table\u003e","parameter":true,"display_type":"text","show_data_tab":true},{"name":"range","description":"Instead of iterating over specific items in an array, you can specify a numeric range to iterate over.\n\n\u003e Note:\n\u003e You can define the range using both literal and variable values.\n","syntax":"{% tablerow variable in (number..number) %}\n expression\n{% endtablerow %}\n","path":"/","raw_liquid":"\u003ctable\u003e\n {% tablerow i in (1..3) %}\n {{ i }}\n {% endtablerow %}\n\u003c/table\u003e\n\n{%- assign lower_limit = 2 -%}\n{%- assign upper_limit = 4 -%}\n\n\u003ctable\u003e\n {% tablerow i in (lower_limit..upper_limit) %}\n {{ i }}\n {% endtablerow %}\n\u003c/table\u003e","parameter":true,"display_type":"text","show_data_tab":true}]},{"category":"platformOS","deprecated":false,"deprecation_reason":"","description":"Allows to specify search paths for theme partials via app/config.yml property \"theme_render_paths\"\n\nAssuming app/config.yml looks like this:\n\ntheme_search_paths :\n- theme/{{ context.constants.MY_THEME | default: \"custom\" }}\n- theme/simple","syntax":"\nWhen you render a partial using theme_render\n\n{% theme_render_rc 'product' %}\n\nThe system will try to render theme/custom/product, and if it does not exist, it will fallback to theme/simple/product (if it also does not exist, the missing partial error is raised)","name":"theme_render_rc","parameters":[],"return_type":[],"examples":[{"name":"","description":"","syntax":"","path":"","raw_liquid":"\nWhen you render a partial using theme_render\n\n{% theme_render_rc 'product' %}\n\nThe system will try to render theme/custom/product, and if it does not exist, it will fallback to theme/simple/product (if it also does not exist, the missing partial error is raised)","parameter":false,"display_type":"text","show_data_tab":true}]},{"category":"platformOS","deprecated":false,"deprecation_reason":"","description":"Allows to catch errors, especially useful with `liquid_raise_mode: true` setting in app/config.yml.","syntax":"{% liquid\n try\n include template_path\n catch err\n unless err.message contains \"can't find partial\"\n log err, type: 'error when including template file'\n endunless\n include fallback_template_path\n endtry\n%}","name":"try","parameters":[],"return_type":[],"examples":[{"name":"","description":"","syntax":"","path":"","raw_liquid":"{% liquid\n try\n include template_path\n catch err\n unless err.message contains \"can't find partial\"\n log err, type: 'error when including template file'\n endunless\n include fallback_template_path\n endtry\n%}","parameter":false,"display_type":"text","show_data_tab":true}]},{"category":"conditional","deprecated":false,"deprecation_reason":"","description":"\u003e Tip:\n\u003e Similar to the [`if` tag](/docs/api/liquid/tags/if), you can use `elsif` to add more conditions to an `unless` tag.","parameters":[],"summary":"Renders an expression unless a specific condition is `true`.","name":"unless","syntax":"{% unless condition %}\n expression\n{% endunless %}","syntax_keywords":[{"keyword":"condition","description":"The condition to evaluate."},{"keyword":"expression","description":"The expression to render unless the condition is met."}],"examples":[{"name":"","description":"","syntax":"","path":"/products/health-potion","raw_liquid":"{% unless product.has_only_default_variant %}\n // Variant selection functionality\n{% endunless %}","parameter":false,"display_type":"text","show_data_tab":true}]},{"category":"platformOS","deprecated":false,"deprecation_reason":"","description":"Execute code wrapped inside content_for","syntax":"Use this in a liquid view first. Then you can use yield inside the layout (for example) or another subsequently rendered view, like below:\n{% content_for 'greeting' %}Hello world{% endcontent_for %}\n\n# another_file.liquid\n{% yield 'greeting' %}","name":"yield","parameters":[{"description":"name of content_for block","name":"name","required":false,"types":["untyped"]}],"return_type":[],"examples":[{"name":"","description":"","syntax":"","path":"","raw_liquid":"Use this in a liquid view first. Then you can use yield inside the layout (for example) or another subsequently rendered view, like below:\n{% content_for 'greeting' %}Hello world{% endcontent_for %}\n\n# another_file.liquid\n{% yield 'greeting' %}","parameter":false,"display_type":"text","show_data_tab":true}]}]
5
5
 
6
6
 
data/docs/api/check.md CHANGED
@@ -1,14 +1,15 @@
1
1
  # Check API
2
2
 
3
- PlatformOS Check uses static analysis. It parses theme files into an AST, and then calls the appropriate checks to analyze it.
3
+ PlatformOS Check uses static analysis by parsing platformOS files into an Abstract Syntax Tree (AST), and then applying various checks to this structure.
4
4
 
5
- An [AST](https://en.wikipedia.org/wiki/Abstract_syntax_tree) is a tree of node, representing the theme file.
5
+ An [AST](https://en.wikipedia.org/wiki/Abstract_syntax_tree), or Abstract Syntax Tree, is a tree representation of the abstract syntactic structure of a platformOS file. Each node in the tree corresponds to a part of the code.
6
6
 
7
- Checks are Ruby classes with callback methods:
8
- - `on_TYPE` that runs before a node of the specific TYPE is visited.
9
- - `after_TYPE` that runs after a node of the specific TYPE is visited.
7
+ The checks are implemented as Ruby classes with callback methods:
10
8
 
11
- There are three types of checks currently supported:
9
+ - `on_TYPE`: Runs before a node of the specific TYPE is visited.
10
+ - `after_TYPE`: Runs after a node of the specific TYPE has been visited.
11
+
12
+ Currently, PlatformOS Check supports three types of checks:
12
13
 
13
14
  - [`LiquidCheck`](/docs/api/liquid_check.md)
14
15
  - [`HtmlCheck`](/docs/api/html_check.md)
@@ -1,33 +1,32 @@
1
- # HTML check API
1
+ # HTML Check API
2
2
 
3
- For checking HTML elements in `.liquid` files.
3
+ This API is designed for checking HTML elements within `.liquid` files.
4
4
 
5
- If you need to check an HTML tag or its attributes, use an `HtmlCheck`.
6
-
7
- The HTML in Liquid files is parsed using the Nokogiri, by consequence you will get [`Nokogiri::XML::Node`][nokogiri].
5
+ To check HTML tags or attributes, use the `HtmlCheck` class.
8
6
 
7
+ HTML content in Liquid files is parsed using Nokogiri, which results in each element being represented as a [`Nokogiri::XML::Node`][nokogiri].
9
8
 
10
9
  ```ruby
11
10
  module PlatformosCheck
12
11
  class MyCheckName < HtmlCheck
13
12
  category :html,
14
- # A check can belong to multiple categories. Valid ones:
13
+ # A check can belong to multiple categories. Valid categories are:
15
14
  categories :translation, :performance
16
15
  severity :suggestion # :error or :style
17
16
 
18
17
  def on_document(node)
19
- # Called with the root node of all theme files
20
- node.value # is an instance of Nokogiri::XML::Node
21
- node.app_file # is the html_file being analyzed, See lib/platformos_check/app_file.rb.
18
+ # Called with the root node of all theme files.
19
+ node.value # returns the value of the node, an instance of Nokogiri::XML::Node.
20
+ node.app_file # points to the HTML file being analyzed. See lib/platformos_check/app_file.rb.
22
21
  node.parent # is the parent node.
23
- node.children # are the children nodes.
24
- # See lib/platformos_check/html_node.rb for more helper methods
25
- theme # Gives you access to all the theme files in the theme. See lib/platformos_check/theme.rb.
22
+ node.children # are the child nodes.
23
+ # Additional helper methods are available in lib/platformos_check/html_node.rb.
24
+ theme # Gives you access to all the theme files in the theme. See lib/platformos_check/app.rb.
26
25
  end
27
26
 
28
27
  def on_img(node)
29
28
  # Called for every <img> element in the file.
30
- node.attributes["class"] # Get the class attribute of the img element.
29
+ node.attributes["class"] # Retrieves the 'class' attribute of the <img> tag.
31
30
  end
32
31
 
33
32
  def on_a(node)
@@ -1,40 +1,37 @@
1
- # Liquid check API
1
+ # Liquid Check API
2
2
 
3
- For checking the Liquid code in `.liquid` files.
4
-
5
- All code inside `{% ... %}` or `{{ ... }}` is Liquid code.
6
-
7
- Liquid files are parsed using the Liquid parser, by consequence you will get Liquid nodes (tags, blocks) in your callback methods. Check the Liquid source for details on those nodes: [Liquid source][liquidsource].
3
+ This API is designed to check Liquid code in `.liquid` files.
8
4
 
5
+ All code inside `{% ... %}` or `{{ ... }}` is Liquid code, and liquid files are parsed using the Liquid parser. This parsing process converts the code into Liquid nodes, such as tags and blocks, which are then used in your callback methods. For a deeper understanding of these nodes, refer to the [Liquid source][liquidsource].
9
6
 
10
7
  ```ruby
11
8
  module PlatformosCheck
12
9
  class MyCheckName < LiquidCheck
13
10
  category :liquid,
14
- # A check can belong to multiple categories. Valid ones:
11
+ # A check can belong to multiple categories. Valid categories are:
15
12
  categories :translation, :performance
16
13
  severity :suggestion # :error or :style
17
14
 
18
15
  def on_document(node)
19
- # Called with the root node of all liquid_file
16
+ # Called with the root node of all liquid_file.
20
17
  node.value # is the original Liquid object for this node. See Liquid source code for details.
21
- node.app_file # is the liquid_file being analyzed, See lib/platformos_check/liquid_file.rb.
18
+ node.app_file # is the liquid_file being analyzed. See lib/platformos_check/liquid_file.rb.
22
19
  node.parent # is the parent node.
23
- node.children # are the children nodes.
24
- # See lib/platformos_check/node.rb for more helper methods
25
- theme # Gives you access to all the theme files in the theme. See lib/platformos_check/theme.rb.
20
+ node.children # are the child nodes.
21
+ # Additional helper methods are available in lib/platformos_check/node.rb.
22
+ theme # Gives you access to all the theme files in the theme. See lib/platformos_check/app.rb.
26
23
  end
27
24
 
28
25
  def on_node(node)
29
- # Called for every node
26
+ # Called for every node.
30
27
  end
31
28
 
32
29
  def on_tag(node)
33
- # Called for each tag (if, include, for, assign, etc.)
30
+ # Called for each tag (if, include, for, assign, etc.).
34
31
  end
35
32
 
36
33
  def after_tag(node)
37
- # Called after the tag children have been visited
34
+ # Called after visiting the children of a tag.
38
35
 
39
36
  # If you find an issue, add an offense:
40
37
  add_offense("Describe the problem...", node: node)
@@ -43,14 +40,13 @@ module PlatformosCheck
43
40
  end
44
41
 
45
42
  def on_assign(node)
46
- # Called only for {% assign ... %} tags
43
+ # Specifically for {% assign ... %} tags.
47
44
  end
48
45
 
49
46
  def on_string(node)
50
- # Called for every `String` (including inside if conditions).
47
+ # Called for every `String`, including those within if conditions.
51
48
  if node.parent.block?
52
- # If parent is a block, `node.value` is a String written directly to the output when
53
- # the theme file is rendered.
49
+ # If the parent is a block, `node.value` is a String written directly to the output when the theme file is rendered.
54
50
  end
55
51
  end
56
52
 
@@ -59,11 +55,11 @@ module PlatformosCheck
59
55
  end
60
56
 
61
57
  def on_error(exception)
62
- # Called each time a Liquid exception is raised while parsing the theme file
58
+ # Called each time a Liquid exception is raised while parsing the theme file.
63
59
  end
64
60
 
65
61
  def on_end
66
- # A special callback after we're done visiting all the files of the theme
62
+ # A special callback after we're done visiting all the files of the theme.
67
63
  end
68
64
 
69
65
  # Each type of node has a corresponding `on_node_class_name` & `after_node_class_name`
@@ -1,12 +1,12 @@
1
- # JSON check API
1
+ # YAML Check API
2
2
 
3
- For checking the content of `.yml` files.
3
+ This API is designed for checking the content of `.yml` files.
4
4
 
5
5
  ```ruby
6
6
  module PlatformosCheck
7
7
  class MyCheckName < YamlCheck
8
8
  category :yaml,
9
- # A check can belong to multiple categories. Valid ones:
9
+ # A check can belong to multiple categories. Valid categories are:
10
10
  categories :translation, :performance
11
11
  severity :suggestion # :error or :style
12
12