docs: website for LiquidJS
@@ -0,0 +1,3 @@
|
||||
en: English
|
||||
zh-cn:
|
||||
name: 简体中文
|
||||
@@ -0,0 +1,5 @@
|
||||
tutorials: /tutorials/overview.html
|
||||
tags: /tags/overview.html
|
||||
filters: /filters/overview.html
|
||||
playground: /playground.html
|
||||
api: /api/classes/liquid_.liquid.html
|
||||
@@ -0,0 +1,24 @@
|
||||
-
|
||||
url: https://github.com/harttle/liquidjs/pull/5
|
||||
date: '2016-09-12'
|
||||
title:
|
||||
zh-cn: '异步化:重写了解析器和渲染器,使 LiquidJS 可以提供 Promise API 并支持异步的自定义 Tag 实现。'
|
||||
en: 'Async spike: rewrite the parser and render to support Promise, which enables async tags.'
|
||||
-
|
||||
url: https://opencollective.com/liquidjs/#section-contribute
|
||||
date: '2020-02-26'
|
||||
title:
|
||||
zh-cn: '赞助人:第一个 backer 通过 Open Collective 贡献于 LiquidJS。'
|
||||
en: 'Backers: the first backer contributed to LiquidJS via Open Collective.'
|
||||
-
|
||||
url: https://github.com/harttle/liquidjs/pull/202
|
||||
date: '2020-03-11'
|
||||
title:
|
||||
zh-cn: '内存优化:用更精细的手法重写了解析器,来避免临时字符串的生成,内存占用降低 57.7% 以上。'
|
||||
en: 'Memory Optimization: a more elaborate parser reducing the memory footprint by 57.7%.'
|
||||
-
|
||||
url: https://github.com/harttle/liquidjs/pull/205
|
||||
date: '2016-09-15'
|
||||
title:
|
||||
zh-cn: '性能提升:引入 AST 并重新设计 Token 类型系统,使渲染性能平均提升 100.3%。'
|
||||
en: 'Performance Boost: a simple AST to improve render performance by 100.3%.'
|
||||
@@ -0,0 +1,135 @@
|
||||
tutorials:
|
||||
getting_started:
|
||||
overview: overview.html
|
||||
syntax: syntax.html
|
||||
render_file: render-file.html
|
||||
partials: partials-and-layouts.html
|
||||
express: use-in-expressjs.html
|
||||
advanced:
|
||||
caching: caching.html
|
||||
registeration: register-filters-tags.html
|
||||
whitespace: whitespace-control.html
|
||||
plugins: plugins.html
|
||||
operators: operators.html
|
||||
truth: truthy-and-falsy.html
|
||||
miscellaneous:
|
||||
migration9: migrate-to-9.html
|
||||
contribution_guidelines: contribution-guidelines.html
|
||||
|
||||
filters:
|
||||
overview: overview.html
|
||||
abs: abs.html
|
||||
append: append.html
|
||||
at_least: at_least.html
|
||||
at_most: at_most.html
|
||||
capitalize: capitalize.html
|
||||
ceil: ceil.html
|
||||
date: date.html
|
||||
default: default.html
|
||||
divided_by: divided_by.html
|
||||
downcase: downcase.html
|
||||
escape: escape.html
|
||||
escape_once: escape_once.html
|
||||
first: first.html
|
||||
floor: floor.html
|
||||
join: join.html
|
||||
json: json.html
|
||||
last: last.html
|
||||
lstrip: lstrip.html
|
||||
map: map.html
|
||||
minus: minus.html
|
||||
modulo: modulo.html
|
||||
newline_to_br: newline_to_br.html
|
||||
plus: plus.html
|
||||
prepend: prepend.html
|
||||
remove: remove.html
|
||||
remove_first: remove_first.html
|
||||
replace: replace.html
|
||||
replace_first: replace_first.html
|
||||
reverse: reverse.html
|
||||
round: round.html
|
||||
rstrip: rstrip.html
|
||||
size: size.html
|
||||
slice: slice.html
|
||||
sort: sort.html
|
||||
sort_natural: sort_natural.html
|
||||
split: split.html
|
||||
strip: strip.html
|
||||
strip_html: strip_html.html
|
||||
strip_newlines: strip_newlines.html
|
||||
times: times.html
|
||||
truncate: truncate.html
|
||||
truncatewords: truncatewords.html
|
||||
uniq: uniq.html
|
||||
upcase: upcase.html
|
||||
url_decode: url_decode.html
|
||||
url_encode: url_encode.html
|
||||
where: where.html
|
||||
|
||||
tags:
|
||||
overview: overview.html
|
||||
assign: assign.html
|
||||
capture: capture.html
|
||||
case: case.html
|
||||
comment: comment.html
|
||||
cycle: cycle.html
|
||||
decrement: decrement.html
|
||||
for: for.html
|
||||
if: if.html
|
||||
include: include.html
|
||||
increment: increment.html
|
||||
layout: layout.html
|
||||
raw: raw.html
|
||||
render: render.html
|
||||
tablerow: tablerow.html
|
||||
unless: unless.html
|
||||
|
||||
api:
|
||||
quick_entry:
|
||||
Liquid: "../classes/liquid_.liquid.html"
|
||||
LiquidOptions: "../interfaces/liquid_options_.liquidoptions.html"
|
||||
FS: "../interfaces/fs_fs_.fs.html"
|
||||
Cache: "../interfaces/cache_cache_.cache.html"
|
||||
classes:
|
||||
BlankDrop: "../classes/drop_blank_drop_.blankdrop.html"
|
||||
Context: "../classes/context_context_.context.html"
|
||||
DelimitedToken: "../classes/tokens_delimited_token_.delimitedtoken.html"
|
||||
Drop: "../classes/drop_drop_.drop.html"
|
||||
EmptyDrop: "../classes/drop_empty_drop_.emptydrop.html"
|
||||
Expression: "../classes/render_expression_.expression.html"
|
||||
FilterToken: "../classes/tokens_filter_token_.filtertoken.html"
|
||||
ForloopDrop: "../classes/drop_forloop_drop_.forloopdrop.html"
|
||||
HTMLToken: "../classes/tokens_html_token_.htmltoken.html"
|
||||
HashToken: "../classes/tokens_hash_token_.hashtoken.html"
|
||||
LRU: "../classes/cache_lru_.lru.html"
|
||||
Liquid: "../classes/liquid_.liquid.html"
|
||||
LiteralToken: "../classes/tokens_literal_token_.literaltoken.html"
|
||||
NullDrop: "../classes/drop_null_drop_.nulldrop.html"
|
||||
NumberToken: "../classes/tokens_number_token_.numbertoken.html"
|
||||
OperatorToken: "../classes/tokens_operator_token_.operatortoken.html"
|
||||
OutputToken: "../classes/tokens_output_token_.outputtoken.html"
|
||||
ParseError: "../classes/util_error_.parseerror.html"
|
||||
ParseStream: "../classes/parser_parse_stream_.parsestream.html"
|
||||
Parser: "../classes/parser_parser_.parser.html"
|
||||
PropertyaccessToken: "../classes/tokens_property_access_token_.propertyaccesstoken.html"
|
||||
QuotedToken: "../classes/tokens_quoted_token_.quotedtoken.html"
|
||||
RangeToken: "../classes/tokens_range_token_.rangetoken.html"
|
||||
Render: "../classes/render_render_.render.html"
|
||||
RenderError: "../classes/util_error_.rendererror.html"
|
||||
TablerowloopDrop: "../classes/drop_tablerowloop_drop_.tablerowloopdrop.html"
|
||||
TagToken: "../classes/tokens_tag_token_.tagtoken.html"
|
||||
Token: "../classes/tokens_token_.token.html"
|
||||
TokenizationError: "../classes/util_error_.tokenizationerror.html"
|
||||
Tokenizer: "../classes/parser_tokenizer_.tokenizer.html"
|
||||
WordToken: "../classes/tokens_word_token_.wordtoken.html"
|
||||
enums:
|
||||
BlockMode: "../enums/context_block_mode_.blockmode.html"
|
||||
TokenKind: "../enums/parser_token_kind_.tokenkind.html"
|
||||
interfaces:
|
||||
Cache: "../interfaces/cache_cache_.cache.html"
|
||||
FilterImplOptions: "../interfaces/template_filter_filter_impl_options_.filterimploptions.html"
|
||||
FS: "../interfaces/fs_fs_.fs.html"
|
||||
LiquidOptions: "../interfaces/liquid_options_.liquidoptions.html"
|
||||
NormalizedFullOptions: "../interfaces/liquid_options_.normalizedfulloptions.html"
|
||||
PlainObject: "../interfaces/context_scope_.plainobject.html"
|
||||
TagImplOptions: "../interfaces/template_tag_tag_impl_options_.tagimploptions.html"
|
||||
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<browserconfig>
|
||||
<msapplication>
|
||||
<tile>
|
||||
<square70x70logo src="/icon/mstile-70x70.png"/>
|
||||
<square150x150logo src="/icon/mstile-150x150.png"/>
|
||||
<square310x310logo src="/icon/mstile-310x310.png"/>
|
||||
<wide310x150logo src="/icon/mstile-310x150.png"/>
|
||||
<TileColor>#2f83cd</TileColor>
|
||||
</tile>
|
||||
</msapplication>
|
||||
</browserconfig>
|
||||
|
After Width: | Height: | Size: 9.4 KiB |
@@ -0,0 +1,37 @@
|
||||
---
|
||||
title: abs
|
||||
---
|
||||
|
||||
Liquid filter that returns the absolute value of a number.
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{{ -17 | abs }}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
17
|
||||
```
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{{ 4 | abs }}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
4
|
||||
```
|
||||
|
||||
`abs` will also work on a string that only contains a number:
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{{ "-19.86" | abs }}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
19.86
|
||||
```
|
||||
@@ -0,0 +1,29 @@
|
||||
---
|
||||
title: append
|
||||
---
|
||||
|
||||
Concatenates two strings and returns the concatenated value.
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{{ "/my/fancy/url" | append: ".html" }}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
/my/fancy/url.html
|
||||
```
|
||||
|
||||
`append` can also be used with variables:
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{% assign filename = "/index.html" %}
|
||||
{{ "website.com" | append: filename }}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
|
||||
website.com/index.html
|
||||
```
|
||||
@@ -0,0 +1,25 @@
|
||||
---
|
||||
title: at_least
|
||||
---
|
||||
|
||||
Limits a number to a minimum value.
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{{ 4 | at_least: 5 }}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
5
|
||||
```
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{{ 4 | at_least: 3 }}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
4
|
||||
```
|
||||
@@ -0,0 +1,25 @@
|
||||
---
|
||||
title: at_most
|
||||
---
|
||||
|
||||
Limits a number to a maximum value.
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{{ 4 | at_most: 5 }}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
4
|
||||
```
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{{ 4 | at_most: 3 }}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
3
|
||||
```
|
||||
@@ -0,0 +1,27 @@
|
||||
---
|
||||
title: capitalize
|
||||
---
|
||||
|
||||
Makes the first character of a string capitalized.
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{{ "title" | capitalize }}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
Title
|
||||
```
|
||||
|
||||
`capitalize` only capitalizes the first character of a string, so later words are not affected:
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{{ "my great title" | capitalize }}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
My great title
|
||||
```
|
||||
@@ -0,0 +1,47 @@
|
||||
---
|
||||
title: ceil
|
||||
---
|
||||
|
||||
Rounds the input up to the nearest whole number. LiquidJS tries to convert the input to a number before the filter is applied.
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{{ 1.2 | ceil }}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
2
|
||||
```
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{{ 2.0 | ceil }}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
2
|
||||
```
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{{ 183.357 | ceil }}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
184
|
||||
```
|
||||
|
||||
Here the input value is a string:
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{{ "3.5" | ceil }}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
4
|
||||
```
|
||||
@@ -0,0 +1,47 @@
|
||||
---
|
||||
title: compact
|
||||
---
|
||||
|
||||
Removes any `nil` values from an array.
|
||||
|
||||
For this example, assume `site.pages` is an array of content pages for a website, and some of these pages have an attribute called `category` that specifies their content category. If we `map` those categories to an array, some of the array items might be `nil` if any pages do not have a `category` attribute.
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{% assign site_categories = site.pages | map: "category" %}
|
||||
|
||||
{% for category in site_categories %}
|
||||
- {{ category }}
|
||||
{% endfor %}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
- business
|
||||
- celebrities
|
||||
-
|
||||
- lifestyle
|
||||
- sports
|
||||
-
|
||||
- technology
|
||||
```
|
||||
|
||||
By using `compact` when we create our `site_categories` array, we can remove all the `nil` values in the array.
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{% assign site_categories = site.pages | map: "category" | compact %}
|
||||
|
||||
{% for category in site_categories %}
|
||||
- {{ category }}
|
||||
{% endfor %}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
- business
|
||||
- celebrities
|
||||
- lifestyle
|
||||
- sports
|
||||
- technology
|
||||
```
|
||||
@@ -0,0 +1,53 @@
|
||||
---
|
||||
title: concat
|
||||
---
|
||||
|
||||
Concatenates (joins together) multiple arrays. The resulting array contains all the items from the input arrays.
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{% assign fruits = "apples, oranges, peaches" | split: ", " %}
|
||||
{% assign vegetables = "carrots, turnips, potatoes" | split: ", " %}
|
||||
|
||||
{% assign everything = fruits | concat: vegetables %}
|
||||
|
||||
{% for item in everything %}
|
||||
- {{ item }}
|
||||
{% endfor %}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
- apples
|
||||
- oranges
|
||||
- peaches
|
||||
- carrots
|
||||
- turnips
|
||||
- potatoes
|
||||
```
|
||||
|
||||
You can string together `concat` filters to join more than two arrays:
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{% assign furniture = "chairs, tables, shelves" | split: ", " %}
|
||||
|
||||
{% assign everything = fruits | concat: vegetables | concat: furniture %}
|
||||
|
||||
{% for item in everything %}
|
||||
- {{ item }}
|
||||
{% endfor %}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
- apples
|
||||
- oranges
|
||||
- peaches
|
||||
- carrots
|
||||
- turnips
|
||||
- potatoes
|
||||
- chairs
|
||||
- tables
|
||||
- shelves
|
||||
```
|
||||
@@ -0,0 +1,53 @@
|
||||
---
|
||||
title: date
|
||||
---
|
||||
|
||||
Converts a timestamp into another date format. The format for this syntax is the same as [`strftime`](http://strftime.net). The input is first converted to Date object by [new Date()][newDate].
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{{ article.published_at | date: "%a, %b %d, %y" }}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
Fri, Jul 17, 15
|
||||
```
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{{ article.published_at | date: "%Y" }}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
2015
|
||||
```
|
||||
|
||||
`date` works on strings if they contain well-formatted dates:
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{{ "March 14, 2016" | date: "%b %d, %y" }}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
Mar 14, 16
|
||||
```
|
||||
|
||||
To get the current time, pass the special word `"now"` (or `"today"`) to `date`:
|
||||
|
||||
Input
|
||||
```liquid
|
||||
This page was last updated at {{ "now" | date: "%Y-%m-%d %H:%M" }}.
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
This page was last updated at 2020-03-25 15:57.
|
||||
```
|
||||
|
||||
{% note info now %}Note that the value will be the current time of when the page was last generated from the template, not when the page is presented to a user if caching or static site generation is involved.{% endnote %}
|
||||
|
||||
[newDate]: https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Date
|
||||
@@ -0,0 +1,45 @@
|
||||
---
|
||||
title: default
|
||||
---
|
||||
|
||||
Allows you to specify a fallback in case a value doesn't exist. `default` will show its value if the left side is [falsy][falsy] or empty (`string` or `Array`).
|
||||
|
||||
In this example, `product_price` is not defined, so the default value is used.
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{{ product_price | default: 2.99 }}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
2.99
|
||||
```
|
||||
|
||||
In this example, `product_price` is defined, so the default value is not used.
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{% assign product_price = 4.99 %}
|
||||
{{ product_price | default: 2.99 }}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
4.99
|
||||
```
|
||||
|
||||
In this example, `product_price` is empty, so the default value is used.
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{% assign product_price = "" %}
|
||||
{{ product_price | default: 2.99 }}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
2.99
|
||||
```
|
||||
|
||||
[falsy]: ../tutorials/truthy-and-falsy.html
|
||||
@@ -0,0 +1,29 @@
|
||||
---
|
||||
title: divided_by
|
||||
---
|
||||
|
||||
Divides a number by another number. The result is the string obtained by JavaScript `.toString()` of the result number.
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{{ 16 | divided_by: 4 }}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
4
|
||||
```
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{{ 5 | divided_by: 3 }}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
1.6666666666666667
|
||||
```
|
||||
|
||||
{% note info Integer Arithmetic %}Since JavaScript doesn't differentiate integers and floats, LiquidJS is not capable of integer arithmetic and the return type is always `number`, the string representation of which depends on its value.{% endnote %}
|
||||
|
||||
[floor]: ./floor.html
|
||||
@@ -0,0 +1,25 @@
|
||||
---
|
||||
title: downcase
|
||||
---
|
||||
|
||||
Makes each character in a string lowercase. It has no effect on strings which are already all lowercase.
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{{ "Parker Moore" | downcase }}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
parker moore
|
||||
```
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{{ "apple" | downcase }}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
apple
|
||||
```
|
||||
@@ -0,0 +1,25 @@
|
||||
---
|
||||
title: escape
|
||||
---
|
||||
|
||||
Escapes a string by replacing HTML special characters with escape sequences. It doesn't change strings that don't have anything to escape.
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{{ "Have you read 'James & the Giant Peach'?" | escape }}
|
||||
```
|
||||
|
||||
Output
|
||||
<pre class="highlight">
|
||||
{{"Have you read 'James & the Giant Peach'?" | escape}}
|
||||
</pre>
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{{ "Tetsuro Takara" | escape }}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
Tetsuro Takara
|
||||
```
|
||||
@@ -0,0 +1,25 @@
|
||||
---
|
||||
title: escape_once
|
||||
---
|
||||
|
||||
Escapes a string without changing existing escaped entities. It doesn't change strings that don't have anything to escape.
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{{ "1 < 2 & 3" | escape_once }}
|
||||
```
|
||||
|
||||
Output
|
||||
<pre class="highlight">
|
||||
{{"1 < 2 & 3" | escape}}
|
||||
</pre>
|
||||
|
||||
Input
|
||||
<pre class="highlight">
|
||||
{{ "{{"1 < 2 & 3" | escape}}" | escape_once }}
|
||||
</pre>
|
||||
|
||||
Output
|
||||
<pre class="highlight">
|
||||
{{"1 < 2 & 3" | escape}}
|
||||
</pre>
|
||||
@@ -0,0 +1,35 @@
|
||||
---
|
||||
title: first
|
||||
---
|
||||
|
||||
Returns the first item of an array.
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{{ "Ground control to Major Tom." | split: " " | first }}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
Ground
|
||||
```
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{% assign my_array = "zebra, octopus, giraffe, tiger" | split: ", " %}
|
||||
{{ my_array.first }}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
|
||||
zebra
|
||||
```
|
||||
|
||||
You can use `first` with dot notation when you need to use the filter inside a tag:
|
||||
|
||||
```liquid
|
||||
{% if my_array.first == "zebra" %}
|
||||
Here comes a zebra!
|
||||
{% endif %}
|
||||
```
|
||||
@@ -0,0 +1,47 @@
|
||||
---
|
||||
title: floor
|
||||
---
|
||||
|
||||
Rounds the input down to the nearest whole number. LiquidJS tries to convert the input to a number before the filter is applied.
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{{ 1.2 | floor }}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
1
|
||||
```
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{{ 2.0 | floor }}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
2
|
||||
```
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{{ 183.357 | floor }}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
183
|
||||
```
|
||||
|
||||
Here the input value is a string:
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{{ "3.5" | floor }}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
3
|
||||
```
|
||||
@@ -0,0 +1,17 @@
|
||||
---
|
||||
title: join
|
||||
---
|
||||
|
||||
Combines the items in an array into a single string using the argument as a separator.
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{% assign beatles = "John, Paul, George, Ringo" | split: ", " %}
|
||||
{{ beatles | join: " and " }}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
|
||||
John and Paul and George and Ringo
|
||||
```
|
||||
@@ -0,0 +1,16 @@
|
||||
---
|
||||
title: json
|
||||
---
|
||||
|
||||
Convert values to string via `JSON.stringify()`, for debug purpose.
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{% assign arr = "foo bar coo" | split: " " %}
|
||||
{{ arr | json }}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
["foo","bar","coo"]
|
||||
```
|
||||
@@ -0,0 +1,35 @@
|
||||
---
|
||||
title: last
|
||||
---
|
||||
|
||||
Returns the last item of an array.
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{{ "Ground control to Major Tom." | split: " " | last }}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
Tom.
|
||||
```
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{% assign my_array = "zebra, octopus, giraffe, tiger" | split: ", " %}
|
||||
{{ my_array.last }}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
|
||||
tiger
|
||||
```
|
||||
|
||||
You can use `last` with dot notation when you need to use the filter inside a tag:
|
||||
|
||||
```liquid
|
||||
{% if my_array.last == "tiger" %}
|
||||
There goes a tiger!
|
||||
{% endif %}
|
||||
```
|
||||
@@ -0,0 +1,15 @@
|
||||
---
|
||||
title: lstrip
|
||||
---
|
||||
|
||||
Removes all whitespace (tabs, spaces, and newlines) from the left side of a string. It does not affect spaces between words.
|
||||
|
||||
Input
|
||||
```liquid
|
||||
BEGIN{{ " So much room for activities! " | lstrip }}END
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
BEGINSo much room for activities! END
|
||||
```
|
||||
@@ -0,0 +1,25 @@
|
||||
---
|
||||
title: map
|
||||
---
|
||||
|
||||
Creates an array of values by extracting the values of a named property from another object.
|
||||
|
||||
In this example, assume the object `site.pages` contains all the metadata for a website. Using `assign` with the `map` filter creates a variable that contains only the values of the `category` properties of everything in the `site.pages` object.
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{% assign all_categories = site.pages | map: "category" %}
|
||||
|
||||
{% for item in all_categories %}
|
||||
- {{ item }}
|
||||
{% endfor %}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
- business
|
||||
- celebrities
|
||||
- lifestyle
|
||||
- sports
|
||||
- technology
|
||||
```
|
||||
@@ -0,0 +1,35 @@
|
||||
---
|
||||
title: minus
|
||||
---
|
||||
|
||||
Subtracts a number from another number.
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{{ 4 | minus: 2 }}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
2
|
||||
```
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{{ 16 | minus: 4 }}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
12
|
||||
```
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{{ 183.357 | minus: 12 }}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
171.357
|
||||
```
|
||||
@@ -0,0 +1,35 @@
|
||||
---
|
||||
title: modulo
|
||||
---
|
||||
|
||||
Returns the remainder of a division operation.
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{{ 3 | modulo: 2 }}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
1
|
||||
```
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{{ 24 | modulo: 7 }}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
3
|
||||
```
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{{ 183.357 | modulo: 12 }}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
3.3569999999999993
|
||||
```
|
||||
@@ -0,0 +1,21 @@
|
||||
---
|
||||
title: newline_to_br
|
||||
---
|
||||
|
||||
Replaces every newline (`\n`) in a string with an HTML line break (`<br />`).
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{% capture string_with_newlines %}
|
||||
Hello
|
||||
there
|
||||
{% endcapture %}
|
||||
|
||||
{{ string_with_newlines | newline_to_br }}
|
||||
```
|
||||
|
||||
Output
|
||||
```html
|
||||
|
||||
<br/>Hello<br/>there<br/>
|
||||
```
|
||||
@@ -0,0 +1,17 @@
|
||||
---
|
||||
title: Filters
|
||||
---
|
||||
|
||||
LiquidJS implements business-logic independent filters that are typically implemented in [shopify/liquid][shopify/liquid]. This section contains the specification and demoes for all the filters implemented by LiquidJS.
|
||||
|
||||
There's 40+ filters supported by LiquidJS. These filters can be categorized into these groups:
|
||||
|
||||
Categories | Filters
|
||||
--- | ---
|
||||
Math | plus, minus, modulo, times, floor, ceil, round, divided_by, abs
|
||||
String | append, prepend, capitalize, upcase, downcase, strip, lstrip, rstrip, strip_newlines, split, replace, replace_first, remove, remove_first, truncate, truncatewords
|
||||
HTML/URI | escape, escape_once, url_encode, url_decode, strip_html, newline_to_br
|
||||
Array | slice, map, sort, sort_natural, uniq, wheres, first, last, join, reverse
|
||||
Date | date
|
||||
|
||||
[shopify/liquid]: https://github.com/Shopify/liquid
|
||||
@@ -0,0 +1,35 @@
|
||||
---
|
||||
title: plus
|
||||
---
|
||||
|
||||
Adds a number to another number.
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{{ 4 | plus: 2 }}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
6
|
||||
```
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{{ 16 | plus: 4 }}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
20
|
||||
```
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{{ 183.357 | plus: 12 }}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
195.357
|
||||
```
|
||||
@@ -0,0 +1,29 @@
|
||||
---
|
||||
title: prepend
|
||||
---
|
||||
|
||||
Adds the specified string to the beginning of another string.
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{{ "apples, oranges, and bananas" | prepend: "Some fruit: " }}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
Some fruit: apples, oranges, and bananas
|
||||
```
|
||||
|
||||
`prepend` can also be used with variables:
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{% assign url = "example.com" %}
|
||||
{{ "/index.html" | prepend: url }}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
|
||||
example.com/index.html
|
||||
```
|
||||
@@ -0,0 +1,15 @@
|
||||
---
|
||||
title: remove
|
||||
---
|
||||
|
||||
Removes every occurrence of the specified substring from a string.
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{{ "I strained to see the train through the rain" | remove: "rain" }}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
I strained to see the t through the
|
||||
```
|
||||
@@ -0,0 +1,15 @@
|
||||
---
|
||||
title: remove_first
|
||||
---
|
||||
|
||||
Removes only the first occurrence of the specified substring from a string.
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{{ "I strained to see the train through the rain" | remove_first: "rain" }}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
I strained to see the t through the rain
|
||||
```
|
||||
@@ -0,0 +1,15 @@
|
||||
---
|
||||
title: replace
|
||||
---
|
||||
|
||||
Replaces every occurrence of the first argument in a string with the second argument.
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{{ "Take my protein pills and put my helmet on" | replace: "my", "your" }}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
Take your protein pills and put your helmet on
|
||||
```
|
||||
@@ -0,0 +1,15 @@
|
||||
---
|
||||
title: replace_first
|
||||
---
|
||||
|
||||
Replaces only the first occurrence of the first argument in a string with the second argument.
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{{ "Take my protein pills and put my helmet on" | replace_first: "my", "your" }}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
Take your protein pills and put my helmet on
|
||||
```
|
||||
@@ -0,0 +1,31 @@
|
||||
---
|
||||
title: reverse
|
||||
---
|
||||
|
||||
Reverses the order of the items in an array. `reverse` cannot reverse a string.
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{% assign my_array = "apples, oranges, peaches, plums" | split: ", " %}
|
||||
|
||||
{{ my_array | reverse | join: ", " }}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
|
||||
|
||||
plums, peaches, oranges, apples
|
||||
```
|
||||
|
||||
Although `reverse` cannot be used directly on a string, you can split a string into an array, reverse the array, and rejoin it by chaining together filters:
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{{ "Ground control to Major Tom." | split: "" | reverse | join: "" }}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
.moT rojaM ot lortnoc dnuorG
|
||||
```
|
||||
@@ -0,0 +1,35 @@
|
||||
---
|
||||
title: round
|
||||
---
|
||||
|
||||
Rounds a number to the nearest integer or, if a number is passed as an argument, to that number of decimal places.
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{{ 1.2 | round }}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
1
|
||||
```
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{{ 2.7 | round }}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
3
|
||||
```
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{{ 183.357 | round: 2 }}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
183.36
|
||||
```
|
||||
@@ -0,0 +1,15 @@
|
||||
---
|
||||
title: rstrip
|
||||
---
|
||||
|
||||
Removes all whitespace (tabs, spaces, and newlines) from the right side of a string. It does not affect spaces between words.
|
||||
|
||||
Input
|
||||
```liquid
|
||||
BEGIN{{ " So much room for activities! " | rstrip }}END
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
BEGIN So much room for activities!END
|
||||
```
|
||||
@@ -0,0 +1,37 @@
|
||||
---
|
||||
title: size
|
||||
---
|
||||
|
||||
Returns the number of characters in a string or the number of items in an array.
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{{ "Ground control to Major Tom." | size }}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
28
|
||||
```
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{% assign my_array = "apples, oranges, peaches, plums" | split: ", " %}
|
||||
|
||||
{{ my_array.size }}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
|
||||
|
||||
4
|
||||
```
|
||||
|
||||
You can use `size` with dot notation when you need to use the filter inside a tag:
|
||||
|
||||
```liquid
|
||||
{% if site.pages.size > 10 %}
|
||||
This is a big website!
|
||||
{% endif %}
|
||||
```
|
||||
@@ -0,0 +1,49 @@
|
||||
---
|
||||
title: slice
|
||||
---
|
||||
|
||||
Returns a substring of 1 character beginning at the index specified by the first argument. An optional second argument specifies the length of the substring to be returned.
|
||||
|
||||
String indices are numbered starting from 0.
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{{ "Liquid" | slice: 0 }}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
L
|
||||
```
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{{ "Liquid" | slice: 2 }}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
q
|
||||
```
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{{ "Liquid" | slice: 2, 5 }}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
quid
|
||||
```
|
||||
|
||||
If the first argument is a negative number, the indices are counted from the end of the string:
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{{ "Liquid" | slice: -3, 2 }}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
ui
|
||||
```
|
||||
@@ -0,0 +1,28 @@
|
||||
---
|
||||
title: sort
|
||||
---
|
||||
|
||||
Sorts items in an array in case-sensitive order.
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{% assign my_array = "zebra, octopus, giraffe, Sally Snake" | split: ", " %}
|
||||
|
||||
{{ my_array | sort | join: ", " }}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
|
||||
|
||||
Sally Snake, giraffe, octopus, zebra
|
||||
```
|
||||
|
||||
An optional argument specifies which property of the array's items to use for sorting.
|
||||
|
||||
```liquid
|
||||
{% assign products_by_price = collection.products | sort: "price" %}
|
||||
{% for product in products_by_price %}
|
||||
<h4>{{ product.title }}</h4>
|
||||
{% endfor %}
|
||||
```
|
||||
@@ -0,0 +1,28 @@
|
||||
---
|
||||
title: sort_natural
|
||||
---
|
||||
|
||||
Sorts items in an array in case-insensitive order.
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{% assign my_array = "zebra, octopus, giraffe, Sally Snake" | split: ", " %}
|
||||
|
||||
{{ my_array | sort_natural | join: ", " }}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
|
||||
|
||||
giraffe, octopus, Sally Snake, zebra
|
||||
```
|
||||
|
||||
An optional argument specifies which property of the array's items to use for sorting.
|
||||
|
||||
```liquid
|
||||
{% assign products_by_company = collection.products | sort_natural: "company" %}
|
||||
{% for product in products_by_company %}
|
||||
<h4>{{ product.title }}</h4>
|
||||
{% endfor %}
|
||||
```
|
||||
@@ -0,0 +1,29 @@
|
||||
---
|
||||
title: split
|
||||
---
|
||||
|
||||
Divides a string into an array using the argument as a separator. `split` is commonly used to convert comma-separated items from a string to an array.
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{% assign beatles = "John, Paul, George, Ringo" | split: ", " %}
|
||||
|
||||
{% for member in beatles %}
|
||||
{{ member }}
|
||||
{% endfor %}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
|
||||
|
||||
|
||||
|
||||
John
|
||||
|
||||
Paul
|
||||
|
||||
George
|
||||
|
||||
Ringo
|
||||
```
|
||||
@@ -0,0 +1,15 @@
|
||||
---
|
||||
title: strip
|
||||
---
|
||||
|
||||
Removes all whitespace (tabs, spaces, and newlines) from both the left and right sides of a string. It does not affect spaces between words.
|
||||
|
||||
Input
|
||||
```liquid
|
||||
BEGIN{{ " So much room for activities! " | strip }}END
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
BEGINSo much room for activities!END
|
||||
```
|
||||
@@ -0,0 +1,15 @@
|
||||
---
|
||||
title: strip_html
|
||||
---
|
||||
|
||||
Removes any HTML tags from a string.
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{{ "Have <em>you</em> read <strong>Ulysses</strong>?" | strip_html }}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
Have you read Ulysses?
|
||||
```
|
||||
@@ -0,0 +1,21 @@
|
||||
---
|
||||
title: strip_newlines
|
||||
---
|
||||
|
||||
Removes any newline characters (line breaks) from a string.
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{% capture string_with_newlines %}
|
||||
Hello
|
||||
there
|
||||
{% endcapture %}
|
||||
|
||||
{{ string_with_newlines | strip_newlines }}
|
||||
```
|
||||
|
||||
Output
|
||||
```html
|
||||
|
||||
Hellothere
|
||||
```
|
||||
@@ -0,0 +1,35 @@
|
||||
---
|
||||
title: times
|
||||
---
|
||||
|
||||
Multiplies a number by another number.
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{{ 3 | times: 2 }}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
6
|
||||
```
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{{ 24 | times: 7 }}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
168
|
||||
```
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{{ 183.357 | times: 12 }}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
2200.284
|
||||
```
|
||||
@@ -0,0 +1,47 @@
|
||||
---
|
||||
title: truncate
|
||||
---
|
||||
|
||||
Shortens a string down to the number of characters passed as an argument. If the specified number of characters is less than the length of the string, an ellipsis (...) is appended to the string and is included in the character count.
|
||||
|
||||
## Basic Usage
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{{ "Ground control to Major Tom." | truncate: 20 }}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
Ground control to...
|
||||
```
|
||||
|
||||
## Custom ellipsis
|
||||
|
||||
`truncate` takes an optional second argument that specifies the sequence of characters to be appended to the truncated string. By default this is an ellipsis (...), but you can specify a different sequence.
|
||||
|
||||
The length of the second argument counts against the number of characters specified by the first argument. For example, if you want to truncate a string to exactly 10 characters, and use a 3-character ellipsis, use **13** for the first argument of `truncate`, since the ellipsis counts as 3 characters.
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{{ "Ground control to Major Tom." | truncate: 25, ", and so on" }}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
Ground control, and so on
|
||||
```
|
||||
|
||||
## No ellipsis
|
||||
|
||||
You can truncate to the exact number of characters specified by the first argument and avoid showing trailing characters by passing a blank string as the second argument:
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{{ "Ground control to Major Tom." | truncate: 20, "" }}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
Ground control to Ma
|
||||
```
|
||||
@@ -0,0 +1,43 @@
|
||||
---
|
||||
title: truncatewords
|
||||
---
|
||||
|
||||
Shortens a string down to the number of words passed as an argument. If the specified number of words is less than the number of words in the string, an ellipsis (...) is appended to the string.
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{{ "Ground control to Major Tom." | truncatewords: 3 }}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
Ground control to...
|
||||
```
|
||||
|
||||
### Custom ellipsis
|
||||
|
||||
`truncatewords` takes an optional second argument that specifies the sequence of characters to be appended to the truncated string. By default this is an ellipsis (...), but you can specify a different sequence.
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{{ "Ground control to Major Tom." | truncatewords: 3, "--" }}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
Ground control to--
|
||||
```
|
||||
|
||||
### No ellipsis
|
||||
|
||||
You can avoid showing trailing characters by passing a blank string as the second argument:
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{{ "Ground control to Major Tom." | truncatewords: 3, "" }}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
Ground control to
|
||||
```
|
||||
@@ -0,0 +1,16 @@
|
||||
---
|
||||
title: uniq
|
||||
---
|
||||
|
||||
Removes any duplicate elements in an array.
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{% assign my_array = "ants, bugs, bees, bugs, ants" | split: ", " %}
|
||||
{{ my_array | uniq | join: ", " }}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
|
||||
ants, bugs, bees```
|
||||
@@ -0,0 +1,25 @@
|
||||
---
|
||||
title: upcase
|
||||
---
|
||||
|
||||
Makes each character in a string uppercase. It has no effect on strings which are already all uppercase.
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{{ "Parker Moore" | upcase }}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
PARKER MOORE
|
||||
```
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{{ "APPLE" | upcase }}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
APPLE
|
||||
```
|
||||
@@ -0,0 +1,15 @@
|
||||
---
|
||||
title: url_decode
|
||||
---
|
||||
|
||||
Decodes a string that has been encoded as a URL.
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{{ "%27Stop%21%27+said+Fred" | url_decode }}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
'Stop!' said Fred
|
||||
```
|
||||
@@ -0,0 +1,25 @@
|
||||
---
|
||||
title: url_encode
|
||||
---
|
||||
|
||||
Converts any URL-unsafe characters in a string into percent-encoded characters.
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{{ "john@liquid.com" | url_encode }}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
john%40liquid.com
|
||||
```
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{{ "Tetsuro Takara" | url_encode }}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
Tetsuro+Takara
|
||||
```
|
||||
@@ -0,0 +1,80 @@
|
||||
---
|
||||
title: where
|
||||
---
|
||||
|
||||
Creates an array including only the objects with a given property value, or any [truthy][truthy] value by default.
|
||||
|
||||
In this example, assume you have a list of products and you want to show your kitchen products separately. Using `where`, you can create an array containing only the products that have a `"type"` of `"kitchen"`.
|
||||
|
||||
Input
|
||||
```liquid
|
||||
All products:
|
||||
{% for product in products %}
|
||||
- {{ product.title }}
|
||||
{% endfor %}
|
||||
|
||||
{% assign kitchen_products = products | where: "type", "kitchen" %}
|
||||
|
||||
Kitchen products:
|
||||
{% for product in kitchen_products %}
|
||||
- {{ product.title }}
|
||||
{% endfor %}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
All products:
|
||||
- Vacuum
|
||||
- Spatula
|
||||
- Television
|
||||
- Garlic press
|
||||
|
||||
Kitchen products:
|
||||
- Spatula
|
||||
- Garlic press
|
||||
```
|
||||
|
||||
Say instead you have a list of products and you only want to show those that are available to buy. You can `where` with a property name but no target value to include all products with a [truthy][truthy] `"available"` value.
|
||||
|
||||
Input
|
||||
```liquid
|
||||
All products:
|
||||
{% for product in products %}
|
||||
- {{ product.title }}
|
||||
{% endfor %}
|
||||
|
||||
{% assign available_products = products | where: "available" %}
|
||||
|
||||
Available products:
|
||||
{% for product in available_products %}
|
||||
- {{ product.title }}
|
||||
{% endfor %}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
All products:
|
||||
- Coffee mug
|
||||
- Limited edition sneakers
|
||||
- Boring sneakers
|
||||
|
||||
Available products:
|
||||
- Coffee mug
|
||||
- Boring sneakers
|
||||
```
|
||||
|
||||
The `where` filter can also be used to find a single object in an array when combined with the `first` filter. For example, say you want to show off the shirt in your new fall collection.
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{% assign new_shirt = products | where: "type", "shirt" | first %}
|
||||
|
||||
Featured product: {{ new_shirt.title }}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
Featured product: Hawaiian print sweater vest
|
||||
```
|
||||
|
||||
[truthy]: ../tutorials/truthy-and-falsy.html
|
||||
|
After Width: | Height: | Size: 2.5 KiB |
|
After Width: | Height: | Size: 3.4 KiB |
|
After Width: | Height: | Size: 4.1 KiB |
|
After Width: | Height: | Size: 4.3 KiB |
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 1.7 KiB |
|
After Width: | Height: | Size: 1.8 KiB |
|
After Width: | Height: | Size: 5.0 KiB |
|
After Width: | Height: | Size: 10 KiB |
|
After Width: | Height: | Size: 6.4 KiB |
|
After Width: | Height: | Size: 4.5 KiB |
|
After Width: | Height: | Size: 669 B |
|
After Width: | Height: | Size: 5.4 KiB |
|
After Width: | Height: | Size: 992 B |
|
After Width: | Height: | Size: 2.2 KiB |
|
After Width: | Height: | Size: 10 KiB |
|
After Width: | Height: | Size: 4.1 KiB |
|
After Width: | Height: | Size: 4.3 KiB |
|
After Width: | Height: | Size: 5.2 KiB |
|
After Width: | Height: | Size: 9.0 KiB |
|
After Width: | Height: | Size: 1.7 KiB |
@@ -0,0 +1,29 @@
|
||||
layout: index
|
||||
description: LiquidJS is a simple, expressive and safe template engine.
|
||||
subtitle: A simple, expressive and safe template engine.
|
||||
---
|
||||
ul#intro-feature-list
|
||||
li.intro-feature-wrap
|
||||
.intro-feature
|
||||
.intro-feature-icon
|
||||
i.icon-shield
|
||||
h3.intro-feature-title Safe Rendering
|
||||
p.intro-feature-desc All outputs are automatically escaped for safe and customer facing HTML rendering. Operators and expressions are parsed to AST and no #[code eval] or #[code new Function] are used.
|
||||
li.intro-feature-wrap
|
||||
.intro-feature
|
||||
.intro-feature-icon
|
||||
i.icon-javascript
|
||||
h3.intro-feature-title Pure JavaScript
|
||||
p.intro-feature-desc Written with zero npm dependencies and no native bindings, available for both Node.js and the browsers. All of the CMD, ESM and CJS bundles are available on CDN.
|
||||
li.intro-feature-wrap
|
||||
.intro-feature
|
||||
.intro-feature-icon
|
||||
i.icon-shopify
|
||||
h3.intro-feature-title Shopify Compatible
|
||||
p.intro-feature-desc Almost all features, filters and tags from Ruby #[a(href="https://github.com/shopify/liquid") shopify/liquid] are also supported by LiquidJS. #[a(href="https://jekyllrb.com/") Jekyll sites], #[a(href="https://pages.github.com/") Github Pages] and #[a(href="https://themes.shopify.com/") Shopify templates] can be ported to Node.js without pain.
|
||||
li.intro-feature-wrap
|
||||
.intro-feature
|
||||
.intro-feature-icon
|
||||
i.icon-cog
|
||||
h3.intro-feature-title Extensibility
|
||||
p.intro-feature-desc The whole repo is re-written in TypeScript strict mode to ensure the APIs are consistent and the documentation is always up to date. Apart from 60+ builtin tags and filters, LiquidJS provides APIs to register yours.
|
||||
@@ -0,0 +1,3 @@
|
||||
---
|
||||
layout: playground
|
||||
---
|
||||
@@ -0,0 +1 @@
|
||||
User-agent: *
|
||||
@@ -0,0 +1,59 @@
|
||||
/* globals self, caches, fetch */
|
||||
'use strict';
|
||||
|
||||
const CACHE_NAME = '{{site.time}}';
|
||||
const urlsToCache = [
|
||||
'/',
|
||||
'/css/navy.css',
|
||||
'/js/main.js',
|
||||
'/icon/logo.png',
|
||||
'/fonts/icomoon.ttf?e8nnma'
|
||||
];
|
||||
const blackList = [
|
||||
/google-analytics.com.*collect/
|
||||
];
|
||||
|
||||
self.addEventListener('install', event => {
|
||||
event.waitUntil(caches.open(CACHE_NAME).then(cache => cache.addAll(urlsToCache)));
|
||||
});
|
||||
|
||||
self.addEventListener('activate', event => {
|
||||
event.waitUntil(caches.keys().then(cacheNames => Promise.all(
|
||||
cacheNames.map(cacheName => cacheName !== CACHE_NAME && caches.delete(cacheName))
|
||||
)));
|
||||
});
|
||||
|
||||
self.addEventListener('fetch', event => {
|
||||
if (
|
||||
event.request.cache === 'only-if-cached' && event.request.mode !== 'same-origin'
|
||||
) return cache(event.request);
|
||||
if (
|
||||
event.request.method !== 'GET' || blackList.some(regex => regex.exec(event.request.url))
|
||||
) return network(event.request);
|
||||
const pn = networkAndSave(event.request);
|
||||
event.respondWith(cache(event.request).then(res => res || pn).catch(() => pn));
|
||||
});
|
||||
|
||||
function cache(req) {
|
||||
return caches.open(CACHE_NAME).then(cache => cache.match(req.clone()));
|
||||
}
|
||||
|
||||
function networkAndSave(req) {
|
||||
return network(req).then(res => {
|
||||
if (validate(res)) save(req.clone(), res.clone());
|
||||
return res;
|
||||
});
|
||||
}
|
||||
|
||||
function network(req) {
|
||||
return fetch(req.clone());
|
||||
}
|
||||
|
||||
function save(key, val) {
|
||||
return caches.open(CACHE_NAME).then(cache => cache.put(key, val));
|
||||
}
|
||||
|
||||
function validate(res) {
|
||||
if (res && res.type === 'basic' && res.status !== 200) return false;
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
---
|
||||
title: Assign
|
||||
---
|
||||
|
||||
Creates a new variable.
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{% assign my_variable = false %}
|
||||
{% if my_variable != true %}
|
||||
This statement is valid.
|
||||
{% endif %}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
This statement is valid.
|
||||
```
|
||||
|
||||
Wrap a variable value in quotations `"` to save it as a string.
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{% assign foo = "bar" %}
|
||||
{{ foo }}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
bar
|
||||
```
|
||||
@@ -0,0 +1,35 @@
|
||||
---
|
||||
title: capture
|
||||
---
|
||||
|
||||
Captures the string inside of the opening and closing tags and assigns it to a variable. Variables created through `capture` are strings.
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{% capture my_variable %}I am being captured.{% endcapture %}
|
||||
{{ my_variable }}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
I am being captured.
|
||||
```
|
||||
|
||||
Using `capture`, you can create complex strings using other variables created with `assign`:
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{% assign favorite_food = "pizza" %}
|
||||
{% assign age = 35 %}
|
||||
|
||||
{% capture about_me %}
|
||||
I am {{ age }} and my favorite food is {{ favorite_food }}.
|
||||
{% endcapture %}
|
||||
|
||||
{{ about_me }}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
I am 35 and my favourite food is pizza.
|
||||
```
|
||||
@@ -0,0 +1,23 @@
|
||||
---
|
||||
title: case
|
||||
---
|
||||
|
||||
Creates a switch statement to compare a variable with different values. `case` initializes the switch statement, and `when` compares its values.
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{% assign handle = "cake" %}
|
||||
{% case handle %}
|
||||
{% when "cake" %}
|
||||
This is a cake
|
||||
{% when "cookie" %}
|
||||
This is a cookie
|
||||
{% else %}
|
||||
This is not a cake nor a cookie
|
||||
{% endcase %}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
This is a cake
|
||||
```
|
||||
@@ -0,0 +1,17 @@
|
||||
---
|
||||
title: Comment
|
||||
---
|
||||
|
||||
Allows you to leave un-rendered code inside a Liquid template. Any text within the opening and closing `comment` blocks will not be printed, and any Liquid code within will not be executed.
|
||||
|
||||
Input
|
||||
```liquid
|
||||
Anything you put between {% comment %} and {% endcomment %} tags
|
||||
is turned into a comment.
|
||||
```
|
||||
|
||||
Output
|
||||
```liquid
|
||||
Anything you put between tags
|
||||
is turned into a comment.
|
||||
```
|
||||
@@ -0,0 +1,48 @@
|
||||
---
|
||||
title: cycle
|
||||
---
|
||||
|
||||
Loops through a group of strings and prints them in the order that they were passed as arguments. Each time `cycle` is called, the next string argument is printed.
|
||||
|
||||
## Basic Usage
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{% cycle "one", "two", "three" %}
|
||||
{% cycle "one", "two", "three" %}
|
||||
{% cycle "one", "two", "three" %}
|
||||
{% cycle "one", "two", "three" %}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
one
|
||||
two
|
||||
three
|
||||
one
|
||||
```
|
||||
|
||||
Uses for `cycle` include:
|
||||
|
||||
- applying odd/even classes to rows in a table
|
||||
- applying a unique class to the last product thumbnail in a row
|
||||
|
||||
## Parameters
|
||||
|
||||
`cycle` accepts a "cycle group" parameter in cases where you need multiple `cycle` blocks in one template. If no name is supplied for the cycle group, then it is assumed that multiple calls with the same parameters are one group.
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{% cycle "first": "one", "two", "three" %}
|
||||
{% cycle "second": "one", "two", "three" %}
|
||||
{% cycle "second": "one", "two", "three" %}
|
||||
{% cycle "first": "one", "two", "three" %}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
one
|
||||
one
|
||||
two
|
||||
two
|
||||
```
|
||||
@@ -0,0 +1,25 @@
|
||||
---
|
||||
title: Decrement
|
||||
---
|
||||
|
||||
Creates a new number variable, and decreases its value by one every time it is called. The first value is `-1`.
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{% decrement variable %}
|
||||
{% decrement variable %}
|
||||
{% decrement variable %}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
-1
|
||||
-2
|
||||
-3
|
||||
```
|
||||
|
||||
Like [increment][increment], variables declared inside `decrement` are independent from variables created through [assign][assign] or [capture][capture].
|
||||
|
||||
[increment]: ./increment.html
|
||||
[assign]: ./assign.html
|
||||
[capture]: ./capture.html
|
||||
@@ -0,0 +1,201 @@
|
||||
---
|
||||
title: For
|
||||
---
|
||||
|
||||
Iteration tags run blocks of code repeatedly.
|
||||
|
||||
## Basic Usage
|
||||
|
||||
### for...in
|
||||
|
||||
Repeatedly executes a block of code. For a full list of attributes available within a `for` loop.
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{% for product in collection.products %}
|
||||
{{ product.title }}
|
||||
{% endfor %}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
hat shirt pants
|
||||
```
|
||||
|
||||
### else
|
||||
|
||||
Specifies a fallback case for a `for` loop which will run if the loop has zero length.
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{% for product in collection.products %}
|
||||
{{ product.title }}
|
||||
{% else %}
|
||||
The collection is empty.
|
||||
{% endfor %}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
The collection is empty.
|
||||
```
|
||||
|
||||
### break
|
||||
|
||||
Causes the loop to stop iterating when it encounters the `break` tag.
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{% for i in (1..5) %}
|
||||
{% if i == 4 %}
|
||||
{% break %}
|
||||
{% else %}
|
||||
{{ i }}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
1 2 3
|
||||
```
|
||||
|
||||
### continue
|
||||
|
||||
Causes the loop to skip the current iteration when it encounters the `continue` tag.
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{% for i in (1..5) %}
|
||||
{% if i == 4 %}
|
||||
{% continue %}
|
||||
{% else %}
|
||||
{{ i }}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
1 2 3 5
|
||||
```
|
||||
|
||||
### forloop
|
||||
|
||||
There's a `forloop` object available inside `for` loops. It's used to indicate the current state of `for` loop.
|
||||
|
||||
The `forloop.first`, `forloop.last` and `forloop.length` property:
|
||||
|
||||
Input
|
||||
```
|
||||
{% for i in (1..5) %}
|
||||
{%- if forloop.first == true -%} First
|
||||
{%- elsif forloop.last == true -%} Last
|
||||
{%- else -%} {{ forloop.length }}
|
||||
{%- endif %}
|
||||
{% endfor -%}
|
||||
```
|
||||
|
||||
Output
|
||||
```
|
||||
First
|
||||
5
|
||||
5
|
||||
5
|
||||
Last
|
||||
```
|
||||
|
||||
The `forloop.index`, `forloop.index0`, `forloop.rindex` and `forloop.rindex0` property:
|
||||
|
||||
Input
|
||||
```
|
||||
index index0 rindex rindex0
|
||||
{% for i in (1..5) %}
|
||||
{{- forloop.index }} {{ forloop.index0 }} {{ forloop.rindex }} {{ forloop.rindex0 }}
|
||||
{% endfor -%}
|
||||
```
|
||||
|
||||
Output
|
||||
```
|
||||
index index0 rindex rindex0
|
||||
1 0 5 4
|
||||
2 1 4 3
|
||||
3 2 3 2
|
||||
4 3 2 1
|
||||
5 4 1 0
|
||||
```
|
||||
|
||||
## Parameters
|
||||
|
||||
### limit
|
||||
|
||||
Limits the loop to the specified number of iterations.
|
||||
|
||||
Input
|
||||
```liquid
|
||||
<!-- if array = [1,2,3,4,5,6] -->
|
||||
{% for item in array limit:2 %}
|
||||
{{ item }}
|
||||
{% endfor %}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
1 2
|
||||
```
|
||||
|
||||
### offset
|
||||
|
||||
Begins the loop at the specified index.
|
||||
|
||||
Input
|
||||
```liquid
|
||||
<!-- if array = [1,2,3,4,5,6] -->
|
||||
{% for item in array offset:2 %}
|
||||
{{ item }}
|
||||
{% endfor %}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
3 4 5 6
|
||||
```
|
||||
|
||||
### range
|
||||
|
||||
Defines a range of numbers to loop through. The range can be defined by both literal and variable numbers.
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{% for i in (3..5) %}
|
||||
{{ i }}
|
||||
{% endfor %}
|
||||
|
||||
{% assign num = 4 %}
|
||||
{% for i in (1..num) %}
|
||||
{{ i }}
|
||||
{% endfor %}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
3 4 5
|
||||
1 2 3 4
|
||||
```
|
||||
|
||||
### reversed
|
||||
|
||||
Reverses the order of the loop. Note that this flag's spelling is different from the filter `reverse`.
|
||||
|
||||
Input
|
||||
```liquid
|
||||
<!-- if array = [1,2,3,4,5,6] -->
|
||||
{% for item in array reversed %}
|
||||
{{ item }}
|
||||
{% endfor %}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
6 5 4 3 2 1
|
||||
```
|
||||
@@ -0,0 +1,40 @@
|
||||
---
|
||||
title: If
|
||||
---
|
||||
|
||||
Executes a block of code only if a certain condition is `true`.
|
||||
|
||||
## if
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{% if product.title == "Awesome Shoes" %}
|
||||
These shoes are awesome!
|
||||
{% endif %}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
These shoes are awesome!
|
||||
```
|
||||
|
||||
## elsif / else
|
||||
|
||||
Adds more conditions within an `if` or `unless` block.
|
||||
|
||||
Input
|
||||
```liquid
|
||||
<!-- If customer.name = "anonymous" -->
|
||||
{% if customer.name == "kevin" %}
|
||||
Hey Kevin!
|
||||
{% elsif customer.name == "anonymous" %}
|
||||
Hey Anonymous!
|
||||
{% else %}
|
||||
Hi Stranger!
|
||||
{% endif %}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
Hey Anonymous!
|
||||
```
|
||||
@@ -0,0 +1,46 @@
|
||||
---
|
||||
title: Include
|
||||
---
|
||||
|
||||
{% note warn Deprecated %}
|
||||
This tag is deprecated, use <a href="./render.html">render</a> tag instead for better encapsulation.
|
||||
{% endnote %}
|
||||
|
||||
## Include a Template
|
||||
|
||||
Renders a partial template from the template [roots][root].
|
||||
|
||||
```liquid
|
||||
{% include 'footer.liquid' %}
|
||||
```
|
||||
|
||||
When the [extname][extname] option is set, the above `.liquid` extension can be omitted and writes:
|
||||
|
||||
```liquid
|
||||
{% include 'footer' %}
|
||||
```
|
||||
|
||||
When a partial template is rendered by `include`, the code inside it can access its parent's variables but its parent cannot access variables defined inside a included template.
|
||||
|
||||
## Passing Variables
|
||||
|
||||
Variables defined in parent's scope can be passed to a the partial template by listing them as parameters on the `include` tag:
|
||||
|
||||
```liquid
|
||||
{% assign my_variable = 'apples' %}
|
||||
{% include 'name', my_variable: my_variable, my_other_variable: 'oranges' %}
|
||||
```
|
||||
|
||||
## The `with` Parameter
|
||||
|
||||
A single object can be passed to a snippet by using the `with...as` syntax:
|
||||
|
||||
```liquid
|
||||
{% assign featured_product = all_products['product_handle'] %}
|
||||
{% include 'product' with featured_product as product %}
|
||||
```
|
||||
|
||||
In the example above, the `product` variable in the partial template will hold the value of `featured_product` in the parent template.
|
||||
|
||||
[extname]: ../api/interfaces/liquid_options_.liquidoptions.html#Optional-extname
|
||||
[root]: ../api/interfaces/liquid_options_.liquidoptions.html#Optional-root
|
||||
@@ -0,0 +1,43 @@
|
||||
---
|
||||
title: Increment
|
||||
---
|
||||
|
||||
Creates a new number variable, and increases its value by one every time it is called. The first value is `0`.
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{% increment my_counter %}
|
||||
{% increment my_counter %}
|
||||
{% increment my_counter %}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
0
|
||||
1
|
||||
2
|
||||
```
|
||||
|
||||
Variables created through the `increment` tag are independent from variables created through [assign][assign] or [capture][capture].
|
||||
|
||||
In the example below, a variable named "var" is created through `assign`. The `increment` tag is then used several times on a variable with the same name. Note that the `increment` tag does not affect the value of "var" that was created through `assign`.
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{% assign var = 10 %}
|
||||
{% increment var %}
|
||||
{% increment var %}
|
||||
{% increment var %}
|
||||
{{ var }}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
0
|
||||
1
|
||||
2
|
||||
10
|
||||
```
|
||||
|
||||
[assign]: ./assign.html
|
||||
[capture]: ./capture.html
|
||||
@@ -0,0 +1,64 @@
|
||||
---
|
||||
title: Layout
|
||||
---
|
||||
|
||||
## Using a Layout Template
|
||||
|
||||
Renders current template inside a layout template from the template [roots][root].
|
||||
|
||||
```liquid
|
||||
{% layout 'footer.liquid' %}
|
||||
```
|
||||
|
||||
Whe the [extname][extname] option is set, the above `.liquid` extension can be omitted and writes:
|
||||
|
||||
```liquid
|
||||
{% layout 'footer' %}
|
||||
```
|
||||
|
||||
When a partial template is rendered by `layout`, the code inside it can access its caller's variables but its parent cannot access variables defined inside a included template.
|
||||
|
||||
## Passing Variables
|
||||
|
||||
Variables defined in current template can be passed to a the layout template by listing them as parameters on the `layout` tag:
|
||||
|
||||
```liquid
|
||||
{% assign my_variable = 'apples' %}
|
||||
{% layout 'name', my_variable: my_variable, my_other_variable: 'oranges' %}
|
||||
```
|
||||
|
||||
## Blocks
|
||||
|
||||
The layout file can contain multiple `block`s which will be populated by the child template (the caller). For example we have a `default-layout.liquid` file with the following contents:
|
||||
|
||||
```
|
||||
Header
|
||||
{% block content %}My default content{% endblock %}
|
||||
Footer
|
||||
```
|
||||
|
||||
And it's called by a `page.liquid` file with `layout` tag:
|
||||
|
||||
```
|
||||
{% layout "default-layout" %}
|
||||
{% block content %}My page content{% endblock %}
|
||||
```
|
||||
|
||||
The render result of `page.liquid` will be :
|
||||
|
||||
```
|
||||
Header
|
||||
My page content
|
||||
Footer
|
||||
```
|
||||
|
||||
{% note tip Block %}
|
||||
<ul>
|
||||
<li>Multiple blocks can be defined within a layout template;</li>
|
||||
<li>The block name is optional when there's only one block.</li>
|
||||
<li>The block contents will fallback to parent's corresponding block if not provided by child template.</li>
|
||||
</ul>
|
||||
{% endnote %}
|
||||
|
||||
[extname]: ../api/interfaces/liquid_options_.liquidoptions.html#Optional-extname
|
||||
[root]: ../api/interfaces/liquid_options_.liquidoptions.html#Optional-root
|
||||
@@ -0,0 +1,17 @@
|
||||
---
|
||||
title: Tags
|
||||
---
|
||||
|
||||
LiquidJS implements business-logic independent tags that are typically implemented in [shopify/liquid][shopify/liquid]. This section contains the specification and demoes for all the tags implemented by LiquidJS.
|
||||
|
||||
There're a dozen of tags supported by LiquidJS, with all tags in [shopify/liquid][shopify/liquid]. These tags can be categorized into these groups:
|
||||
|
||||
Category | Purpose | Tags
|
||||
--- | --- | ---
|
||||
Iteration | iterate over a collection | for, cycle, tablerow
|
||||
Control Flow | control the execution branch of template rendering | if, unless, elif, else, case, when
|
||||
Variable | define and alter variables | assign, increment, decrement
|
||||
File | include another template or extend a layout template | render, include, layout
|
||||
Language | temporarily disable LiquidJS syntax | raw, comment
|
||||
|
||||
[shopify/liquid]: https://github.com/Shopify/liquid
|
||||
@@ -0,0 +1,19 @@
|
||||
---
|
||||
title: Raw
|
||||
---
|
||||
|
||||
Raw temporarily disables tag processing. This is useful for generating content
|
||||
(eg, Mustache, Handlebars) which uses conflicting syntax.
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{% raw %}
|
||||
In Handlebars, {{ this }} will be HTML-escaped, but
|
||||
{{{ that }}} will not.
|
||||
{% endraw %}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
In Handlebars, {{ this }} will be HTML-escaped, but {{{ that }}} will not.
|
||||
```
|
||||
@@ -0,0 +1,64 @@
|
||||
---
|
||||
title: Render
|
||||
---
|
||||
|
||||
## Basic Usage
|
||||
|
||||
### Render a Template
|
||||
|
||||
Renders a partial template from the template [root][root]s.
|
||||
|
||||
```liquid
|
||||
{% render 'footer.liquid' %}
|
||||
```
|
||||
|
||||
When the [extname][extname] option is set, the above `.liquid` extension can be omitted and writes:
|
||||
|
||||
```liquid
|
||||
{% render 'footer' %}
|
||||
```
|
||||
|
||||
{% note info Variable Scope %}
|
||||
When a partial template is rendered, the code inside it can't access its parent's variables and its variables won't be accessible by its parent. This encapsulation helps make theme code easier to understand and maintain.{% endnote %}
|
||||
|
||||
### Passing Variables
|
||||
|
||||
Variables defined in parent's scope can be passed to a the partial template by listing them as parameters on the render tag:
|
||||
|
||||
```liquid
|
||||
{% assign my_variable = 'apples' %}
|
||||
{% render 'name', my_variable: my_variable, my_other_variable: 'oranges' %}
|
||||
```
|
||||
|
||||
[globals][globals] don't need to be passed down. They are accessible from all files.
|
||||
|
||||
## Parameters
|
||||
|
||||
### The `with` Parameter
|
||||
|
||||
A single object can be passed to a snippet by using the `with...as` syntax:
|
||||
|
||||
```liquid
|
||||
{% assign featured_product = all_products['product_handle'] %}
|
||||
{% render 'product' with featured_product as product %}
|
||||
```
|
||||
|
||||
In the example above, the `product` variable in the partial template will hold the value of `featured_product` in the parent template.
|
||||
|
||||
### The `for` Parameter
|
||||
|
||||
A partial template can be rendered once for each value of an enumerable by using the `for...as` syntax:
|
||||
|
||||
```liquid
|
||||
{% assign variants = product.variants %}
|
||||
{% render 'variant' for variants as variant %}
|
||||
```
|
||||
|
||||
In the example above, the partial template will be rendered once for each `variant` of the `product`, and the `variant` variable will hold a product's variant object within the snippet.
|
||||
|
||||
{% note tip The forloop object %} When using the for parameter, the <a href="./for.html#forloop">forloop</a> object is accessible within the snippet.{% endnote %}
|
||||
|
||||
[forloop]: ./for.html
|
||||
[extname]: ../api/interfaces/liquid_options_.liquidoptions.html#Optional-extname
|
||||
[root]: ../api/interfaces/liquid_options_.liquidoptions.html#Optional-root
|
||||
[globals]: ../api/interfaces/liquid_options_.liquidoptions.html#Optional-globals
|
||||
@@ -0,0 +1,128 @@
|
||||
---
|
||||
title: Table Row
|
||||
---
|
||||
|
||||
Generates an HTML table. Must be wrapped in opening `<table>` and closing `</table>` HTML tags.
|
||||
|
||||
## Basic Usage
|
||||
|
||||
Input
|
||||
```liquid
|
||||
<table>
|
||||
{% tablerow product in collection.products %}
|
||||
{{ product.title }}
|
||||
{% endtablerow %}
|
||||
</table>
|
||||
```
|
||||
|
||||
Output
|
||||
```html
|
||||
<table>
|
||||
<tr class="row1">
|
||||
<td class="col1">
|
||||
Cool Shirt
|
||||
</td>
|
||||
<td class="col2">
|
||||
Alien Poster
|
||||
</td>
|
||||
<td class="col3">
|
||||
Batman Poster
|
||||
</td>
|
||||
<td class="col4">
|
||||
Bullseye Shirt
|
||||
</td>
|
||||
<td class="col5">
|
||||
Another Classic Vinyl
|
||||
</td>
|
||||
<td class="col6">
|
||||
Awesome Jeans
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
```
|
||||
|
||||
## Parameters
|
||||
|
||||
### cols
|
||||
|
||||
Defines how many columns the tables should have.
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{% tablerow product in collection.products cols:2 %}
|
||||
{{ product.title }}
|
||||
{% endtablerow %}
|
||||
```
|
||||
|
||||
Output
|
||||
```html
|
||||
<table>
|
||||
<tr class="row1">
|
||||
<td class="col1">
|
||||
Cool Shirt
|
||||
</td>
|
||||
<td class="col2">
|
||||
Alien Poster
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="row2">
|
||||
<td class="col1">
|
||||
Batman Poster
|
||||
</td>
|
||||
<td class="col2">
|
||||
Bullseye Shirt
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="row3">
|
||||
<td class="col1">
|
||||
Another Classic Vinyl
|
||||
</td>
|
||||
<td class="col2">
|
||||
Awesome Jeans
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
```
|
||||
|
||||
### limit
|
||||
|
||||
Exits the tablerow after a specific index.
|
||||
|
||||
```liquid
|
||||
{% tablerow product in collection.products cols:2 limit:3 %}
|
||||
{{ product.title }}
|
||||
{% endtablerow %}
|
||||
```
|
||||
|
||||
### offset
|
||||
|
||||
Starts the tablerow after a specific index.
|
||||
|
||||
```liquid
|
||||
{% tablerow product in collection.products cols:2 offset:3 %}
|
||||
{{ product.title }}
|
||||
{% endtablerow %}
|
||||
```
|
||||
|
||||
### range
|
||||
|
||||
Defines a range of numbers to loop through. The range can be defined by both literal and variable numbers.
|
||||
|
||||
```liquid
|
||||
<!--variable number example-->
|
||||
|
||||
{% assign num = 4 %}
|
||||
<table>
|
||||
{% tablerow i in (1..num) %}
|
||||
{{ i }}
|
||||
{% endtablerow %}
|
||||
</table>
|
||||
|
||||
<!--literal number example-->
|
||||
|
||||
<table>
|
||||
{% tablerow i in (3..5) %}
|
||||
{{ i }}
|
||||
{% endtablerow %}
|
||||
</table>
|
||||
```
|
||||
@@ -0,0 +1,25 @@
|
||||
---
|
||||
title: Unless
|
||||
---
|
||||
|
||||
The opposite of `if` – executes a block of code only if a certain condition is **not** met.
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{% unless product.title == "Awesome Shoes" %}
|
||||
These shoes are not awesome.
|
||||
{% endunless %}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
These shoes are not awesome.
|
||||
```
|
||||
|
||||
This would be the equivalent of doing the following:
|
||||
|
||||
```liquid
|
||||
{% if product.title != "Awesome Shoes" %}
|
||||
These shoes are not awesome.
|
||||
{% endif %}
|
||||
```
|
||||
@@ -0,0 +1,55 @@
|
||||
---
|
||||
title: Caching
|
||||
---
|
||||
|
||||
In a typical website project, we'll have a directory of view templates and they'll be rendered multiple times. In production environment the template files are not likely to be changed over time (other than re-deployments). Thus it makes sense to cache the file contents and the parsed templates (in a kind of AST) to improve performance.
|
||||
|
||||
LiquidJS provides multiple ways to cache the parsed templates to improve performance.
|
||||
|
||||
## Programmaticly
|
||||
|
||||
The [.parse()][parse], [.parseFile()][parseFile], [.parseFileSync()][parseFileSync] APIs are used to parse templates from string or files. The result template can be then rendered multiple times with different context.
|
||||
|
||||
Parse from string:
|
||||
|
||||
```javascript
|
||||
var tpl = engine.parse('{{name | capitalize}}');
|
||||
|
||||
engine.renderSync(tpl, {name: 'alice'}) // 'Alice'
|
||||
engine.renderSync(tpl, {name: 'bob'}) // 'Bob'
|
||||
```
|
||||
|
||||
Parse from file:
|
||||
|
||||
```javascript
|
||||
var tpl = engine.parseFileSync('hello'); // contents of `hello.liquid`: {{name}}
|
||||
|
||||
engine.renderSync(tpl, {name: 'alice'}) // 'Alice'
|
||||
engine.renderSync(tpl, {name: 'bob'}) // 'Bob'
|
||||
```
|
||||
|
||||
The template string/file is parsed only once and renderd multiple times using different context. Templates for different files can be stored into a `Map` and can be retrieved directly for subsequent renders.
|
||||
|
||||
## The `cache` Option
|
||||
|
||||
The [cache option][cache] can be set to instruct liquidjs to use cached parsed templates each time you call [renderFile][renderFile] or [renderFileSync][renderFileSync].
|
||||
|
||||
```javascript
|
||||
var { Liquid } = require('liquidjs');
|
||||
var engine = new Liquid({
|
||||
cache: true
|
||||
});
|
||||
|
||||
// liquidjs parses the hello.liquid, then renders it with {name: 'alice'}
|
||||
engine.renderFileSync('hello', {name: 'alice'})
|
||||
|
||||
// liquidjs finds the cached template, then renders it with {name: 'bob'}
|
||||
engine.renderFileSync('hello', {name: 'bob'})
|
||||
```
|
||||
|
||||
[parse]: ../api/classes/liquid_.liquid.html#parse
|
||||
[cache]: ../api/interfaces/liquid_options_.liquidoptions.html#Optional-cache
|
||||
[parseFile]: ../api/classes/liquid_.liquid.html#parseFile
|
||||
[parseFileSync]: ../api/classes/liquid_.liquid.html#parseFileSync
|
||||
[renderFile]: ../api/classes/liquid_.liquid.html#renderFile
|
||||
[renderFileSync]: ../api/classes/liquid_.liquid.html#renderFilesync
|
||||
@@ -0,0 +1,39 @@
|
||||
---
|
||||
title: Contribution Guideline
|
||||
---
|
||||
|
||||
## Show Me Your Code
|
||||
|
||||
**Code Style**: LiquidJS applies [standard](https://github.com/standard/eslint-config-standard) and [@typescript-eslint/recommended](https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/eslint-plugin/src/configs/recommended.json) rules, make sure it's still valid before commit:
|
||||
|
||||
```bash
|
||||
npm run lint
|
||||
```
|
||||
|
||||
**Testing**: Make sure test cases pass with your patch merged:
|
||||
|
||||
```bash
|
||||
npm test
|
||||
```
|
||||
|
||||
**Commit Message**: Please align to [the Angular Commit Message Guidelines](https://github.com/angular/angular.js/blob/master/DEVELOPERS.md#commits), especially note the [type identifier](https://github.com/angular/angular.js/blob/master/DEVELOPERS.md#type), on which semantic-release bot depends.
|
||||
|
||||
## Star on Github 👉 [][liquidjs]
|
||||
|
||||
This is the easiest way to support us: boost its rank and expose it to more people, which in turn makes it better.
|
||||
|
||||
## Financial Support
|
||||
|
||||
LiquidJS is Open Source and Free and **without** capitalists support and **without** any ADs. To help it live and thrive, consider contribute on [Open Collective][oc] or [Patreon][pt]. To acknowledge your contribution, your name and avatar will be listed here and on [Github README][liquidjs].
|
||||
|
||||
<object type="image/svg+xml" data="https://opencollective.com/liquidjs/tiers/backer.svg?avatarHeight=72"></object>
|
||||
|
||||
[](https://www.patreon.com/bePatron?u=32321060)
|
||||
|
||||
[oc]: https://opencollective.com/liquidjs/
|
||||
[pt]: https://www.patreon.com/harttle
|
||||
[shopify/liquid]: https://shopify.github.io/liquid/
|
||||
[caniuse-promises]: http://caniuse.com/#feat=promises
|
||||
[pp]: https://github.com/taylorhakes/promise-polyfill
|
||||
[tutorial]: https://shopify.github.io/liquid/basics/introduction/
|
||||
[liquidjs]: https://github.com/harttle/liquidjs
|
||||