Homepage

Liquid - platformOS Liquid Tags

Last edit: Jul 14, 2023

background

Invokes code within the tag asynchronously, in the background. You 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 to explicitly pass page/layout metadata if you want to use it, as well as device and constants.

Params

Name Type Description
options Hash Any variable provided to the background tag will become accessible in the code.
options.delay Float which defines the number of minutes to delay running code (defaults to 0, which means run code as soon as possible)
options.priority String low, default or high - see AsyncCallbackPriorityEnum GraphQL Object
options.max_attempts Integer the number of time to re-try job upon failing. Default is 1, maximum is 5
options.source_name String your label of the job, which would help you identify it

Examples


        Run background code from partial
The 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
explicitly provided to the background tag: "data" and "hey". Note that you will not have access to the "my_data" variable. Also note
that the result of this background tag will not be rendered, and you will not have access to any variable inside the background tag.

# app/views/partials/example_partial.liquid
{% liquid
  log not_available_in_background  # Will be null, as this variable was not passed to the background tag
  log data                         # You will see { "hello": "world" }, as it was provided to the background tag
  log hey                          # You will see "hello" as it was provided to the background tag
  log context                      # You will copy the current request context and make it available in the background
  assign not_available_outside = "You will not see me"

%}

# app/views/pages/test.liquid
{% liquid
  assign my_data = null | hash_merge: hello: "world"
  assign not_available_in_job = "You will not see me "
  background job_id = 'example_partial', delay: 0.1, max_attempts: 3, source_name: 'custom_job', data: my_data, hey: 'hello'

  # This variable will be rendered in the background, meaning you won't see anything on the page
  echo not_available_outside
%}
      

        Deprecated
The 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
explicitly provided to the background tag: "data" and "hey". Note that you will not have access to the "my_data" variable. Also note
that the result of this background tag will not be rendered, and you will not have access to any variable inside the background tag.

