# Filters

A filter is a Ruby method that takes one or more parameters and returns a value. Parameters are passed to filters by position: the first parameter is the expression that precedes the pipe character, and additional parameters can be passed using the name: arg1, arg2 syntax.

Output markup can take filters, which modify the result of the output statement. You can invoke filters by following the output statement's main expression with:

  • A pipe character (|)
  • The name of the filter
  • Optionally, a colon (:) and a comma-separated list of additional parameters to the filter. Each additional parameter must be a valid expression, and each filter predefines the parameters it accepts and the order in which they must be passed.

Filters can also be chained together by adding additional filter statements (starting with another pipe character). The output of the previous filter will be the input for the next one.

Hello {{ 'tobi' | upcase }}
Hello tobi has {{ 'tobi' | size }} letters!
Hello {{ '*tobi*' | textilize | upcase }}
Hello {{ 'now' | date: "%Y %h" }}

# Basics

# Append

Adds a string e.g. {{ 'foo' | append:'bar' }} #=> 'foobar'

# Base64 decode

Decodes a Base64-encoded string e.g. {{ 'SGVsbG8gd29ybGQ=' | base64_decode }} #=> 'Hello world'

# Base64 encode

Encodes a string to Base64 e.g. {{ 'Hello world' | base64_encode }} #=> 'SGVsbG8gd29ybGQ='

# Capitalize

Capitalizes the first letter of each word in the input string.

# Ceiling

Rounds up a decimal number to the next integer, e.g. {{ 4.6 | ceil }} #=> 5

# Date

Formats a date (syntax reference (opens new window))

# Default

Returns the given variable unless it is null or empty string, then it returns the given value, e.g. {{ undefined_variable | default: "Default value" }} #=> "Default value"

# Divided by

Integer division e.g. {{ 10 | divided_by:3 }} #=> 3

# Downcase

Converts an input string to lowercase.

# Escape

HTML escapes a string.

# Escape once

Returns an escaped version of html without affecting existing escape entities.

# First

Gets the first element of the passed array.

# Floor

Rounds a decimal number down to the nearest integer, e.g. {{ 4.6 | floor }} #=> 4

# Format date

Formats a date with the site's localization, uses the same syntax as date.

# Join

Joins array elements with a certain character between them.

# Last

Gets the last element of the passed array.

# Lstrip

Removes all whitespace from the beginning of a string.

# Map

Maps/collects an array into a given property.

# Minus

Subtraction e.g. {{ 4 | minus:2 }} #=> 2

# Modulo

Modulo e.g. {{ 3 | modulo:2 }} #=> 1

# Newline to br

Replaces each newline (\n) with HTML break tag.

# Plus

Performs addition e.g. {{ '1' | plus:'1' }} #=> 2, {{ 1 | plus:1 }} #=> 2

# Prepend

Prepends a string e.g. {{ 'bar' | prepend:'foo' }} #=> 'foobar'

# Remove

Removes all occurrences e.g. {{ 'foobarfoobar' | remove:'foo' }} #=> 'barbar'

# Remove first

Removes the first occurrence e.g. {{ 'barbar' | remove_first:'bar' }} #=> 'bar'

# Replace

Replaces all occurrences e.g. {{ 'foofoo' | replace:'foo','bar' }} #=> 'barbar'

# Replace first

Replaces the first occurrence e.g. {{ 'barbar' | replace_first:'bar','foo' }} #=> 'foobar'

# Reverse

Reverses the given array.

# Round

Rounds to the nearest integer or to the specified number of decimals e.g. {{ 4.5612 | round: 2 }} #=> 4.56

# Rstrip

Removes all whitespace from the end of a string

# Script tag

Generates the HTML <script> tag for JavaScript, taking as parameters the URL and attributes of the form attr: 'value', e.g. {{ 'my-js-url' | script_tag: async: 'async', defer: 'defer' }} => <script src='my-js-url' type='text/javascript' async='async' defer='defer'></script>

# Size

Returns the size of an array or string

# Slice

Splits a string. Takes an offset and length, e.g. {{ "hello" | slice: -3, 3 }} #=> llo

# Sort

Sorts array elements

# Split

Splits a string on a matching pattern e.g. {{ "a~b" | split:"~" }} #=> ['a','b']

# Times

Multiplies e.g. {{ 5 | times:4 }} #=> 20

# Truncate

