mirror of
https://github.com/harttle/liquidjs.git
synced 2026-09-15 04:10:40 -07:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
495bef2d0c | ||
|
|
fcb930f0dd | ||
|
|
b4e12232be | ||
|
|
3a67eb7f1c | ||
|
|
fc42438283 | ||
|
|
8acf405949 | ||
|
|
e9da7f39de | ||
|
|
87e83b63fc | ||
|
|
e347e603d7 | ||
|
|
0480d3317d | ||
|
|
82ba54845f | ||
|
|
05c478c322 | ||
|
|
87d4cc7e14 | ||
|
|
202556115f | ||
|
|
db67118a75 | ||
|
|
ba8b842452 | ||
|
|
dca9ab52b8 | ||
|
|
7ceff17fcb | ||
|
|
648b158dbd | ||
|
|
33b3c010af | ||
|
|
21ee27b575 | ||
|
|
c2a8365054 | ||
|
|
b2a1dc972e | ||
|
|
1bddd60b01 | ||
|
|
7b87ea82d3 | ||
|
|
8037f7b4a4 | ||
|
|
75aba92733 | ||
|
|
b9f8d85c65 | ||
|
|
e50267feaa | ||
|
|
04d62f070a | ||
|
|
d04ccd79c9 | ||
|
|
9d823937cc | ||
|
|
da93102c1c | ||
|
|
c6cde9cd10 | ||
|
|
dccb90c591 | ||
|
|
228a5c3bed | ||
|
|
4542ddcfc3 | ||
|
|
2def145cf6 | ||
|
|
14e059c933 | ||
|
|
771b9b9eba | ||
|
|
9c0dc5fa39 | ||
|
|
42d25902e8 | ||
|
|
d4e519c4a6 | ||
|
|
5f4a004e90 | ||
|
|
3fb66465c6 | ||
|
|
d9cac4efca | ||
|
|
8ef920928c | ||
|
|
d489916231 | ||
|
|
24c8a1e372 | ||
|
|
a6618538d1 | ||
|
|
c0c3c07ba1 | ||
|
|
a55f44f095 | ||
|
|
7f76e1311f | ||
|
|
312000366d | ||
|
|
3f21382d43 | ||
|
|
aafaa0b4f9 | ||
|
|
964e5e8961 | ||
|
|
fb6a9f8717 | ||
|
|
7526d4062d | ||
|
|
2663ee16a0 | ||
|
|
d24655887f | ||
|
|
a9f93d7235 | ||
|
|
0f4916bc5a | ||
|
|
f4a033ecea | ||
|
|
5ac3765612 | ||
|
|
e6db371519 | ||
|
|
a2d949209d | ||
|
|
08a0c1322c | ||
|
|
dad75ee877 | ||
|
|
d17813ef52 | ||
|
|
46ffe036a8 | ||
|
|
f47d91a9a6 | ||
|
|
8a1efc0f2e | ||
|
|
ff4fd44666 | ||
|
|
6c3f1c1e0c | ||
|
|
b4d1e27420 | ||
|
|
6f0a68080c | ||
|
|
89c6c7676d | ||
|
|
b7ab357964 | ||
|
|
9b9ef374a8 | ||
|
|
5bbdc08eff | ||
|
|
1380ac931a | ||
|
|
4e1a30a20c | ||
|
|
92992689cd | ||
|
|
1f6ce7c822 | ||
|
|
7eb621601c | ||
|
|
ffefd91fbc | ||
|
|
b115077e12 | ||
|
|
bb58d3e549 | ||
|
|
ff112a4750 | ||
|
|
907c4dea06 | ||
|
|
7a714855df | ||
|
|
cd918ccb85 | ||
|
|
8061e559ac | ||
|
|
33e97db903 | ||
|
|
9cfc8fd2df | ||
|
|
f62b2109f2 | ||
|
|
bf6b5c7da1 | ||
|
|
a58fe449e3 | ||
|
|
99516cb75f | ||
|
|
850ab0c749 | ||
|
|
33c7c8f301 | ||
|
|
32f613fb43 | ||
|
|
71a1dc6e72 | ||
|
|
375a19b0fd | ||
|
|
4e17fdc3b1 | ||
|
|
01c25044ac | ||
|
|
4a9b467c1b | ||
|
|
78f2120a85 | ||
|
|
adfc27c480 | ||
|
|
0075be9e6e | ||
|
|
bbf00f37bf | ||
|
|
0997530bab | ||
|
|
071368afe1 | ||
|
|
2089b9bb6c | ||
|
|
fd7002f6bb | ||
|
|
905a6dd149 | ||
|
|
e874b4060b | ||
|
|
753e8f94c0 | ||
|
|
0a1d60453e | ||
|
|
4ad383d9be | ||
|
|
66eb3b842a | ||
|
|
c41a5d5bab | ||
|
|
0aca2dd8c1 | ||
|
|
4289b4e804 | ||
|
|
c3e51caa70 | ||
|
|
a19feea7c4 | ||
|
|
e87f068067 | ||
|
|
392b859381 | ||
|
|
ed95d9a760 | ||
|
|
0f824355fa | ||
|
|
3dc4290b56 | ||
|
|
2f87708989 | ||
|
|
4a0186d62a | ||
|
|
c9e4220c88 | ||
|
|
bb8f8f569d | ||
|
|
2f6d84befc | ||
|
|
463a165e5e | ||
|
|
f88490cd3c | ||
|
|
e69a51025e | ||
|
|
ace5309c08 | ||
|
|
5a90c5bf74 | ||
|
|
f6e047867e | ||
|
|
c467630e0b | ||
|
|
b377dad9e3 | ||
|
|
ecc04c99c5 | ||
|
|
9e024ff2bc | ||
|
|
eec381ec72 | ||
|
|
c7216c6358 | ||
|
|
fe78890d35 | ||
|
|
d5771ba42c | ||
|
|
776d235fca | ||
|
|
a56af6bbfb | ||
|
|
1af8553651 | ||
|
|
049685b9a0 | ||
|
|
c503cb23df | ||
|
|
01014edc49 | ||
|
|
27e579e0e2 | ||
|
|
d3e3fecf53 | ||
|
|
33009bb988 | ||
|
|
aa955173d4 | ||
|
|
15b78ebd9d | ||
|
|
575f3e2338 | ||
|
|
7dfb620d30 | ||
|
|
21b78d9ba0 | ||
|
|
5d077f461a | ||
|
|
13343040c6 | ||
|
|
ca3240c2c4 | ||
|
|
2b0c5696bc | ||
|
|
dab8a29070 | ||
|
|
f395295721 | ||
|
|
200f6648aa | ||
|
|
31aa4ec318 | ||
|
|
231574903f | ||
|
|
dbc0497386 | ||
|
|
ab5e245fba | ||
|
|
78ce5662df | ||
|
|
8b880f65a2 | ||
|
|
d605158f96 | ||
|
|
1a44b908ce | ||
|
|
a0817e5dd7 | ||
|
|
703675e1e0 | ||
|
|
819d060a92 | ||
|
|
c3d7ecbde1 | ||
|
|
8bdb70878f | ||
|
|
2e1537d50c | ||
|
|
d4afbc038f | ||
|
|
58d03890b4 | ||
|
|
e3fb47a90b | ||
|
|
e4ad93ee8c | ||
|
|
0bdf6792d1 | ||
|
|
7e99efc513 | ||
|
|
527858fc14 | ||
|
|
9da41c8a37 | ||
|
|
2717dae127 | ||
|
|
8db6c7b28d | ||
|
|
298db97b84 | ||
|
|
bd8e2b0f96 | ||
|
|
117eaf57c3 | ||
|
|
1e69d86b0c | ||
|
|
cc6b66216d | ||
|
|
ca82416dea | ||
|
|
394d5a1ae2 | ||
|
|
371da3da74 | ||
|
|
7814285479 | ||
|
|
53824a2d00 | ||
|
|
9966d846b5 | ||
|
|
8c27a84059 | ||
|
|
388d0fbbc4 | ||
|
|
d71d0a0c20 | ||
|
|
191a0130d2 | ||
|
|
2c3ebaca0c | ||
|
|
7677f848c0 |
@@ -459,6 +459,124 @@
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "ameyaapte1",
|
||||
"name": "Ameya Apte",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/16054747?v=4",
|
||||
"profile": "https://github.com/ameyaapte1",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "tbdrz",
|
||||
"name": "tbdrz",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/50599116?v=4",
|
||||
"profile": "https://github.com/tbdrz",
|
||||
"contributions": [
|
||||
"doc"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "santialbo",
|
||||
"name": "Santi Albo",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/1557563?v=4",
|
||||
"profile": "http://santialbo.com",
|
||||
"contributions": [
|
||||
"doc"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "YahangWu",
|
||||
"name": "Yahang Wu",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/12295975?v=4",
|
||||
"profile": "https://github.com/YahangWu",
|
||||
"contributions": [
|
||||
"doc"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "hongl-1",
|
||||
"name": "hongl",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/101576612?v=4",
|
||||
"profile": "https://github.com/hongl-1",
|
||||
"contributions": [
|
||||
"doc"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "zxx-457",
|
||||
"name": "zxx-457",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/114141362?v=4",
|
||||
"profile": "https://github.com/zxx-457",
|
||||
"contributions": [
|
||||
"doc"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "prassie",
|
||||
"name": "prassie",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/1357831?v=4",
|
||||
"profile": "https://github.com/prassie",
|
||||
"contributions": [
|
||||
"doc"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "slavivanov",
|
||||
"name": "Slav Ivanov",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/713329?v=4",
|
||||
"profile": "http://slavv.com/",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "DaRosenberg",
|
||||
"name": "Daniel Rosenberg",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/3889090?v=4",
|
||||
"profile": "http://www.orgflow.io/",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "bobgubko",
|
||||
"name": "bobgubko",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/733312?v=4",
|
||||
"profile": "https://github.com/bobgubko",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "bangank36",
|
||||
"name": "BaNgan",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/10071857?v=4",
|
||||
"profile": "https://github.com/bangank36",
|
||||
"contributions": [
|
||||
"doc"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "mahyar-pasarzangene",
|
||||
"name": "Mahyar Pasarzangene",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/16485039?v=4",
|
||||
"profile": "https://github.com/mahyar-pasarzangene",
|
||||
"contributions": [
|
||||
"doc"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "TomasHubelbauer",
|
||||
"name": "Tomáš Hübelbauer",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/6831144?v=4",
|
||||
"profile": "https://hubelbauer.net/",
|
||||
"contributions": [
|
||||
"code",
|
||||
"doc"
|
||||
]
|
||||
}
|
||||
],
|
||||
"contributorsPerLine": 7,
|
||||
|
||||
@@ -3,3 +3,4 @@ dist
|
||||
demo
|
||||
coverage
|
||||
docs
|
||||
private.*
|
||||
|
||||
+16
-1
@@ -7,13 +7,18 @@
|
||||
"node": true
|
||||
},
|
||||
"parser": "@typescript-eslint/parser",
|
||||
"parserOptions": {
|
||||
"project": "tsconfig.json"
|
||||
},
|
||||
"plugins": [
|
||||
"deprecation",
|
||||
"mocha",
|
||||
"standard",
|
||||
"@typescript-eslint",
|
||||
"promise"
|
||||
],
|
||||
"rules": {
|
||||
"deprecation/deprecation": "error",
|
||||
"no-var": 2,
|
||||
"prefer-const": 2,
|
||||
"no-unused-vars": "off",
|
||||
@@ -32,9 +37,19 @@
|
||||
"@typescript-eslint/no-unused-vars": ["error", { "vars": "all", "args": "none", "ignoreRestSiblings": false }]
|
||||
},
|
||||
"overrides": [{
|
||||
"files": ["**/*.js", "*.js"],
|
||||
"files": ["**/filters/*.ts"],
|
||||
"rules": {
|
||||
"camelcase": "off"
|
||||
}
|
||||
}, {
|
||||
"files": ["**/*.js", "**/*.mjs"],
|
||||
"rules": {
|
||||
"@typescript-eslint/no-var-requires": "off"
|
||||
}
|
||||
}, {
|
||||
"files": ["test/**/*.ts"],
|
||||
"rules": {
|
||||
"deprecation/deprecation": "off"
|
||||
}
|
||||
}]
|
||||
}
|
||||
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
# These are supported funding model platforms
|
||||
|
||||
# github: harttle
|
||||
patreon: harttle
|
||||
github: harttle
|
||||
# patreon: harttle
|
||||
open_collective: liquidjs
|
||||
ko_fi: # Replace with a single Ko-fi username
|
||||
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
name: Check
|
||||
on: [push, pull_request]
|
||||
jobs:
|
||||
release:
|
||||
check:
|
||||
name: Check
|
||||
runs-on: ubuntu-18.04
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-latest, macos-latest]
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
@@ -20,11 +23,19 @@ jobs:
|
||||
- name: Test
|
||||
run: |
|
||||
npm run lint
|
||||
npm run test
|
||||
TZ=Etc/GMT npm run test
|
||||
TZ=Asia/Shanghai npm run test
|
||||
TZ=America/New_York npm run test
|
||||
- name: Coverage
|
||||
uses: coverallsapp/[email protected]
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Performance
|
||||
run: |
|
||||
npm run perf:diff
|
||||
npm run perf:diff
|
||||
- name: Archive npm failure logs
|
||||
uses: actions/upload-artifact@v2
|
||||
if: failure()
|
||||
with:
|
||||
name: npm-logs
|
||||
path: ~/.npm/_logs
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
name: Docs
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
jobs:
|
||||
docs:
|
||||
name: Docs
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: '14'
|
||||
- name: Build
|
||||
run: |
|
||||
npm ci
|
||||
npm run build
|
||||
- name: Publish
|
||||
uses: JamesIves/[email protected]
|
||||
with:
|
||||
branch: gh-pages
|
||||
folder: docs/public
|
||||
- name: Archive npm failure logs
|
||||
uses: actions/upload-artifact@v2
|
||||
if: failure()
|
||||
with:
|
||||
name: npm-logs
|
||||
path: ~/.npm/_logs
|
||||
@@ -0,0 +1,17 @@
|
||||
name: "PR Title Checker"
|
||||
|
||||
on:
|
||||
pull_request_target:
|
||||
types:
|
||||
- opened
|
||||
- edited
|
||||
- synchronize
|
||||
|
||||
jobs:
|
||||
main:
|
||||
name: Validate PR title
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: amannn/action-semantic-pull-request@v5
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
@@ -3,7 +3,7 @@ on: workflow_dispatch
|
||||
jobs:
|
||||
release:
|
||||
name: Release
|
||||
runs-on: ubuntu-18.04
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
@@ -16,7 +16,7 @@ jobs:
|
||||
- name: Build
|
||||
run: |
|
||||
npm ci
|
||||
npm run build
|
||||
npm run build:dist
|
||||
- name: Test
|
||||
run: |
|
||||
npm run lint
|
||||
@@ -30,8 +30,9 @@ jobs:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||
run: npx semantic-release
|
||||
- name: Publish Docs
|
||||
uses: JamesIves/github-pages-deploy-acti[email protected]
|
||||
with:
|
||||
branch: gh-pages
|
||||
folder: docs/public
|
||||
- name: Archive npm failure logs
|
||||
uses: actions/upload-artifact@v2
|
||||
if: failure()
|
||||
with:
|
||||
name: npm-logs
|
||||
path: ~/.npm/_logs
|
||||
+352
@@ -1,3 +1,355 @@
|
||||
## [10.8.2](https://github.com/harttle/liquidjs/compare/v10.8.1...v10.8.2) (2023-06-04)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* sample filter randomness and count=1 case ([fcb930f](https://github.com/harttle/liquidjs/commit/fcb930f0ddf2489fa74cd323f24398d7e9f7717f))
|
||||
|
||||
## [10.8.1](https://github.com/harttle/liquidjs/compare/v10.8.0...v10.8.1) (2023-06-04)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* incorrect error message for browser UMD bundle ([3a67eb7](https://github.com/harttle/liquidjs/commit/3a67eb7f1cc7e54d2ec94a985eca4c1f147cdd61))
|
||||
|
||||
# [10.8.0](https://github.com/harttle/liquidjs/compare/v10.7.1...v10.8.0) (2023-06-03)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* proper error message for filter syntax error, [#610](https://github.com/harttle/liquidjs/issues/610) ([0480d33](https://github.com/harttle/liquidjs/commit/0480d3317d0e46519ad2adf4ac43f53cddf467c6))
|
||||
* sed invocations to work out of the box on macOS ([#615](https://github.com/harttle/liquidjs/issues/615)) ([87d4cc7](https://github.com/harttle/liquidjs/commit/87d4cc7e14ece14161285a740be63afc8a88b63c))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* Add support for the Jekyll sample filter ([#612](https://github.com/harttle/liquidjs/issues/612)) ([ba8b842](https://github.com/harttle/liquidjs/commit/ba8b84245266589e43c0e70d99e12b981d349809))
|
||||
* Add support for the Jekyll push filter ([#611](https://github.com/harttle/liquidjs/issues/611))
|
||||
* introduce a matrix with latest Ubuntu and macOS to test the build on macOS as well ([82ba548](https://github.com/harttle/liquidjs/commit/82ba54845f4cd4e1e7660c1557e3cfaa22d68924)), closes [#615](https://github.com/harttle/liquidjs/issues/615)
|
||||
* precise line/col for tokenization Error, [#613](https://github.com/harttle/liquidjs/issues/613) ([e347e60](https://github.com/harttle/liquidjs/commit/e347e603d76c039cec191d417deab34e7ef1f9a7))
|
||||
|
||||
## [10.7.1](https://github.com/harttle/liquidjs/compare/v10.7.0...v10.7.1) (2023-04-24)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* incorrect timezone correction for DST dates, fixes [#604](https://github.com/harttle/liquidjs/issues/604) ([33b3c01](https://github.com/harttle/liquidjs/commit/33b3c010af0cd17a303621331feab0119ca840ce))
|
||||
* timezoneOffset ignored in date when preserveTimezones is enabled, fixes [#605](https://github.com/harttle/liquidjs/issues/605) ([21ee27b](https://github.com/harttle/liquidjs/commit/21ee27b57503f9d57f228973e1699972484e6089))
|
||||
|
||||
# [10.7.0](https://github.com/harttle/liquidjs/compare/v10.6.2...v10.7.0) (2023-03-21)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* update remove.md ([#601](https://github.com/harttle/liquidjs/issues/601)) ([1bddd60](https://github.com/harttle/liquidjs/commit/1bddd60b0191032d324526292027bc7fcd190dc1))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* JSON format by `space` in `json` filter ([7b87ea8](https://github.com/harttle/liquidjs/commit/7b87ea82d3d63420e548743c5a84a073f0cdad22))
|
||||
|
||||
## [10.6.2](https://github.com/harttle/liquidjs/compare/v10.6.1...v10.6.2) (2023-03-19)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* sample FS in render-file.md ([#594](https://github.com/harttle/liquidjs/issues/594)) ([4542ddc](https://github.com/harttle/liquidjs/commit/4542ddcfc3d5e245112a119bf22f0e00cb925791))
|
||||
|
||||
## [10.6.1](https://github.com/harttle/liquidjs/compare/v10.6.0...v10.6.1) (2023-03-02)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* [expression] apply value equal for arrays, [#589](https://github.com/harttle/liquidjs/issues/589) ([9c0dc5f](https://github.com/harttle/liquidjs/commit/9c0dc5fa39a31d477a5c5a2c5212034174bf0516))
|
||||
* strip_html for multi line <script>/<style>/comments, [#70](https://github.com/harttle/liquidjs/issues/70) ([42d2590](https://github.com/harttle/liquidjs/commit/42d25902e855d3c06d5ead071bf55604f495c205))
|
||||
|
||||
# [10.6.0](https://github.com/harttle/liquidjs/compare/v10.5.0...v10.6.0) (2023-02-22)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* LiquidOptions.dateFormat to override default date format ([#587](https://github.com/harttle/liquidjs/issues/587)) ([3fb6646](https://github.com/harttle/liquidjs/commit/3fb66465c6fe1bf4dc2e1ace9157c23d0fc8f859))
|
||||
|
||||
# [10.5.0](https://github.com/harttle/liquidjs/compare/v10.4.0...v10.5.0) (2023-02-14)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* "ownPropertyOnly" not respected when passed via "renderOptions" ([d489916](https://github.com/harttle/liquidjs/commit/d489916231779149e110183400e3e597b8ee02ba))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* Adds support for options to CLI and improves usability ([#586](https://github.com/harttle/liquidjs/issues/586)) ([24c8a1e](https://github.com/harttle/liquidjs/commit/24c8a1e3722e5359f02934e2814f9abfa888ee86))
|
||||
|
||||
# [10.4.0](https://github.com/harttle/liquidjs/compare/v10.3.3...v10.4.0) (2023-01-02)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* support `not` operator, [#575](https://github.com/harttle/liquidjs/issues/575) ([3f21382](https://github.com/harttle/liquidjs/commit/3f21382d43cafa1e32162e58adabd22d5c3709ed))
|
||||
* support calling `date` without format string, [#573](https://github.com/harttle/liquidjs/issues/573) ([aafaa0b](https://github.com/harttle/liquidjs/commit/aafaa0b4f9e84f466fbcc2cb2ae37fe8704c5272))
|
||||
|
||||
## [10.3.3](https://github.com/harttle/liquidjs/compare/v10.3.2...v10.3.3) (2022-12-18)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* type compatible with v9 tag definition, support `Context` as scope in various render APIs, [#570](https://github.com/harttle/liquidjs/issues/570) ([fb6a9f8](https://github.com/harttle/liquidjs/commit/fb6a9f8717cd57522d53687da7e4718b28a7f68a))
|
||||
|
||||
## [10.3.2](https://github.com/harttle/liquidjs/compare/v10.3.1...v10.3.2) (2022-12-13)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* re-export error classes, [#569](https://github.com/harttle/liquidjs/issues/569) ([2663ee1](https://github.com/harttle/liquidjs/commit/2663ee16a066c74cbd387fe40154fdeb2136f35a))
|
||||
|
||||
## [10.3.1](https://github.com/harttle/liquidjs/compare/v10.3.0...v10.3.1) (2022-12-12)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* support `Context` as `evalValue` parameter, [#568](https://github.com/harttle/liquidjs/issues/568) ([0f4916b](https://github.com/harttle/liquidjs/commit/0f4916bc5a93f5e744e4246336c68f2e89774272))
|
||||
|
||||
# [10.3.0](https://github.com/harttle/liquidjs/compare/v10.2.0...v10.3.0) (2022-12-11)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* support disable outputEscape for specific filters, [#565](https://github.com/harttle/liquidjs/issues/565) ([e6db371](https://github.com/harttle/liquidjs/commit/e6db371519f0fb3b0068347cfb2016aed386c8fa))
|
||||
|
||||
# [10.2.0](https://github.com/harttle/liquidjs/compare/v10.1.0...v10.2.0) (2022-12-02)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* `case` should render multiple `when` statements ([d17813e](https://github.com/harttle/liquidjs/commit/d17813ef5217264bd08f741b0e1f713bedf2d464))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* add remove_last filter ([6c3f1c1](https://github.com/harttle/liquidjs/commit/6c3f1c1e0c0c5d30ef77eaf20df65e149e51e693))
|
||||
* add replace_last filter ([b4d1e27](https://github.com/harttle/liquidjs/commit/b4d1e27420fcf36ae6d5dbc92cfe4a26299690f2))
|
||||
|
||||
# [10.1.0](https://github.com/harttle/liquidjs/compare/v10.0.0...v10.1.0) (2022-11-29)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* timezone name for `opts.timezoneOffset` and `date` argument, fixes [#553](https://github.com/harttle/liquidjs/issues/553) ([89c6c76](https://github.com/harttle/liquidjs/commit/89c6c7676d40f23090472a28cbf2fb22f93daad3))
|
||||
|
||||
# [10.0.0](https://github.com/harttle/liquidjs/compare/v9.43.0...v10.0.0) (2022-11-27)
|
||||
|
||||
|
||||
### Code Refactoring
|
||||
|
||||
* rename filters to snake style, [#487](https://github.com/harttle/liquidjs/issues/487) ([ff112a4](https://github.com/harttle/liquidjs/commit/ff112a4750f91475e9eccdb301d7a468e895f6ca))
|
||||
* `_evalToken` renamed to `evalToken` ([4e1a30a](https://github.com/harttle/liquidjs/commit/4e1a30a20c579408c87f2d28b9b6ec8e1dda65cc))
|
||||
* change `ownPropertyOnly` default value to `true` ([7eb6216](https://github.com/harttle/liquidjs/commit/7eb621601c2b05d6e379e5ce42219f2b1f556208))
|
||||
* delay creation of `operatorsTrie` and hide this implementation ([bb58d3e](https://github.com/harttle/liquidjs/commit/bb58d3e549dc5a5e067895ec4a0b3257b434f225))
|
||||
* remove `toThenable` export ([ffefd91](https://github.com/harttle/liquidjs/commit/ffefd91fbc0195c589c8c34ae80f2017acfe557c))
|
||||
* remove use of internal `Context` class in `evalValue` argument ([b115077](https://github.com/harttle/liquidjs/commit/b115077e122a7b90e7972d58174d68aea8edd7bf))
|
||||
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* target Node.js 14 for cjs bundle (main entry) ([1f6ce7c](https://github.com/harttle/liquidjs/commit/1f6ce7c8224123cea318d1aa6c12aa091d6e0518))
|
||||
|
||||
|
||||
### BREAKING CHANGES
|
||||
|
||||
* `evalToken` now returns a generator (LiquidJS async), which is different from `evalToken` in previous LiquidJS versions.
|
||||
* main entry need Node.js>=14 to run, you can build LiquidJS by your own by using ESM entry.
|
||||
* `ownPropertyOnly` default value changed to `true`
|
||||
* `<liquidjs>.toThenable` is removed, use `<liquidjs>.toPromise` instead
|
||||
* `evalValue` won't support `Context` as second argument anymore.
|
||||
* use `operators` instead of `operatorsTrie` as Tokenizer constructor argument, #500
|
||||
* keys in `<liquidjs>.filters` are now in snake case (instead of camel case), identical to that in Liquid template.
|
||||
|
||||
# [9.43.0](https://github.com/harttle/liquidjs/compare/v9.42.1...v9.43.0) (2022-11-27)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* support timezone offset argument for date filter, [#553](https://github.com/harttle/liquidjs/issues/553) ([7a71485](https://github.com/harttle/liquidjs/commit/7a714855df9ba188e2e82839d248f6623ce94a87))
|
||||
|
||||
## [9.42.1](https://github.com/harttle/liquidjs/compare/v9.42.0...v9.42.1) (2022-10-21)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* truncatewords should use at least one word, [#537](https://github.com/harttle/liquidjs/issues/537) ([32f613f](https://github.com/harttle/liquidjs/commit/32f613fb43e90f97364ee6a020589992dbb553cf))
|
||||
|
||||
# [9.42.0](https://github.com/harttle/liquidjs/compare/v9.41.0...v9.42.0) (2022-08-27)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* promise in expression & nested property, [#533](https://github.com/harttle/liquidjs/issues/533) [#276](https://github.com/harttle/liquidjs/issues/276) ([bbf00f3](https://github.com/harttle/liquidjs/commit/bbf00f37bf6080d38ebc258d1921d3ff0d504186))
|
||||
|
||||
# [9.41.0](https://github.com/harttle/liquidjs/compare/v9.40.0...v9.41.0) (2022-08-24)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* use evalValue to parse & render expression, [#527](https://github.com/harttle/liquidjs/issues/527) ([071368a](https://github.com/harttle/liquidjs/commit/071368afe1c4fd36ebdb0e1d300c367db1766f7f))
|
||||
|
||||
# [9.40.0](https://github.com/harttle/liquidjs/compare/v9.39.2...v9.40.0) (2022-08-14)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* target ES6 for ESM bundles, fixes [#526](https://github.com/harttle/liquidjs/issues/526) ([905a6dd](https://github.com/harttle/liquidjs/commit/905a6dd1491705c1154b6679a67c1eb1ffe7eef5))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* export toValueSync & defaultOptions to evaluate expression, see [#527](https://github.com/harttle/liquidjs/issues/527) ([e874b40](https://github.com/harttle/liquidjs/commit/e874b4060b46195e05a5cc6690626bdaa532154c))
|
||||
|
||||
## [9.39.2](https://github.com/harttle/liquidjs/compare/v9.39.1...v9.39.2) (2022-07-21)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* expression support Drop.valueOf, fixes [#522](https://github.com/harttle/liquidjs/issues/522) ([4ad383d](https://github.com/harttle/liquidjs/commit/4ad383d9beb57f5683805decc1851778db64aea4))
|
||||
|
||||
## [9.39.1](https://github.com/harttle/liquidjs/compare/v9.39.0...v9.39.1) (2022-07-14)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* throw ParseError instead of RenderError for invalid assign expression, closes [#519](https://github.com/harttle/liquidjs/issues/519) ([c41a5d5](https://github.com/harttle/liquidjs/commit/c41a5d5babf85ccedbcb3b6f9a3cf5c326f72ae1))
|
||||
|
||||
# [9.39.0](https://github.com/harttle/liquidjs/compare/v9.38.0...v9.39.0) (2022-07-09)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* for tag not respecting Drop#valueOf(), fixes [#515](https://github.com/harttle/liquidjs/issues/515) ([c3e51ca](https://github.com/harttle/liquidjs/commit/c3e51caa701fd4449ed5257e23569a37ef12dea2))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* iteration protocols ([a19feea](https://github.com/harttle/liquidjs/commit/a19feea7c46fc476139a150bda051f485328afe8))
|
||||
|
||||
# [9.38.0](https://github.com/harttle/liquidjs/compare/v9.37.0...v9.38.0) (2022-07-07)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* stack overflow on large number of templates, [#513](https://github.com/harttle/liquidjs/issues/513) ([3dc4290](https://github.com/harttle/liquidjs/commit/3dc4290b56265cfafbee8d9836e912d9b8492f90))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* inline comment tag ([#514](https://github.com/harttle/liquidjs/issues/514)) ([2f87708](https://github.com/harttle/liquidjs/commit/2f8770898963e35ac4491f6975a8abd03dc09067))
|
||||
|
||||
# [9.37.0](https://github.com/harttle/liquidjs/compare/v9.36.2...v9.37.0) (2022-04-21)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* support integer arithmetic for `divided_by`, closes [#465](https://github.com/harttle/liquidjs/issues/465) ([e69a510](https://github.com/harttle/liquidjs/commit/e69a51025efa7dec7d60d0067200a1466988ebbc))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* automatic output escaping, closes [#500](https://github.com/harttle/liquidjs/issues/500) ([f88490c](https://github.com/harttle/liquidjs/commit/f88490cd3cd0b5316c43c3ca76837544d99ce0b0))
|
||||
|
||||
## [9.36.2](https://github.com/harttle/liquidjs/compare/v9.36.1...v9.36.2) (2022-04-19)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* lazy createRequire to allow exceptions being catched, fixes [#497](https://github.com/harttle/liquidjs/issues/497) ([b377dad](https://github.com/harttle/liquidjs/commit/b377dad9e34c3de3e0eedc1ee6f17a0e9d919669))
|
||||
|
||||
## [9.36.1](https://github.com/harttle/liquidjs/compare/v9.36.0...v9.36.1) (2022-04-17)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* contains operator does not support Drop, fixes [#492](https://github.com/harttle/liquidjs/issues/492) ([9e024ff](https://github.com/harttle/liquidjs/commit/9e024ff2bcf17e7ac19c718389d4cef39b8a51f7))
|
||||
* responsive header ([a56af6b](https://github.com/harttle/liquidjs/commit/a56af6bbfb5b698db55fbeb87e8e0872688fbe19))
|
||||
* use `createRequire` for ESM, fixes [#334](https://github.com/harttle/liquidjs/issues/334) ([eec381e](https://github.com/harttle/liquidjs/commit/eec381ec72db3858452799b7a3264e240be3044d))
|
||||
|
||||
# [9.36.0](https://github.com/harttle/liquidjs/compare/v9.35.2...v9.36.0) (2022-03-05)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* Access array item by negative index, closes [#486](https://github.com/harttle/liquidjs/issues/486) ([049685b](https://github.com/harttle/liquidjs/commit/049685b9a0271ba03875e24ff2f6c7870cae62a7))
|
||||
* allow strip filter with specified char, closes [#390](https://github.com/harttle/liquidjs/issues/390) ([c503cb2](https://github.com/harttle/liquidjs/commit/c503cb23dfbdd6f146d6dea16a84eab3df1f7aa9))
|
||||
* appropriate error for malformed filters, fixes [#271](https://github.com/harttle/liquidjs/issues/271) ([01014ed](https://github.com/harttle/liquidjs/commit/01014edc491e12d38981045442da9faee598cdf7))
|
||||
|
||||
## [9.35.2](https://github.com/harttle/liquidjs/compare/v9.35.1...v9.35.2) (2022-03-02)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* corner case for concat filter without argument, [#481](https://github.com/harttle/liquidjs/issues/481) ([aa95517](https://github.com/harttle/liquidjs/commit/aa955173d4c7adc585e862934429f1f4c5f64969))
|
||||
* export all builtin tags from LiquidJS, [#464](https://github.com/harttle/liquidjs/issues/464) ([33009bb](https://github.com/harttle/liquidjs/commit/33009bb988eb74c58f390992750d91b967cb3428))
|
||||
|
||||
## [9.35.1](https://github.com/harttle/liquidjs/compare/v9.35.0...v9.35.1) (2022-02-26)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* some filters throw on nil input, see [#481](https://github.com/harttle/liquidjs/issues/481) ([7dfb620](https://github.com/harttle/liquidjs/commit/7dfb620d30f8818685e1cfb8e7492313a0d036ab))
|
||||
|
||||
# [9.35.0](https://github.com/harttle/liquidjs/compare/v9.34.1...v9.35.0) (2022-02-23)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* `url_encode` throws on undefined value, fixes [#479](https://github.com/harttle/liquidjs/issues/479) ([ca3240c](https://github.com/harttle/liquidjs/commit/ca3240c2c4d157095d2ebe0024d0c71bc5e435f8))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* expose all tags/filters and TimezoneDate, closes [#464](https://github.com/harttle/liquidjs/issues/464) ([dab8a29](https://github.com/harttle/liquidjs/commit/dab8a29070b2508f2e6532717b7663966f610bec))
|
||||
|
||||
## [9.34.1](https://github.com/harttle/liquidjs/compare/v9.34.0...v9.34.1) (2022-02-20)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* array output now join with "" instead of "," ([ab5e245](https://github.com/harttle/liquidjs/commit/ab5e245fba9a0f6936275319d4e5e25aadb0f7c1))
|
||||
* sort filter unexpectedly modifies original array, [#475](https://github.com/harttle/liquidjs/issues/475) ([dbc0497](https://github.com/harttle/liquidjs/commit/dbc049738633b1b6f578d9d20f830b548ba67a22))
|
||||
|
||||
# [9.34.0](https://github.com/harttle/liquidjs/compare/v9.33.1...v9.34.0) (2022-01-28)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* where-filter null handling ([#457](https://github.com/harttle/liquidjs/issues/457)) ([9da41c8](https://github.com/harttle/liquidjs/commit/9da41c8a37d9c49ee4a16d5bd520fd6ae01c14ec))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* `ownPropertyOnly` option to protect prototype, [#454](https://github.com/harttle/liquidjs/issues/454) ([7e99efc](https://github.com/harttle/liquidjs/commit/7e99efc5131e20cf3f59e1fc2c371a15aa4109db))
|
||||
|
||||
## [9.33.1](https://github.com/harttle/liquidjs/compare/v9.33.0...v9.33.1) (2022-01-19)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* liquidjs.version on npm package ([53824a2](https://github.com/harttle/liquidjs/commit/53824a2d00f978214fcd83a48118b7900cf97449))
|
||||
|
||||
# [9.33.0](https://github.com/harttle/liquidjs/compare/v9.32.1...v9.33.0) (2022-01-19)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* support `offset:continue`, see [#439](https://github.com/harttle/liquidjs/issues/439) ([8c27a84](https://github.com/harttle/liquidjs/commit/8c27a84059384ae730eb0fa1524df04e122e27a0))
|
||||
* support Jekyll-like include syntax, see [#441](https://github.com/harttle/liquidjs/issues/441) ([388d0fb](https://github.com/harttle/liquidjs/commit/388d0fbbc42fe8cd69faba61c1dc29e9bb5ec2d0))
|
||||
|
||||
## [9.32.1](https://github.com/harttle/liquidjs/compare/v9.32.0...v9.32.1) (2022-01-12)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* remove limit on operator char length ([7677f84](https://github.com/harttle/liquidjs/commit/7677f848c0c57335dd1c4f1e3ec251fbf9b1663f))
|
||||
|
||||
# [9.32.0](https://github.com/harttle/liquidjs/compare/v9.31.0...v9.32.0) (2022-01-02)
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
# Contributing
|
||||
|
||||
1. Build everything and run tests to learn how to do both:
|
||||
- `npm run build`
|
||||
- `npm run test`
|
||||
|
||||
Tests won't at first unless you've done a build at least once.
|
||||
Subsequent changes to tests do not need re-builds but changes to the code and
|
||||
then tests need a build to pick up the new code by the tests.
|
||||
|
||||
2. Make your changes and add a test for them
|
||||
- Build after you've made your changes
|
||||
- Run tests as per the above to validate your changes
|
||||
|
||||
3. Create a pull request
|
||||
- Ensure the build runs because the Husky pre-commit hook checks it
|
||||
- `npm run check` checks runs the build, tests, lint and perf tests
|
||||
- `commitlint` checks the commit message format
|
||||
|
||||
If there is a problem you will see it in the pre-commit hook output.
|
||||
In VS Code, this output will be shown in a new file in a new tab if the
|
||||
pre-commit hook fails.
|
||||
If you want to check the commit message without using the VS Code Source
|
||||
Control UI, you can run `echo "feat: my commit message" > npx commitlint`
|
||||
directly.
|
||||
|
||||
- `git switch -c your_branch_name` (do this in your fork not the main repo)
|
||||
- `git add .`
|
||||
- `git commit -m "feat: Adding my change"`
|
||||
- `git push`
|
||||
- Go to GitHub and find your fork, open a PR against the upstream from it
|
||||
|
||||
## Playground
|
||||
|
||||
The Playground runs off the `docs` directory.
|
||||
`npm run:docs` is used to build it and that's included in `npm run build`.
|
||||
|
||||
To start the site locally, go to `docs` and run `npm start`, then visit
|
||||
http://localhost:4000/playground.html.
|
||||
|
||||
At the moment, the Playground uses the latest NPM version of the LiquidJS
|
||||
library instead of using the built artifact produced by `npm run build:dist`
|
||||
(also included in `npm run build`).
|
||||
|
||||
To use the Playground with the local build of the library, make these changes:
|
||||
|
||||
- Copy `dist/liquid.browser.min.js` to `docs/public/js/liquid.browser.min.js`
|
||||
- Open `docs/themes/navy/layout/partial/after_footer.swig`
|
||||
- Remove `https://cdn.jsdelivr.net/npm/liquidjs/dist/liquid.browser.min.js` line
|
||||
- Add `{{ js('liquid.browser.min.js') }}` line before `{{ js('js/main') }}` line
|
||||
- Refresh the Playground site for the changes to take effect
|
||||
- Replace `liquid.browser.min.js` each time after making changes and building
|
||||
|
||||
```diff
|
||||
{% if page.layout === 'playground' %}
|
||||
-<script src="https://cdn.jsdelivr.net/npm/liquidjs/dist/liquid.browser.min.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/[email protected]/src-min/ace.js"></script>
|
||||
{% endif %}
|
||||
|
||||
+{{ js('js/liquid.browser.min.js') }}
|
||||
{{ js('js/main') }}
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/docsearch.js@2/dist/cdn/docsearch.min.js"></script>
|
||||
```
|
||||
@@ -2,7 +2,7 @@
|
||||
[](https://www.npmjs.org/package/liquidjs)
|
||||
[](https://www.npmjs.org/package/liquidjs)
|
||||
[](https://coveralls.io/github/harttle/liquidjs?branch=master)
|
||||
[](https://github.com/harttle/liquidjs/actions/workflows/check.yml?query=branch%3Amaster)
|
||||
[](https://github.com/harttle/liquidjs/actions/workflows/check.yml?query=branch%3Amaster)
|
||||
[](https://github.com/harttle/liquidjs/blob/master/LICENSE)
|
||||
[](https://github.com/harttle/liquidjs)
|
||||
|
||||
@@ -42,20 +42,34 @@ Or use the UMD bundle from jsDelivr:
|
||||
<script src="https://cdn.jsdelivr.net/npm/liquidjs/dist/liquid.browser.min.js"></script>
|
||||
```
|
||||
|
||||
More details, refer to [The Setup Guide][setup].
|
||||
Or render directly from CLI using npx:
|
||||
|
||||
## Related Packages
|
||||
```bash
|
||||
npx liquidjs --template 'Hello, {{ name }}!' --context '{"name": "Snake"}'
|
||||
```
|
||||
|
||||
For more details, refer to the [Setup Guide][setup].
|
||||
|
||||
## Related Projects
|
||||
|
||||
* [@11ty/eleventy](https://www.npmjs.com/package/@11ty/eleventy): A simpler static site generator. An alternative to Jekyll. Written in JavaScript. Transforms a directory of templates (of varying types) into HTML.
|
||||
* [gulp-liquidjs](https://www.npmjs.com/package/@tuanpham-dev/gulp-liquidjs): A shopify compatible Liquid template engine for Gulp using liquidjs.
|
||||
* [grunt-liquify](https://www.npmjs.com/package/grunt-liquify): A Grunt task to process Liquid using liquidjs. Use it to add Liquid magic to your scripts and css assets.
|
||||
* [react-liquid](https://github.com/aquibm/react-liquid#readme): Liquid templating language component for React
|
||||
* [@11ty/eleventy](https://www.npmjs.com/package/@11ty/eleventy): A simpler static site generator. An alternative to Jekyll. Written in JavaScript. Transforms a directory of templates (of varying types) into HTML.
|
||||
|
||||
## Backers
|
||||
## Financial Support
|
||||
|
||||
If you love LiquidJS or your company is using LiquidJS? Please consider [support us on Open Collective or Patreon][financial-support].
|
||||
|
||||

|
||||
### Backers
|
||||
If you personally like LiquidJS and find it useful to you, you can buy me a coffee!
|
||||
|
||||
<img src="https://opencollective.com/liquidjs/backers.svg?avatarHeight=72">
|
||||
|
||||
### Sponsors
|
||||
If LiquidJS is benefiting your business/company, please sponsor us to contribute to our effort!
|
||||
|
||||
<img src="https://opencollective.com/liquidjs/sponsors.svg?avatarHeight=72">
|
||||
|
||||
## Contributors ✨
|
||||
|
||||
@@ -65,69 +79,88 @@ Want to contribute? see [Contribution Guidelines][contribution]. Thanks goes to
|
||||
<!-- prettier-ignore-start -->
|
||||
<!-- markdownlint-disable -->
|
||||
<table>
|
||||
<tr>
|
||||
<td align="center"><a href="https://harttle.land"><img src="https://avatars3.githubusercontent.com/u/4427974?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Jun Yang</b></sub></a><br /><a href="#maintenance-harttle" title="Maintenance">🚧</a> <a href="https://github.com/harttle/liquidjs/commits?author=harttle" title="Code">💻</a></td>
|
||||
<td align="center"><a href="https://github.com/chenos"><img src="https://avatars0.githubusercontent.com/u/2993310?v=4?s=100" width="100px;" alt=""/><br /><sub><b>chenos</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=chenos" title="Code">💻</a></td>
|
||||
<td align="center"><a href="https://zachleat.com/"><img src="https://avatars2.githubusercontent.com/u/39355?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Zach Leatherman</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/issues?q=author%3Azachleat" title="Bug reports">🐛</a></td>
|
||||
<td align="center"><a href="https://github.com/thardy"><img src="https://avatars3.githubusercontent.com/u/120636?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Tim Hardy</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=thardy" title="Code">💻</a></td>
|
||||
<td align="center"><a href="https://paulrobertlloyd.com/"><img src="https://avatars3.githubusercontent.com/u/813383?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Paul Robert Lloyd</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=paulrobertlloyd" title="Code">💻</a> <a href="https://github.com/harttle/liquidjs/issues?q=author%3Apaulrobertlloyd" title="Bug reports">🐛</a></td>
|
||||
<td align="center"><a href="https://twitter.com/alecdotbiz"><img src="https://avatars2.githubusercontent.com/u/1925840?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Alec Larson</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=aleclarson" title="Code">💻</a></td>
|
||||
<td align="center"><a href="https://github.com/pmalouin"><img src="https://avatars1.githubusercontent.com/u/1411117?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Patrick Malouin</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=pmalouin" title="Code">💻</a> <a href="https://github.com/harttle/liquidjs/commits?author=pmalouin" title="Documentation">📖</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center"><a href="https://jaswrks.com"><img src="https://avatars3.githubusercontent.com/u/1563559?v=4?s=100" width="100px;" alt=""/><br /><sub><b>jaswrks</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=jaswrks" title="Code">💻</a></td>
|
||||
<td align="center"><a href="https://oott123.com"><img src="https://avatars2.githubusercontent.com/u/905663?v=4?s=100" width="100px;" alt=""/><br /><sub><b>三三</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=oott123" title="Code">💻</a> <a href="#ideas-oott123" title="Ideas, Planning, & Feedback">🤔</a></td>
|
||||
<td align="center"><a href="https://github.com/ssendev"><img src="https://avatars0.githubusercontent.com/u/450793?v=4?s=100" width="100px;" alt=""/><br /><sub><b>ssendev</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=ssendev" title="Code">💻</a> <a href="https://github.com/harttle/liquidjs/commits?author=ssendev" title="Documentation">📖</a></td>
|
||||
<td align="center"><a href="https://github.com/wojtask9"><img src="https://avatars3.githubusercontent.com/u/6099236?v=4?s=100" width="100px;" alt=""/><br /><sub><b>wojtask9</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=wojtask9" title="Code">💻</a></td>
|
||||
<td align="center"><a href="https://github.com/thelornenelson"><img src="https://avatars3.githubusercontent.com/u/24596583?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Andrew Barclay</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=thelornenelson" title="Code">💻</a></td>
|
||||
<td align="center"><a href="https://www.stam.pr/"><img src="https://avatars2.githubusercontent.com/u/142338?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Cory Mawhorter</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=cmawhorter" title="Code">💻</a></td>
|
||||
<td align="center"><a href="https://github.com/thehappybug"><img src="https://avatars0.githubusercontent.com/u/3393530?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Mehdi Jaffery</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=thehappybug" title="Code">💻</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center"><a href="https://github.com/robinbijlani"><img src="https://avatars0.githubusercontent.com/u/2503108?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Robin Bijlani</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=robinbijlani" title="Code">💻</a> <a href="https://github.com/harttle/liquidjs/issues?q=author%3Arobinbijlani" title="Bug reports">🐛</a></td>
|
||||
<td align="center"><a href="https://www.rmkennedy.com"><img src="https://avatars3.githubusercontent.com/u/8356669?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Ryan Kennedy</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=ryaninvents" title="Code">💻</a></td>
|
||||
<td align="center"><a href="https://github.com/strax"><img src="https://avatars2.githubusercontent.com/u/587213?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Sami Kukkonen</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=strax" title="Code">💻</a></td>
|
||||
<td align="center"><a href="https://ScottFreeCode.github.io/"><img src="https://avatars3.githubusercontent.com/u/16506071?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Scott Santucci</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=ScottFreeCode" title="Code">💻</a></td>
|
||||
<td align="center"><a href="http://stevenrescigno.com"><img src="https://avatars3.githubusercontent.com/u/8505293?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Steven </b></sub></a><br /><a href="#example-stevenanthonyrevo" title="Examples">💡</a> <a href="https://github.com/harttle/liquidjs/commits?author=stevenanthonyrevo" title="Code">💻</a></td>
|
||||
<td align="center"><a href="https://efcl.info/"><img src="https://avatars1.githubusercontent.com/u/19714?v=4?s=100" width="100px;" alt=""/><br /><sub><b>azu</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=azu" title="Documentation">📖</a></td>
|
||||
<td align="center"><a href="https://github.com/wyozi"><img src="https://avatars3.githubusercontent.com/u/4894573?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Joonas</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=wyozi" title="Code">💻</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center"><a href="https://github.com/jamelait"><img src="https://avatars1.githubusercontent.com/u/14369255?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Jamel A.</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=jamelait" title="Code">💻</a></td>
|
||||
<td align="center"><a href="https://brandonpittman.net"><img src="https://avatars0.githubusercontent.com/u/967145?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Brandon Pittman</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=brandonpittman" title="Code">💻</a></td>
|
||||
<td align="center"><a href="https://github.com/tgrandgent"><img src="https://avatars3.githubusercontent.com/u/17069042?v=4?s=100" width="100px;" alt=""/><br /><sub><b>tgrandgent</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=tgrandgent" title="Code">💻</a></td>
|
||||
<td align="center"><a href="https://github.com/mastodon0"><img src="https://avatars1.githubusercontent.com/u/7924332?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Martin Schuster</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=mastodon0" title="Code">💻</a></td>
|
||||
<td align="center"><a href="http://js.chenlei.me"><img src="https://avatars0.githubusercontent.com/u/6339390?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Ray</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=richardo2016" title="Tests">⚠️</a> <a href="https://github.com/harttle/liquidjs/commits?author=richardo2016" title="Code">💻</a></td>
|
||||
<td align="center"><a href="https://github.com/CriGoT"><img src="https://avatars0.githubusercontent.com/u/1936786?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Cristofer Gonzales</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=CriGoT" title="Code">💻</a></td>
|
||||
<td align="center"><a href="https://www.raymondcamden.com"><img src="https://avatars3.githubusercontent.com/u/393660?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Raymond Camden</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=cfjedimaster" title="Documentation">📖</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center"><a href="https://stedman.dev"><img src="https://avatars1.githubusercontent.com/u/183122?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Steve Stedman</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=stedman" title="Documentation">📖</a></td>
|
||||
<td align="center"><a href="https://ciccarello.me"><img src="https://avatars0.githubusercontent.com/u/11273838?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Anthony Ciccarello</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=aciccarello" title="Documentation">📖</a></td>
|
||||
<td align="center"><a href="https://twitter.com/IAmTrySound"><img src="https://avatars0.githubusercontent.com/u/5635476?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Bogdan Chadkin</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=TrySound" title="Code">💻</a></td>
|
||||
<td align="center"><a href="https://hightouch.io"><img src="https://avatars0.githubusercontent.com/u/5959235?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Tejas Manohar</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=tejasmanohar" title="Code">💻</a></td>
|
||||
<td align="center"><a href="http://about.me/peterdehaan"><img src="https://avatars2.githubusercontent.com/u/557895?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Peter deHaan</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=pdehaan" title="Documentation">📖</a></td>
|
||||
<td align="center"><a href="https://github.com/amit777"><img src="https://avatars0.githubusercontent.com/u/2703309?v=4?s=100" width="100px;" alt=""/><br /><sub><b>amit777</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=amit777" title="Code">💻</a> <a href="#financial-amit777" title="Financial">💵</a></td>
|
||||
<td align="center"><a href="http://www.ifi.uzh.ch/en/ce/people/schuldenzucker.html"><img src="https://avatars3.githubusercontent.com/u/1100776?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Steffen Schuldenzucker</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=sschuldenzucker" title="Code">💻</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center"><a href="https://github.com/Pixcell"><img src="https://avatars0.githubusercontent.com/u/4005291?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Pixcell</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=Pixcell" title="Code">💻</a></td>
|
||||
<td align="center"><a href="https://jasonet.co"><img src="https://avatars.githubusercontent.com/u/10660468?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Jason Etcovitch</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=JasonEtco" title="Code">💻</a></td>
|
||||
<td align="center"><a href="https://github.com/kayuapi"><img src="https://avatars.githubusercontent.com/u/10304328?v=4?s=100" width="100px;" alt=""/><br /><sub><b>ZC</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=kayuapi" title="Documentation">📖</a></td>
|
||||
<td align="center"><a href="https://memmie.lenglet.name"><img src="https://avatars.githubusercontent.com/u/729275?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Memmie Lenglet</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=mems" title="Code">💻</a></td>
|
||||
<td align="center"><a href="https://github.com/ilhamdev0"><img src="https://avatars.githubusercontent.com/u/57636145?v=4?s=100" width="100px;" alt=""/><br /><sub><b>ilhamdev0</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=ilhamdev0" title="Documentation">📖</a></td>
|
||||
<td align="center"><a href="https://github.com/c412216887"><img src="https://avatars.githubusercontent.com/u/29691650?v=4?s=100" width="100px;" alt=""/><br /><sub><b>一饮一啄皆是人生</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=c412216887" title="Documentation">📖</a></td>
|
||||
<td align="center"><a href="https://digitalinspiration.com/"><img src="https://avatars.githubusercontent.com/u/1344071?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Amit Agarwal</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=labnol" title="Documentation">📖</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center"><a href="https://n1ru4l.cloud/"><img src="https://avatars.githubusercontent.com/u/14338007?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Laurin Quast</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=n1ru4l" title="Code">💻</a></td>
|
||||
<td align="center"><a href="https://github.com/mattvague"><img src="https://avatars.githubusercontent.com/u/64985?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Matt Vague</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=mattvague" title="Code">💻</a></td>
|
||||
<td align="center"><a href="https://github.com/bglw"><img src="https://avatars.githubusercontent.com/u/40188355?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Liam Bigelow</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=bglw" title="Code">💻</a></td>
|
||||
<td align="center"><a href="https://about.me/jasonkurian"><img src="https://avatars.githubusercontent.com/u/2642545?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Jason Kurian</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=JaKXz" title="Documentation">📖</a></td>
|
||||
<td align="center"><a href="https://github.com/dphm"><img src="https://avatars.githubusercontent.com/u/1707217?v=4?s=100" width="100px;" alt=""/><br /><sub><b>d pham (they/them)</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=dphm" title="Documentation">📖</a></td>
|
||||
<td align="center"><a href="https://www.aleksandrhovhannisyan.com/"><img src="https://avatars.githubusercontent.com/u/19352442?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Aleksandr Hovhannisyan</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=AleksandrHovhannisyan" title="Code">💻</a></td>
|
||||
<td align="center"><a href="https://github.com/jg-rp"><img src="https://avatars.githubusercontent.com/u/72664870?v=4?s=100" width="100px;" alt=""/><br /><sub><b>jg-rp</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=jg-rp" title="Code">💻</a></td>
|
||||
</tr>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://harttle.land"><img src="https://avatars3.githubusercontent.com/u/4427974?v=4?s=100" width="100px;" alt="Jun Yang"/><br /><sub><b>Jun Yang</b></sub></a><br /><a href="#maintenance-harttle" title="Maintenance">🚧</a> <a href="https://github.com/harttle/liquidjs/commits?author=harttle" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/chenos"><img src="https://avatars0.githubusercontent.com/u/2993310?v=4?s=100" width="100px;" alt="chenos"/><br /><sub><b>chenos</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=chenos" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://zachleat.com/"><img src="https://avatars2.githubusercontent.com/u/39355?v=4?s=100" width="100px;" alt="Zach Leatherman"/><br /><sub><b>Zach Leatherman</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/issues?q=author%3Azachleat" title="Bug reports">🐛</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/thardy"><img src="https://avatars3.githubusercontent.com/u/120636?v=4?s=100" width="100px;" alt="Tim Hardy"/><br /><sub><b>Tim Hardy</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=thardy" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://paulrobertlloyd.com/"><img src="https://avatars3.githubusercontent.com/u/813383?v=4?s=100" width="100px;" alt="Paul Robert Lloyd"/><br /><sub><b>Paul Robert Lloyd</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=paulrobertlloyd" title="Code">💻</a> <a href="https://github.com/harttle/liquidjs/issues?q=author%3Apaulrobertlloyd" title="Bug reports">🐛</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://twitter.com/alecdotbiz"><img src="https://avatars2.githubusercontent.com/u/1925840?v=4?s=100" width="100px;" alt="Alec Larson"/><br /><sub><b>Alec Larson</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=aleclarson" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/pmalouin"><img src="https://avatars1.githubusercontent.com/u/1411117?v=4?s=100" width="100px;" alt="Patrick Malouin"/><br /><sub><b>Patrick Malouin</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=pmalouin" title="Code">💻</a> <a href="https://github.com/harttle/liquidjs/commits?author=pmalouin" title="Documentation">📖</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://jaswrks.com"><img src="https://avatars3.githubusercontent.com/u/1563559?v=4?s=100" width="100px;" alt="jaswrks"/><br /><sub><b>jaswrks</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=jaswrks" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://oott123.com"><img src="https://avatars2.githubusercontent.com/u/905663?v=4?s=100" width="100px;" alt="三三"/><br /><sub><b>三三</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=oott123" title="Code">💻</a> <a href="#ideas-oott123" title="Ideas, Planning, & Feedback">🤔</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/ssendev"><img src="https://avatars0.githubusercontent.com/u/450793?v=4?s=100" width="100px;" alt="ssendev"/><br /><sub><b>ssendev</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=ssendev" title="Code">💻</a> <a href="https://github.com/harttle/liquidjs/commits?author=ssendev" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/wojtask9"><img src="https://avatars3.githubusercontent.com/u/6099236?v=4?s=100" width="100px;" alt="wojtask9"/><br /><sub><b>wojtask9</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=wojtask9" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/thelornenelson"><img src="https://avatars3.githubusercontent.com/u/24596583?v=4?s=100" width="100px;" alt="Andrew Barclay"/><br /><sub><b>Andrew Barclay</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=thelornenelson" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://www.stam.pr/"><img src="https://avatars2.githubusercontent.com/u/142338?v=4?s=100" width="100px;" alt="Cory Mawhorter"/><br /><sub><b>Cory Mawhorter</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=cmawhorter" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/thehappybug"><img src="https://avatars0.githubusercontent.com/u/3393530?v=4?s=100" width="100px;" alt="Mehdi Jaffery"/><br /><sub><b>Mehdi Jaffery</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=thehappybug" title="Code">💻</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/robinbijlani"><img src="https://avatars0.githubusercontent.com/u/2503108?v=4?s=100" width="100px;" alt="Robin Bijlani"/><br /><sub><b>Robin Bijlani</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=robinbijlani" title="Code">💻</a> <a href="https://github.com/harttle/liquidjs/issues?q=author%3Arobinbijlani" title="Bug reports">🐛</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://www.rmkennedy.com"><img src="https://avatars3.githubusercontent.com/u/8356669?v=4?s=100" width="100px;" alt="Ryan Kennedy"/><br /><sub><b>Ryan Kennedy</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=ryaninvents" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/strax"><img src="https://avatars2.githubusercontent.com/u/587213?v=4?s=100" width="100px;" alt="Sami Kukkonen"/><br /><sub><b>Sami Kukkonen</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=strax" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://ScottFreeCode.github.io/"><img src="https://avatars3.githubusercontent.com/u/16506071?v=4?s=100" width="100px;" alt="Scott Santucci"/><br /><sub><b>Scott Santucci</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=ScottFreeCode" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="http://stevenrescigno.com"><img src="https://avatars3.githubusercontent.com/u/8505293?v=4?s=100" width="100px;" alt="Steven "/><br /><sub><b>Steven </b></sub></a><br /><a href="#example-stevenanthonyrevo" title="Examples">💡</a> <a href="https://github.com/harttle/liquidjs/commits?author=stevenanthonyrevo" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://efcl.info/"><img src="https://avatars1.githubusercontent.com/u/19714?v=4?s=100" width="100px;" alt="azu"/><br /><sub><b>azu</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=azu" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/wyozi"><img src="https://avatars3.githubusercontent.com/u/4894573?v=4?s=100" width="100px;" alt="Joonas"/><br /><sub><b>Joonas</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=wyozi" title="Code">💻</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/jamelait"><img src="https://avatars1.githubusercontent.com/u/14369255?v=4?s=100" width="100px;" alt="Jamel A."/><br /><sub><b>Jamel A.</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=jamelait" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://brandonpittman.net"><img src="https://avatars0.githubusercontent.com/u/967145?v=4?s=100" width="100px;" alt="Brandon Pittman"/><br /><sub><b>Brandon Pittman</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=brandonpittman" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/tgrandgent"><img src="https://avatars3.githubusercontent.com/u/17069042?v=4?s=100" width="100px;" alt="tgrandgent"/><br /><sub><b>tgrandgent</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=tgrandgent" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/mastodon0"><img src="https://avatars1.githubusercontent.com/u/7924332?v=4?s=100" width="100px;" alt="Martin Schuster"/><br /><sub><b>Martin Schuster</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=mastodon0" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="http://js.chenlei.me"><img src="https://avatars0.githubusercontent.com/u/6339390?v=4?s=100" width="100px;" alt="Ray"/><br /><sub><b>Ray</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=richardo2016" title="Tests">⚠️</a> <a href="https://github.com/harttle/liquidjs/commits?author=richardo2016" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/CriGoT"><img src="https://avatars0.githubusercontent.com/u/1936786?v=4?s=100" width="100px;" alt="Cristofer Gonzales"/><br /><sub><b>Cristofer Gonzales</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=CriGoT" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://www.raymondcamden.com"><img src="https://avatars3.githubusercontent.com/u/393660?v=4?s=100" width="100px;" alt="Raymond Camden"/><br /><sub><b>Raymond Camden</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=cfjedimaster" title="Documentation">📖</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://stedman.dev"><img src="https://avatars1.githubusercontent.com/u/183122?v=4?s=100" width="100px;" alt="Steve Stedman"/><br /><sub><b>Steve Stedman</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=stedman" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://ciccarello.me"><img src="https://avatars0.githubusercontent.com/u/11273838?v=4?s=100" width="100px;" alt="Anthony Ciccarello"/><br /><sub><b>Anthony Ciccarello</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=aciccarello" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://twitter.com/IAmTrySound"><img src="https://avatars0.githubusercontent.com/u/5635476?v=4?s=100" width="100px;" alt="Bogdan Chadkin"/><br /><sub><b>Bogdan Chadkin</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=TrySound" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://hightouch.io"><img src="https://avatars0.githubusercontent.com/u/5959235?v=4?s=100" width="100px;" alt="Tejas Manohar"/><br /><sub><b>Tejas Manohar</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=tejasmanohar" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="http://about.me/peterdehaan"><img src="https://avatars2.githubusercontent.com/u/557895?v=4?s=100" width="100px;" alt="Peter deHaan"/><br /><sub><b>Peter deHaan</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=pdehaan" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/amit777"><img src="https://avatars0.githubusercontent.com/u/2703309?v=4?s=100" width="100px;" alt="amit777"/><br /><sub><b>amit777</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=amit777" title="Code">💻</a> <a href="#financial-amit777" title="Financial">💵</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="http://www.ifi.uzh.ch/en/ce/people/schuldenzucker.html"><img src="https://avatars3.githubusercontent.com/u/1100776?v=4?s=100" width="100px;" alt="Steffen Schuldenzucker"/><br /><sub><b>Steffen Schuldenzucker</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=sschuldenzucker" title="Code">💻</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Pixcell"><img src="https://avatars0.githubusercontent.com/u/4005291?v=4?s=100" width="100px;" alt="Pixcell"/><br /><sub><b>Pixcell</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=Pixcell" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://jasonet.co"><img src="https://avatars.githubusercontent.com/u/10660468?v=4?s=100" width="100px;" alt="Jason Etcovitch"/><br /><sub><b>Jason Etcovitch</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=JasonEtco" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/kayuapi"><img src="https://avatars.githubusercontent.com/u/10304328?v=4?s=100" width="100px;" alt="ZC"/><br /><sub><b>ZC</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=kayuapi" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://memmie.lenglet.name"><img src="https://avatars.githubusercontent.com/u/729275?v=4?s=100" width="100px;" alt="Memmie Lenglet"/><br /><sub><b>Memmie Lenglet</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=mems" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/ilhamdev0"><img src="https://avatars.githubusercontent.com/u/57636145?v=4?s=100" width="100px;" alt="ilhamdev0"/><br /><sub><b>ilhamdev0</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=ilhamdev0" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/c412216887"><img src="https://avatars.githubusercontent.com/u/29691650?v=4?s=100" width="100px;" alt="一饮一啄皆是人生"/><br /><sub><b>一饮一啄皆是人生</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=c412216887" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://digitalinspiration.com/"><img src="https://avatars.githubusercontent.com/u/1344071?v=4?s=100" width="100px;" alt="Amit Agarwal"/><br /><sub><b>Amit Agarwal</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=labnol" title="Documentation">📖</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://n1ru4l.cloud/"><img src="https://avatars.githubusercontent.com/u/14338007?v=4?s=100" width="100px;" alt="Laurin Quast"/><br /><sub><b>Laurin Quast</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=n1ru4l" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/mattvague"><img src="https://avatars.githubusercontent.com/u/64985?v=4?s=100" width="100px;" alt="Matt Vague"/><br /><sub><b>Matt Vague</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=mattvague" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/bglw"><img src="https://avatars.githubusercontent.com/u/40188355?v=4?s=100" width="100px;" alt="Liam Bigelow"/><br /><sub><b>Liam Bigelow</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=bglw" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://about.me/jasonkurian"><img src="https://avatars.githubusercontent.com/u/2642545?v=4?s=100" width="100px;" alt="Jason Kurian"/><br /><sub><b>Jason Kurian</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=JaKXz" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/dphm"><img src="https://avatars.githubusercontent.com/u/1707217?v=4?s=100" width="100px;" alt="d pham (they/them)"/><br /><sub><b>d pham (they/them)</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=dphm" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://www.aleksandrhovhannisyan.com/"><img src="https://avatars.githubusercontent.com/u/19352442?v=4?s=100" width="100px;" alt="Aleksandr Hovhannisyan"/><br /><sub><b>Aleksandr Hovhannisyan</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=AleksandrHovhannisyan" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/jg-rp"><img src="https://avatars.githubusercontent.com/u/72664870?v=4?s=100" width="100px;" alt="jg-rp"/><br /><sub><b>jg-rp</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=jg-rp" title="Code">💻</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/ameyaapte1"><img src="https://avatars.githubusercontent.com/u/16054747?v=4?s=100" width="100px;" alt="Ameya Apte"/><br /><sub><b>Ameya Apte</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=ameyaapte1" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/tbdrz"><img src="https://avatars.githubusercontent.com/u/50599116?v=4?s=100" width="100px;" alt="tbdrz"/><br /><sub><b>tbdrz</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=tbdrz" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="http://santialbo.com"><img src="https://avatars.githubusercontent.com/u/1557563?v=4?s=100" width="100px;" alt="Santi Albo"/><br /><sub><b>Santi Albo</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=santialbo" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/YahangWu"><img src="https://avatars.githubusercontent.com/u/12295975?v=4?s=100" width="100px;" alt="Yahang Wu"/><br /><sub><b>Yahang Wu</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=YahangWu" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/hongl-1"><img src="https://avatars.githubusercontent.com/u/101576612?v=4?s=100" width="100px;" alt="hongl"/><br /><sub><b>hongl</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=hongl-1" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/zxx-457"><img src="https://avatars.githubusercontent.com/u/114141362?v=4?s=100" width="100px;" alt="zxx-457"/><br /><sub><b>zxx-457</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=zxx-457" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/prassie"><img src="https://avatars.githubusercontent.com/u/1357831?v=4?s=100" width="100px;" alt="prassie"/><br /><sub><b>prassie</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=prassie" title="Documentation">📖</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" valign="top" width="14.28%"><a href="http://slavv.com/"><img src="https://avatars.githubusercontent.com/u/713329?v=4?s=100" width="100px;" alt="Slav Ivanov"/><br /><sub><b>Slav Ivanov</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=slavivanov" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="http://www.orgflow.io/"><img src="https://avatars.githubusercontent.com/u/3889090?v=4?s=100" width="100px;" alt="Daniel Rosenberg"/><br /><sub><b>Daniel Rosenberg</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=DaRosenberg" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/bobgubko"><img src="https://avatars.githubusercontent.com/u/733312?v=4?s=100" width="100px;" alt="bobgubko"/><br /><sub><b>bobgubko</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=bobgubko" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/bangank36"><img src="https://avatars.githubusercontent.com/u/10071857?v=4?s=100" width="100px;" alt="BaNgan"/><br /><sub><b>BaNgan</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=bangank36" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/mahyar-pasarzangene"><img src="https://avatars.githubusercontent.com/u/16485039?v=4?s=100" width="100px;" alt="Mahyar Pasarzangene"/><br /><sub><b>Mahyar Pasarzangene</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=mahyar-pasarzangene" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://hubelbauer.net/"><img src="https://avatars.githubusercontent.com/u/6831144?v=4?s=100" width="100px;" alt="Tomáš Hübelbauer"/><br /><sub><b>Tomáš Hübelbauer</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=TomasHubelbauer" title="Code">💻</a> <a href="https://github.com/harttle/liquidjs/commits?author=TomasHubelbauer" title="Documentation">📖</a></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<!-- markdownlint-restore -->
|
||||
|
||||
+4
-4
@@ -6,8 +6,8 @@ Only the latest major version is supported with security updates. It can be chan
|
||||
|
||||
## Reporting a Vulnerability
|
||||
|
||||
Please contact yangjvn@126.com to report a vulnerability.
|
||||
Please contact yangjvn@126.com to report a vulnerability or change request.
|
||||
|
||||
- It will be fixed very soon (maybe within 1 week or couple of days) if that vulnerability obviously affects common use cases.
|
||||
- Otherwise, it'll be scheduled with a priority just like requested features (which is lower than bugs).
|
||||
- If it's declined, you'll receive an email (more oftenly there will be a discuss).
|
||||
- If the vulnerability in question affects common use cases, it will be treated as a bug and fixed very soon (typically within 1 week).
|
||||
- Otherwise, it'll be scheduled in the same priority of feature request (which is lower than bugs).
|
||||
- If the request is declined, you'll receive a reply email anyway (most likely there will be a discussion).
|
||||
|
||||
@@ -8,17 +8,6 @@ const engine = new Liquid({
|
||||
extname: '.liquid'
|
||||
})
|
||||
|
||||
engine.registerTag('header', {
|
||||
parse: function (token) {
|
||||
const [key, val] = token.args.split(':')
|
||||
this[key] = val
|
||||
},
|
||||
render: function (ctx) {
|
||||
const title = this.liquid.evalValue(this.content, ctx)
|
||||
return `<h1>${title}</h1>`
|
||||
}
|
||||
})
|
||||
|
||||
function demo () {
|
||||
console.log(' demo')
|
||||
console.log('------------------------')
|
||||
|
||||
+2
-26
@@ -1,28 +1,4 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -ex
|
||||
|
||||
rm -rf docs/source/api docs/source/zh-cn/api
|
||||
typedoc ./src --gitRevision master --out docs/source/api --plugin typedoc-plugin-markdown --ignoreCompilerErrors true --theme vuepress
|
||||
rm docs/source/api/README.md
|
||||
|
||||
for file in $(find docs/source/api -name "*.md"); do
|
||||
sed -i \
|
||||
-e 's/\(\]([^_)]*\)\/_/\1\//g' \
|
||||
-e 's/\(\]([^)]*\.\)md/\1html/g' \
|
||||
-e 's/\](_/\](/g' \
|
||||
-e 's/{%/{% raw %}{%{% endraw %}/g' \
|
||||
-e 's/{{/{% raw %}{{{% endraw %}/g' \
|
||||
-e '1 s/"/\"/g' \
|
||||
-e '1 s/</\</g' \
|
||||
-e '1 s/>/\>/g' \
|
||||
-e '1 s/\*//g' \
|
||||
-e '1 s/^# \(.*\)/---\ntitle: "\1"\nauto: true\n---/' \
|
||||
$file
|
||||
target=${file/\/_/\/}
|
||||
if [ "$file" != "$target" ]; then
|
||||
mv $file $target
|
||||
fi
|
||||
done
|
||||
|
||||
cp -r docs/source/api docs/source/zh-cn/api
|
||||
rm -rf docs/source/api
|
||||
typedoc ./src --gitRevision master --out docs/source/api
|
||||
|
||||
+14
-3
@@ -1,8 +1,17 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Run `sed` in a way that's compatible with both macOS (BSD) and Linux (GNU)
|
||||
sedi() {
|
||||
if [[ "$OSTYPE" == "darwin"* ]]; then
|
||||
sed -i '' "$@"
|
||||
else
|
||||
sed -i "$@"
|
||||
fi
|
||||
}
|
||||
|
||||
cd docs
|
||||
cp ../CHANGELOG.md source/tutorials/changelog.md
|
||||
sed -i \
|
||||
sedi \
|
||||
-e 's/{%/{% raw %}{%{% endraw %}/g' \
|
||||
-e 's/{{/{% raw %}{{{% endraw %}/g' \
|
||||
-e '1 s/"/\"/g' \
|
||||
@@ -11,5 +20,7 @@ sed -i \
|
||||
source/tutorials/changelog.md
|
||||
cp source/tutorials/changelog.md source/zh-cn/tutorials/changelog.md
|
||||
|
||||
sed -i '1i ---\ntitle: Changelog\nauto: true\n---\n' source/tutorials/changelog.md
|
||||
sed -i '1i ---\ntitle: 更新日志\nauto: true\n---\n' source/zh-cn/tutorials/changelog.md
|
||||
sedi -e '1i\
|
||||
---\ntitle: Changelog\nauto: true\n---\n' source/tutorials/changelog.md
|
||||
sedi -e '1i\
|
||||
---\ntitle: 更新日志\nauto: true\n---\n' source/zh-cn/tutorials/changelog.md
|
||||
|
||||
@@ -1,10 +1,19 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Run `sed` in a way that's compatible with both macOS (BSD) and Linux (GNU)
|
||||
sedi() {
|
||||
if [[ "$OSTYPE" == "darwin"* ]]; then
|
||||
sed -i '' "$@"
|
||||
else
|
||||
sed -i "$@"
|
||||
fi
|
||||
}
|
||||
|
||||
cp .all-contributorsrc docs/.all-contributorsrc
|
||||
sed -i \
|
||||
-e 's/README.md/docs\/themes\/navy\/layout\/partial\/all-contributors.swig/g' \
|
||||
-e 's/"contributorsPerLine": 7/"contributorsPerLine": 65535/g' \
|
||||
docs/.all-contributorsrc
|
||||
sedi \
|
||||
-e 's/README.md/docs\/themes\/navy\/layout\/partial\/all-contributors.swig/g' \
|
||||
-e 's/"contributorsPerLine": 7/"contributorsPerLine": 65535/g' \
|
||||
docs/.all-contributorsrc
|
||||
|
||||
all-contributors --config docs/.all-contributorsrc generate
|
||||
sed -i 's/<br \/>.*<\/td>/<\/a><\/td>/g' docs/themes/navy/layout/partial/all-contributors.swig
|
||||
sedi 's/<br \/>.*<\/td>/<\/a><\/td>/g' docs/themes/navy/layout/partial/all-contributors.swig
|
||||
|
||||
Executable
+18
@@ -0,0 +1,18 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
// In Hexo, content inside markdown code/code fences,
|
||||
// will not go through nunjucks.
|
||||
// So we're escaping special chars outside code only.
|
||||
let backTick = 0
|
||||
process.stdin.on('data', (buffer) => {
|
||||
for (const c of buffer.toString()) {
|
||||
if (c === '`') {
|
||||
backTick++
|
||||
}
|
||||
const shouldEscape = '{%%}'.includes(c) && backTick % 2 === 0
|
||||
if (shouldEscape) {
|
||||
const code = c.charCodeAt(0).toString(16)
|
||||
process.stdout.write(`&#x${code};`)
|
||||
} else process.stdout.write(c)
|
||||
}
|
||||
})
|
||||
+130
-15
@@ -1,24 +1,139 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
const fs = require('fs/promises')
|
||||
const Liquid = require('..').Liquid
|
||||
const contextArg = process.argv.slice(2)[0]
|
||||
let context = {}
|
||||
|
||||
if (contextArg) {
|
||||
if (contextArg.endsWith('.json')) {
|
||||
const fs = require('fs')
|
||||
context = JSON.parse(fs.readFileSync(contextArg, 'utf8'))
|
||||
// Preserve compatibility by falling back to legacy CLI behavior if:
|
||||
// - stdin is redirected (i.e. not connected to a terminal) AND
|
||||
// - there are either no arguments, or only a single argument which does not start with a dash
|
||||
// TODO: Remove this fallback for 11.0
|
||||
|
||||
let renderPromise = null
|
||||
if (!process.stdin.isTTY && (process.argv.length === 2 || (process.argv.length === 3 && !process.argv[2].startsWith('-')))) {
|
||||
renderPromise = renderLegacy()
|
||||
} else {
|
||||
renderPromise = render()
|
||||
}
|
||||
|
||||
renderPromise.catch(err => {
|
||||
process.stderr.write(`${err.message}\n`)
|
||||
process.exitCode = 1
|
||||
})
|
||||
|
||||
async function render () {
|
||||
const { program } = require('commander')
|
||||
|
||||
program
|
||||
.name('liquidjs')
|
||||
.description('Render a Liquid template')
|
||||
.requiredOption('-t, --template <liquid | @path>', 'liquid template to render (@- to read from stdin)') // TODO: Change to argument in 11.0
|
||||
.option('-c, --context <json | @path>', 'input context in JSON format (@- to read from stdin)')
|
||||
.option('-o, --output <path>', 'write rendered output to file (omit to write to stdout)')
|
||||
.option('--cache [size]', 'cache previously parsed template structures (default cache size: 1024)')
|
||||
.option('--extname <string>', 'use a default filename extension when resolving partials and layouts')
|
||||
.option('--jekyll-include', 'use jekyll-style include (pass parameters to include variable of current scope)')
|
||||
.option('--js-truthy', 'use JavaScript-style truthiness')
|
||||
.option('--layouts <path...>', 'directories from where to resolve layouts (defaults to --root)')
|
||||
.option('--lenient-if', 'do not throw on undefined variables in conditional expressions (when using --strict-variables)')
|
||||
.option('--no-dynamic-partials', 'always treat file paths for partials and layouts as a literal value')
|
||||
.option('--no-greedy', 'disable greedy matching for --trim* options')
|
||||
.option('--no-relative-reference', 'require absolute file paths for partials and layouts')
|
||||
.option('--ordered-filter-parameters', 'respect parameter order when using filters')
|
||||
.option('--output-delimiter-left <string>', 'left delimiter to use for liquid outputs')
|
||||
.option('--output-delimiter-right <string>', 'right delimiter to use for liquid outputs')
|
||||
.option('--partials <path...>', 'directories from where to resolve partials (defaults to --root)')
|
||||
.option('--preserve-timezones', 'preserve input timezone in date filter')
|
||||
.option('--root <path...>', 'directories from where to resolve partials and layouts (defaults to ".")')
|
||||
.option('--strict-filters', 'throw on undefined filters instead of skipping them')
|
||||
.option('--strict-variables', 'throw on undefined variables instead of rendering them as empty string')
|
||||
.option('--tag-delimiter-left', 'left delimiter to use for liquid tags')
|
||||
.option('--tag-delimiter-right', 'right delimiter to use for liquid tags')
|
||||
.option('--timezone-offset <value>', 'JavaScript timezone name or timezoneOffset value to use in date filter (defaults to local timezone)')
|
||||
.option('--trim-output-left', 'trim whitespace from left of liquid outputs')
|
||||
.option('--trim-output-right', 'trim whitespace from right of liquid outputs')
|
||||
.option('--trim-tag-left', 'trim whitespace from left of liquid tags')
|
||||
.option('--trim-tag-right', 'trim whitespace from right of liquid tags')
|
||||
.showHelpAfterError('Use -h or --help for additional information.')
|
||||
.parse()
|
||||
|
||||
const options = program.opts()
|
||||
|
||||
if (Object.values(options).filter((value) => value === '@-').length > 1) {
|
||||
throw new Error(`The stdin input specifier '@-' must only be used once.`)
|
||||
}
|
||||
|
||||
const template = await resolveInputOption(options.template)
|
||||
const context = await resolveContext(options.context)
|
||||
const liquid = new Liquid(options)
|
||||
const output = liquid.parseAndRenderSync(template, context)
|
||||
if (options.output) {
|
||||
await fs.writeFile(options.output, output)
|
||||
} else {
|
||||
context = JSON.parse(contextArg)
|
||||
process.stdout.write(output)
|
||||
}
|
||||
}
|
||||
|
||||
let tpl = ''
|
||||
process.stdin.on('data', chunk => (tpl += chunk))
|
||||
process.stdin.on('end', () => render(tpl))
|
||||
|
||||
async function render (tpl) {
|
||||
const liquid = new Liquid()
|
||||
const html = await liquid.parseAndRender(tpl, context)
|
||||
process.stdout.write(html)
|
||||
async function resolveContext (contextOption) {
|
||||
let contextJson = '{}'
|
||||
if (contextOption) {
|
||||
contextJson = await resolveInputOption(contextOption)
|
||||
}
|
||||
const context = JSON.parse(contextJson)
|
||||
return context
|
||||
}
|
||||
|
||||
async function resolveInputOption (option) {
|
||||
let content = null
|
||||
if (option) {
|
||||
if (option === '@-') {
|
||||
content = await readStream(process.stdin)
|
||||
} else if (option.startsWith('@')) {
|
||||
const filePath = option.slice(1)
|
||||
const stat = await fs.stat(filePath, { throwIfNoEntry: false })
|
||||
if (!stat || !stat.isFile) {
|
||||
throw new Error(`'${filePath}' does not exist or is not a file`)
|
||||
}
|
||||
content = await fs.readFile(filePath, 'utf8')
|
||||
} else {
|
||||
content = option
|
||||
}
|
||||
}
|
||||
return content
|
||||
}
|
||||
|
||||
async function readStream (stream) {
|
||||
const chunks = []
|
||||
for await (const chunk of stream) {
|
||||
chunks.push(chunk)
|
||||
}
|
||||
return Buffer.concat(chunks).toString('utf8')
|
||||
}
|
||||
|
||||
// TODO: Remove for 11.0
|
||||
async function renderLegacy () {
|
||||
process.stderr.write('Reading template from stdin. This mode will be removed in next major version, use --template option instead.\n')
|
||||
const contextArg = process.argv.slice(2)[0]
|
||||
let context = {}
|
||||
if (contextArg) {
|
||||
const contextJson = await resolveInputOptionLegacy(contextArg)
|
||||
context = JSON.parse(contextJson)
|
||||
}
|
||||
const template = await readStream(process.stdin)
|
||||
const liquid = new Liquid()
|
||||
const output = liquid.parseAndRenderSync(template, context)
|
||||
process.stdout.write(output)
|
||||
}
|
||||
|
||||
// TODO: Remove for 11.0
|
||||
async function resolveInputOptionLegacy (option) {
|
||||
let content = null
|
||||
if (option) {
|
||||
const stat = await fs.stat(option).catch(e => null)
|
||||
if (stat && stat.isFile) {
|
||||
content = await fs.readFile(option, 'utf8')
|
||||
} else {
|
||||
content = option
|
||||
}
|
||||
}
|
||||
return content
|
||||
}
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
# Using LiquidJS in ESM
|
||||
|
||||
## Get Started
|
||||
|
||||
```bash
|
||||
cd demo/nodejs
|
||||
npm install
|
||||
npm start
|
||||
```
|
||||
@@ -0,0 +1,30 @@
|
||||
import { Liquid } from 'liquidjs'
|
||||
|
||||
const engine = new Liquid({
|
||||
extname: '.liquid',
|
||||
globals: { title: 'LiquidJS Demo' },
|
||||
// root files for `.render()` and `.parse()`
|
||||
root: process.cwd(),
|
||||
// layout files for `{% layout %}`
|
||||
layouts: process.cwd() + '/layouts',
|
||||
// partial files for `{% include %}` and `{% render %}`
|
||||
partials: process.cwd() + '/partials'
|
||||
})
|
||||
|
||||
const ctx = {
|
||||
todos: ['fork and clone', 'make it better', 'make a pull request']
|
||||
}
|
||||
|
||||
async function main () {
|
||||
console.log('==========renderFile===========')
|
||||
const html = await engine.renderFile('todolist', ctx)
|
||||
console.log(html)
|
||||
|
||||
console.log('===========Streamed===========')
|
||||
const tpls = await engine.parseFile('todolist')
|
||||
engine.renderToNodeStream(tpls, ctx)
|
||||
.on('data', data => process.stdout.write(data))
|
||||
.on('end', () => console.log(''))
|
||||
}
|
||||
|
||||
main()
|
||||
@@ -0,0 +1,7 @@
|
||||
<html>
|
||||
<head><meta name="title" content="{{title}}"></head>
|
||||
<body>
|
||||
{% block %}{% endblock %}
|
||||
{% render "footer.liquid" %}
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"name": "liquidjs-demo-nodejs",
|
||||
"description": "Node.js demo for liquidjs",
|
||||
"private": true,
|
||||
"main": "index.mjs",
|
||||
"scripts": {
|
||||
"start": "node index.mjs"
|
||||
},
|
||||
"dependencies": {
|
||||
"hello-liquid": "^1.0.0",
|
||||
"liquidjs": "^9.28.3"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
<small>{{title}}</small>
|
||||
@@ -0,0 +1 @@
|
||||
<li>{{index}} - {{todo}}</li>
|
||||
@@ -0,0 +1,7 @@
|
||||
{% layout 'html.liquid' %}
|
||||
<h1>{% include "hello-liquid" %}</h1>
|
||||
<ul>
|
||||
{% for todo in todos %}
|
||||
{% render 'todo.liquid' with todo, index: forloop.index%}
|
||||
{% endfor %}
|
||||
</ul>
|
||||
@@ -1,4 +1,4 @@
|
||||
# LiquidJS for Express.js
|
||||
# Using LiquidJS with Express.js
|
||||
|
||||
## Get Started
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
const { Liquid } = require('liquidjs')
|
||||
const { Liquid, Tag, Value } = require('liquidjs')
|
||||
|
||||
const engine = new Liquid({
|
||||
extname: '.liquid',
|
||||
@@ -11,13 +11,13 @@ const engine = new Liquid({
|
||||
partials: './partials'
|
||||
})
|
||||
|
||||
engine.registerTag('header', {
|
||||
parse: function (token) {
|
||||
const [key, val] = token.args.split(':')
|
||||
this[key] = val
|
||||
},
|
||||
render: async function (scope, emitter) {
|
||||
const title = await this.liquid.evalValue(this.content, scope)
|
||||
engine.registerTag('header', class HeaderTag extends Tag {
|
||||
constructor (token, remainTokens, liquid) {
|
||||
super(token, remainTokens, liquid)
|
||||
this.value = new Value(token.args, liquid)
|
||||
}
|
||||
* render (ctx, emitter) {
|
||||
const title = yield this.value.value(ctx)
|
||||
emitter.write(`<h1>${title}</h1>`)
|
||||
}
|
||||
})
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{% layout 'html.liquid' %}
|
||||
{%header content: title | capitalize%}
|
||||
{%header title | capitalize%}
|
||||
<ul>
|
||||
{% for todo in todos %}
|
||||
{% render 'todo.liquid' with todo, index: forloop.index%}
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
# LiquidJS for Node.js
|
||||
|
||||
## Get Started
|
||||
|
||||
```bash
|
||||
cd demo/nodejs
|
||||
npm install
|
||||
npm start
|
||||
```
|
||||
@@ -0,0 +1,25 @@
|
||||
import { Output, Template, Tag } from 'liquidjs'
|
||||
import { isLayoutTag, isIfTag, isUnlessTag, isLiquidTag, isCaseTag, isCaptureTag, isTablerowTag, isForTag } from './type-guards'
|
||||
|
||||
/**
|
||||
* iterate over all `{{ output }}`
|
||||
*/
|
||||
export function * getOutputs (templates: Template[]): Generator<Output, void> {
|
||||
for (const template of templates) {
|
||||
if (template instanceof Tag) {
|
||||
if (isIfTag(template) || isUnlessTag(template) || isCaseTag(template)) {
|
||||
for (const branch of template.branches) {
|
||||
yield * getOutputs(branch.templates)
|
||||
}
|
||||
yield * getOutputs(template.elseTemplates)
|
||||
} else if (isForTag(template)) {
|
||||
yield * getOutputs(template.templates)
|
||||
yield * getOutputs(template.elseTemplates)
|
||||
} else if (isLiquidTag(template) || isCaptureTag(template) || isTablerowTag(template) || isLayoutTag(template)) {
|
||||
yield * getOutputs(template.templates)
|
||||
}
|
||||
} else if (template instanceof Output) {
|
||||
yield template
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
import { Liquid } from 'liquidjs'
|
||||
import { getOutputs } from './get-outputs'
|
||||
|
||||
const engine = new Liquid({
|
||||
root: __dirname,
|
||||
extname: '.liquid'
|
||||
})
|
||||
|
||||
const templates = engine.parseFileSync('todolist')
|
||||
|
||||
for (const output of getOutputs(templates)) {
|
||||
const token = output.token
|
||||
const [line, col] = token.getPosition()
|
||||
const text = token.getText()
|
||||
console.log(`[${line}:${col}] ${text}`)
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"name": "liquidjs-demo-template",
|
||||
"private": true,
|
||||
"description": "liquid template parsing",
|
||||
"main": "index.ts",
|
||||
"scripts": {
|
||||
"start": "ts-node index.ts"
|
||||
},
|
||||
"dependencies": {
|
||||
"liquidjs": "latest",
|
||||
"ts-node": "^8.10.2",
|
||||
"typescript": "^4.2.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^14.14.37"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
{% layout 'html.liquid' %}
|
||||
|
||||
<h1>{{ title | capitalize }}</h1>
|
||||
<a>
|
||||
{% if authed %} Sign out {{ username }}
|
||||
{% else %} Sign in
|
||||
{% endif %}
|
||||
</a>
|
||||
<ul>
|
||||
{% for todo in todos %}
|
||||
<p>{{ todo }}</p>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"downlevelIteration": true,
|
||||
"types": [
|
||||
"node"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
import { LayoutTag, ForTag, LiquidTag, CaptureTag, CaseTag, UnlessTag, TablerowTag, Tag, IfTag } from 'liquidjs'
|
||||
|
||||
export function isIfTag (tag: Tag): tag is IfTag {
|
||||
return tag.name === 'if'
|
||||
}
|
||||
|
||||
export function isUnlessTag (tag: Tag): tag is UnlessTag {
|
||||
return tag.name === 'unless'
|
||||
}
|
||||
|
||||
export function isLiquidTag (tag: Tag): tag is LiquidTag {
|
||||
return tag.name === 'liquid'
|
||||
}
|
||||
|
||||
export function isCaseTag (tag: Tag): tag is CaseTag {
|
||||
return tag.name === 'case'
|
||||
}
|
||||
|
||||
export function isCaptureTag (tag: Tag): tag is CaptureTag {
|
||||
return tag.name === 'capture'
|
||||
}
|
||||
|
||||
export function isTablerowTag (tag: Tag): tag is TablerowTag {
|
||||
return tag.name === 'tablerow'
|
||||
}
|
||||
|
||||
export function isForTag (tag: Tag): tag is ForTag {
|
||||
return tag.name === 'for'
|
||||
}
|
||||
|
||||
export function isLayoutTag (tag: Tag): tag is LayoutTag {
|
||||
return tag.name === 'layout'
|
||||
}
|
||||
+11
-11
@@ -1,25 +1,25 @@
|
||||
import { Liquid, TagToken, Context, Emitter } from 'liquidjs'
|
||||
import { Value, Liquid, TagToken, Context, Emitter, Tag, TopLevelToken } from 'liquidjs'
|
||||
|
||||
const engine = new Liquid({
|
||||
root: __dirname,
|
||||
extname: '.liquid'
|
||||
})
|
||||
|
||||
engine.registerTag('header', {
|
||||
parse: function (token: TagToken) {
|
||||
const [key, val] = token.args.split(':')
|
||||
this[key] = val
|
||||
},
|
||||
render: async function (context: Context, emitter: Emitter) {
|
||||
const title = await this.liquid.evalValue(this['content'], context)
|
||||
engine.registerTag('header', class HeaderTag extends Tag {
|
||||
private value: Value
|
||||
constructor (token: TagToken, remainTokens: TopLevelToken[], liquid: Liquid) {
|
||||
super(token, remainTokens, liquid)
|
||||
this.value = new Value(token.args, liquid)
|
||||
}
|
||||
* render (ctx: Context, emitter: Emitter) {
|
||||
const title = yield this.value.value(ctx)
|
||||
emitter.write(`<h1>${title}</h1>`)
|
||||
}
|
||||
})
|
||||
|
||||
const ctx = {
|
||||
const scope = {
|
||||
todos: ['fork and clone', 'make it better', 'make a pull request'],
|
||||
title: 'Welcome to liquidjs!'
|
||||
}
|
||||
|
||||
// console.log('isTruthy:', isTruthy('a string here'));
|
||||
engine.renderFile('todolist', ctx).then(console.log)
|
||||
engine.renderFile('todolist', scope).then(console.log)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
{%header content: title | capitalize%}
|
||||
{%header title | capitalize%}
|
||||
|
||||
<ul>
|
||||
{% for todo in todos %}
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"types": [
|
||||
"node"
|
||||
]
|
||||
"target": "es6",
|
||||
"moduleResolution": "node",
|
||||
"types": [
|
||||
"node"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
# Using LiquidJS with Webpack
|
||||
|
||||
## Get Started
|
||||
|
||||
```bash
|
||||
cd demo/nodejs
|
||||
npm install
|
||||
npm run build
|
||||
npm start
|
||||
```
|
||||
@@ -0,0 +1,7 @@
|
||||
<html>
|
||||
<head><meta name="title" content="{{title}}"></head>
|
||||
<body>
|
||||
{% block %}{% endblock %}
|
||||
{% render "footer.liquid" %}
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"name": "liquidjs-demo-nodejs",
|
||||
"description": "Node.js demo for liquidjs",
|
||||
"private": true,
|
||||
"main": "dist/index.js",
|
||||
"scripts": {
|
||||
"start": "node dist/index.js",
|
||||
"build": "webpack"
|
||||
},
|
||||
"dependencies": {
|
||||
"hello-liquid": "^1.0.0",
|
||||
"liquidjs": "^9.28.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"webpack": "^5.74.0",
|
||||
"webpack-cli": "^4.10.0"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
<small>{{title}}</small>
|
||||
@@ -0,0 +1 @@
|
||||
<li>{{index}} - {{todo}}</li>
|
||||
@@ -0,0 +1,30 @@
|
||||
import { Liquid } from 'liquidjs'
|
||||
|
||||
const engine = new Liquid({
|
||||
extname: '.liquid',
|
||||
globals: { title: 'LiquidJS Demo' },
|
||||
// root files for `.render()` and `.parse()`
|
||||
root: process.cwd(),
|
||||
// layout files for `{% layout %}`
|
||||
layouts: process.cwd() + '/layouts',
|
||||
// partial files for `{% include %}` and `{% render %}`
|
||||
partials: process.cwd() + '/partials'
|
||||
})
|
||||
|
||||
const ctx = {
|
||||
todos: ['fork and clone', 'make it better', 'make a pull request']
|
||||
}
|
||||
|
||||
async function main () {
|
||||
console.log('==========renderFile===========')
|
||||
const html = await engine.renderFile('todolist', ctx)
|
||||
console.log(html)
|
||||
|
||||
console.log('===========Streamed===========')
|
||||
const tpls = await engine.parseFile('todolist')
|
||||
engine.renderToNodeStream(tpls, ctx)
|
||||
.on('data', data => process.stdout.write(data))
|
||||
.on('end', () => console.log(''))
|
||||
}
|
||||
|
||||
main()
|
||||
@@ -0,0 +1,6 @@
|
||||
{% layout 'html.liquid' %}
|
||||
<ul>
|
||||
{% for todo in todos %}
|
||||
{% render 'todo.liquid' with todo, index: forloop.index%}
|
||||
{% endfor %}
|
||||
</ul>
|
||||
@@ -0,0 +1,15 @@
|
||||
const path = require('path');
|
||||
const { ContextReplacementPlugin } = require('webpack')
|
||||
|
||||
module.exports = {
|
||||
entry: './src/index.js',
|
||||
mode: 'development',
|
||||
target: 'node',
|
||||
plugins: [
|
||||
new ContextReplacementPlugin(/liquidjs/)
|
||||
],
|
||||
output: {
|
||||
filename: 'index.js',
|
||||
path: path.resolve(__dirname, 'dist'),
|
||||
},
|
||||
};
|
||||
+9
-3
@@ -2,7 +2,9 @@ title: LiquidJS
|
||||
subtitle: "A simple, expressive and safe template engine."
|
||||
description: "LiquidJS is a simple, expressive and safe Shopify / Github Pages compatible template engine in pure JavaScript."
|
||||
author: Harttle
|
||||
language: en
|
||||
language:
|
||||
- en
|
||||
- zh-cn
|
||||
timezone: UTC
|
||||
|
||||
url: https://liquidjs.com
|
||||
@@ -17,10 +19,14 @@ pretty_urls:
|
||||
trailing_html: false
|
||||
|
||||
theme: navy
|
||||
|
||||
skip_render: "api/**/*"
|
||||
highlight:
|
||||
enable: false
|
||||
prismjs:
|
||||
enable: true
|
||||
line_number: false
|
||||
preprocess: true
|
||||
line_number: true
|
||||
tab_replace: ''
|
||||
|
||||
algolia:
|
||||
applicationID: 0X19J927JZ
|
||||
|
||||
Generated
+706
-388
File diff suppressed because it is too large
Load Diff
+2
-2
@@ -23,7 +23,7 @@
|
||||
"hexo-renderer-marked": "^2.0.0",
|
||||
"hexo-renderer-pug": "^2.0.0",
|
||||
"hexo-renderer-stylus": "^1.0.0",
|
||||
"hexo-renderer-swig": "^1.1.0",
|
||||
"hexo-renderer-swig": "^2.0.0",
|
||||
"hexo-server": "^1.0.0",
|
||||
"hexo-uglify": "^1.0.0"
|
||||
},
|
||||
@@ -35,4 +35,4 @@
|
||||
"engines": {
|
||||
"node": ">=8.10.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,4 +2,4 @@ tutorials: /tutorials/intro-to-liquid.html
|
||||
tags: /tags/overview.html
|
||||
filters: /filters/overview.html
|
||||
playground: /playground.html
|
||||
api: /api/classes/liquid_.liquid.html
|
||||
api: /api/classes/Liquid.html
|
||||
|
||||
@@ -9,6 +9,10 @@ tutorials:
|
||||
advanced:
|
||||
caching: caching.html
|
||||
registeration: register-filters-tags.html
|
||||
access_scope_in_filters: access-scope-in-filters.html
|
||||
parse_parameters: parse-parameters.html
|
||||
render_tag_content: render-tag-content.html
|
||||
sync_and_async: sync-and-async.html
|
||||
whitespace: whitespace-control.html
|
||||
plugins: plugins.html
|
||||
operators: operators.html
|
||||
@@ -47,10 +51,13 @@ filters:
|
||||
newline_to_br: newline_to_br.html
|
||||
plus: plus.html
|
||||
prepend: prepend.html
|
||||
raw: raw.html
|
||||
remove: remove.html
|
||||
remove_first: remove_first.html
|
||||
remove_last: remove_last.html
|
||||
replace: replace.html
|
||||
replace_first: replace_first.html
|
||||
replace_last: replace_last.html
|
||||
reverse: reverse.html
|
||||
round: round.html
|
||||
rstrip: rstrip.html
|
||||
@@ -73,6 +80,7 @@ filters:
|
||||
|
||||
tags:
|
||||
overview: overview.html
|
||||
"#": inline_comment.html
|
||||
assign: assign.html
|
||||
capture: capture.html
|
||||
case: case.html
|
||||
@@ -80,6 +88,8 @@ tags:
|
||||
cycle: cycle.html
|
||||
decrement: decrement.html
|
||||
echo: echo.html
|
||||
else: if.html
|
||||
elsif: if.html
|
||||
for: for.html
|
||||
if: if.html
|
||||
include: include.html
|
||||
@@ -90,6 +100,7 @@ tags:
|
||||
render: render.html
|
||||
tablerow: tablerow.html
|
||||
unless: unless.html
|
||||
when: case.html
|
||||
|
||||
api:
|
||||
quick_entry:
|
||||
|
||||
+43
-40
@@ -1,63 +1,66 @@
|
||||
---
|
||||
title: date
|
||||
---
|
||||
|
||||
{% since %}v1.9.1{% endsince %}
|
||||
|
||||
Converts a timestamp into another date format. LiquidJS tries to be conformant with Shopify/Liquid which is using Ruby's core [Time#strftime(string)](http://www.ruby-doc.org/core/Time.html#method-i-strftime). The input is firstly converted to `Date` object via [new Date()][newDate].
|
||||
# Format
|
||||
* Converts a timestamp into another date format
|
||||
* LiquidJS tries to be conformant with Shopify/Liquid which is using Ruby's core [Time#strftime(string)](http://www.ruby-doc.org/core/Time.html#method-i-strftime)
|
||||
* Refer [format flags](https://ruby-doc.org/core/strftime_formatting_rdoc.html)
|
||||
* Not all options are supported though - refer [differences here](/tutorials/differences.html#Differences)
|
||||
* The input is firstly converted to `Date` object via [new Date()][jsDate]
|
||||
* Date format can be provided individually as a filter option
|
||||
* If not provided, then `%A, %B %-e, %Y at %-l:%M %P %z` format will be used as default format
|
||||
* Override this using [`dateFormat`](/api/interfaces/LiquidOptions.html#dateFormat) LiquidJS option, to set your preferred default format for all date filters
|
||||
|
||||
Input
|
||||
### Examples
|
||||
```liquid
|
||||
{{ article.published_at | date: "%a, %b %d, %y" }}
|
||||
{{ article.published_at | date: '%a, %b %d, %y' }} => Fri, Jul 17, 15
|
||||
{{ "now" | date: "%Y-%m-%d %H:%M" }} => 2020-03-25 15:57
|
||||
|
||||
// equivalent to setting options.dateFormat = %d%q of %b %Y at %I:%M %P %Z
|
||||
{{ '1990-12-31T23:30:28Z' | date: '%d%q of %b %Y at %I:%M %P %Z', -330 }} => 01st of Jan 1991 at 05:00 am +0530;
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
Fri, Jul 17, 15
|
||||
```
|
||||
# TimeZone
|
||||
* By default, dates will be converted to local timezone before output
|
||||
* You can override that by,
|
||||
* setting a timezone for each individual `date` filter via the second parameter
|
||||
* using the [`timezoneOffset`](/api/interfaces/LiquidOptions.html#timezoneOffset) LiquidJS option
|
||||
* Its default value is your local timezone offset which can be obtained by `new Date().getTimezoneOffset()`
|
||||
* Offset can be set as,
|
||||
* minutes: `-360` means `'+06:00'` and `360` means `'-06:00'`
|
||||
* timeZone ID: `Asia/Colombo` or `America/New_York`
|
||||
* Use minutes for better performance with repeated processing of templates with many dates like, converting template for each email recipient
|
||||
* Refer [here](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones) for TZ database values
|
||||
|
||||
{% note info TimeZone %}
|
||||
Date will be converted to local time before output. To avoid that, you can set `timezoneOffset` LiquidJS option to `0`, its default value is your local timezone offset which can be obtained by `new Date().getTimezoneOffset()`.
|
||||
{% endnote %}
|
||||
|
||||
Input
|
||||
### Examples
|
||||
```liquid
|
||||
{{ article.published_at | date: "%Y" }}
|
||||
// equivalent to setting `options.timezoneOffset` to `360`
|
||||
{{ "1990-12-31T23:00:00Z" | date: "%Y-%m-%dT%H:%M:%S", 360 }} => 1990-12-31T17:00:00
|
||||
{{ "1990-12-31T23:00:00Z" | date: "%Y-%m-%dT%H:%M:%S", "Asia/Colombo" }} => 1991-01-01T04:30:00
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
2015
|
||||
```
|
||||
|
||||
`date` works on strings if they contain well-formatted dates:
|
||||
# Input
|
||||
* `date` works on strings if they contain well-formatted dates
|
||||
* Note that LiquidJS is using [JavaScript Date][jsDate] to parse the input string, that means [IETF-compliant RFC 2822 timestamps](https://datatracker.ietf.org/doc/html/rfc2822#page-14) and strings in [a version of ISO8601](https://www.ecma-international.org/ecma-262/11.0/#sec-date.parse) are supported.
|
||||
|
||||
Input
|
||||
### Examples
|
||||
```liquid
|
||||
{{ "March 14, 2016" | date: "%b %d, %y" }}
|
||||
{{ "1990-12-31T23:00:00Z" | date: "%Y-%m-%dT%H:%M:%S", 360 }} => 1990-12-31T17:00:00
|
||||
{{ "March 14, 2016" | date: "%b %d, %y" }} => Mar 14, 16
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
Mar 14, 16
|
||||
```
|
||||
|
||||
{% note info Timestamp Strings %}
|
||||
Note that LiquidJS is using JavaScript [Date][newDate] to parse the input string, that means [IETF-compliant RFC 2822 timestamps](https://datatracker.ietf.org/doc/html/rfc2822#page-14) and strings in [a version of ISO8601](https://www.ecma-international.org/ecma-262/11.0/#sec-date.parse) are supported.
|
||||
{% endnote %}
|
||||
# Current Date
|
||||
* To get the current time, pass the special word `"now"` or `"today"` as input
|
||||
* 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
|
||||
|
||||
To get the current time, pass the special word `"now"` (or `"today"`) to `date`:
|
||||
|
||||
Input
|
||||
### Example
|
||||
```liquid
|
||||
This page was last updated at {{ "now" | date: "%Y-%m-%d %H:%M" }}.
|
||||
Last updated on: {{ "now" | date: "%Y-%m-%d %H:%M" }} => Last updated on: 2020-03-25 15:57
|
||||
Last updated on: {{ "today" | date: "%Y-%m-%d %H:%M" }} => Last updated on: 2020-03-25 15:57
|
||||
```
|
||||
|
||||
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
|
||||
[jsDate]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date
|
||||
|
||||
@@ -26,6 +26,23 @@ Output
|
||||
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 %}
|
||||
In JavaScript, float and integer shares the same type `number` and we cannot tell the difference. For example:
|
||||
|
||||
```javascript
|
||||
// always true
|
||||
5.0 === 5
|
||||
```
|
||||
|
||||
You'll need to pass another `integerArithmetic` argument to enforce integer divide:
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{{ 5 | divided_by: 3, true }}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
1
|
||||
```
|
||||
|
||||
[floor]: ./floor.html
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
---
|
||||
title: Filters
|
||||
description: Description and demo for each Liquid filter
|
||||
---
|
||||
|
||||
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.
|
||||
@@ -8,10 +9,11 @@ There's 40+ filters supported by LiquidJS. These filters can be categorized into
|
||||
|
||||
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
|
||||
Math | plus, minus, modulo, times, floor, ceil, round, divided_by, abs, at_least, at_most
|
||||
String | append, prepend, capitalize, upcase, downcase, strip, lstrip, rstrip, strip_newlines, split, replace, replace_first, replace_last,remove, remove_first, remove_last, truncate, truncatewords
|
||||
HTML/URI | escape, escape_once, url_encode, url_decode, strip_html, newline_to_br
|
||||
Array | slice, map, sort, sort_natural, uniq, where, first, last, join, reverse, concat
|
||||
Array | slice, map, sort, sort_natural, uniq, where, first, last, join, reverse, concat, compact, size
|
||||
Date | date
|
||||
Misc | default, json, raw
|
||||
|
||||
[shopify/liquid]: https://github.com/Shopify/liquid
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
---
|
||||
title: raw
|
||||
---
|
||||
|
||||
{% since %}v9.37.0{% endsince %}
|
||||
|
||||
Liquid filter that directly returns the value of the variable. Useful when [outputEscape](/api/interfaces/LiquidOptions.html#outputEscape) is set.
|
||||
|
||||
{% note info Auto escape %}
|
||||
By default `outputEscape` is not set. That means LiquidJS output is not escaped by default, thus `raw` filter is not useful until `outputEscape` is set.
|
||||
{% endnote %}
|
||||
|
||||
Input (`outputEscape` not set)
|
||||
```liquid
|
||||
{{ "<" }}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
<
|
||||
```
|
||||
|
||||
Input (`outputEscape="escape"`)
|
||||
```liquid
|
||||
{{ "<" }}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
<
|
||||
```
|
||||
|
||||
Input (`outputEscape="json"`)
|
||||
```liquid
|
||||
{{ "<" }}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
"<"
|
||||
```
|
||||
|
||||
Input (`outputEscape="escape"`)
|
||||
```liquid
|
||||
{{ "<" | raw }}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
<
|
||||
```
|
||||
@@ -13,5 +13,5 @@ Input
|
||||
|
||||
Output
|
||||
```text
|
||||
I strained to see the t through the
|
||||
I sted to see the t through the
|
||||
```
|
||||
|
||||
@@ -13,5 +13,5 @@ Input
|
||||
|
||||
Output
|
||||
```text
|
||||
I strained to see the t through the rain
|
||||
I sted to see the train through the rain
|
||||
```
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
---
|
||||
title: remove_last
|
||||
---
|
||||
|
||||
{% since %}v10.2.0{% endsince %}
|
||||
|
||||
Removes only the last occurrence of the specified substring from a string.
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{{ "I strained to see the train through the rain" | remove_last: "rain" }}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
I strained to see the train through the
|
||||
```
|
||||
@@ -0,0 +1,17 @@
|
||||
---
|
||||
title: replace_last
|
||||
---
|
||||
|
||||
{% since %}v10.2.0{% endsince %}
|
||||
|
||||
Replaces only the last occurrence of the first argument in a string with the second argument.
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{{ "Take my protein pills and put my helmet on" | replace_last: "my", "your" }}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
Take my protein pills and put your helmet on
|
||||
```
|
||||
@@ -14,5 +14,5 @@ Input
|
||||
|
||||
Output
|
||||
```text
|
||||
|
||||
ants, bugs, bees```
|
||||
ants, bugs, bees
|
||||
```
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
{
|
||||
"short_name": "LiquidJS",
|
||||
"name": "LiquidJS",
|
||||
"description": "A simple, expressive and safe Shopify / Github Pages compatible template engine in pure JavaScript.",
|
||||
"icons": [
|
||||
{
|
||||
"src": "/icon/apple-touch-icon-57x57.png",
|
||||
@@ -23,6 +24,33 @@
|
||||
"sizes": "512x512"
|
||||
}
|
||||
],
|
||||
"shortcuts" : [
|
||||
{
|
||||
"name": "Tutorials",
|
||||
"url": "/tutorials/intro-to-liquid.html",
|
||||
"description": "A set of articles describing how to use LiquidJS"
|
||||
},
|
||||
{
|
||||
"name": "Tags",
|
||||
"url": "/tags/overview.html",
|
||||
"description": "Description and demo for each Liquid tag"
|
||||
},
|
||||
{
|
||||
"name": "Filters",
|
||||
"url": "/filters/overview.html",
|
||||
"description": "Description and demo for each Liquid filter"
|
||||
},
|
||||
{
|
||||
"name": "Playground",
|
||||
"url": "/playground.html",
|
||||
"description": "An online code editor to try out and share Liquid templates"
|
||||
},
|
||||
{
|
||||
"name": "API",
|
||||
"url": "/api/classes/Liquid.html",
|
||||
"description": "TypeScript doc for LiquidJS classes and interfaces"
|
||||
}
|
||||
],
|
||||
"start_url": "/",
|
||||
"display": "standalone",
|
||||
"theme_color": "#0f83ce",
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
---
|
||||
layout: playground
|
||||
title: Playground
|
||||
description: An online code editor to try out and share Liquid templates
|
||||
---
|
||||
|
||||
+9
-2
@@ -9,6 +9,7 @@ const urlsToCache = [
|
||||
'/fonts/icomoon.ttf?e8nnma'
|
||||
]
|
||||
const blackList = [
|
||||
/chrome-extension:/,
|
||||
/google-analytics.com.*collect/
|
||||
]
|
||||
|
||||
@@ -29,8 +30,14 @@ self.addEventListener('fetch', event => {
|
||||
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))
|
||||
if (event.request.url.match(/\.githubusercontent\.com/)) {
|
||||
// cache first
|
||||
const pn = networkAndSave(event.request)
|
||||
event.respondWith(cache(event.request).then(res => res || pn).catch(() => pn))
|
||||
} else {
|
||||
// network first
|
||||
event.respondWith(networkAndSave(event.request).catch(() => cache(event.request)))
|
||||
}
|
||||
})
|
||||
|
||||
function cache (req) {
|
||||
|
||||
+62
-20
@@ -66,17 +66,17 @@ Causes the loop to stop iterating when it encounters the `break` tag.
|
||||
Input
|
||||
```liquid
|
||||
{% for i in (1..5) %}
|
||||
{% if i == 4 %}
|
||||
{%- if i == 4 -%}
|
||||
{% break %}
|
||||
{% else %}
|
||||
{%- else -%}
|
||||
{{ i }}
|
||||
{% endif %}
|
||||
{%- endif -%}
|
||||
{% endfor %}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
1 2 3
|
||||
123
|
||||
```
|
||||
|
||||
### continue
|
||||
@@ -86,17 +86,17 @@ Causes the loop to skip the current iteration when it encounters the `continue`
|
||||
Input
|
||||
```liquid
|
||||
{% for i in (1..5) %}
|
||||
{% if i == 4 %}
|
||||
{% continue %}
|
||||
{% else %}
|
||||
{%- if i == 4 -%}
|
||||
{%- continue -%}
|
||||
{%- else -%}
|
||||
{{ i }}
|
||||
{% endif %}
|
||||
{%- endif -%}
|
||||
{% endfor %}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
1 2 3 5
|
||||
1235
|
||||
```
|
||||
|
||||
### forloop
|
||||
@@ -152,15 +152,15 @@ Limits the loop to the specified number of iterations.
|
||||
|
||||
Input
|
||||
```liquid
|
||||
<!-- if array = [1,2,3,4,5,6] -->
|
||||
<!-- for array = [1,2,3,4,5,6] -->
|
||||
{% for item in array limit:2 %}
|
||||
{{ item }}
|
||||
{{- item -}}
|
||||
{% endfor %}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
1 2
|
||||
12
|
||||
```
|
||||
|
||||
### offset
|
||||
@@ -169,15 +169,57 @@ Begins the loop at the specified index.
|
||||
|
||||
Input
|
||||
```liquid
|
||||
<!-- if array = [1,2,3,4,5,6] -->
|
||||
<!-- for array = [1,2,3,4,5,6] -->
|
||||
{% for item in array offset:2 %}
|
||||
{{ item }}
|
||||
{{- item -}}
|
||||
{% endfor %}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
3 4 5 6
|
||||
3456
|
||||
```
|
||||
|
||||
#### offset:continue
|
||||
|
||||
{% since %}v9.33.0{% endsince %}
|
||||
|
||||
Offset value can be `continue` to continue previous loop. For example:
|
||||
|
||||
Input
|
||||
```liquid
|
||||
<!-- for array = [1,2,3,4,5,6] -->
|
||||
{% for item in array limit:2 %}
|
||||
{{- item -}}
|
||||
{% endfor%}
|
||||
{% for item in array offset:continue %}
|
||||
{{- item -}}
|
||||
{% endfor%}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
12
|
||||
3456
|
||||
```
|
||||
|
||||
For the same variable name (`"item"` in this case) and same collection (`"array"` in this case), there's one position record. That means you can start a new loop with a different variable name:
|
||||
|
||||
Input
|
||||
```liquid
|
||||
<!-- for array = [1,2,3,4,5,6] -->
|
||||
{% for item in array limit:2 %}
|
||||
{{- item -}}
|
||||
{% endfor%}
|
||||
{% for item2 in array offset:continue %}
|
||||
{{- item2 -}}
|
||||
{% endfor%}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
12
|
||||
123456
|
||||
```
|
||||
|
||||
### range
|
||||
@@ -187,19 +229,19 @@ Defines a range of numbers to loop through. The range can be defined by both lit
|
||||
Input
|
||||
```liquid
|
||||
{% for i in (3..5) %}
|
||||
{{ i }}
|
||||
{% endfor %}
|
||||
{{- i -}}
|
||||
{% endfor-%}
|
||||
|
||||
{% assign num = 4 %}
|
||||
{% for i in (1..num) %}
|
||||
{{ i }}
|
||||
{{- i -}}
|
||||
{% endfor %}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
3 4 5
|
||||
1 2 3 4
|
||||
345
|
||||
1234
|
||||
```
|
||||
|
||||
### reversed
|
||||
|
||||
@@ -53,12 +53,12 @@ When filename is specified as literal string, it supports Liquid output and filt
|
||||
```
|
||||
|
||||
{% note info Escaping %}
|
||||
In LiquidJS, `"` within quoted string literals need to be escaped. Adding a slash before the quote, e.g. `\"`. Using Jekyll-like filenames can make this easier, see below.
|
||||
In LiquidJS, `"` within quoted string literals need to be escaped by adding a slash before the quote, e.g. `\"`. Using Jekyll-like filenames can make this easier, see below.
|
||||
{% endnote %}
|
||||
|
||||
## Jekyll-like filenames
|
||||
|
||||
Setting [dynamicPartials][dynamicPartials] to `false` will enable Jekyll-like includes, file names are specified as literal string. And it also supports Liquid outputs and filters.
|
||||
Setting [dynamicPartials][dynamicPartials] to `false` will enable Jekyll-like filenames, where file names are specified as literal string without surrounding quotes. Liquid outputs and filters are also supported within that, for example:
|
||||
|
||||
```liquid
|
||||
{% include prefix/{{ page.my_variable }}/suffix %}
|
||||
@@ -70,6 +70,41 @@ This way, you don't need to escape `"` in the filename expression.
|
||||
{% include prefix/{{name | append: ".html"}} %}
|
||||
```
|
||||
|
||||
[extname]: ../api/interfaces/liquid_options_.liquidoptions.html#Optional-extname
|
||||
[root]: ../api/interfaces/liquid_options_.liquidoptions.html#Optional-root
|
||||
[dynamicPartials]: ../api/interfaces/liquid_options_.liquidoptions.html#dynamicPartials
|
||||
## Jekyll include
|
||||
|
||||
{% since %}v9.33.0{% endsince %}
|
||||
|
||||
[jekyllInclude][jekyllInclude] is used to enable Jekyll-like include syntax. Defaults to `false`, when set to `true`:
|
||||
|
||||
- Filename will be static: `dynamicPartials` now defaults to `false` (instead of `true`). And you can set `dynamicPartials` back to `true`.
|
||||
- Use `=` instead of `:` to separate parameter key-values.
|
||||
- Parameters are under `include` variable instead of current scope.
|
||||
|
||||
For example, the following template:
|
||||
|
||||
```liquid
|
||||
{% include article.html header="HEADER" content="CONTENT" %}
|
||||
```
|
||||
|
||||
`article.html` with following content:
|
||||
|
||||
```liquid
|
||||
<article>
|
||||
<header>{{include.header}}</header>
|
||||
{{include.content}}
|
||||
</article>
|
||||
```
|
||||
|
||||
Note that we're referencing the first parameter by `include.header` instead of `header`. Will output following:
|
||||
|
||||
```html
|
||||
<article>
|
||||
<header>HEADER</header>
|
||||
CONTENT
|
||||
</article>
|
||||
```
|
||||
|
||||
[extname]: /api/interfaces/LiquidOptions.html#extname
|
||||
[root]: /api/interfaces/LiquidOptions.html#root
|
||||
[dynamicPartials]: /api/interfaces/LiquidOptions.html#dynamicPartials
|
||||
[jekyllInclude]: /api/interfaces/LiquidOptions.html#jekyllInclude
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
---
|
||||
title: "# (inline comment)"
|
||||
---
|
||||
|
||||
{% since %}v9.38.0{% endsince %}
|
||||
|
||||
Add comments to a Liquid template using an inline tag. Text enclosed in an inline comment tag will not be printed.
|
||||
|
||||
Input
|
||||
```liquid
|
||||
Anything inside an inline comment tag will not be printed.
|
||||
{% # this is an inline comment %}
|
||||
But every line must start with a '#'.
|
||||
{%
|
||||
# this is a comment
|
||||
# that spans multiple lines
|
||||
%}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
Anything inside an inline comment tag will not be printed.
|
||||
But every line must start with a '#'.
|
||||
```
|
||||
|
||||
Inline comments are useful inside <a href="./liquid.html">`liquid`</a> tags too.
|
||||
|
||||
```liquid
|
||||
{% liquid
|
||||
# required args
|
||||
assign product = collection.products.first
|
||||
|
||||
# optional args
|
||||
assign should_show_border = should_show_border | default: true
|
||||
assign should_highlight = should_highlight | default: false
|
||||
%}
|
||||
```
|
||||
|
||||
But they don't work well for commenting out blocks of Liquid code. The <a href="./comment.html">`comment`</a> block tag is the better option when you need to temporarily stop other tags from being executed.
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{%- # {% echo 'Welcome to LiquidJS!' %} -%}
|
||||
{% comment %}{% echo 'Welcome to LiquidJS!' %}{% endcomment %}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
-%}
|
||||
```
|
||||
@@ -101,7 +101,7 @@ This way, you don't need to escape `"` in the filename expression.
|
||||
{% layout prefix/{{name | append: ".html"}} %}
|
||||
```
|
||||
|
||||
[extname]: ../api/interfaces/liquid_options_.liquidoptions.html#Optional-extname
|
||||
[root]: ../api/interfaces/liquid_options_.liquidoptions.html#Optional-root
|
||||
[layouts]: ../api/interfaces/liquid_options_.liquidoptions.html#Optional-layouts
|
||||
[dynamicPartials]: ../api/interfaces/liquid_options_.liquidoptions.html#dynamicPartials
|
||||
[extname]: /api/interfaces/LiquidOptions.html#extname
|
||||
[root]: /api/interfaces/LiquidOptions.html#root
|
||||
[layouts]: /api/interfaces/LiquidOptions.html#layouts
|
||||
[dynamicPartials]: /api/interfaces/LiquidOptions.html#dynamicPartials
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
---
|
||||
title: Tags
|
||||
description: Description and demo for each Liquid tag
|
||||
---
|
||||
|
||||
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.
|
||||
@@ -10,8 +11,8 @@ Category | Purpose | Tags
|
||||
--- | --- | ---
|
||||
Iteration | iterate over a collection | for, cycle, tablerow
|
||||
Control Flow | control the execution branch of template rendering | if, unless, elsif, else, case, when
|
||||
Variable | define and alter variables | assign, increment, decrement
|
||||
Variable | define and alter variables | assign, increment, decrement, capture, echo
|
||||
File | include another template or extend a layout template | render, include, layout
|
||||
Language | temporarily disable LiquidJS syntax | raw, comment
|
||||
Language | temporarily disable LiquidJS syntax | # (inline comment), raw, comment, liquid
|
||||
|
||||
[shopify/liquid]: https://github.com/Shopify/liquid
|
||||
|
||||
@@ -94,8 +94,8 @@ In the example above, the partial template will be rendered once for each `varia
|
||||
{% 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
|
||||
[partials]: ../api/interfaces/liquid_options_.liquidoptions.html#Optional-partials
|
||||
[globals]: ../api/interfaces/liquid_options_.liquidoptions.html#Optional-globals
|
||||
[dynamicPartials]: ../api/interfaces/liquid_options_.liquidoptions.html#dynamicPartials
|
||||
[extname]: /api/interfaces/LiquidOptions.html#extname
|
||||
[root]: /api/interfaces/LiquidOptions.html#root
|
||||
[partials]: /api/interfaces/LiquidOptions.html#partials
|
||||
[globals]: /api/interfaces/LiquidOptions.html#globals
|
||||
[dynamicPartials]: /api/interfaces/LiquidOptions.html#dynamicPartials
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
---
|
||||
title: Access Scope in Filters
|
||||
---
|
||||
|
||||
As covered in [Register Filters/Tags][register-filters], we can access filter arguments directly in filter function like:
|
||||
|
||||
```javascript
|
||||
// Usage: {{ 1 | add: 2, 3 }}
|
||||
// Output: 6
|
||||
engine.registerFilter('add', (initial, arg1, arg2) => initial + arg1 + arg2)
|
||||
```
|
||||
|
||||
When it comes to stateful filters, for example transform a URL path to full URL, we'll need to access a `origin` in current scope:
|
||||
|
||||
```javascript
|
||||
// Usage: {{ '/index.html' | fullURL }}
|
||||
// Scope: { origin: "https://liquidjs.com" }
|
||||
// Output: https://liquidjs.com/index.html
|
||||
|
||||
engine.registerFilter('fullURL', function (path) {
|
||||
const origin = this.context.get(['origin'])
|
||||
return new URL(path, origin).toString()
|
||||
})
|
||||
```
|
||||
|
||||
See this JSFiddle: <http://jsfiddle.net/ctj364up/1/>
|
||||
|
||||
{% note warn Arrow Functions %}
|
||||
<code>this</code> in arrow functions is bound to current JavaScript context, you'll need to use <code>function(){}</code> instead of <code>()=>{}</code> syntax to access <code>this.context</code> correctly.
|
||||
{% endnote %}
|
||||
|
||||
[register-filters]: /tutorials/register-filters-tags.html
|
||||
@@ -47,9 +47,9 @@ engine.renderFileSync('hello', {name: 'alice'})
|
||||
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
|
||||
[parse]: /api/classes/Liquid.html#parse
|
||||
[cache]: /api/interfaces/LiquidOptions.html#cache
|
||||
[parseFile]: /api/classes/Liquid.html#parseFile
|
||||
[parseFileSync]: /api/classes/Liquid.html#parseFileSync
|
||||
[renderFile]: /api/classes/Liquid.html#renderFile
|
||||
[renderFileSync]: /api/classes/Liquid.html#renderFileSync
|
||||
|
||||
@@ -2,23 +2,17 @@
|
||||
title: Contribution Guideline
|
||||
---
|
||||
|
||||
## Star on Github 👉 [][liquidjs]
|
||||
## 👉👉👉 Star LiquidJS [][liquidjs]
|
||||
|
||||
Starring LiquidJS is the most important and easiest way to support us: boost its rank and expose it to more people, which in turn makes it better.
|
||||
|
||||
## 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:
|
||||
Getting started and building is described in [CONTRIBUTING.md](https://github.com/harttle/liquidjs/blob/master/CONTRIBUTING.md).
|
||||
|
||||
```bash
|
||||
npm run lint
|
||||
```
|
||||
**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.
|
||||
|
||||
**Testing**: Make sure test cases pass with your patch merged:
|
||||
|
||||
```bash
|
||||
npm test
|
||||
```
|
||||
**Testing**: Make sure test cases pass with your patch merged by running `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.
|
||||
|
||||
@@ -26,14 +20,19 @@ npm test
|
||||
|
||||
## Financial Support
|
||||
|
||||
LiquidJS is Open Source and Free. To help it live and thrive, please consider contribute on [Open Collective][oc] or [Patreon][pt]. To acknowledge your contribution, your name and avatar will be listed here, [homepage](https://liquidjs.com/) for LiquidJS and on [Github README][liquidjs].
|
||||
LiquidJS is Open Source and Free. To help it live and thrive, please consider contribute on [Open Collective][oc]. To acknowledge your contribution, your name and avatar will be listed here, on LiquidJS [homepage](https://liquidjs.com/) and on [Github README][liquidjs]. Please provide your Github ID by openning an issue or contacting me through Twitter (harttleharttle), I can help add you into [the contributors table](https://github.com/harttle/liquidjs#contributors-).
|
||||
|
||||
<object type="image/svg+xml" data="https://opencollective.com/liquidjs/tiers/backer.svg?avatarHeight=72"></object>
|
||||
### Backers
|
||||
If you personally like LiquidJS and find it's useful to you, you can become a backer!
|
||||
|
||||
[](https://www.patreon.com/bePatron?u=32321060)
|
||||
<object type="image/svg+xml" data="https://opencollective.com/liquidjs/backers.svg?avatarHeight=72"></object>
|
||||
|
||||
[oc]: https://opencollective.com/liquidjs/
|
||||
[pt]: https://www.patreon.com/harttle
|
||||
### Sponsors
|
||||
If LiquidJS is benefiting your business/company, please sponsor us to make it better!
|
||||
|
||||
<object type="image/svg+xml" data="https://opencollective.com/liquidjs/sponsors.svg?avatarHeight=72"></object>
|
||||
|
||||
[oc]: https://opencollective.com/liquidjs/contribute/backer-10665/checkout
|
||||
[shopify/liquid]: https://shopify.github.io/liquid/
|
||||
[caniuse-promises]: http://caniuse.com/#feat=promises
|
||||
[pp]: https://github.com/taylorhakes/promise-polyfill
|
||||
|
||||
@@ -2,7 +2,25 @@
|
||||
title: Differences with Shopify/liquid
|
||||
---
|
||||
|
||||
All filters and tags in [shopify/liquid](https://github.com/Shopify/liquid) are supposed to be built in LiquidJS, but not those business-logic specific tags/filters which are typically from Shopify themes (see [Plugins List][plugins] in case you're looking for them and feel free to add yours to the list). Though being compatible the Ruby version is one of our priorities, there are still some differences:
|
||||
## Compatibility
|
||||
|
||||
Being compatible the Ruby version is one of our priorities. Liquid language is originally [implemented in Ruby][ruby-liquid] and used by Shopify, Jekyll and thus Github Pages, as you can see it's one of the most popular template engines in Ruby. There're lots of people using LiquidJS to serve their templates originally written for Shopify themes and Jekyll sites.
|
||||
|
||||
So "being compatible" means serve developers from Shopify and Jekyll well:
|
||||
|
||||
- **Well-formed Liquid template should work just fine in LiquidJS**. For example, `forloop.index` should be 1-indexed, `nil` should be rendered as empty string rather than `undefined`, etc. Although some features (e.g. [#236][#236]) are not feasible in JavaScript, at least we're trying to implement all the semantics of Liquid language.
|
||||
- **All filters and tags in [shopify/liquid][ruby-liquid] are supposed to be built in LiquidJS**. But not those business-logic specific tags/filters typically defined by Shopify platform. Those features should be maintained as [plugins][plugins]. For filters/tags that are not business-logic specific, like `{% layout %}`, and extremely useful, feel free to file an issue.
|
||||
|
||||
In the meantime, it's now implemented in JavaScript, that means it has to be more powerful:
|
||||
|
||||
* **Async as first-class citizen**. Filters and tags can be implemented asynchronously by return a `Promise`.
|
||||
* **Also can be sync**. For scenarios that are not I/O intensive, render synchronously can be much faster. You can call synchronous APIs like `.renderSync()` as long as all the filters and tags in template support to be rendered synchronously. All builtin filters/tags support both sync and async render.
|
||||
* **[Abstract file system][afs]**. Along with async feature, LiquidJS can be used to serve templates stored in Databases [#414][#414], on remote HTTP server [#485][#485], and so on.
|
||||
* **Additional tags and filters** like `layout` and `json`.
|
||||
|
||||
## Differences
|
||||
|
||||
Though we're trying to be compatible with the Ruby version, there are still some differences:
|
||||
|
||||
* Truthy and Falsy. All values except `undefined`, `null`, `false` are truthy, whereas in Ruby Liquid all except `nil` and `false` are truthy. See [#26][#26].
|
||||
* Number. In JavaScript we cannot distinguish or convert between `float` and `integer`, see [#59][#59]. And when applied `size` filter, numbers always return 0, which is 8 for integer in ruby, cause they do not have a `length` property.
|
||||
@@ -11,11 +29,21 @@ All filters and tags in [shopify/liquid](https://github.com/Shopify/liquid) are
|
||||
* Iteration order for objects. The iteration order of JavaScript objects, and thus LiquidJS objects, is a combination of the insertion order for string keys, and ascending order for number-like keys, while the iteration order of Ruby Hash is simply the insertion order.
|
||||
* Sort stability. The [sort][sort] stability is also not defined in both shopify/liquid and LiquidJS, but it's [considered stable][stable-sort] for LiquidJS in Node.js 12+ and Google Chrome 70+.
|
||||
* Trailing unmatched characters inside filters are allowed in shopify/liquid but not in LiquidJS. It means filter arguments without a colon like `{%raw%}{{ "a b" | split " "}}{%endraw%}` will throw an error in LiquidJS. This is intended to improve Liquid usability, see [#208][#208] and [#212][#212].
|
||||
* LiquidJS has additional tags: [layout][layout] and corresponding `block` tag.
|
||||
* LiquidJS [date][date] filter supports `%q` for date ordinals like `{{ '2023/02/02' | date: '%d%q of %b'}}` => `02nd of Feb`
|
||||
|
||||
[date]: https://liquidjs.com/filters/date.html
|
||||
[layout]: https://liquidjs.com/tags/layout.html
|
||||
[json]: https://liquidjs.com/filters/json.html
|
||||
[#26]: https://github.com/harttle/liquidjs/pull/26
|
||||
[#59]: https://github.com/harttle/liquidjs/issues/59
|
||||
[#208]: https://github.com/harttle/liquidjs/issues/208
|
||||
[#212]: https://github.com/harttle/liquidjs/issues/212
|
||||
[#236]: https://github.com/harttle/liquidjs/issues/236
|
||||
[#414]: https://github.com/harttle/liquidjs/discussions/414
|
||||
[#485]: https://github.com/harttle/liquidjs/discussions/485
|
||||
[sort]: https://liquidjs.com/filters/sort.html
|
||||
[stable-sort]: https://v8.dev/features/stable-sort
|
||||
[plugins]: ./plugins.html#Plugin-List
|
||||
[ruby-liquid]: https://github.com/Shopify/liquid
|
||||
[afs]: https://liquidjs.com/tutorials/render-file.html#Abstract-File-System
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
---
|
||||
title: The Liquid Template Language
|
||||
describe: A short introduction to the Liquid template language and some simple demos.
|
||||
---
|
||||
|
||||
LiquidJS is a simple, expressive and safe [Shopify][shopify/liquid] / Github Pages compatible template engine in pure JavaScript. The purpose of this repo is to provide a standard Liquid implementation for the JavaScript community. Liquid is originally implemented in Ruby and used by Github Pages, Jekyll and Shopify, see [Differences with Shopify/liquid][diff].
|
||||
|
||||
@@ -12,7 +12,7 @@ const engine = new Liquid({
|
||||
```
|
||||
|
||||
{% note info API Document %}
|
||||
Following is an overview for all the options, for exact types and signatures please refer to <a href="https://liquidjs.com/api/interfaces/liquid_options_.liquidoptions.html" target="_self">LiquidOptions | API</a>.
|
||||
Following is an overview for all the options, for exact types and signatures please refer to <a href="https://liquidjs.com/api/interfaces/LiquidOptions.html" target="_self">LiquidOptions | API</a>.
|
||||
{% endnote %}
|
||||
|
||||
## cache
|
||||
@@ -52,6 +52,29 @@ Setting `dynamicPartials: false`, LiquidJS will try to include the file named `f
|
||||
{% note warn Common Pitfall %}
|
||||
LiquidJS defaults this option to <code>true</code> to be compatible with shopify/liquid, but if you're from <a href="https://github.com/11ty/eleventy" target="_blank">eleventy</a> it's set to <code>false</code> by default (see <a href="https://www.11ty.dev/docs/languages/liquid/#quoted-include-paths" target="_blank">Quoted Include Paths</a>) which I believe is trying to be compatible with Jekyll.{% endnote %}
|
||||
|
||||
## Jekyll include
|
||||
|
||||
{% since %}v9.33.0{% endsince %}
|
||||
|
||||
[jekyllInclude][jekyllInclude] is used to enable Jekyll-like include syntax. Defaults to `false`, when set to `true`:
|
||||
|
||||
- Filename will be static: `dynamicPartials` now defaults to `false` (instead of `true`). And you can set `dynamicPartials` back to `true`.
|
||||
- Use `=` instead of `:` to separate parameter key-values.
|
||||
- Parameters are under `include` variable instead of current scope.
|
||||
|
||||
For example in the following template, `name.html` is not quoted, `header` and `"HEADER"` are separated by `=`, and the `header` parameter is referenced by `include.header`. More details please check out [include][include].
|
||||
|
||||
```liquid
|
||||
// entry template
|
||||
{% include article.html header="HEADER" content="CONTENT" %}
|
||||
|
||||
// article.html
|
||||
<article>
|
||||
<header>{{include.header}}</header>
|
||||
{{include.content}}
|
||||
</article>
|
||||
```
|
||||
|
||||
## extname
|
||||
|
||||
**extname** defines the default extension name to be appended into filenames if the filename has no extension name. Defaults to `''` which means it's disabled by default. By setting it to `.liquid`:
|
||||
@@ -85,6 +108,8 @@ it defaults to false. For example, when set to true, a blank string would evalu
|
||||
|
||||
**preserveTimezones** is a boolean effects only literal timestamps. When set to `true`, all literal timestamps will remain the same when output. This is a parser option, so Date objects passed to LiquidJS as data will not be affected. Note that `preserveTimezones` has a higher priority than `timezoneOffset`.
|
||||
|
||||
**dateFormat** is used to specify a default format to output dates. `%A, %B %-e, %Y at %-l:%M %P %z` will be used if not specified. For example, set `dateFormat: %Y-%m-%dT%H:%M:%S:%LZ` to output all dates in [JavaScript Date.toJson()][https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toJSON] format.
|
||||
|
||||
## Trimming
|
||||
|
||||
**greedy**, **trimOutputLeft**, **trimOutputRight**, **trimTagLeft**, **trimTagRight** options are used to eliminate extra newlines and indents in templates around Liquid Constructs. See [Whitespace Control][wc] for details.
|
||||
@@ -105,6 +130,8 @@ it defaults to false. For example, when set to true, a blank string would evalu
|
||||
|
||||
**lenientIf** modifies the behavior of `strictVariables` to allow handling optional variables. If set to `true`, an undefined variable will *not* cause an exception in the following two situations: a) it is the condition to an `if`, `elsif`, or `unless` tag; b) it occurs right before a `default` filter. Irrelevant if `strictVariables` is not set. Defaults to `false`.
|
||||
|
||||
**ownPropertyOnly** hides scope variables from prototypes, useful when you're passing a not sanitized object into LiquidJS or need to hide prototypes from templates. Defaults to `true`.
|
||||
|
||||
{% note info Non-existent Tags %}
|
||||
Non-existent tags always throw errors during parsing and this behavior can not be customized.
|
||||
{% endnote %}
|
||||
@@ -113,7 +140,7 @@ Non-existent tags always throw errors during parsing and this behavior can not b
|
||||
|
||||
Parameter orders are ignored by default, for ea `{% for i in (1..8) reversed limit:3 %}` will always perform `limit` before `reversed`, even if `reversed` occurs before `limit`. To make parameter order respected, set **orderedFilterParameters** to `true`. Its default value is `false`.
|
||||
|
||||
[liquid]: ../api/classes/liquid_.liquid.html
|
||||
[liquid]: /api/classes/Liquid.html
|
||||
[caching]: ./caching.html
|
||||
[abstract-fs]: ./render-file.html#Abstract-File-System
|
||||
[render-file]: ./render-file.html
|
||||
@@ -123,3 +150,4 @@ Parameter orders are ignored by default, for ea `{% for i in (1..8) reversed lim
|
||||
[layout]: ../tags/layout.html
|
||||
[wc]: ./whitespace-control.html
|
||||
[intro]: ./intro-to-liquid.html
|
||||
[jekyllInclude]: /api/interfaces/LiquidOptions.html#jekyllInclude
|
||||
|
||||
@@ -0,0 +1,100 @@
|
||||
---
|
||||
title: Parse Parameters
|
||||
---
|
||||
|
||||
## Access Raw Parameters
|
||||
|
||||
As covered in [Register Filters/Tags][register-tags], tag parameters is available on `tagToken.args` as a raw string. For example:
|
||||
|
||||
```javascript
|
||||
// Usage: {% random foo bar coo %}
|
||||
// Output: "foo", "bar" or "coo"
|
||||
engine.registerTag('random', {
|
||||
parse(tagToken) {
|
||||
// tagToken.args === "foo bar coo"
|
||||
this.items = tagToken.args.split(' ')
|
||||
},
|
||||
render(context, emitter) {
|
||||
// get a random index
|
||||
const index = Math.floor(this.items.length * Math.random())
|
||||
// output that item
|
||||
emitter.write(this.items[index])
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
Here's a JSFiddle version: <http://jsfiddle.net/ctj364up/2/>
|
||||
|
||||
## Parse Parameters as Values
|
||||
|
||||
Sometimes we need more dynamic tags and want to pass values to the custom tag instead of static strings. Variables in LiquidJS can be literal (string, number, etc.) or a variable from current context scope.
|
||||
|
||||
The following modified template also contains 3 values to random from, but they're values instead of static strings. The first one is string literal, second one is an identifier, third one is a property access sequence containing two identifiers.
|
||||
|
||||
```liquid
|
||||
{% random "foo" bar obj.coo %}
|
||||
```
|
||||
|
||||
It can be tricky to parse all these cases manually, but there's a [Tokenizer][Tokenizer] class in LiquidJS you can make use of.
|
||||
|
||||
```javascript
|
||||
const { Liquid, Tokenizer, evalToken } = require('liquidjs')
|
||||
engine.registerTag('random', {
|
||||
parse(tagToken) {
|
||||
const tokenizer = new Tokenizer(tagToken.args)
|
||||
this.items = []
|
||||
while (!tokenizer.end()) {
|
||||
// here readValue() returns a LiteralToken or PropertyAccessToken
|
||||
this.items.push(tokenizer.readValue())
|
||||
}
|
||||
},
|
||||
* render(context, emitter) {
|
||||
const index = Math.floor(this.items.length * Math.random())
|
||||
const token = this.items[index]
|
||||
// in LiquidJS, we use yield to wait for async call
|
||||
const value = yield evalToken(token, context)
|
||||
emitter.write(value)
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
Calling this tag in scope `{ bar: "bar", obj: { coo: "coo" } }` yields exactly the same result as the first example. See this JSFiddle: <http://jsfiddle.net/ctj364up/3/>
|
||||
|
||||
{% note info Async ans Promises %}
|
||||
Async calls in LiquidJS are implemented by generators directly, for we can call generators in synchronous manner so this tag implementation is also valid for `renderSync()`, `parseAndRenderSync()`, `renderFileSync()`. If you need to await a promise in tag implementation, simply replace `await somePromise` with `yield somePromise` and keep `* render()` instead of `async render()` will do the trick. See <a href="/tutorials/sync-and-async.html">Sync and Async</a> for more details.
|
||||
{% endnote %}
|
||||
|
||||
## Parse Key-Value Pairs as Named Parameters
|
||||
|
||||
Named parameters become very handy when there're optional parameters or lots of parameters, in which case the order of parameters is not important. This is exactly what [Hash][Hash] class is invented for.
|
||||
|
||||
```liquid
|
||||
{% random from:2, to:max %}
|
||||
```
|
||||
|
||||
In the above example, we're trying to generate a random number in the range [2, max]. We'll use `Hash` to parse `from` and `to` parameters.
|
||||
|
||||
```javascript
|
||||
const { Liquid, Hash } = require('liquidjs')
|
||||
|
||||
engine.registerTag('random', {
|
||||
parse(tagToken) {
|
||||
// parse the parameters structure into `this.args`
|
||||
this.args = new Hash(tagToken.args)
|
||||
},
|
||||
* render(context, emitter) {
|
||||
// evaluate the parameters in `context`
|
||||
const {from, to} = yield this.args.render(context)
|
||||
const length = to - from + 1
|
||||
const value = from + Math.floor(length * Math.random())
|
||||
emitter.write(value)
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
Rendering `{% random from:2, to:max %}` in scope `{ max: 10 }` will generate a random number in the range [2, 10]. See this JSFiddle: <http://jsfiddle.net/ctj364up/4/>
|
||||
|
||||
|
||||
[register-tags]: /tutorials/register-filters-tags.html
|
||||
[Tokenizer]: /api/classes/Tokenizer.html
|
||||
[Hash]: /api/classes/Hash.html
|
||||
@@ -43,5 +43,5 @@ Here's a list of plugins that backfill those features. Feel free to add yours, t
|
||||
* Sections Tags (WIP): https://github.com/harttle/liquidjs-section-tags
|
||||
* Color Filters: https://github.com/harttle/liquidjs-color-filters
|
||||
|
||||
[liquid]: ../api/classes/liquid_.liquid.html
|
||||
[liquid]: /api/classes/Liquid.html
|
||||
[register]: /harttle/liquidjs/wiki/Register-Filters-Tags
|
||||
@@ -6,14 +6,14 @@ title: Register Filters/Tags
|
||||
|
||||
```typescript
|
||||
// Usage: {% upper name %}
|
||||
import { TagToken, Context, Emitter, TopLevelToken } from 'liquidjs'
|
||||
import { Value, TagToken, Context, Emitter, TopLevelToken } from 'liquidjs'
|
||||
|
||||
engine.registerTag('upper', {
|
||||
parse: function(tagToken: TagToken, remainTokens: TopLevelToken[]) {
|
||||
this.str = tagToken.args; // name
|
||||
this.value = new Value(token.args, liquid)
|
||||
},
|
||||
render: async function(ctx: Context) {
|
||||
var str = await this.liquid.evalValue(this.str, ctx); // 'alice'
|
||||
render: function*(ctx: Context) {
|
||||
const str = yield this.value.value(ctx); // 'alice'
|
||||
return str.toUpperCase() // 'ALICE'
|
||||
}
|
||||
});
|
||||
@@ -22,7 +22,26 @@ engine.registerTag('upper', {
|
||||
* `parse`: Read tokens from `remainTokens` until your end token.
|
||||
* `render`: Combine scope data with your parsed tokens into HTML string.
|
||||
|
||||
See existing tag implementations here: <https://github.com/harttle/liquidjs/tree/master/src/builtin/tags>
|
||||
For complex tag implementation, you can also provide a tag class:
|
||||
|
||||
```typescript
|
||||
// Usage: {% upper name:"alice" %}
|
||||
import { Hash, Tag, TagToken, Context, Emitter, TopLevelToken, Liquid } from 'liquidjs'
|
||||
|
||||
engine.registerTag('upper', class UpperTag extends Tag {
|
||||
private hash: Hash
|
||||
constructor(tagToken: TagToken, remainTokens: TopLevelToken[], liquid: Liquid) {
|
||||
super(tagToken, remainTokens, liquid)
|
||||
this.hash = new Hash(tagToken.args)
|
||||
}
|
||||
* render(ctx: Context) {
|
||||
const hash = yield this.hash.render();
|
||||
return hash.name.toUpperCase() // 'ALICE'
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
See existing tag implementations here: <https://github.com/harttle/liquidjs/tree/master/src/tags>
|
||||
See demo example here: https://github.com/harttle/liquidjs/blob/master/demo/typescript/index.ts
|
||||
|
||||
## Register Filters
|
||||
@@ -39,7 +58,7 @@ Filter arguments will be passed to the registered filter function, for example:
|
||||
engine.registerFilter('add', (initial, arg1, arg2) => initial + arg1 + arg2)
|
||||
```
|
||||
|
||||
See existing filter implementations here: <https://github.com/harttle/liquidjs/tree/master/src/builtin/filters>
|
||||
See existing filter implementations here: <https://github.com/harttle/liquidjs/tree/master/src/filters>
|
||||
|
||||
## Unregister Tags/Filters
|
||||
|
||||
@@ -61,4 +80,4 @@ function disabledFilter(name) {
|
||||
}
|
||||
}
|
||||
engine.registerFilter('plus', disabledFilter('plus'));
|
||||
```
|
||||
```
|
||||
@@ -68,7 +68,7 @@ Here's a demo for browsers: [demo/browser](https://github.com/harttle/liquidjs/t
|
||||
|
||||
## Abstract File System
|
||||
|
||||
LiquidJS defines an abstract file system interface in [src/fs/ifs.ts][ifs] and the default implementation is [src/fs/node.ts][fs-node] for Node.js and [src/fs/browser.ts][fs-browser] for the browser bundle.
|
||||
LiquidJS defines an abstract file system interface in [src/fs/fs.ts][ifs] and the default implementation is [src/fs/fs-impl.ts][fs-node] for Node.js and [src/build/fs-impl-browser.ts][fs-browser] for the browser bundle.
|
||||
|
||||
The `Liquid` constructor provides a [fs][fs] option to specify the file system implementation. It's supposed to be used to define customized template fetching logic, i.e. fetch template from a database table, like:
|
||||
|
||||
@@ -85,7 +85,7 @@ var engine = new Liquid({
|
||||
existsSync () {
|
||||
return true
|
||||
},
|
||||
exists () {
|
||||
async exists () {
|
||||
return true
|
||||
},
|
||||
contains () {
|
||||
@@ -100,14 +100,14 @@ var engine = new Liquid({
|
||||
|
||||
{% note warn Path Traversal Vulnerability %}The default value of <code>contains()</code> always returns true. That means when specifying an abstract file system, you'll need to provide a proper <code>contains()</code> to avoid expose such vulnerabilities.{% endnote %}
|
||||
|
||||
[fs]: ../api/interfaces/liquid_options_.liquidoptions.html#Optional-fs
|
||||
[ifs]: https://github.com/harttle/liquidjs/blob/master/src/fs/ifs.ts
|
||||
[fs-node]: https://github.com/harttle/liquidjs/blob/master/src/fs/node.ts
|
||||
[fs-browser]: https://github.com/harttle/liquidjs/blob/master/src/fs/browser.ts
|
||||
[fs]: /api/interfaces/LiquidOptions.html#fs
|
||||
[ifs]: /api/interfaces/FS.html
|
||||
[fs-node]: https://github.com/harttle/liquidjs/blob/master/src/fs/fs-impl.ts
|
||||
[fs-browser]: https://github.com/harttle/liquidjs/blob/master/src/fs/fs-impl-browser.ts
|
||||
[layout]: https://help.shopify.com/en/themes/liquid/tags/theme-tags#layout
|
||||
[include]: https://help.shopify.com/themes/liquid/tags/theme-tags#include
|
||||
[renderFile]: ../api/classes/liquid_.liquid.html#renderFile
|
||||
[renderFileSync]: ../api/classes/liquid_.liquid.html#renderFilesync
|
||||
[parseFile]: ../api/classes/liquid_.liquid.html#parseFile
|
||||
[parseFileSync]: ../api/classes/liquid_.liquid.html#parseFileSync
|
||||
[root]: ../api/interfaces/liquid_options_.liquidoptions.html#Optional-root
|
||||
[renderFile]: /api/classes/Liquid.html#renderFile
|
||||
[renderFileSync]: /api/classes/Liquid.html#renderFileSync
|
||||
[parseFile]: /api/classes/Liquid.html#parseFile
|
||||
[parseFileSync]: /api/classes/Liquid.html#parseFileSync
|
||||
[root]: /api/interfaces/LiquidOptions.html#root
|
||||
|
||||
@@ -0,0 +1,137 @@
|
||||
---
|
||||
title: Render Tag Content
|
||||
---
|
||||
|
||||
Custom tags can have content template and can be nested. This article describes how to implement custom tags that consists of a *begin tag*, an *end tag*, and template content between them.
|
||||
|
||||
## Render Tag Content
|
||||
|
||||
We'll start with a simple tag `wrap` which wraps its content into a `<div class="wrapper"></div>` element:
|
||||
|
||||
```liquid
|
||||
{% wrap %}
|
||||
{{ "hello world!" | capitalize }}
|
||||
{% endwrap %}
|
||||
```
|
||||
|
||||
Expected output:
|
||||
|
||||
```html
|
||||
<div class='wrapper'>
|
||||
Hello world!
|
||||
</div>
|
||||
```
|
||||
|
||||
Firstly, [register][register-tags] a tag with name `wrap` and parse the content into `this.tpls`. Here in `parse(tagToken, remainTokens)`,
|
||||
|
||||
- `tagToken` is current token `{% wrap %}`, and
|
||||
- `remainTokens` is an array of all tokens following `{% wrap %}` until the end of this template file.
|
||||
|
||||
Basically, what we need to do is take/`.shift()` enough tags from `remainTokens` until we got a `endwrap` token (the name can be arbitrary, but in convention, we need it to be `endwrap`). And if there's no `endwrap` until the end of template file, we need to throw an tag-not-closed `Error`.
|
||||
|
||||
```javascript
|
||||
engine.registerTag('wrap', {
|
||||
parse(tagToken, remainTokens) {
|
||||
this.tpls = []
|
||||
let closed = false
|
||||
while(remainTokens.length) {
|
||||
let token = remainTokens.shift()
|
||||
// we got the end tag! stop taking tokens
|
||||
if (token.name === 'endwrap') {
|
||||
closed = true
|
||||
break
|
||||
}
|
||||
// parse token into template
|
||||
// parseToken() may consume more than 1 tokens
|
||||
// e.g. {% if %}...{% endif %}
|
||||
let tpl = this.liquid.parser.parseToken(token, remainTokens)
|
||||
this.tpls.push(tpl)
|
||||
}
|
||||
if (!closed) throw new Error(`tag ${tagToken.getText()} not closed`)
|
||||
},
|
||||
* render(context, emitter) {
|
||||
emitter.write("<div class='wrapper'>")
|
||||
yield this.liquid.renderer.renderTemplates(this.tpls, context, emitter)
|
||||
emitter.write("</div>")
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
`.renderTemplates()` can be async, we need `yield` to wait it complete. More details on async in LiquidJS, please refer to [Sync and Async][async]. Other parts of `render()` method is quite straightforward. Here's a JSFiddle version: <http://jsfiddle.net/por0zcn1/3/>
|
||||
|
||||
## Using ParseStream
|
||||
|
||||
When it comes to complex tags like [for][for] and [if][if], the `parse()` can be very complicated. There's a [ParseStream][ParseStream] utility to organize the `parse()` in event-based style. Following is a re-written `parse()` using `ParseStream` and does exactly the same as above example.
|
||||
|
||||
```javascript
|
||||
parse(tagToken, remainTokens) {
|
||||
this.tpls = []
|
||||
this.liquid.parser.parseStream(remainTokens)
|
||||
.on('template', tpl => this.tpls.push(tpl))
|
||||
// note that we cannot use arrow function because we need `this`
|
||||
.on('tag:endwrap', function () { this.stop() })
|
||||
.on('end', () => { throw new Error(`tag ${tagToken.getText()} not closed`) })
|
||||
.start()
|
||||
}
|
||||
```
|
||||
|
||||
Here's a JSFiddle version: <http://jsfiddle.net/por0zcn1/4/>. For simplicity, the following examples are implemented using `ParseStream`.
|
||||
|
||||
## Manipulate the Context
|
||||
|
||||
The `wrap` tag above doesn't seem to be very useful, without using that tag we can render the content anyway. Now we're going to implement a `repeat` tag to render the content 2 times (we can also add a [parameter][parameter] to render arbitrary times).
|
||||
|
||||
```liquid
|
||||
{% repeat %}
|
||||
{{ repeat.i }}. {{ "hello world!" | capitalize }}
|
||||
{% endrepeat %}`
|
||||
```
|
||||
|
||||
Expected outputs:
|
||||
|
||||
```html
|
||||
1. Hello world!
|
||||
2. Hello world!
|
||||
```
|
||||
|
||||
As you've noticed, there's an additional `repeat.i` in the context of `repeat`. That is implemented by manipulating the *Context*.
|
||||
|
||||
{% note info Context %}
|
||||
<em>Context</em> defines the value of each variable in Liquid template. In LiquidJS, a `Context` consists of a stack of `Scope`s. A *Scope* is a plain object like the one specified in `engine.render(tpl, scope)`.
|
||||
{% endnote %}
|
||||
|
||||
Each time we enter a new *Context*, we need to push a new *Scope*. And when we finish rendering and exit the *Context*, we pop the *Scope* from the *Context*. As you can see in the following implementation:
|
||||
|
||||
```javascript
|
||||
engine.registerTag('repeat', {
|
||||
parse(tagToken, remainTokens) {
|
||||
this.tpls = []
|
||||
this.liquid.parser.parseStream(remainTokens)
|
||||
.on('template', tpl => this.tpls.push(tpl))
|
||||
.on('tag:endrepeat', function () { this.stop() })
|
||||
.on('end', () => { throw new Error(`tag ${tagToken.getText()} not closed`) })
|
||||
.start()
|
||||
},
|
||||
* render(context, emitter) {
|
||||
const repeat = { i: 1 }
|
||||
context.push({ repeat })
|
||||
yield this.liquid.renderer.renderTemplates(this.tpls, context, emitter)
|
||||
repeat.i++
|
||||
yield this.liquid.renderer.renderTemplates(this.tpls, context, emitter)
|
||||
context.pop()
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
The `parse()` is exactly the same as `wrap` tag, we repeat the content simply by calling `.renderTemplates(this.tpls)` twice during `render()`. Here's the JSFiddle: <http://jsfiddle.net/por0zcn1/2/>
|
||||
|
||||
{% note warn Use Push & Pop in Pairs %}
|
||||
`context.push()` and `context.pop()` have to be used in pairs. Failing to `pop()` the *Scope* you pushed will leak the *Scope* to latter templates and may corrupt the *Context* stack.
|
||||
{% endnote %}
|
||||
|
||||
[register-tags]: ./register-filters-tags.html
|
||||
[async]: ./sync-and-async.html
|
||||
[for]: ../tags/for.html
|
||||
[if]: ../tags/if.html
|
||||
[ParseStream]: /api/classes/ParseStream.html
|
||||
[parameter]: ./parse-parameters.html
|
||||
@@ -53,20 +53,51 @@ Pre-built UMD bundles are also available:
|
||||
|
||||
## LiquidJS in CLI
|
||||
|
||||
LiquidJS is also available from CLI:
|
||||
LiquidJS can also be used to render a template directly from CLI using `npx`:
|
||||
|
||||
```bash
|
||||
echo '{{"hello" | capitalize}}' | npx liquidjs
|
||||
npx liquidjs --template '{{"hello" | capitalize}}'
|
||||
```
|
||||
|
||||
If you pass a path to a JSON file or a JSON string as the first argument, it will be used as the context for your template.
|
||||
You can either pass the template inline (as shown above) or you can read it from a file by using the `@` character followed by a path, like so:
|
||||
|
||||
```bash
|
||||
echo 'Hello, {{ name }}.' | npx liquidjs '{"name": "Snake"}'
|
||||
npx liquidjs --template @./some-template.liquid
|
||||
```
|
||||
|
||||
You can also use the `@-` syntax to read the template from `stdin`:
|
||||
|
||||
```bash
|
||||
echo '{{"hello" | capitalize}}' | npx liquidjs --template @-
|
||||
```
|
||||
|
||||
A context can be passed in the same ways (i.e. inline, from a path or piped through `stdin`). The following three are equivalent:
|
||||
|
||||
```bash
|
||||
npx liquidjs --template 'Hello, {{ name }}!' --context '{"name": "Snake"}'
|
||||
npx liquidjs --template 'Hello, {{ name }}!' --context @./some-context.json
|
||||
echo '{"name": "Snake"}' | npx liquidjs --template 'Hello, {{ name }}!' --context @-
|
||||
```
|
||||
|
||||
Note that you can only use the `stdin` specifier `@-` for a single argument. If you try to use it for both `--template` and `--context` you will get an error.
|
||||
|
||||
The rendered output is written to `stdout` by default, but you can also specify an output file (if the file exists, it will be overwritten):
|
||||
|
||||
```bash
|
||||
npx liquidjs --template '{{"hello" | capitalize}}' --output ./hello.txt
|
||||
```
|
||||
|
||||
You can also pass a number of options to customize template rendering behavior. For example, the `--js-truthy` option can be used to enable JavaScript truthiness:
|
||||
|
||||
```bash
|
||||
npx liquidjs --template @./some-template.liquid --js-truthy
|
||||
```
|
||||
|
||||
Most of the [options available through the JavaScript API][options] are also available from the CLI. For help on available options, use `npx liquidjs --help`.
|
||||
|
||||
## Miscellaneous
|
||||
|
||||
A ReactJS demo is also added by [@stevenanthonyrevo](https://github.com/stevenanthonyrevo), see [liquidjs/demo/reactjs/](https://github.com/harttle/liquidjs/blob/master/demo/reactjs/).
|
||||
|
||||
[intro]: ./intro-to-liquid.html
|
||||
[options]: ./options.md
|
||||
|
||||
@@ -0,0 +1,116 @@
|
||||
---
|
||||
title: Sync and Async
|
||||
---
|
||||
|
||||
LiquidJS supports both sync and async evaluate, and can be used with Promises. To reuse the same set of tag/filter implementations in both sync and async, LiquidJS tags are implemented as generators.
|
||||
|
||||
## Sync and Async API
|
||||
|
||||
All major methods on [Liquid][Liquid] supports both sync and async. These methods return Promises:
|
||||
|
||||
- `render()`
|
||||
- `renderFile()`
|
||||
- `parseFile()`
|
||||
- `parseAndRender()`
|
||||
- `evalValue()`
|
||||
|
||||
The synchronous version of methods contains a `Sync` suffix:
|
||||
|
||||
- `renderSync()`
|
||||
- `renderFileSync()`
|
||||
- `parseFileSync()`
|
||||
- `parseAndRenderSync()`
|
||||
- `evalValueSync()`
|
||||
|
||||
## Implement Sync-Compatible Tags
|
||||
|
||||
LiquidJS uses a generator-based async implementation to support both async and sync in one piece of tag implementation. For example, below `UpperTag` can be used in both `engine.renderSync()` and `engine.render()`.
|
||||
|
||||
```typescript
|
||||
import { TagToken, Context, Emitter, TopLevelToken, Value, Tag, Liquid } from 'liquidjs'
|
||||
|
||||
// Usage: {% upper "alice" %}
|
||||
// Output: ALICE
|
||||
engine.registerTag('upper', class UpperTag extends Tag {
|
||||
private value: Value
|
||||
constructor (token: TagToken, remainTokens: TopLevelToken[], liquid: Liquid) {
|
||||
super(token, remainTokens, liquid)
|
||||
this.value = new Value(token.args, liquid)
|
||||
}
|
||||
* render (ctx: Context, emitter: Emitter) {
|
||||
const title = yield this.value.value(ctx)
|
||||
emitter.write(title.toUpperCase())
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
All builtin tags are implemented this way and safe to use in both sync and async (I'll call it *sync-compatible*). To make your custom tag *sync-compatible*, you'll need to:
|
||||
|
||||
- declare render function as `* render()`, in which
|
||||
- do not directly `return <Promise>`, and
|
||||
- do not call any APIs that returns a Promise.
|
||||
|
||||
## Call APIs that return a Promise
|
||||
|
||||
But LiquidJS is Promise-friendly, right? You can still call Promise-based functions and wait for that Promise within tag implementations. Just replace `await` with `yield`. e.g. we're calling `fs.readFile()` which returns a `Promise`:
|
||||
|
||||
```typescript
|
||||
* render (ctx: Context, emitter: Emitter) {
|
||||
const file = yield this.value.value(ctx)
|
||||
const title = yield fs.readFile(file, 'utf8')
|
||||
emitter.write(title.toUpperCase())
|
||||
}
|
||||
```
|
||||
|
||||
Now that this `* render()` calls an API that returns a Promise, so it's no longer *sync-compatible*.
|
||||
|
||||
{% note info Non Sync-Compatible Tags %}
|
||||
Non <em>sync-compatible</em> tags are also valid tags, will work just fine for asynchronous API calls. When called synchronously, tags that return a <code>Promise</code> will be rendered as <code>[object Promise]</code>.
|
||||
{% endnote %}
|
||||
|
||||
## Convert LiquidJS async Generator to Promise
|
||||
|
||||
You can convert a Generator to Promise by [toPromise][toPromise], for example:
|
||||
|
||||
```typescript
|
||||
import { TagToken, Context, Emitter, TopLevelToken, Value, Tag, Liquid, toPromise } from 'liquidjs'
|
||||
|
||||
// Usage: {% upper "alice" %}
|
||||
// Output: ALICE
|
||||
engine.registerTag('upper', class UpperTag extends Tag {
|
||||
private value: Value
|
||||
constructor (token: TagToken, remainTokens: TopLevelToken[], liquid: Liquid) {
|
||||
super(token, remainTokens, liquid)
|
||||
this.value = new Value(token.args, liquid)
|
||||
}
|
||||
async render (ctx: Context, emitter: Emitter) {
|
||||
const title = await toPromise(this.value.value(ctx))
|
||||
emitter.write(title.toUpperCase())
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
## Async only Tags
|
||||
|
||||
If your tag is intend to be used only asynchronously, it can be declared as `async render()` so you can use `await` in its implementation directly:
|
||||
|
||||
```typescript
|
||||
import { toPromise, TagToken, Context, Emitter, TopLevelToken, Value, Tag, Liquid } from 'liquidjs'
|
||||
|
||||
// Usage: {% upper "alice" %}
|
||||
// Output: ALICE
|
||||
engine.registerTag('upper', class UpperTag extends Tag {
|
||||
private value: Value
|
||||
constructor (token: TagToken, remainTokens: TopLevelToken[], liquid: Liquid) {
|
||||
super(token, remainTokens, liquid)
|
||||
this.value = new Value(token.args, liquid)
|
||||
}
|
||||
async render (ctx: Context, emitter: Emitter) {
|
||||
const title = await toPromise(this.value.value(ctx))
|
||||
emitter.write(`<h1>${title}</h1>`)
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
[Liquid]: /api/classes/Liquid.html
|
||||
[toPromise]: /api/functions/toPromise.html
|
||||
@@ -59,12 +59,12 @@ var engine = new Liquid({
|
||||
});
|
||||
```
|
||||
|
||||
[cache]: ../api/interfaces/liquid_options_.liquidoptions.html#Optional-cache
|
||||
[cache]: /api/interfaces/LiquidOptions.html#cache
|
||||
[express-views]: http://expressjs.com/en/guide/using-template-engines.html
|
||||
[parseFile]: ../api/classes/liquid_.liquid.html#parseFile
|
||||
[parseFileSync]: ../api/classes/liquid_.liquid.html#parseFileSync
|
||||
[parseFile]: /api/classes/Liquid.html#parseFile
|
||||
[parseFileSync]: /api/classes/Liquid.html#parseFileSync
|
||||
[layout]: https://help.shopify.com/en/themes/liquid/tags/theme-tags#layout
|
||||
[include]: https://help.shopify.com/themes/liquid/tags/theme-tags#include
|
||||
[root]: ../api/interfaces/liquid_options_.liquidoptions.html#Optional-root
|
||||
[root]: /api/interfaces/LiquidOptions.html#root
|
||||
[render-a-file]: ./render-a-file.html
|
||||
[Caching]: ./caching.html
|
||||
|
||||
@@ -41,7 +41,7 @@ Alternatively, LiquidJS provides these per engine options to enable whitespace c
|
||||
|
||||
* `trimTagLeft`
|
||||
* `trimTagRight`
|
||||
* `trimValueRight`
|
||||
* `trimValueLeft`
|
||||
* `trimValueRight`
|
||||
|
||||
[LiquidJS][liquidjs] will **NOT** trim any whitespace by default, aka. above options all default to `false`. For details of these options, see the [options][options].
|
||||
@@ -52,5 +52,5 @@ In greedy mode (enabled by the [greedy option][greedy]), all consecutive whitesp
|
||||
|
||||
[shopify/liquid]: https://github.com/Shopify/liquid
|
||||
[liquidjs]: https://github.com/harttle/liquidjs
|
||||
[options]: ../api/interfaces/liquid_options_.liquidoptions.html
|
||||
[greedy]: ../api/interfaces/liquid_options_.liquidoptions.html#Optional-greedy
|
||||
[options]: /api/interfaces/LiquidOptions.html
|
||||
[greedy]: /api/interfaces/LiquidOptions.html#greedy
|
||||
|
||||
@@ -20,6 +20,21 @@ Fri, Jul 17, 15
|
||||
日期在输出时会转换为当地时区,设置 `timezoneOffset` LiquidJS 参数可以指定一个不同的时区。或者设置 `preserveTimezones` 为 `true` 来保持字面量时间戳的时区,数据中的日期对象不受此参数的影响。
|
||||
{% endnote %}
|
||||
|
||||
你也可以在使用 `date` 时再设置时区:
|
||||
|
||||
输入
|
||||
```liquid
|
||||
{{ "1990-12-31T23:00:00Z" | date: "%Y-%m-%dT%H:%M:%S", 360}} // 等价于设置 `options.timezoneOffset` to `360`.
|
||||
{{ "1990-12-31T23:00:00Z" | date: "%Y-%m-%dT%H:%M:%S", "Asia/Colombo" }}
|
||||
```
|
||||
|
||||
输出
|
||||
```liquid
|
||||
1990-12-31T17:00:00
|
||||
1991-01-01T04:30:00
|
||||
```
|
||||
|
||||
|
||||
输入
|
||||
```liquid
|
||||
{{ article.published_at | date: "%Y" }}
|
||||
@@ -30,7 +45,7 @@ Fri, Jul 17, 15
|
||||
2015
|
||||
```
|
||||
|
||||
对于包含格式正确的字符串也好使:
|
||||
输入也可以是符合 JavaScript `Date` 格式的字符串::
|
||||
|
||||
输入
|
||||
```liquid
|
||||
|
||||
@@ -26,6 +26,23 @@ title: divided_by
|
||||
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 %}
|
||||
在 JavaScript 里数字没有浮点和整数的区分,它们的类型都是 `number`:
|
||||
|
||||
```javascript
|
||||
// always true
|
||||
5.0 === 5
|
||||
```
|
||||
|
||||
因此如果需要做整数运算,需要传入额外的 `integerArithmetic` 参数:
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{{ 5 | divided_by: 3, true }}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
1
|
||||
```
|
||||
|
||||
[floor]: ./floor.html
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
---
|
||||
title: 过滤器
|
||||
description: 每个 Liquid 过滤器的描述和示例
|
||||
---
|
||||
|
||||
LiquidJS 支持 Liquid 语法中具体业务无关的过滤器,基本上 [shopify/liquid 核心][shopify/liquid] 支持的 LiquidJS 都支持。这部分包含了所有 LiquidJS 支持的过滤器的文档和使用示例。
|
||||
@@ -8,10 +9,11 @@ LiquidJS 共支持 40+ 个过滤器,可以分为如下几类:
|
||||
|
||||
类别 | 过滤器
|
||||
--- | ---
|
||||
数学 | plus, minus, modulo, times, floor, ceil, round, divided_by, abs
|
||||
字符串 | append, prepend, capitalize, upcase, downcase, strip, lstrip, rstrip, strip_newlines, split, replace, replace_first, remove, remove_first, truncate, truncatewords
|
||||
数学 | plus, minus, modulo, times, floor, ceil, round, divided_by, abs, at_least, at_most
|
||||
字符串 | append, prepend, capitalize, upcase, downcase, strip, lstrip, rstrip, strip_newlines, split, replace, replace_first, replace_last, remove, remove_first, remove_last, truncate, truncatewords
|
||||
HTML/URI | escape, escape_once, url_encode, url_decode, strip_html, newline_to_br
|
||||
数组 | slice, map, sort, sort_natural, uniq, wheres, first, last, join, reverse, concat
|
||||
数组 | slice, map, sort, sort_natural, uniq, wheres, first, last, join, reverse, concat, compact, size
|
||||
日期 | date
|
||||
其他 | default, json
|
||||
|
||||
[shopify/liquid]: https://github.com/Shopify/liquid
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
---
|
||||
title: raw
|
||||
---
|
||||
|
||||
{% since %}v9.37.0{% endsince %}
|
||||
|
||||
直接返回变量的值。配合 [outputEscape](/api/interfaces/LiquidOptions.html#outputEscape) 参数使用。
|
||||
|
||||
{% note info 自动转义 %}
|
||||
默认情况下 `outputEscape` 为 `undefined`,这意味着 LiquidJS 输出不会默认转义,因此这时使用 `raw` 没有意义。
|
||||
{% endnote %}
|
||||
|
||||
输入(未设置 `outputEscape`)
|
||||
```liquid
|
||||
{{ "<" }}
|
||||
```
|
||||
|
||||
输出
|
||||
```text
|
||||
<
|
||||
```
|
||||
|
||||
输入(`outputEscape="escape"`)
|
||||
```liquid
|
||||
{{ "<" }}
|
||||
```
|
||||
|
||||
输出
|
||||
```text
|
||||
<
|
||||
```
|
||||
|
||||
输入(`outputEscape="json"`)
|
||||
```liquid
|
||||
{{ "<" }}
|
||||
```
|
||||
|
||||
输出
|
||||
```text
|
||||
"<"
|
||||
```
|
||||
|
||||
输入(`outputEscape="escape"`)
|
||||
```liquid
|
||||
{{ "<" | raw }}
|
||||
```
|
||||
|
||||
输出
|
||||
```text
|
||||
<
|
||||
```
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
---
|
||||
title: remove_last
|
||||
---
|
||||
|
||||
{% since %}v10.2.0{% endsince %}
|
||||
|
||||
移除字符串中出现的最后一个指定子字符串。
|
||||
|
||||
输入
|
||||
```liquid
|
||||
{{ "I strained to see the train through the rain" | remove_last: "rain" }}
|
||||
```
|
||||
|
||||
输出
|
||||
```text
|
||||
I strained to see the train through the
|
||||
```
|
||||
@@ -0,0 +1,17 @@
|
||||
---
|
||||
title: replace_last
|
||||
---
|
||||
|
||||
{% since %}v10.2.0{% endsince %}
|
||||
|
||||
把字符串中出现的最后一个指定子字符串替换为另一个字符串。
|
||||
|
||||
输入
|
||||
```liquid
|
||||
{{ "Take my protein pills and put my helmet on" | replace_last: "my", "your" }}
|
||||
```
|
||||
|
||||
输出
|
||||
```text
|
||||
Take my protein pills and put your helmet on
|
||||
```
|
||||
@@ -0,0 +1,58 @@
|
||||
{
|
||||
"short_name": "LiquidJS",
|
||||
"name": "LiquidJS",
|
||||
"description": "LiquidJS 是一个简单的、安全的、兼容 Shopify 的、纯 JavaScript 编写的模板引擎。",
|
||||
"icons": [
|
||||
{
|
||||
"src": "/icon/apple-touch-icon-57x57.png",
|
||||
"type": "image/png",
|
||||
"sizes": "57x57"
|
||||
},
|
||||
{
|
||||
"src": "/icon/favicon-96x96.png",
|
||||
"type": "image/png",
|
||||
"sizes": "96x96"
|
||||
},
|
||||
{
|
||||
"src": "/icon/favicon-196x196.png",
|
||||
"type": "image/png",
|
||||
"sizes": "196x196"
|
||||
},
|
||||
{
|
||||
"src": "/icon/apple-touch-icon.png",
|
||||
"type": "image/png",
|
||||
"sizes": "512x512"
|
||||
}
|
||||
],
|
||||
"shortcuts" : [
|
||||
{
|
||||
"name": "教程",
|
||||
"url": "/zh-cn/tutorials/intro-to-liquid.html",
|
||||
"description": "一系列描述如何使用 LiquidJS 的文章"
|
||||
},
|
||||
{
|
||||
"name": "标签",
|
||||
"url": "/zh-cn/tags/overview.html",
|
||||
"description": "每个 Liquid 标签的描述和示例"
|
||||
},
|
||||
{
|
||||
"name": "过滤器",
|
||||
"url": "/zh-cn/filters/overview.html",
|
||||
"description": "每个 Liquid 过滤器的描述和示例"
|
||||
},
|
||||
{
|
||||
"name": "演示",
|
||||
"url": "/zh-cn/playground.html",
|
||||
"description": "一个用来尝试和分享 Liquid 模板的在线编辑器"
|
||||
},
|
||||
{
|
||||
"name": "API",
|
||||
"url": "/api/classes/Liquid.html",
|
||||
"description": "LiquidJS 类和接口的 TypeScript 文档"
|
||||
}
|
||||
],
|
||||
"start_url": "/zh-cn",
|
||||
"display": "standalone",
|
||||
"theme_color": "#0f83ce",
|
||||
"background_color": "#0f83ce"
|
||||
}
|
||||
@@ -1,3 +1,5 @@
|
||||
---
|
||||
layout: playground
|
||||
title: 演示
|
||||
description: 一个用来尝试和分享 Liquid 模板的在线编辑器
|
||||
---
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
---
|
||||
title: Echo
|
||||
---
|
||||
|
||||
{% since %}v9.31.0{% endsince %}
|
||||
|
||||
根据表达式输出渲染 HTML。和使用 `{{` expression `}}` 包裹模板效果一样,不同的是 echo 可以在 liquid 标签中使用,同时也支持过滤器。
|
||||
|
||||
## echo
|
||||
|
||||
输入
|
||||
```liquid
|
||||
{% assign username = 'Bob' %}
|
||||
{% echo username | append: ", welcome to LiquidJS!" | capitalize %}
|
||||
```
|
||||
|
||||
输出
|
||||
```text
|
||||
Bob, welcome to LiquidJS!
|
||||
```
|
||||
@@ -49,17 +49,17 @@ The collection is empty.
|
||||
输入
|
||||
```liquid
|
||||
{% for i in (1..5) %}
|
||||
{% if i == 4 %}
|
||||
{%- if i == 4 -%}
|
||||
{% break %}
|
||||
{% else %}
|
||||
{%- else -%}
|
||||
{{ i }}
|
||||
{% endif %}
|
||||
{%- endif -%}
|
||||
{% endfor %}
|
||||
```
|
||||
|
||||
输出
|
||||
```text
|
||||
1 2 3
|
||||
123
|
||||
```
|
||||
|
||||
### continue
|
||||
@@ -69,17 +69,17 @@ The collection is empty.
|
||||
输入
|
||||
```liquid
|
||||
{% for i in (1..5) %}
|
||||
{% if i == 4 %}
|
||||
{% continue %}
|
||||
{% else %}
|
||||
{%- if i == 4 -%}
|
||||
{%- continue -%}
|
||||
{%- else -%}
|
||||
{{ i }}
|
||||
{% endif %}
|
||||
{%- endif -%}
|
||||
{% endfor %}
|
||||
```
|
||||
|
||||
输出
|
||||
```text
|
||||
1 2 3 5
|
||||
1235
|
||||
```
|
||||
|
||||
### forloop
|
||||
@@ -137,13 +137,13 @@ index index0 rindex rindex0
|
||||
```liquid
|
||||
<!-- if array = [1,2,3,4,5,6] -->
|
||||
{% for item in array limit:2 %}
|
||||
{{ item }}
|
||||
{{- item -}}
|
||||
{% endfor %}
|
||||
```
|
||||
|
||||
输出
|
||||
```text
|
||||
1 2
|
||||
12
|
||||
```
|
||||
|
||||
### offset
|
||||
@@ -152,15 +152,57 @@ index index0 rindex rindex0
|
||||
|
||||
输入
|
||||
```liquid
|
||||
<!-- if array = [1,2,3,4,5,6] -->
|
||||
<!-- for array = [1,2,3,4,5,6] -->
|
||||
{% for item in array offset:2 %}
|
||||
{{ item }}
|
||||
{{- item -}}
|
||||
{% endfor %}
|
||||
```
|
||||
|
||||
输出
|
||||
```text
|
||||
3 4 5 6
|
||||
3456
|
||||
```
|
||||
|
||||
#### offset:continue
|
||||
|
||||
{% since %}v9.33.0{% endsince %}
|
||||
|
||||
`offset` 的值可以是 `continue`,用来继续上一次循环。例如:
|
||||
|
||||
输入
|
||||
```liquid
|
||||
<!-- for array = [1,2,3,4,5,6] -->
|
||||
{% for item in array limit:2 %}
|
||||
{{- item -}}
|
||||
{% endfor%}
|
||||
{% for item in array offset:continue %}
|
||||
{{- item -}}
|
||||
{% endfor%}
|
||||
```
|
||||
|
||||
输出
|
||||
```text
|
||||
12
|
||||
3456
|
||||
```
|
||||
|
||||
对同样的变量名和集合名(这个例子中是 `"item-array"`),存在唯一的位置记录。也就是说用新的变量名就可以开启一个新的循环:
|
||||
|
||||
输入
|
||||
```liquid
|
||||
<!-- for array = [1,2,3,4,5,6] -->
|
||||
{% for item in array limit:2 %}
|
||||
{{- item -}}
|
||||
{% endfor%}
|
||||
{% for item2 in array offset:continue %}
|
||||
{{- item2 -}}
|
||||
{% endfor%}
|
||||
```
|
||||
|
||||
输出
|
||||
```text
|
||||
12
|
||||
123456
|
||||
```
|
||||
|
||||
### range
|
||||
|
||||
@@ -44,5 +44,67 @@ title: Include
|
||||
|
||||
上面的例子中,子模板中 `product` 会保有父模板中的 `featured_product` 变量的值。
|
||||
|
||||
[extname]: ../../api/interfaces/liquid_options_.liquidoptions.html#Optional-extname
|
||||
[root]: ../../api/interfaces/liquid_options_.liquidoptions.html#Optional-root
|
||||
## 输出和过滤器
|
||||
|
||||
文件名为字符串字面量时,支持 Liquid 输出和过滤器。在拼接文件名时很方便:
|
||||
|
||||
```liquid
|
||||
{% include "prefix/{{name | append: \".html\"}}" %}
|
||||
```
|
||||
|
||||
{% note info 转义 %}
|
||||
字符串字面量里的 `"` 需要转义为 `\"`,使用静态文件名可以避免这个问题,见下面的 Jekyll-like 文件名。
|
||||
{% endnote %}
|
||||
|
||||
## Jekyll-like 文件名
|
||||
|
||||
设置 [dynamicPartials][dynamicPartials] 为 `false` 来启用 Jekyll-like 文件名,这时文件名不需要用引号包含,会被当作字面量处理。 这样的字符串里面仍然支持 Liquid 输出和过滤器,例如:
|
||||
|
||||
```liquid
|
||||
{% include prefix/{{ page.my_variable }}/suffix %}
|
||||
```
|
||||
|
||||
这样文件名里的 `"` 就不用转义了。
|
||||
|
||||
```liquid
|
||||
{% include prefix/{{name | append: ".html"}} %}
|
||||
```
|
||||
|
||||
## Jekyll include
|
||||
|
||||
{% since %}v9.33.0{% endsince %}
|
||||
|
||||
[jekyllInclude][jekyllInclude] 用来启用 Jekyll-like include 语法。默认为 `false`,当设置为 `true` 时:
|
||||
|
||||
- 默认启用静态文件名:`dynamicPartials` 的默认值变为 `false`(而非 `true`)。但你也可以把它设置回 `true`。
|
||||
- 参数的键和值之间由 `=` 分隔(本来是 `:`)。
|
||||
- 参数放到了 `include` 变量下,而非当前作用域。
|
||||
|
||||
例如下面的模板:
|
||||
|
||||
```liquid
|
||||
{% include article.html header="HEADER" content="CONTENT" %}
|
||||
```
|
||||
|
||||
其中 `article.html` 的内容是:
|
||||
|
||||
```liquid
|
||||
<article>
|
||||
<header>{{include.header}}</header>
|
||||
{{include.content}}
|
||||
</article>
|
||||
```
|
||||
|
||||
注意我们通过 `include.header` 引用第一个参数,而不是 `header`。输出如下:
|
||||
|
||||
```html
|
||||
<article>
|
||||
<header>HEADER</header>
|
||||
CONTENT
|
||||
</article>
|
||||
```
|
||||
|
||||
[extname]: /api/interfaces/LiquidOptions.html#extname
|
||||
[root]: /api/interfaces/LiquidOptions.html#root
|
||||
[dynamicPartials]: /api/interfaces/LiquidOptions.html#dynamicPartials
|
||||
[jekyllInclude]: /api/interfaces/LiquidOptions.html#jekyllInclude
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
---
|
||||
title: "#(单行注释)"
|
||||
---
|
||||
|
||||
{% since %}v9.38.0{% endsince %}
|
||||
|
||||
在 Liquid 模板中添加注释,注释标签内的文字不会被输出。
|
||||
|
||||
输入
|
||||
```liquid
|
||||
注释标签内的东西都不会输出。
|
||||
{% # this is an inline comment %}
|
||||
但每行都必须以 '#' 开头。
|
||||
{%
|
||||
# this is a comment
|
||||
# that spans multiple lines
|
||||
%}
|
||||
```
|
||||
|
||||
输出
|
||||
```text
|
||||
注释标签内的东西都不会输出。
|
||||
但每行都必须以 '#' 开头。
|
||||
```
|
||||
|
||||
在 <a href="./liquid.html">`liquid`</a> 标签里也可以使用注释标签。
|
||||
|
||||
```liquid
|
||||
{% liquid
|
||||
# required args
|
||||
assign product = collection.products.first
|
||||
|
||||
# optional args
|
||||
assign should_show_border = should_show_border | default: true
|
||||
assign should_highlight = should_highlight | default: false
|
||||
%}
|
||||
```
|
||||
|
||||
但注释标签不能用于把其他标签注释掉。这时应该使用 <a href="./comment.html">`comment`</a> 标签来临时禁用其他标签。
|
||||
|
||||
输入
|
||||
```liquid
|
||||
{%- # {% echo 'Welcome to LiquidJS!' %} -%}
|
||||
{% comment %}{% echo 'Welcome to LiquidJS!' %}{% endcomment %}
|
||||
```
|
||||
|
||||
输出
|
||||
```text
|
||||
-%}
|
||||
```
|
||||
@@ -62,5 +62,5 @@ Footer
|
||||
</ul>
|
||||
{% endnote %}
|
||||
|
||||
[extname]: ../../api/interfaces/liquid_options_.liquidoptions.html#Optional-extname
|
||||
[root]: ../../api/interfaces/liquid_options_.liquidoptions.html#Optional-root
|
||||
[extname]: /api/interfaces/LiquidOptions.html#extname
|
||||
[root]: /api/interfaces/LiquidOptions.html#root
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
---
|
||||
title: Liquid
|
||||
---
|
||||
|
||||
{% since %}v9.31.0{% endsince %}
|
||||
|
||||
通过 liquid 标签可以在一个分隔符中使用多个标签, 使 Liquid 逻辑书写更简洁。
|
||||
|
||||
## liquid
|
||||
|
||||
输入
|
||||
```liquid
|
||||
{% liquid
|
||||
assign names = 'Bob, Sally' | split: ', '
|
||||
|
||||
for name in names
|
||||
echo 'Hello, ' | append: name
|
||||
unless forloop.last
|
||||
echo ', '
|
||||
endunless
|
||||
endfor
|
||||
%}
|
||||
```
|
||||
|
||||
输出
|
||||
```text
|
||||
Hello, Bob, Hello Sally
|
||||
```
|
||||
@@ -1,5 +1,6 @@
|
||||
---
|
||||
title: 标签
|
||||
description: 每个 Liquid 标签的描述和示例
|
||||
---
|
||||
|
||||
LiquidJS 支持 Liquid 语法中具体业务无关的标签,包含 [shopify/liquid 核心][shopify/liquid] 里的所有标签。这部分包含了所有 LiquidJS 支持的标签的文档和使用示例。
|
||||
@@ -10,8 +11,8 @@ LiquidJS 支持十几个过滤器,可以分为如下几类:
|
||||
--- | --- | ---
|
||||
迭代 | 遍历一个集合 | for, cycle, tablerow
|
||||
控制流 | 控制模板渲染的执行分支 | if, unless, elif, else, case, when
|
||||
变量 | 定义和修改变量 | assign, increment, decrement
|
||||
变量 | 定义和修改变量 | assign, increment, decrement, capture, echo
|
||||
文件 | 引入或继承其他模板 | render, include, layout
|
||||
语言 | 暂时禁用 Liquid 语法 | raw, comment
|
||||
语言 | 暂时禁用 Liquid 语法 | # (单行注释), raw, comment, liquid
|
||||
|
||||
[shopify/liquid]: https://github.com/Shopify/liquid
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user