{% parse_json my_data %}{ "hello": "world" }{% endparse_json %}
{% assign not_available_in_background = "You will not see me" %}
{% background priority: 'low', delay: 0.5, max_attempts: 3, source_name: "my custom job", data: my_data, hey: 'hello' %}
  {% log not_available_in_background %} {% comment %}Will be null, as this variable was not passed to the background tag {% endcomment %}
  {% log data %} {% comment %}You will see { "hello": "world" }, as it was provided to the background tag{% endcomment %}
  {% log hey %} {% comment %}You will see "hello" as it was provided to the background tag{% endcomment %}
  {% log context %} {% comment %}You will copy the current request context and make it available in the background{% endcomment %}
  {% assign not_available_outside = "You will not see me" %}
  {{ not_available_outside }} {% comment %}This variable will be rendered in the background, meaning you won't see anything on the page{% endcomment %}
{% endbackground %}
{{ 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 %}
      

cache

Checks if there's string cached for the given key. If yes, it just returns the value without processing anything inside the cache tag, otherwise it executes code, stores the result in the cache. When you hit the page with such code for the first time, the code will be executed and hence it will iterate through the loop and generate random strings. However, then the result of the block will be cached and all the following requests within 20 seconds would not invoke the code - instead, it would just take the value from the cache. The output will not change. When the cache expires, the code will be evaluated again, producing another set of random string. Cache is automatically invalidated if any changes are applied to any view/translation.

Params

Name Type Description
key String the key which should uniquely identify the cached fragment
expire Integer optional. number of seconds since populating the cache to expiration

Examples


        {% cache 'this is my key', expire: 20 %}
  <ul>
    {% for i in (1..100) %}
      <li>{{ 18 | random_string }}</li>
    {% endfor %}
  </ul>
{% endcache %}
      

        {% parse_json pagesUpdatedAt %}
  {%- cache pagesUpdatedAtCache -%}
    {%- graphql g = 'pages_updated_at' | dig: 'admin_pages', 'results' -%}
    {{- g -}}
  {%- endcache -%}
{% endparse_json %}
{%- export pagesUpdatedAt, namespace: 'nav' -%}
      

content_for

Stores a block of markup in an identifier for later use. Render it later with `yield` tag.

Params

Name Type Description
name String the markups will be stored under this name
flush Boolean optional. If the flush parameter is true content_for replaces the blocks it is given instead of appending content to the existing one

Examples


        {% content_for 'header' %}
  Hello world
{% endcontent_for %}
      

context

Set locale in context to given language

Params

Name Type Description
language String language 2 letter

Examples


        {% context language: 'de' %}
      

export

Makes variables defined inside partial accessible anywhere via context.exports.`namespace`

Params

Name Type Description
variable Any variable to be stored inside the namespace
namespace String namespace under which variable will be in context.exports

Examples


        {% liquid
  assign a = 'value for a'
  assign b = 'value for b'
  export a, b, namespace: 'my_hash'
%}

{{ context.exports.my_hash }} => { "a": "value for a", "b": "value for b" }
{% parse_json company %}
{
  "name": "platformOS",
  "technologies": ["liquid", "graphql"],
  "countries": { "USA": 5, "Poland": 5, "Romania": 2 }
}
{% endparse_json %}

{% export company, namespace: 'data' %}

{{ context.exports.data }} =>
  {"company"=>{"name"=>"platformOS", "technologies"=>["liquid", "graphql"], "countries"=>{"USA"=>5, "Poland"=>5, "Romania"=>2}}}
{{ context.exports.data.company.technologies }} => liquidgraphql
{{ context.exports.data.company.name }} => platformOS
      

form

Used to generate a html form element for a resource. Use within `form configuration`. Inside the tag you can use `form_builder` variable.

Params

Name Type Description
html-id String set id attribute in `<form id="">` element
html-novalidate String add `novalidate` attribute to `<form novalidate>` element
html-class String add css class `<form class="">` element
html-multipart Boolean add `enctype="multipart/form-data"` attribute to `<form enctype="multipart/form-data">` element.<br />Multipart is enabled by default
html-data- attr [String] add data attribute to `<form data-[attr]="">` element

Examples


        {% form %}
  {{ form_builder }}
{% endform %}
      

        {% form html-id: 'someid', html-novalidate: true, html-class: 'big-form green-form', html-data-user-id: '12345', html-multipart: false %}
{% endform %}
      

function

Allows to store a variable returned by a partial. Partial needs to return data with `return` tag. All variables needs to be passed explicitly to function. Variables from upper scope are not visible in function. *Note:* `context` is not available inside the function partial unless explicitly passed as a variable.

Examples


        {% function res = 'path/to/my/partial', arg1: 'hello' %}
      

        # path/to/my/partial
{% liquid
  assign res = 'hello' | append: foo | append: ' ' | append: context.location.host
  return res
%}
# path/to/my/partial

{% liquid
  assign foo = 'hello'
  function res = 'path/to/my/partial', foo: foo, context: context
%}
      

graphql

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. It returns a hash with the data or the errors that occurred (for example, variable type mismatch, required variable not provided, syntax error) etc.

Params

Name Type Description
query_name String name of the GraphQL query. For get_users.graphql file name of the query is get_users
arguments Hash optional. key:value pair(s) which will be passed to GraphQL query. For example, if<br />your query looks like `query my_query($email: String!)`, then you can provide `email: "my-email@example.com"`
args Hash|JSON optional. Either a Hash or a String) of the arguments which will be passed to GraphQL query. See examples below.

Examples


        Invoke query "get_models" and store the result in variable "g":
{% graphql g = "get_models", model_id: context.params.slug2 %}
      

        Chain filters to extract results in one line:
{% graphql g = "get_models", model_id: context.params.slug2 | fetch: 'models' | fetch: 'results' %}
      

        Pass all arguments at once as a hash to have graphql tag in one line and/or compose arguments hash dynamically:
{% parse_json arguments %}
  {
    "model_id": {{ context.params.slug2 | json }},
    "user_id": {{ context.params.user_id | json }}
  }
{% endparse_json %}

{% graphql g = "get_models", args: arguments %}
      

        Pass all arguments at once as a JSON string:

{% capture arguments %}
{
   "per_page": 20,
   "page": 2
}
{% endcapture %}

