mirror of
https://github.com/harttle/liquidjs.git
synced 2026-09-14 20:00:39 -07:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
417432fb8a | ||
|
|
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 |
@@ -495,6 +495,88 @@
|
||||
"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
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
name: Build
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
os:
|
||||
required: true
|
||||
type: string
|
||||
bundles:
|
||||
required: false
|
||||
type: string
|
||||
env:
|
||||
BUNDLES: ${{ inputs.bundles }}
|
||||
jobs:
|
||||
build:
|
||||
name: Build
|
||||
runs-on: ${{ inputs.os }}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: '14'
|
||||
- name: Install dependencies
|
||||
run: npm ci
|
||||
- name: Build
|
||||
run: npm run build
|
||||
- name: Archive artifacts
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: dist-${{ inputs.os }}
|
||||
path: dist
|
||||
- name: Archive npm failure logs
|
||||
uses: actions/upload-artifact@v3
|
||||
if: failure()
|
||||
with:
|
||||
name: npm-logs
|
||||
path: ~/.npm/_logs
|
||||
@@ -1,30 +0,0 @@
|
||||
name: Check
|
||||
on: [push, pull_request]
|
||||
jobs:
|
||||
release:
|
||||
name: Check
|
||||
runs-on: ubuntu-18.04
|
||||
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: Test
|
||||
run: |
|
||||
npm run lint
|
||||
npm run test
|
||||
- name: Coverage
|
||||
uses: coverallsapp/[email protected]
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Performance
|
||||
run: |
|
||||
npm run perf:diff
|
||||
@@ -0,0 +1,28 @@
|
||||
name: CI Build
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- 'master'
|
||||
- 'test'
|
||||
jobs:
|
||||
build:
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-latest, macos-latest]
|
||||
uses: ./.github/workflows/build.yml
|
||||
with:
|
||||
os: ${{ matrix.os }}
|
||||
lint:
|
||||
uses: ./.github/workflows/lint.yml
|
||||
test:
|
||||
needs: build
|
||||
uses: ./.github/workflows/test.yml
|
||||
coverage:
|
||||
uses: ./.github/workflows/coverage.yml
|
||||
performance:
|
||||
needs: build
|
||||
uses: ./.github/workflows/performance.yml
|
||||
with:
|
||||
os: ubuntu-latest
|
||||
docs:
|
||||
uses: ./.github/workflows/docs.yml
|
||||
@@ -0,0 +1,29 @@
|
||||
name: Test Coverage
|
||||
on: [workflow_dispatch, workflow_call]
|
||||
jobs:
|
||||
coverage:
|
||||
name: Test Coverage
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: '14'
|
||||
- name: Install dependencies
|
||||
run: npm ci
|
||||
- name: Test
|
||||
run: npm run test:coverage
|
||||
- name: Coverage
|
||||
uses: coverallsapp/[email protected]
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Archive npm failure logs
|
||||
uses: actions/upload-artifact@v3
|
||||
if: failure()
|
||||
with:
|
||||
name: npm-logs
|
||||
path: ~/.npm/_logs
|
||||
@@ -1,19 +1,16 @@
|
||||
name: Docs
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
on: [workflow_dispatch, workflow_call]
|
||||
jobs:
|
||||
docs:
|
||||
name: Docs
|
||||
runs-on: ubuntu-18.04
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v2
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: '14'
|
||||
- name: Build
|
||||
@@ -21,7 +18,14 @@ jobs:
|
||||
npm ci
|
||||
npm run build:docs
|
||||
- name: Publish
|
||||
if: github.ref == 'refs/heads/master'
|
||||
uses: JamesIves/[email protected]
|
||||
with:
|
||||
branch: gh-pages
|
||||
folder: docs/public
|
||||
folder: docs/public
|
||||
- name: Archive npm failure logs
|
||||
uses: actions/upload-artifact@v3
|
||||
if: failure()
|
||||
with:
|
||||
name: npm-logs
|
||||
path: ~/.npm/_logs
|
||||
@@ -0,0 +1,25 @@
|
||||
name: Lint
|
||||
on: [workflow_dispatch, workflow_call]
|
||||
jobs:
|
||||
lint:
|
||||
name: Lint
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: '14'
|
||||
- name: Install dependencies
|
||||
run: npm ci
|
||||
- name: Lint
|
||||
run: npm run lint
|
||||
- name: Archive npm failure logs
|
||||
uses: actions/upload-artifact@v3
|
||||
if: failure()
|
||||
with:
|
||||
name: npm-logs
|
||||
path: ~/.npm/_logs
|
||||
@@ -0,0 +1,33 @@
|
||||
name: Performance Check
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
os:
|
||||
required: true
|
||||
type: string
|
||||
jobs:
|
||||
performance:
|
||||
name: Performance
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: '14'
|
||||
- name: Download artifacts
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: dist-${{ inputs.os }}
|
||||
path: dist
|
||||
- name: Check Performance
|
||||
run: npm run perf:diff
|
||||
- name: Archive npm failure logs
|
||||
uses: actions/upload-artifact@v3
|
||||
if: failure()
|
||||
with:
|
||||
name: npm-logs
|
||||
path: ~/.npm/_logs
|
||||
@@ -0,0 +1,22 @@
|
||||
name: PR Build
|
||||
on: pull_request
|
||||
jobs:
|
||||
build:
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-latest, macos-latest]
|
||||
uses: ./.github/workflows/build.yml
|
||||
with:
|
||||
os: ${{ matrix.os }}
|
||||
lint:
|
||||
uses: ./.github/workflows/lint.yml
|
||||
test:
|
||||
needs: build
|
||||
uses: ./.github/workflows/test.yml
|
||||
coverage:
|
||||
uses: ./.github/workflows/coverage.yml
|
||||
performance:
|
||||
needs: build
|
||||
uses: ./.github/workflows/performance.yml
|
||||
with:
|
||||
os: ubuntu-latest
|
||||
@@ -0,0 +1,14 @@
|
||||
name: PR Check
|
||||
on:
|
||||
pull_request_target:
|
||||
types:
|
||||
- opened
|
||||
- edited
|
||||
jobs:
|
||||
title:
|
||||
name: Check PR title
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: amannn/action-semantic-pull-request@v5
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
@@ -1,32 +1,49 @@
|
||||
name: Release
|
||||
on: workflow_dispatch
|
||||
jobs:
|
||||
build:
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-latest, macos-latest]
|
||||
uses: ./.github/workflows/build.yml
|
||||
with:
|
||||
os: ${{ matrix.os }}
|
||||
test:
|
||||
needs: build
|
||||
uses: ./.github/workflows/test.yml
|
||||
release:
|
||||
name: Release
|
||||
runs-on: ubuntu-18.04
|
||||
needs: [build, test]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v2
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: '14'
|
||||
- name: Build
|
||||
run: |
|
||||
npm ci
|
||||
npm run build:dist
|
||||
- name: Test
|
||||
run: |
|
||||
npm run lint
|
||||
npm run test
|
||||
- name: Coverage
|
||||
uses: coverallsapp/[email protected]
|
||||
node-version: '18'
|
||||
- name: Install Dependencies
|
||||
run: npm ci
|
||||
- name: Download artifacts
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
name: dist-ubuntu-latest
|
||||
path: dist
|
||||
- name: Release
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||
run: npx semantic-release
|
||||
run: |
|
||||
if [ ${{ github.ref == 'refs/heads/master' }} ]; then
|
||||
npx semantic-release
|
||||
else
|
||||
npx semantic-release --dry-run
|
||||
fi
|
||||
- name: Archive npm failure logs
|
||||
uses: actions/upload-artifact@v3
|
||||
if: failure()
|
||||
with:
|
||||
name: npm-logs
|
||||
path: ~/.npm/_logs
|
||||
@@ -0,0 +1,34 @@
|
||||
name: Test
|
||||
on: [workflow_dispatch, workflow_call]
|
||||
jobs:
|
||||
test:
|
||||
name: Test
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-latest, macos-latest]
|
||||
timezone: [Etc/GMT, Asia/Shanghai, America/New_York]
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: '14'
|
||||
- name: Install dependencies
|
||||
run: npm ci
|
||||
- name: Download artifacts
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: dist-${{ matrix.os }}
|
||||
path: dist
|
||||
- name: Run Test
|
||||
run: TZ=${{ matrix.timezone }} npm test
|
||||
- name: Archive npm failure logs
|
||||
uses: actions/upload-artifact@v3
|
||||
if: failure()
|
||||
with:
|
||||
name: npm-logs
|
||||
path: ~/.npm/_logs
|
||||
@@ -9,6 +9,9 @@ coverage/
|
||||
|
||||
# modules
|
||||
node_modules/
|
||||
|
||||
# tmp
|
||||
docs/public/js/liquid.browser.min.js
|
||||
dist/
|
||||
demo/*/package-lock.json
|
||||
demo/*/yarn.json
|
||||
|
||||
+215
@@ -1,3 +1,218 @@
|
||||
## [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)
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
# 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 build:docs` is used to build it.
|
||||
|
||||
Then, to start the site locally, go to `docs` and run `npm start`, then visit
|
||||
http://localhost:4000/playground.html.
|
||||
|
||||
The Playground uses a local built LiquidJS, which is created during `npm run build:docs`.
|
||||
To update that, you'll need to run `./bin/build-docs-liquid.sh` each time after making changes.
|
||||
Then refresh the Playground site for the changes to take effect.
|
||||
|
||||
## Performance
|
||||
|
||||
If your change can have a performance impact, you can update and run performance cases under `benchmark/`.
|
||||
|
||||
1. `npm run build:cjs` to build a CommonJS bundle for the perf test.
|
||||
2. `npm run perf:diff` to check whether there's a regression compared against `liquidjs@latest`
|
||||
|
||||
Further more, `benchmark/` contains different cases to check its ops/sec. Useful when debugging perf regressions, to use it:
|
||||
|
||||
- `cd benchmark` go into benchmark project
|
||||
- `npm ci` install dependencies
|
||||
- `npm start` run the cases
|
||||
@@ -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,28 +42,35 @@ 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.
|
||||
|
||||
## 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's useful to you, you can become a backer!
|
||||
If you personally like LiquidJS and find it useful to you, you can buy me a coffee!
|
||||
|
||||
<object type="image/svg+xml" data="https://opencollective.com/liquidjs/backers.svg?avatarHeight=72"></object>
|
||||
<img src="https://opencollective.com/liquidjs/backers.svg?avatarHeight=72">
|
||||
|
||||
### Sponsors
|
||||
If LiquidJS is benefiting your business/company, please sponsor us to make it better!
|
||||
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">
|
||||
|
||||
<object type="image/svg+xml" data="https://opencollective.com/liquidjs/sponsors.svg?avatarHeight=72"></object>
|
||||
## Contributors ✨
|
||||
|
||||
Want to contribute? see [Contribution Guidelines][contribution]. Thanks goes to these wonderful people:
|
||||
@@ -72,75 +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>
|
||||
<tr>
|
||||
<td align="center"><a href="https://github.com/ameyaapte1"><img src="https://avatars.githubusercontent.com/u/16054747?v=4?s=100" width="100px;" alt=""/><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"><a href="https://github.com/tbdrz"><img src="https://avatars.githubusercontent.com/u/50599116?v=4?s=100" width="100px;" alt=""/><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"><a href="http://santialbo.com"><img src="https://avatars.githubusercontent.com/u/1557563?v=4?s=100" width="100px;" alt=""/><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"><a href="https://github.com/YahangWu"><img src="https://avatars.githubusercontent.com/u/12295975?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Yahang Wu</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=YahangWu" title="Documentation">📖</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 -->
|
||||
|
||||
@@ -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
-22
@@ -1,24 +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 '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/\/_/\/}
|
||||
cat $file | ./bin/escape-nunjucks.js > $target
|
||||
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
+6
@@ -0,0 +1,6 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
BUNDLES=min npm run build
|
||||
mkdir -p docs/public/js/
|
||||
cp dist/liquid.browser.min.js docs/public/js/
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
set -ex
|
||||
|
||||
./bin/build-docs-liquid.sh
|
||||
./bin/build-contributors.sh
|
||||
./bin/build-apidoc.sh
|
||||
./bin/build-changelog.sh
|
||||
|
||||
+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
|
||||
}
|
||||
|
||||
@@ -9,8 +9,4 @@ if [ ! -f $FILE_LATEST ]; then
|
||||
curl $URL_LATEST > $FILE_LATEST
|
||||
fi
|
||||
|
||||
# if [ ! -f $FILE_LOCAL ]; then
|
||||
BUNDLES=cjs npm run build:dist
|
||||
# fi
|
||||
|
||||
exec node benchmark/diff.js $FILE_LOCAL $FILE_LATEST
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
# LiquidJS for Node.js
|
||||
# Using LiquidJS in ESM
|
||||
|
||||
## Get Started
|
||||
|
||||
|
||||
@@ -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
-10
@@ -1,24 +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!'
|
||||
}
|
||||
|
||||
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'),
|
||||
},
|
||||
};
|
||||
+1
-1
@@ -19,7 +19,7 @@ pretty_urls:
|
||||
trailing_html: false
|
||||
|
||||
theme: navy
|
||||
|
||||
skip_render: "api/**/*"
|
||||
highlight:
|
||||
enable: false
|
||||
prismjs:
|
||||
|
||||
Generated
+669
-358
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
|
||||
|
||||
@@ -54,8 +54,10 @@ filters:
|
||||
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
|
||||
@@ -78,7 +80,7 @@ filters:
|
||||
|
||||
tags:
|
||||
overview: overview.html
|
||||
"# (inline comment)": inline_comment.html
|
||||
"#": inline_comment.html
|
||||
assign: assign.html
|
||||
capture: capture.html
|
||||
case: case.html
|
||||
|
||||
+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
|
||||
|
||||
@@ -10,7 +10,7 @@ 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, at_least, at_most
|
||||
String | append, prepend, capitalize, upcase, downcase, strip, lstrip, rstrip, strip_newlines, split, replace, replace_first, remove, remove_first, truncate, truncatewords
|
||||
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, compact, size
|
||||
Date | date
|
||||
|
||||
@@ -4,7 +4,7 @@ title: raw
|
||||
|
||||
{% since %}v9.37.0{% endsince %}
|
||||
|
||||
Liquid filter that directly returns the value of the variable. Useful when [outputEscape](/api/interfaces/liquid_options_.liquidoptions.html#Optional-outputEscape) is set.
|
||||
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.
|
||||
|
||||
@@ -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
|
||||
```
|
||||
@@ -47,7 +47,7 @@
|
||||
},
|
||||
{
|
||||
"name": "API",
|
||||
"url": "/api/classes/liquid_.liquid.html",
|
||||
"url": "/api/classes/Liquid.html",
|
||||
"description": "TypeScript doc for LiquidJS classes and interfaces"
|
||||
}
|
||||
],
|
||||
|
||||
@@ -104,7 +104,7 @@ Note that we're referencing the first parameter by `include.header` instead of `
|
||||
</article>
|
||||
```
|
||||
|
||||
[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#Optional-dynamicPartials
|
||||
[jekyllInclude]: ../api/interfaces/liquid_options_.liquidoptions.html#Optional-jekyllInclude
|
||||
[extname]: /api/interfaces/LiquidOptions.html#extname
|
||||
[root]: /api/interfaces/LiquidOptions.html#root
|
||||
[dynamicPartials]: /api/interfaces/LiquidOptions.html#dynamicPartials
|
||||
[jekyllInclude]: /api/interfaces/LiquidOptions.html#jekyllInclude
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -8,17 +8,11 @@ Starring LiquidJS is the most important and easiest way to support us: boost its
|
||||
|
||||
## 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,7 +20,7 @@ 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, on LiquidJS [homepage](https://liquidjs.com/) 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-).
|
||||
|
||||
### Backers
|
||||
If you personally like LiquidJS and find it's useful to you, you can become a backer!
|
||||
@@ -38,8 +32,7 @@ If LiquidJS is benefiting your business/company, please sponsor us to make it be
|
||||
|
||||
<object type="image/svg+xml" data="https://opencollective.com/liquidjs/sponsors.svg?avatarHeight=72"></object>
|
||||
|
||||
[oc]: https://opencollective.com/liquidjs/contribute/backer-ii-10666/checkout
|
||||
[pt]: https://www.patreon.com/harttle
|
||||
[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
|
||||
|
||||
@@ -30,8 +30,9 @@ Though we're trying to be compatible with the Ruby version, there are still some
|
||||
* 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 has additional filters: [json][json].
|
||||
* 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
|
||||
|
||||
@@ -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
|
||||
@@ -108,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.
|
||||
@@ -128,7 +130,7 @@ 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 `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.
|
||||
@@ -138,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
|
||||
@@ -148,4 +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/liquid_options_.liquidoptions.html#Optional-jekyllInclude
|
||||
[jekyllInclude]: /api/interfaces/LiquidOptions.html#jekyllInclude
|
||||
|
||||
@@ -96,5 +96,5 @@ Rendering `{% random from:2, to:max %}` in scope `{ max: 10 }` will generate a r
|
||||
|
||||
|
||||
[register-tags]: /tutorials/register-filters-tags.html
|
||||
[Tokenizer]: /api/classes/parser_tokenizer_.tokenizer.html
|
||||
[Hash]: /api/classes/template_tag_hash_.hash.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
|
||||
|
||||
|
||||
@@ -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/fs.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/fs.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
|
||||
|
||||
@@ -133,5 +133,5 @@ The `parse()` is exactly the same as `wrap` tag, we repeat the content simply by
|
||||
[async]: ./sync-and-async.html
|
||||
[for]: ../tags/for.html
|
||||
[if]: ../tags/if.html
|
||||
[ParseStream]: ../api/classes/parser_parse_stream_.parsestream.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
|
||||
|
||||
@@ -24,67 +24,93 @@ The synchronous version of methods contains a `Sync` suffix:
|
||||
|
||||
## Implement Sync-Compatible Tags
|
||||
|
||||
### Requirements
|
||||
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()`.
|
||||
|
||||
All builtin tags are *sync-compatible* and safe to use for both sync and async APIs. To make your custom tag *sync-compatible*, you'll need to avoid return a `Promise`. That means the `render(context, emitter)`:
|
||||
```typescript
|
||||
import { TagToken, Context, Emitter, TopLevelToken, Value, Tag, Liquid } from 'liquidjs'
|
||||
|
||||
- Should not directly `return <Promise>`, and
|
||||
- Should not be declared as `async`.
|
||||
// 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 %}
|
||||
|
||||
### Await Promises
|
||||
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` and keep `* render()` instead of `async render()`. e.g.
|
||||
## Convert LiquidJS async Generator to Promise
|
||||
|
||||
You can convert a Generator to Promise by [toPromise][toPromise], for example:
|
||||
|
||||
```typescript
|
||||
import { TagToken, Context, Emitter, TopLevelToken } from 'liquidjs'
|
||||
import { TagToken, Context, Emitter, TopLevelToken, Value, Tag, Liquid, toPromise } from 'liquidjs'
|
||||
|
||||
// Usage: {% upper "alice" %}
|
||||
// Output: ALICE
|
||||
engine.registerTag('upper', {
|
||||
parse: function(tagToken: TagToken, remainTokens: TopLevelToken[]) {
|
||||
this.str = tagToken.args
|
||||
},
|
||||
* render: function(ctx: Context) {
|
||||
// _evalValue will behave synchronously when called by synchronous API
|
||||
// in which case `ctx.sync == true`
|
||||
var str = yield this.liquid._evalValue(this.str, ctx)
|
||||
return str.toUpperCase()
|
||||
}
|
||||
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())
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
See this JSFiddle: <http://jsfiddle.net/ctj364up/6/>.
|
||||
## Async only Tags
|
||||
|
||||
## Async-only Tags
|
||||
|
||||
For tags that intended to be used only by async API, or those cannot be implemented synchronously, there's no difference between using generator-base syntax or async syntax. I'll call them *async-only tags*.
|
||||
|
||||
For example, if the above `this.liquid._evalValue()` doesn't respect `ctx.sync` and always returns a Promise, even if the tag is implemented using `* render()` and `yield this.liquid._evalValue()`, it will be rendered as `<object Promise>` anyway.
|
||||
|
||||
For *async-only tags*, you can use async syntax at will. Be careful some APIs in LiquidJS return Promises and others return Generators. You'll need [toPromise][toPromise] API to convert a Generator to a Promise, for example:
|
||||
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 { TagToken, Context, Emitter, TopLevelToken, toPromise } from 'liquidjs'
|
||||
import { toPromise, TagToken, Context, Emitter, TopLevelToken, Value, Tag, Liquid } from 'liquidjs'
|
||||
|
||||
// Usage: {% upper "alice" %}
|
||||
// Output: ALICE
|
||||
engine.registerTag('upper', {
|
||||
parse: function(tagToken: TagToken, remainTokens: TopLevelToken[]) {
|
||||
this.str = tagToken.args; // name
|
||||
},
|
||||
render: async function(ctx: Context) {
|
||||
var str = await toPromise(this.liquid._evalValue(this.str, ctx));
|
||||
// Or use the alternate API that returns a Promise
|
||||
// var str = await this.liquid.evalValue(this.str, ctx);
|
||||
return str.toUpperCase()
|
||||
}
|
||||
});
|
||||
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>`)
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
See this JSFiddle: <http://jsfiddle.net/ctj364up/5/>.
|
||||
|
||||
[Liquid]: /api/classes/liquid_.liquid.html
|
||||
[toPromise]: /api/modules/liquid_.html#toPromise
|
||||
[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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -10,7 +10,7 @@ LiquidJS 共支持 40+ 个过滤器,可以分为如下几类:
|
||||
类别 | 过滤器
|
||||
--- | ---
|
||||
数学 | 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, remove, remove_first, truncate, truncatewords
|
||||
字符串 | 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, compact, size
|
||||
日期 | date
|
||||
|
||||
@@ -4,7 +4,7 @@ title: raw
|
||||
|
||||
{% since %}v9.37.0{% endsince %}
|
||||
|
||||
直接返回变量的值。配合 [outputEscape](/api/interfaces/liquid_options_.liquidoptions.html#Optional-outputEscape) 参数使用。
|
||||
直接返回变量的值。配合 [outputEscape](/api/interfaces/LiquidOptions.html#outputEscape) 参数使用。
|
||||
|
||||
{% note info 自动转义 %}
|
||||
默认情况下 `outputEscape` 为 `undefined`,这意味着 LiquidJS 输出不会默认转义,因此这时使用 `raw` 没有意义。
|
||||
|
||||
@@ -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
|
||||
```
|
||||
@@ -47,7 +47,7 @@
|
||||
},
|
||||
{
|
||||
"name": "API",
|
||||
"url": "/zh-cn/api/classes/liquid_.liquid.html",
|
||||
"url": "/api/classes/Liquid.html",
|
||||
"description": "LiquidJS 类和接口的 TypeScript 文档"
|
||||
}
|
||||
],
|
||||
|
||||
@@ -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!
|
||||
```
|
||||
@@ -104,7 +104,7 @@ title: Include
|
||||
</article>
|
||||
```
|
||||
|
||||
[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#Optional-dynamicPartials
|
||||
[jekyllInclude]: ../../api/interfaces/liquid_options_.liquidoptions.html#Optional-jekyllInclude
|
||||
[extname]: /api/interfaces/LiquidOptions.html#extname
|
||||
[root]: /api/interfaces/LiquidOptions.html#root
|
||||
[dynamicPartials]: /api/interfaces/LiquidOptions.html#dynamicPartials
|
||||
[jekyllInclude]: /api/interfaces/LiquidOptions.html#jekyllInclude
|
||||
|
||||
@@ -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
|
||||
```
|
||||
@@ -60,6 +60,6 @@ title: Render
|
||||
|
||||
{% note tip forloop 对象 %} 使用 for 参数时,在子模板中可以访问 <a href="./for.html#forloop">forloop</a> 对象。{% endnote %}
|
||||
|
||||
[extname]: ../../api/interfaces/liquid_options_.liquidoptions.html#Optional-extname
|
||||
[root]: ../../api/interfaces/liquid_options_.liquidoptions.html#Optional-root
|
||||
[globals]: ../../api/interfaces/liquid_options_.liquidoptions.html#Optional-globals
|
||||
[extname]: /api/interfaces/LiquidOptions.html#extname
|
||||
[root]: /api/interfaces/LiquidOptions.html#root
|
||||
[globals]: /api/interfaces/LiquidOptions.html#globals
|
||||
|
||||
@@ -47,8 +47,9 @@ engine.renderFileSync('hello', {name: 'alice'})
|
||||
engine.renderFileSync('hello', {name: 'bob'})
|
||||
```
|
||||
|
||||
[parse]: ../../api/classes/liquid_.liquid.html#parse
|
||||
[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
|
||||
|
||||
@@ -8,17 +8,11 @@ Star 是支持 LiquidJS 最重要的方式,也是最简单的方式:通过
|
||||
|
||||
## 发起 Pull Request
|
||||
|
||||
**代码风格**:LiquidJS 采用 [standard](https://github.com/standard/eslint-config-standard) 和 [@typescript-eslint/recommended](https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/eslint-plugin/src/configs/recommended.json) 规则,提交前确保可以通过风格检查:
|
||||
开发和构建描述在这篇文档里 [CONTRIBUTING.md](https://github.com/harttle/liquidjs/blob/master/CONTRIBUTING.md)。
|
||||
|
||||
```bash
|
||||
npm run lint
|
||||
```
|
||||
**代码风格**:LiquidJS 采用 [standard](https://github.com/standard/eslint-config-standard) 和 [@typescript-eslint/recommended](https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/eslint-plugin/src/configs/recommended.json) 规则。
|
||||
|
||||
**测试**:确保你改动之后测试仍然可以通过:
|
||||
|
||||
```bash
|
||||
npm test
|
||||
```
|
||||
**测试**:确保你改动之后测试仍然可以通过 `npm test`
|
||||
|
||||
**提交消息**:请遵守 [Angular 提交消息规范](https://github.com/angular/angular.js/blob/master/DEVELOPERS.md#commits),尤其注意 [type 标识](https://github.com/angular/angular.js/blob/master/DEVELOPERS.md#type),semantic-release 机器人依赖这个标识自动发布。
|
||||
|
||||
@@ -26,7 +20,7 @@ npm test
|
||||
|
||||
## 资金支持
|
||||
|
||||
LiquidJS 是开源和免费的,但支持 [Open Collective][oc] 或 [Patreon][pt] 赞助,作为感谢你的名字和头像(或 Logo)会展示在这里,[LiquidJS 首页](https://liquidjs.com/)和 [Github README][liquidjs]。
|
||||
LiquidJS 是开源和免费的,但支持 [Open Collective][oc] 赞助,作为感谢你的名字和头像(或 Logo)会展示在这里,[LiquidJS 首页](https://liquidjs.com/)和 [Github README][liquidjs]。
|
||||
|
||||
### 支持者
|
||||
如果你喜欢 LiquidJS,希望支持我们,你可以成为 Open Collective Backer!
|
||||
@@ -39,7 +33,6 @@ LiquidJS 是开源和免费的,但支持 [Open Collective][oc] 或 [Patreon][p
|
||||
<object type="image/svg+xml" data="https://opencollective.com/liquidjs/sponsors.svg?avatarHeight=72"></object>
|
||||
|
||||
[oc]: https://opencollective.com/liquidjs/
|
||||
[pt]: https://www.patreon.com/harttle
|
||||
[shopify/liquid]: https://shopify.github.io/liquid/
|
||||
[caniuse-promises]: http://caniuse.com/#feat=promises
|
||||
[pp]: https://github.com/taylorhakes/promise-polyfill
|
||||
|
||||
@@ -16,7 +16,7 @@ LiquidJS 语法相对简单。LiquidJS 中有两种标记:
|
||||
|
||||
## 输出
|
||||
|
||||
**输出** 用于转换和输出变量到 HTMl。下面的模板将会把 `username` 的值插入到 input 的 `value`:
|
||||
**输出** 用于转换和输出变量到 HTML。下面的模板将会把 `username` 的值插入到 input 的 `value`:
|
||||
|
||||
```liquid
|
||||
<input type="text" name="user" value="{{username}}">
|
||||
|
||||
@@ -12,7 +12,7 @@ const engine = new Liquid({
|
||||
```
|
||||
|
||||
{% note info API 文档 %}
|
||||
下面的所有选项的概述,希望了解具体的类型和签名,请前往 <a href="https://liquidjs.com/api/interfaces/liquid_options_.liquidoptions.html" target="_self">LiquidOptions | API</a>.
|
||||
下面的所有选项的概述,希望了解具体的类型和签名,请前往 <a href="https://liquidjs.com/api/interfaces/LiquidOptions.html" target="_self">LiquidOptions | API</a>.
|
||||
{% endnote %}
|
||||
|
||||
## 缓存
|
||||
@@ -106,6 +106,7 @@ LiquidJS 把这个选项默认值设为 <code>true</code> 以兼容于 shopify/l
|
||||
|
||||
**preserveTimezones** 是一个布尔值,只影响时间戳字面量。当设置为 `true` 时,所有字面量的时间戳字符串会在输出时保持原状,即不论输入时采取怎样的时区,输出时仍然采用那一时区(和 Shopify Liquid 的行为一致)。注意这是一个解析器参数,渲染时传入的数据中的日期的输出不会受此参数影响。注意 `preserveTimezones` 比 `timezoneOffset` 的优先级更高。
|
||||
|
||||
**dateFormat** 用于指定输出日期的默认格式. `%A, %B %-e, %Y at %-l:%M %P %z` 如果未指定,将使用. 例如,设置 `dateFormat: %Y-%m-%dT%H:%M:%S:%LZ` 以输出 [JavaSrcipt Date.toJson()][https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Date/toJSON] 格式.
|
||||
|
||||
## 换行和缩进
|
||||
|
||||
@@ -135,7 +136,7 @@ LiquidJS 把这个选项默认值设为 <code>true</code> 以兼容于 shopify/l
|
||||
|
||||
默认会忽略参数出现的顺序,例如 `{% for i in (1..8) reversed limit:3 %}` 里总是会先执行 `limit` 再执行 `reversed`,虽然 `reversed` 先出现。为了让 LiquidJS 按顺序执行参数,需要设置 **orderedFilterParameters** 为 `true`。它的默认值为 `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
|
||||
@@ -145,4 +146,4 @@ LiquidJS 把这个选项默认值设为 <code>true</code> 以兼容于 shopify/l
|
||||
[layout]: ../tags/layout.html
|
||||
[wc]: ./whitespace-control.html
|
||||
[intro]: ./intro-to-liquid.html
|
||||
[jekyllInclude]: ../api/interfaces/liquid_options_.liquidoptions.html#Optional-jekyllInclude
|
||||
[jekyllInclude]: /api/interfaces/LiquidOptions.html#jekyllInclude
|
||||
|
||||
@@ -96,5 +96,5 @@ engine.registerTag('random', {
|
||||
在 `{ max: 10 }` 上下文上渲染 `{% random from:2, to:max %}` 将会得到 [2, 10] 范围内的随机数。见这个 JSFiddle:<http://jsfiddle.net/ctj364up/4/>。
|
||||
|
||||
[register-tags]: /tutorials/register-filters-tags.html
|
||||
[Tokenizer]: /api/classes/parser_tokenizer_.tokenizer.html
|
||||
[Hash]: /api/classes/template_tag_hash_.hash.html
|
||||
[Tokenizer]: /api/classes/Tokenizer.html
|
||||
[Hash]: /api/classes/Hash.html
|
||||
|
||||
@@ -45,5 +45,5 @@ engine.parseAndRender('{{ "foo" | upup }}').then(console.log)
|
||||
* Sections 标签(开发中): https://github.com/harttle/liquidjs-section-tags
|
||||
* 颜色过滤器: https://github.com/harttle/liquidjs-color-filters
|
||||
|
||||
[liquid]: ../../api/classes/liquid_.liquid.html
|
||||
[liquid]: /api/classes/Liquid.html
|
||||
[register]: ./register-filters-tags.html
|
||||
@@ -8,10 +8,10 @@ title: 注册标签和过滤器
|
||||
// 使用方式: {% upper name %}
|
||||
engine.registerTag('upper', {
|
||||
parse: function(tagToken, remainTokens) {
|
||||
this.str = tagToken.args; // name
|
||||
this.value = new Value(token.args, liquid)
|
||||
},
|
||||
render: async function(scope, hash) {
|
||||
var str = await this.liquid.evalValue(this.str, scope); // 'alice'
|
||||
render: function*(scope, hash) {
|
||||
const str = yield this.value.value(ctx); // 'alice'
|
||||
return str.toUpperCase() // 'Alice'
|
||||
}
|
||||
});
|
||||
@@ -20,7 +20,26 @@ engine.registerTag('upper', {
|
||||
* `parse`: 从 `remainTokens` 中读取后续的标签/输出/HTML,直到找到你期望的结束标签。
|
||||
* `render`: 把 scope 数据和此前解析得到的 Token 结合,输出 HTML 字符串。
|
||||
|
||||
查看已有的标签实现:<https://github.com/harttle/liquidjs/tree/master/src/builtin/tags>
|
||||
对于更复杂的标签实现,可以提供一个继承自 `Tag` 的类:
|
||||
|
||||
```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'
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
可以参考已有的标签实现:<https://github.com/harttle/liquidjs/tree/master/src/tags>
|
||||
|
||||
## 注册过滤器
|
||||
|
||||
@@ -36,7 +55,24 @@ engine.registerFilter('upper', v => v.toUpperCase())
|
||||
engine.registerFilter('add', (initial, arg1, arg2) => initial + arg1 + arg2)
|
||||
```
|
||||
|
||||
查看已有的过滤器实现:<https://github.com/harttle/liquidjs/tree/master/src/builtin/filters>
|
||||
查看已有的过滤器实现:<https://github.com/harttle/liquidjs/tree/master/src/filters>。对于复杂的标签,也可以用一个类来实现:
|
||||
|
||||
```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'
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
## 反注册标签/过滤器
|
||||
|
||||
|
||||
@@ -100,14 +100,14 @@ const engine = new Liquid({
|
||||
});
|
||||
```
|
||||
|
||||
[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
|
||||
|
||||
@@ -133,5 +133,5 @@ engine.registerTag('repeat', {
|
||||
[async]: ./sync-and-async.html
|
||||
[for]: ../tags/for.html
|
||||
[if]: ../tags/if.html
|
||||
[ParseStream]: ../api/classes/parser_parse_stream_.parsestream.html
|
||||
[ParseStream]: /api/classes/ParseStream.html
|
||||
[parameter]: ./parse-parameters.html
|
||||
|
||||
@@ -24,66 +24,89 @@ LiquidJS 支持同步调用也支持异步调用,支持 Promise。为了同异
|
||||
|
||||
## 如何实现兼容同步的标签
|
||||
|
||||
### 要求
|
||||
|
||||
所有内置标签都兼容同步,可以安全地用于同步或异步 API。为了让你的自定义标签页支持同步,你的标签不能返回 `Promise`,这意味着你的 `render(context, emitter)` 函数:
|
||||
|
||||
- 不能直接 `return <Promise>`,
|
||||
- 也不能声明为 `async`。
|
||||
|
||||
{% note info 不兼容同步的标签 %}
|
||||
不兼容同步的标签也仍然是合法标签,在异步 API 下也会正常运行。被同步调用时,返回 <code>Promise</code> 的标签会被渲染成 <code>[object Promise]</code>。
|
||||
{% endnote %}
|
||||
|
||||
### 等待 Promise
|
||||
但 LiquidJS 是支持 `Promise` 的,你仍然可以调用返回 `Promise` 的方法并等它 resolve。只需要把 `await` 换成 `yield` 并保留 `* render()` 不要改成 `async render()`。例如:
|
||||
LiquidJS 使用基于生成器的异步实现,来让同一份代码支持同步和异步调用。例如下面的 `UpperTag` 既可以用于 `engine.renderSync()` 也可以用于 `engine.render()`:
|
||||
|
||||
```typescript
|
||||
import { TagToken, Context, Emitter, TopLevelToken } from 'liquidjs'
|
||||
import { TagToken, Context, Emitter, TopLevelToken, Value, Tag, Liquid } from 'liquidjs'
|
||||
|
||||
// Usage: {% upper "alice" %}
|
||||
// Output: ALICE
|
||||
engine.registerTag('upper', {
|
||||
parse: function(tagToken: TagToken, remainTokens: TopLevelToken[]) {
|
||||
this.str = tagToken.args
|
||||
},
|
||||
* render: function(ctx: Context) {
|
||||
// 同步调用时 `ctx.sync == true`,`_evalValue()` 会同步地执行
|
||||
var str = yield this.liquid._evalValue(this.str, ctx)
|
||||
return str.toUpperCase()
|
||||
}
|
||||
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())
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
见这个 JSFiddle:<http://jsfiddle.net/ctj364up/6/>。
|
||||
所有内置标签都兼容同步,可以安全地用于同步或异步 API。实现同时支持同异步的标签,需要:
|
||||
|
||||
## 只支持异步的标签
|
||||
- render 函数声明成 `* render()`,并且在里面
|
||||
- 不能直接 `return <Promise>`,
|
||||
- 不能调用会返回 Promise 的函数。
|
||||
|
||||
对于只用于异步 API 的标签,或者只能实现为异步的标签,使用生成器语法和 async 语法并没有区别。
|
||||
## 调用返回 Promise 的函数
|
||||
|
||||
例如,如果上面的 `this.liquid._evalValue()` 不会检查 `ctx.sync` 而且总是返回一个 `Promise`,那么即使这个标签用 `* render()` 和 `yield this.liquid._evalValue()` 实现,最终也会渲染成 `<object Promise>`。
|
||||
|
||||
这时可以直接使用 async 语法。注意有些 LiquidJS API 会返回 `Promise`,有些会返回生成器。你需要用 [toPromise][toPromise] API 来把生成器转换为 `Promise`,比如:
|
||||
但 LiquidJS 是支持 `Promise` 的,你仍然可以调用返回 `Promise` 的方法并等它 resolve。只需要把 `await` 换成 `yield`。例如:
|
||||
|
||||
```typescript
|
||||
import { TagToken, Context, Emitter, TopLevelToken, toPromise } from 'liquidjs'
|
||||
* render (ctx: Context, emitter: Emitter) {
|
||||
const file = yield this.value.value(ctx)
|
||||
const title = yield fs.readFile(file, 'utf8')
|
||||
emitter.write(title.toUpperCase())
|
||||
}
|
||||
```
|
||||
|
||||
现在 `* render()` 调用了一个返回 Promise 的 API,它就不再兼容同步了。不兼容同步的标签也仍然是合法标签,在异步 API 下也会正常运行。被同步调用时,返回 <code>Promise</code> 的标签会被渲染成 <code>[object Promise]</code>。
|
||||
|
||||
## 把 LiquidJS 生成器转换成 Promise
|
||||
|
||||
有些 LiquidJS API 会返回 `Promise`,有些会返回生成器。你可以用 [toPromise][toPromise] 来把生成器转换为 `Promise`,比如:
|
||||
|
||||
```typescript
|
||||
import { TagToken, Context, Emitter, TopLevelToken, Value, Tag, Liquid, toPromise } from 'liquidjs'
|
||||
|
||||
// Usage: {% upper "alice" %}
|
||||
// Output: ALICE
|
||||
engine.registerTag('upper', {
|
||||
parse: function(tagToken: TagToken, remainTokens: TopLevelToken[]) {
|
||||
this.str = tagToken.args; // name
|
||||
},
|
||||
render: async function(ctx: Context) {
|
||||
var str = await toPromise(this.liquid._evalValue(this.str, ctx));
|
||||
// Or use the alternate API that returns a Promise
|
||||
// var str = await this.liquid.evalValue(this.str, ctx);
|
||||
return str.toUpperCase()
|
||||
}
|
||||
});
|
||||
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())
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
见这个 JSFiddle:<http://jsfiddle.net/ctj364up/5/>。
|
||||
## 纯异步标签
|
||||
|
||||
[Liquid]: /api/classes/liquid_.liquid.html
|
||||
[toPromise]: /api/modules/liquid_.html#toPromise
|
||||
如果你的标签就不打算支持同步,可以干脆实现成 `async render()`,这样就可以使用更熟悉的 `await` 了:
|
||||
|
||||
```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
|
||||
|
||||
@@ -61,12 +61,12 @@ var engine = new Liquid({
|
||||
|
||||
`cache` 还可以是一个数字表示最大缓存的模板数量,也可以是一个自定义的缓存实现,详情请参考 [cache 选项][cache]。
|
||||
|
||||
[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
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user