docs: website for LiquidJS

This commit is contained in:
harttle
2020-03-28 17:21:07 +08:00
parent 0633dbeabb
commit 3e42d6b1b0
422 changed files with 14509 additions and 50335 deletions
+3
View File
@@ -0,0 +1,3 @@
en: English
zh-cn:
name: 简体中文
+5
View File
@@ -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
+24
View File
@@ -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%.'
+135
View File
@@ -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"
+12
View File
@@ -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>
Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

+37
View File
@@ -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
```
+29
View File
@@ -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
```
+25
View File
@@ -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
```
+25
View File
@@ -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
```
+27
View File
@@ -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
```
+47
View File
@@ -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
```
+47
View File
@@ -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
```
+53
View File
@@ -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
```
+53
View File
@@ -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
+45
View File
@@ -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
+29
View File
@@ -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
+25
View File
@@ -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
```
+25
View File
@@ -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 &#39;James &amp; the Giant Peach&#39;?" | escape}}
</pre>
Input
```liquid
{{ "Tetsuro Takara" | escape }}
```
Output
```text
Tetsuro Takara
```
+25
View File
@@ -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 &lt; 2 &amp; 3" | escape}}
</pre>
Input
<pre class="highlight">
&#x7B;&#x7B; "{{"1 &lt; 2 &amp; 3" | escape}}" | escape_once }}
</pre>
Output
<pre class="highlight">
{{"1 &lt; 2 &amp; 3" | escape}}
</pre>
+35
View File
@@ -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 %}
```
+47
View File
@@ -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
```
+17
View File
@@ -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
```
+16
View File
@@ -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"]
```
+35
View File
@@ -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 %}
```
+15
View File
@@ -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
```
+25
View File
@@ -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
```
+35
View File
@@ -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
```
+35
View File
@@ -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
```
+21
View File
@@ -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/>
```
+17
View File
@@ -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
+35
View File
@@ -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
```
+29
View File
@@ -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
```
+15
View File
@@ -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
```
+15
View File
@@ -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
```
+15
View File
@@ -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
```
+15
View File
@@ -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
```
+31
View File
@@ -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
```
+35
View File
@@ -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
```
+15
View File
@@ -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
```
+37
View File
@@ -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 %}
```
+49
View File
@@ -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
```
+28
View File
@@ -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 %}
```
+28
View File
@@ -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 %}
```
+29
View File
@@ -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
```
+15
View File
@@ -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
```
+15
View File
@@ -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?
```
+21
View File
@@ -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
```
+35
View File
@@ -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
```
+47
View File
@@ -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
```
+43
View File
@@ -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
```
+16
View File
@@ -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```
+25
View File
@@ -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
```
+15
View File
@@ -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
```
+25
View File
@@ -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
```
+80
View File
@@ -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
Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 669 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 992 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

+29
View File
@@ -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.
+3
View File
@@ -0,0 +1,3 @@
---
layout: playground
---
+1
View File
@@ -0,0 +1 @@
User-agent: *
+59
View File
@@ -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;
}
+31
View File
@@ -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
```
+35
View File
@@ -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.
```
+23
View File
@@ -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
```
+17
View File
@@ -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.
```
+48
View File
@@ -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
```
+25
View File
@@ -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
+201
View File
@@ -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
```
+40
View File
@@ -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!
```
+46
View File
@@ -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
+43
View File
@@ -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
+64
View File
@@ -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
+17
View File
@@ -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
+19
View File
@@ -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.
```
+64
View File
@@ -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
+128
View File
@@ -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>
```
+25
View File
@@ -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 %}
```
+55
View File
@@ -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 👉 [![harttle/liquidjs](https://img.shields.io/github/stars/harttle/liquidjs?style=flat-square)][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>
[![Become a Patron!](../icon/[email protected])](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

Some files were not shown because too many files have changed in this diff Show More