Restricts a string to x characters. Also accepts a second parameter that will be appended to the string e.g. {{ 'foobarfoobar' | truncate: 5, '.' }} #=> 'foob.'

# Truncatewords

Restricts a string to x words

# Uniq

Removes duplicate elements from an array, optionally using a given property to check for uniqueness.

# Upcase

Converts an input string to uppercase

# URL encode

URL-encodes a string

# Commerce

These are the liquid filters that alter values related to Commerce.

# Format currency

Adds currency format to a value. e.g. {{ 4 | format_currency }} => $4

{{ 1890.5123 | format_currency: unit: '¥', separator: ',', delimiter: '.', precision: 3 }} = ¥1.890,512

Important

This filter determines the currency format and takes precedence over any other currency configuration.

If you don't specify currency parameters with the currency filter, Modyo uses the realm's payment configuration.

If the site doesn't have an associated realm and you don't specify parameters, the predefined format of the site's language will be applied.

Parameters:

  • unit - currency symbol.
  • separator - decimal separator.
  • delimiter - thousands separator.
  • precision - number of decimal digits.

# Content

These are the liquid filters that alter values related to the Content module in Modyo Platform.

# Asset lookup by UUID

The asset_image, asset_link, asset_url_by_uuid and asset_video filters look the file up by its UUID within the account, not within the site.

Attention

If the UUID doesn't match any file in the account, none of the four fails or returns empty: they print the message Liquid error: Asset with uuid 'the-requested-uuid' does not exist, which ends up published on the page. Check the UUIDs whenever you move templates or content across accounts.

# Asset image

Returns the tags of an image using its uuid from the File Manager. If using Cloudflare for image optimization, you can use these additional parameters: width, height, blur, quality, format and fit. e.g. {{ uuid | asset_image: width: 40, format: 'auto', fit: 'cover' }}

Emits an HTML anchor tag pointing to the File Manager file identified by its UUID. The argument is the visible link text and, if you omit it, the asset's file name is used instead. e.g. {{ uuid | asset_link: 'Download the guide' }} => <a href='https://mydomain.com/uploads/guide.pdf'>Download the guide</a>