{% graphql g = "get_models", args: arguments %}
      

        Invoke inline query and store the result in variable "g". This is recommended for one-time used queries.

{% graphql g, id: context.params.slug2, message: "new message" %}
  mutation set_message($id: ID!, $message: String!) {
   model_update(
     id: $id
     model: {
       properties: [{ name: "message", value: $message }]
     }
   ) {
     id
     message: property(name: "message")
   }
  }
{% endgraphql %}
      

hash_assign

Allows to easily modify a Hash with a syntax same as assign tag.

Examples


        {% parse_json my_hash %}{ "a": { "b": { "c": "12", "d": "hello" } } }{% endparse_json %}
{% hash_assign my_hash["a"]["e"] = "assign" | upcase %}
{{ my_hash }} => {"a":{"b":{"c":"12","d":"hello"},"e":"ASSIGN"}}
      

        {% parse_json my_hash %}{ "a": { "b": { "c": "12", "d": "hello" } } }{% endparse_json %}
{% hash_assign my_hash["a"]["b"]["d"] = "bye" | upcase %}
{{ my_hash }} => {"a":{"b":{"c":"12","d":"BYE"}}}
      

        {% parse_json my_hash %}{ "a": { "b": { "c": "12", "d": "hello" } } }{% endparse_json %}
{% hash_assign my_hash["a"]["b"] = null %}
{{ my_hash }} => {"a":{"b":null}}
      

        {% parse_json my_hash %}{ "a": { "b": { "c": "12", "d": "hello" } } }{% endparse_json %}
{% hash_assign my_hash["a"]["b"]["c"]["e"] = "bye" | upcase %}) => HashAssignTagError: Liquid error: my_hash[a][b][c] is 12, expected Hash
      

include_form

This tag should be used to render forms defined in forms directory

Params

Name Type Description
form_name String name of the form configuration from forms directory
id ID id of the resource you want to edit
parent_resource_id String name of the resource type, f.e. name of custom_model_type, transactable_type, user_profile_type

Examples


        {% include_form 'signup_form' %}
      

        {% include_form 'edit_user', id: user.id %}
      

        {% include_form 'manager_invite_to_interview', parent_resource_id: 'invitation', user: g.user %}
      

log

Print information to environment logs. To view logs run `pos-cli gui serve ` in your application directory and go to `http://localhost:3333/Logs`. If you prefer seeing logs in the terminal, run `pos-cli gui logs `

Params

Name Type Description
message Any Any object that can be printed
type String 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.
env String environment where the entry should be created; can be any of 'all', 'staging', 'production'. Default: 'all'

Examples


        {% log 'hello world' %}
      

        {% log params, type: 'request-params' %}
      

        {% log user.id, type: 'debug' %}
      

        {% log context.current_user, type: 'error' %}
      

        {% log context.current_user, type: 'error', env: 'staging' %}
      

parse_json

Captures and parses the JSON string inside of the opening and closing tags and assigns it to a variable.

Params

Name Type Description
variable_name String variable name that will be used to assign contents after it is parsed
content String valid JSON string to be assigned

Examples


        {% parse_json car %}
  { "type": "SUV", "gearbox": "AT" }
{% endparse_json %}

{{ car }} => {"type"=>"SUV", "gearbox"=>"AT"}
{{ car.type }} => SUV
      

        {% parse_json cars %}
  [
    { "maker": "Honda", "model": "CRX" },
    { "maker": "Subaru", "model": "Forester"},
    { "maker": "Lexus", "model": "LFA" }
  ]
{% endparse_json %}

{{ cars }} => {"maker"=>"Honda", "model"=>"CRX"}{"maker"=>"Subaru", "model"=>"Forester"}{"maker"=>"Lexus", "model"=>"LFA"}
      

        In order to create JSON object from exsting values print them using `json` filter.
This is required only for strings and will escape properly `"` and `'` characters.
Other types will be handled automatically.

{% parse_json nested %}
  {
    "price": 100
  }
{% endparse_json %}
{% assign color = "red" %}
{% assign car = 'Mazda "5"' %}
{% parse_json data %}
  {
    "color": {{ color | json }},
    "car": {{ car | json }},
    "nested": {{ nested }}
  }
{% endparse_json %}