Parameters:

  • uuid (String) — asset uuid
  • label (String) (default: the asset's file name) — visible link text

Tip

If all you need is the file's address, to build your own markup, use asset_url_by_uuid.

# Asset URL by UUID

Returns the URL of an image using its uuid from the File Manager. e.g. {{ uuid | asset_url_by_uuid }}

# Asset video

Returns the tags of a video using its uuid from the File Manager. e.g. {{ uuid | asset_video: 350, 300 }}

Parameters:

  • uuid (String) — asset uuid
  • width (Integer) (default: 300) — width
  • height (Integer) (default: 200) — height

# By category

Returns a list of Entries that belong to the selected Category. e.g. {% assign filtered_entries = entries | by_category: 'category2,category1,category3' %}

Parameters:

  • entries (ArrayEntry) — array with entries
  • list (String) (default: '') — String with comma-separated categories.

# By lang

Returns a list of Entries in the given language. The filter is called by_lang: locale is the name of the parameter, not the name of the filter. e.g. {% assign entries = widget.entries | by_lang: 'es' %} => entries

Parameters:

  • entries (ArrayEntry) — array with entries
  • locale (String) (default: '') — a single locale code

by_lang replaces any language condition the collection already had, it doesn't add to it: the last by_lang in the chain wins.

Attention

It doesn't take a comma-separated list. A value such as 'es,en,pt' is compared as-is against each entry's language, so the result is an empty collection instead of the union of the three languages. If you need several languages, resolve one collection per language and iterate them separately.

Applied to anything that isn't a collection of entries, the filter aborts and the published HTML keeps the comment <!-- Liquid Error --> in place of the block.

# By slug

Returns a list of Entries that belong to a selected slug. e.g. {% assign filtered_entries = entries | by_slug: 'slug2,slug1,slug' %}

Parameters:

  • entries (ArrayEntry) — array with entries
  • slug (String) (default: '') — Comma-separated slugs.

# By tag

Returns a list of Entries that belong to a selected tag. e.g. {% assign entries = widget.entries | by_tag: 'tag2,tag1,tag3' %} => entries

Parameters:

  • entries (ArrayEntry) — array with entries
  • list (String) (default: '') — String with comma-separated tags.

# By type

Returns a list of Entries that belong to a selected Content Type. e.g. {% assign filtered_entries = entries | by_type: 'type2,type1,type3' %}

Parameters:

  • entries (ArrayEntry) — array with entries
  • list (String) (default: '') — String with comma-separated content types.

# By UUID

Filters an array of entries by one or more UUIDs.

Parameters:

  • entries (ArrayEntry) — collection (object before the pipe)
  • uuid_list (String) — comma-separated list of UUIDs

Defaults: If uuid_list is blank returns the original collection.

e.g. {% assign filtered = entries | by_uuid: 'uuid2,uuid1,uuid3' %}

# Composite Entry Filter (by)

Applies multiple entry filters in one call. Supported option keys (all optional):

  • types: comma-separated type slugs (applies by_type)
  • categories: comma-separated category slugs (applies by_category)
  • tags: comma-separated tags (applies by_tag)
  • slugs: comma-separated entry slugs (applies by_slug)
  • uuids: comma-separated UUIDs (applies by_uuid)
  • locale: a single locale code (applies by_lang; a comma-separated list is not supported)
  • from_published_date: date string (>= published_at)
  • to_published_date: date string (<= published_at)
  • sort_by: field name (default: created_at). Accepts name, slug, created_at, updated_at and published_at, or a field with its prefix (fields.<name> or meta.<attribute>); see Sort By
  • order: asc | desc (default: desc)
  • per_page: integer results per page (enables pagination if provided; default: 10)
  • page: integer page number (enables pagination if provided; default: 1)

e.g. {% assign entries = spaces['testing'].entries | by: types: 'promo,basic', locale: 'es', categories: 'starred,favorites', tags: 'test,test2', slugs: 'slug2,slug1', uuids: 'uuid2,uuid1', sort_by: 'name', order: 'asc', per_page: 10, page: 2 %}

sort_by and order are optional in the call, but not in effect: by always applies sort_by, using created_at and desc as defaults. A collection that already came sorted by another criterion, such as a widget with its own order, comes out re-sorted by creation date descending even if the template requests no ordering at all, and there is no way to tell by not to sort. If you need to preserve the original order, chain the simple filters (by_type, by_category, by_tag, by_slug…) instead of using by.

Pagination, on the other hand, is optional: it is applied only if you pass per_page or page. The defaults of those two keys are what the filter uses when you set one and omit the other, and they are subject to the URL parameter precedence described in Paginated.

Attention

Keys that by does not recognize are ignored silently, with no error or warning: a singular type: or a misspelled tag: filters nothing and the listing comes out complete. Check the key names against the list above before giving up on a filter that seems to do nothing.

# Filter By

Returns a list of Entries that match a filter. e.g. {% assign entries = widget.entries | filter_by: field: 'meta.name', eq: 'entry3Cat3' %}

Parameters:

  • entries (ArrayEntry) — array with entries
  • opts (Hash) (default: {}) — hash with field and operator/value pairs

The value of field is always written with its prefix:

  • fields.<name> for the content type's fields.
  • meta.<attribute> for metadata, with these attributes available: meta.uuid, meta.name, meta.slug, meta.category, meta.category_slug, meta.category_name, meta.created_at, meta.updated_at, meta.published_at and meta.unpublished_at. To filter by tags use by_tag.

Attention

A field name without a prefix is silently discarded: the filter raises no error and returns the whole collection, unfiltered. If a listing shows you every entry, check first that the value of field starts with fields. or with meta..

Supported Operators (use as keys in opts):

  • eq — equals (implicit when only field and value provided)
  • not — not equal to. With nil as the value it returns the entries that do have a value in the field
  • gt, lt — greater than / less than
  • in — field value must be one of the comma-separated values
  • nin — field value must NOT be one of the comma-separated values
  • has — array-type field must contain all of the comma-separated values
  • search — searches the text in the attributes of the entry's locations; requires a location field
  • geohash — searches by proximity with a base 32 geohash; requires a location field

Only in, nin and has take a comma-separated string; the rest take a single value. search and geohash behave just like in the Content public API. The all operator, which appears in the Filter By Query String list, is not available in filter_by.

Examples:

Filter entries where the status field is either 'published' or 'featured': {% assign entries = entries | filter_by: field: 'fields.status', in: 'published,featured' %}

Filter entries where the author_id is not 1 or 5: {% assign entries = entries | filter_by: field: 'fields.author_id', nin: '1,5' %}

Filter entries that have both 'tech' and 'news' in their categories array field: {% assign entries = entries | filter_by: field: 'fields.categories', has: 'tech,news' %}

Filter entries whose subtitle field has any value: {% assign entries = entries | filter_by: field: 'fields.subtitle', not: nil %}

Filter entries published after a date: {% assign entries = entries | filter_by: field: 'meta.published_at', gt: '2026-01-01' %}

Attention

There are two cases where filter_by aborts and the published HTML keeps the comment <!-- Liquid Error --> in place of the block: when you call it without field, and when you apply it to a collection whose content type can't be resolved, such as spaces['blog'].entries. Always start from a collection scoped to a single type, such as spaces['blog'].types['post'].entries or widget.entries.

# Filter By Query String

Returns a list of Entries that match a query. You can use logical operators, various meta fields, URLs, or Liquid tags.

Operators:

  • gt, lt, in, all, nin

Fields:

  • meta.category meta.category_slug meta.category_name meta.uuid meta.name meta.created_at meta.updated_at meta.published_at meta.unpublished_at meta.slug meta.tag

URL Examples:

  • https://company.site.com/testsite?meta.category_slug=category3
  • https://company.site.com/testsite?meta.tag=tag_name
  • https://company.site.com/testsite?meta.tag[in][]=tag1_name&meta.tag[in][]=tag2_name
  • https://company.site.com/testsite?meta.created_at=1987-11-19T13:13:13

e.g. {% assign entries = widget.entries | filter_by_query_string %}

Parameters:

  • entries (ArrayEntry) — array with entries

# From Published Date

Returns a list of Entries that have a publication date more recent than the limit. e.g. {% assign entries = widgets.entries | from_published_date: date %}

Parameters:

  • entries (ArrayEntry) — array with entries
  • date (Datetime)(default: Time.zone.now) — limit date

# Limit

Limits the number of results. e.g. {{ entries | limit: 1 }}

Parameters:

  • object(Array) — array
  • limit (Integer)(default: 1) — result limit

# Paginated

Separates the results into pages. e.g. {{ objects | paginated: 10, 2 }}

Parameters:

  • object(Array) — entry collection (object before the pipe)
  • per_page (Integer) (default: 10) — objects per page
  • page (Integer) (default: 1) — page number to display

The page and per_page URL parameters take precedence over the arguments written in the template. With the example above, a visit to my-page.com/landing?page=5 shows page 5 and not page 2: the arguments act as initial values, for the first visit without parameters in the URL. And because those parameters are global to the page, they reach every paginated listing on it at once.

The filter clamps both values, whether they come from the argument or from the URL: per_page is limited to a minimum of 1 and a maximum of 100, and page to a minimum of 1. A per_page of 500 returns 100 results per page.

Attention

Applied to something that is not an entry collection, for example an array already materialized by sort, by map or defined in the template itself, the filter returns the input untouched: it does not paginate and it does not fail either. The listing looks complete, the pagination links do not appear and no clue is left as to why. Chain paginated directly onto the entry collection.

# Sort By

Returns an array with entries sorted by a field e.g. {% assign entries = widgets.entries | sort_by: 'name', 'asc' %}

Parameters:

  • collection (ArrayEntry | ArrayCategory) — collection to sort (object before the pipe)
  • field (String) — field by which you want to sort
  • order (String) (default: 'desc') — asc or desc

The default order is descending and any value that is not exactly asc is treated as desc: an 'ascending' or an 'asc ' with an extra space sort the opposite way from what you asked, with no warning at all.

The accepted fields depend on the collection the filter receives:

  • Category collection: only name, slug and uuid.
  • Entry collection: the five meta attributes name, slug, created_at, updated_at and published_at are sorted directly. Any other name is resolved by the search layer, which requires the container prefix, just like Filter By: fields.<name> for a content type field and meta.<attribute> for the remaining metadata.

Attention

On a category collection, a field outside name, slug and uuid returns an empty collection with no error at all: the listing looks blank and seems to have no data.

On an entry collection, a name without a prefix, such as 'price' instead of 'fields.price', does not sort by the field you expect. Also, sorting by fields.<name> requires, just like filter_by, a collection scoped to a content type: on something like spaces['blog'].entries the filter aborts and the published HTML keeps the <!-- Liquid Error --> comment in place of the block. Start from spaces['blog'].types['post'].entries or from widget.entries.

The filter also aborts, with the same comment in the output, if the field or the order do not arrive as strings, for example | sort_by: 'name', 1.

# To Published Date

Returns a list of Entries that have a publication date older than the limit. e.g. {% assign entries = widgets.entries | to_published_date: date %}

Parameters:

  • entries (ArrayEntry) — array with entries
  • date (Datetime)(default: Time.zone.now) — limit date

# Crypto

These Liquid filters alter values related to Cryptography.

Attention

The only hash filters in Modyo Platform are hmac_sha256 and sha256. md5, sha1 and hmac_sha1 do not exist and, because an unknown filter doesn't interrupt rendering, Liquid returns the input value untransformed: the page publishes the data in the clear where you expected a hash. Review your templates before signing an integration with them.

# HMAC SHA256

Returns the SHA-256 hash of a string using a message authentication code (HMAC), with the key as the argument (e.g. {{ 'Hello world' | hmac_sha256: 'key' }} #=> 'a82b2e160edaf92a6589dc11160d2a10c04449840a58717db308c1ee3512b039').

# SHA 256

Returns the SHA-256 hash of a string (e.g. {{ 'Hello world' | sha256 }} #=> '64ec88ca00b268e5ba1a35678a1b5316d212f4f366b2477232534a8aeca37f3c').

# CSS

These Liquid filters alter CSS-related values in Modyo Platform.

Attention

Every color filter aborts if the input value isn't a valid color, for example a variable that doesn't exist in the context. When that happens, the published HTML keeps the comment <!-- Liquid Error --> in place of the color and the CSS rule that used it is lost.

# Brighten

Adds brightness to a color (e.g. {{ '#00ff00' | brighten: 15 }} #=> '#26ff26').

# Darken

Reduces the brightness of a color (e.g. {{ '#00ff00' | darken: 15 }} #=> '#00b300').

# Desaturate

Desaturates a color (e.g. {{ '#00ff00' | desaturate: 15 }} #=> '#13ec13').

# Grayscale

Converts a color to grayscale (e.g. {{ '#00ff00' | grayscale }} #=> '#808080'). It accepts a second argument, but that argument doesn't change the result because the grayscale conversion never uses it.

# Greyscale

Converts a color to grayscale, with the same output as grayscale, but it only takes the color (e.g. {{ '#00ff00' | greyscale }} #=> '#808080').

Attention

greyscale and grayscale are not interchangeable: greyscale doesn't accept a second argument. A template that passes an amount, such as {{ color | greyscale: 15 }}, aborts because of the number of arguments and the published HTML keeps the comment <!-- Liquid Error -->. The same template with grayscale works.

# Lighten

Lightens a color (e.g. {{ '#00ff00' | lighten: 15 }} #=> '#4dff4d').

# Opacity

Modifies the opacity of a color (e.g. {{ '#00ff00' | opacity: 0.5 }} #=> 'rgba(0, 255, 0, 0.5)').

# RGB

Transforms a color to its RGB equivalent (e.g. {{ '#00ff00' | rgb }} #=> 'rgb(0, 255, 0)').

# Saturate

Saturates a color (e.g. {{ '#00ff00' | saturate: 15 }} #=> '#00ff00').

# Spin

Rotates a color in degrees clockwise (e.g. {{ '#00ff00' | spin: 15 }} #=> 'rgba(0, 255, 0, 0.5)').

# Location

These Liquid filters alter values related to Geolocation in Modyo Platform.

# Dynamic Map

Returns a dynamic Google Maps map (e.g. {{ locations | dynamic_map: '600x300', 10, 'roadmap', '', true }}).

Parameters

  • locations (ArrayHash) — Array of hashes with latitude and longitude points.
  • size (String) (default: '600x300') — Map size in pixels.
  • zoom (Integer) (default: 10) — Zoom level for the map.
  • type (String) (default: 'roadmap') — Map type.
  • icon (String) (default: '') — Map icon.
  • controls (Boolean) (default: true) — Navigation controls for the map.

# Static Map

Returns a static Google Maps map (e.g. {{ locations | static_map: '600x300', 15, 'roadmap' }}).

Parameters

  • locations (ArrayHash) — Array of hashes with latitude and longitude points.
  • size (String) (default: '600x300') — Map size in pixels.
  • zoom (String) (default: '') — Zoom level for the map. With no value, the Google Maps URL is built with an empty zoom= and the framing is left to Google; always pass it when you need a fixed framing.
  • type (String) (default: 'roadmap') — Map type.
  • icon (String) (default: '') — Map icon.

Attention

In both filters the argument that follows size is zoom, not controls. An example such as {{ locations | static_map: '600x300', 'true', 'roadmap' }} builds the Google Maps URL with zoom=true and the map is not framed as you expect. In dynamic_map the order is size, zoom, type, icon, controls, so reaching controls means passing the four preceding arguments.

These Liquid filters alter values related to menu items in Modyo Platform.

# Active Page

Determines if a URL item is active. Returns 'active' when active (e.g. {{ 'company.modyo.com/jobs' | active_page: 'company.modyo.com/jobs' }} #=> 'active').

# Item Rel

Returns 'noopener noreferrer' if a link is "_blank" (e.g. {{ '_blank' | item_rel }} #=> 'noopener noreferrer').

# Resolve URL

Resolves the URL from a path and base URL (e.g. {{ 'dynamic_bank' | resolve_url: 'company.modyo.com' }} #=> 'company.modyo.com/dynamic_bank').

# Visible Items

Returns a list of visible items in a list of items (e.g. {{ items | visible_items }}).

# Origination

These are the liquid filters that alter values related to originations in Modyo Platform.

# By UID

Returns the object with the given UID inside an Origination module collection. It is a single filter, by_uid, that accepts four collection classes:

  • site.originations — the originations of the site.
  • origination.steps — the steps of an origination.
  • step.tasks — the tasks of a step.
  • task.fields — the questions of a user input task. This is the only way to take a specific question by its UID; the objects it returns are question.

Parameters:

  • collection (ArrayOrigination | ArrayStep | ArrayTask | ArrayQuestion) - collection to search in
  • uid (String) - UID of the object to find

The filter returns a single object, not a collection: its result is used directly and is not traversed with a loop. If no element in the collection has that UID, it returns nothing.

e.g.

{% assign my_origination = site.originations | by_uid: 'my-origination' %}
{% assign my_step = my_origination.steps | by_uid: 'step-01' %}
{% assign my_task = my_step.tasks | by_uid: 'task-01' %}
{% assign my_question = my_task.fields | by_uid: 'question-01' %}

Attention

In two cases the filter aborts and the published HTML keeps the <!-- Liquid Error --> comment in place of the block: when it is applied to something that is not a collection, and when it is applied to a collection of an unsupported class. In the second case the message includes the name of the class received, which makes it possible to identify what was passed by mistake.

# Site

These Liquid filters alter values related to Sites in Modyo Platform.

# Removed filters

As of version 10.2 the video_player, audio_player, embedded_video and asset_thumbnail_link_tag filters no longer exist. The bar_code and qr_code filters never existed in Modyo Platform.

Attention

An unknown filter doesn't interrupt rendering: Liquid returns the input value untransformed. A template that still invokes these filters on an asset no longer shows the player or the link, and publishes the internal name of the object it received instead, for example Liquid::Drops::Assets::VideoAssetDrop. There is no error message or visible hint of the cause on the page, so review your templates before upgrading.

To replace video_player and audio_player, build the markup with the file's address, available in url:

{% assign video = assets['video-uuid'] %}
<video src="{{ video.url }}" width="320" height="320" controls="controls"></video>

{% assign audio = assets['audio-uuid'] %}
<audio src="{{ audio.url }}" controls="controls"></audio>

To replace asset_thumbnail_link_tag, wrap the thumbnail, available in thumbnail_url, in a link to the file:

{% assign image = assets['image-uuid'] %}
<a href="{{ image.url }}" class="thumbnail"><img src="{{ image.thumbnail_url }}" alt="{{ image.alt_text }}"></a>

embedded_video, bar_code and qr_code have no replacement: the platform doesn't currently offer an equivalent filter.

# Asset image Tag

Generates the HTML tag of an image (e.g. {{ asset | asset_image_tag: 'original' }}).

# Asset URL

Generates the URL of an Asset object or a template asset path. For Asset objects using Cloudflare for image optimization, you can use the following additional parameters: width, height, blur, quality, format and fit. (e.g. {{ assets['asset_uuid'] | asset_url: blur: 40, format: 'auto', fit: 'cover' }}). For template asset paths from the template builder, specify the asset type as the second argument (e.g. {{ 'base' | asset_url: 'js' }}). You can also use the script_tag or stylesheet_tag filters to automatically generate the complete HTML