{{ data }} => {"color":"red","car":"Mazda \"5\"","nested":{"price":100}}
      

print

Print variable, skipping any additional sanitization. It provides a way to display a variable which consists of both safe and unsafe html. Warning: Do not use it with data entered by users as it is gonna cause XSS.

Params

Name Type Description
variable String Variable containing safe and potentially unsafe HTML

Examples


        {% liquid
  assign invokable_script = "<script>alert('I will be executed')</script>"
  assign malicious_script = "<script>alert('I should be escaped')</script>"
%}
{% capture result %}
  {{ malicious_script }}{{ invokable_script | html_safe }}
{% endcapture %}
{% print result %}
      

redirect_to

Redirects browser to target

Params

Name Type Description
target String path or url
status Int 3xx HTTP code, default 302

Examples


        {% redirect_to '/dashboard' %}
      

        {% redirect_to 'https://example.com/signup' %}
      

        {% redirect_to '/dashboard', status: 301 %}
      

response_headers

Allows you to set additional HTTP headers for the response.

Params

Name Type Description
headers String headers as JSON string, default {}

Examples


        {% response_headers '{"foo": "bar"}' %}
      

        {% response_headers '{"Content-Type": "application/json", "X-Frame-Options": "somevalue" }' %}
      

response_status

Allows you to set HTTP status for the response. Default 200.

Params

Name Type Description
status Int HTTP status, default 200

Examples


        {% response_status 204 %}
      

        {% response_status 404 %}
      

return

Used inside a partial invoked by a function tag to return a variable

Examples


        {% liquid
  assign result = 1 | plus: 3
  return result
%}
      

session

Stores data during user's session Sets field of given name to given value in context.session

Examples


        {% session foo = 'bar' %}
{{ context.session | json }} => { "foo": "bar" }
      

        {% assign bar = "42" }
{% session foo = bar %}
{{ context.session | json }} => { "foo": "42" }
      

        {% session foo = null %}
{{ context.session | json }} => {}
      

        {% session foo = blank %}
{{ context.session | json }} => {}
      

sign_in

Sign in user

Params

Name Type Description
user_id String id of the user you want to sign in
timeout_in_minutes Float number of minutes after user will be log out

Examples


        {% sign_in user_id: '12345' %}
      

        {% sign_in user_id: '12345', timeout_in_minutes: 15 %}
      

spam_protection

Generates html for spam protection. Supports Google reCAPTCHA strategies: recaptcha_v2, recaptcha_v3 and hcaptcha

Params

Name Type Description
strategy String name of protection strategy. Default is recaptcha_v2
action String action name for reCAPTCHA V3, action may only contain alphanumeric characters and slashes

Examples


        {% form %}
  {% spam_protection "recaptcha_v2" %}
{% endform %}
      

        {% form %}
  {% spam_protection "recaptcha_v3", action: "signup" %}
{% endform %}
      

        {% form %}
  {% spam_protection "hcaptcha" %}
{% endform %}
      

theme_render_rc

Allows to specify search paths for theme partials via app/config.yml property "theme_render_paths" Assuming app/config.yml looks like this: theme_search_paths : - theme/{{ context.constants.MY_THEME | default: "custom" }} - theme/simple

Examples


        
When you render a partial using theme_render

{% theme_render_rc 'product' %}

The 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)
      

try

Allows to catch errors, especially useful with `liquid_raise_mode: true` setting in app/config.yml.

Examples


        {% liquid
  try
    include template_path
  catch err
    unless err.message contains "can't find partial"
      log err, type: 'error when including template file'
    endunless
    include fallback_template_path
  endtry
%}
      

yield

Execute code wrapped inside content_for

Params

Name Type Description
name String name of content_for block

Examples


        Use this in a liquid view first. Then you can use yield inside the layout (for example) or another subsequently rendered view, like below:
{% content_for 'greeting' %}Hello world{% endcontent_for %}

# another_file.liquid
{% yield 'greeting' %}
      

Questions?

We are always happy to help with any questions you may have.

contact us