Compare commits

...
234 Commits
Author SHA1 Message Date
Harttle 417432fb8a chore: split Github Actions workflows 2023-06-05 23:23:52 +08:00
semantic-release-bot 495bef2d0c chore(release): 10.8.2 [skip ci]
## [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))
2023-06-04 05:42:37 +00:00
Harttle fcb930f0dd fix: sample filter randomness and count=1 case 2023-06-04 13:34:16 +08:00
semantic-release-bot b4e12232be chore(release): 10.8.1 [skip ci]
## [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))
2023-06-04 04:05:53 +00:00
Harttle 3a67eb7f1c fix: incorrect error message for browser UMD bundle 2023-06-04 12:00:32 +08:00
Harttle fc42438283 docs: add Tomáš Hübelbauer as contributor 2023-06-04 11:41:49 +08:00
Harttle 8acf405949 docs: update ace version for LiquidJS playground 2023-06-04 02:24:06 +08:00
Harttle e9da7f39de docs: add contributing.md into docs/.../contribution-guidelines.md 2023-06-04 02:15:36 +08:00
semantic-release-bot 87e83b63fc chore(release): 10.8.0 [skip ci]
# [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))
* 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))
2023-06-03 18:09:56 +00:00
HarttleandJun Yang e347e603d7 feat: precise line/col for tokenization Error, #613 2023-06-04 02:06:42 +08:00
HarttleandJun Yang 0480d3317d fix: proper error message for filter syntax error, #610 2023-06-04 02:06:42 +08:00
Tomáš HübelbauerandJun Yang 82ba54845f feat: introduce a matrix with latest Ubuntu and macOS to test the build on macOS as well
Once #615 is merged, the build script should work on macOS just as well as it does on Ubuntu and with this GitHub Actions matrix we can keep ensuring that it continues to work as it should.
2023-06-03 23:16:33 +08:00
Tomas HubelbauerandJun Yang 05c478c322 docs: explain how to point the Playground at the local build
This should help anyone looking to test their changes they made to LiquidJS via the Playground site also provided in the repository.

I have also added basic information on where the Playground is and how to run it in general.
2023-06-03 23:06:18 +08:00
Tomáš HübelbauerandGitHub 87d4cc7e14 fix: sed invocations to work out of the box on macOS (#615)
* fix: sed invocations to work out of the box on macOS

These fixes make the sed invocations run on macOS but I am not sure if they will break the GNU sed invocations in return…

* fix: add macOS branches to the shell scripts

The sed command line was difficult (impossible?) to be made portable so I just added macOS conditions.

* Prototype the solution using an alias

It seems that this will not work because I keep getting "sedi: command not found".

* fix: use a Bash function instead of an alias to run sed portably

This seems to work on my local so let's see if it runs in the CI on GitHub.

* fix: use 2 spaces like the original scripts did

Not sure why VS Code went with 4.

* fix: use sedi for the build-changelog `1i\` part as well

I am curious if Ubuntu will handle the newline…
2023-06-03 22:56:25 +08:00
Tomáš HübelbauerandGitHub 202556115f chore: sed invocations for docs build to work on macOS (#615)
* fix: sed invocations to work out of the box on macOS

These fixes make the sed invocations run on macOS but I am not sure if they will break the GNU sed invocations in return…

* fix: add macOS branches to the shell scripts

The sed command line was difficult (impossible?) to be made portable so I just added macOS conditions.

* Prototype the solution using an alias

It seems that this will not work because I keep getting "sedi: command not found".

* fix: use a Bash function instead of an alias to run sed portably

This seems to work on my local so let's see if it runs in the CI on GitHub.

* fix: use 2 spaces like the original scripts did

Not sure why VS Code went with 4.

* fix: use sedi for the build-changelog `1i\` part as well

I am curious if Ubuntu will handle the newline…
2023-06-03 22:55:38 +08:00
Tomáš HübelbauerandGitHub db67118a75 test: Add tests for push (#614)
* Add support for the Jekyll sample filter

See https://jekyllrb.com/docs/liquid/filters

I am sorting the array randomly and then picking the first N items or all items if there is no sample limit.

* Add tests for `push`

I thought `push` was broken because it doesn't work on the Playground but that's not the case. Here are the tests to prove it. Taken from the `concat` tests.

* Remove the sample experiment

This got in from another branch lol.

* Recommend the build:dist command over the whole build

This one works for me locally whereas build:docs is reporting some issues.

* Return the full `build` command and explain how to use `commitlint` to workshop the message

I am working on a PR to make `build` run on macOS because it is a part of the pre-commit hook anyway so all contributors should make it work for them.

I have also shown how to check your messages against `commitlint` from the CLI because it is faster than using the VS Code GUI.
2023-05-30 00:06:22 +08:00
Tomáš HübelbauerandGitHub ba8b842452 feat: Add support for the Jekyll sample filter (#612)
* Add support for the Jekyll sample filter

See https://jekyllrb.com/docs/liquid/filters

I am sorting the array randomly and then picking the first N items or all items if there is no sample limit.

* Remove incorrect spaces before parens

Typo and copy-paste meet
2023-05-27 00:55:39 +08:00
Tomas HubelbauerandJun Yang dca9ab52b8 Add support for the Jekyll push filter
See https://jekyllrb.com/docs/liquid/filters
2023-05-24 02:08:49 +08:00
semantic-release-bot 7ceff17fcb chore(release): 10.7.1 [skip ci]
## [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))
2023-04-24 17:31:07 +00:00
HarttleandJun Yang 648b158dbd chore: update CI runs-on 2023-04-25 01:28:48 +08:00
HarttleandJun Yang 33b3c010af fix: incorrect timezone correction for DST dates, fixes #604 2023-04-25 01:28:48 +08:00
HarttleandJun Yang 21ee27b575 fix: timezoneOffset ignored in date when preserveTimezones is enabled, fixes #605 2023-04-25 01:28:48 +08:00
semantic-release-bot c2a8365054 chore(release): 10.7.0 [skip ci]
# [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))
2023-03-21 16:57:29 +00:00
allcontributors[bot]GitHuballcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com>
b2a1dc972e docs: add mahyar-pasarzangene as a contributor for doc (#602)
* docs: update README.md [skip ci]

* docs: update .all-contributorsrc [skip ci]

---------

Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com>
2023-03-22 00:55:05 +08:00
Mahyar PasarzangeneandGitHub 1bddd60b01 fix: update remove.md (#601)
The output was wrong. Filter would replace the rain all over the text.
2023-03-22 00:54:30 +08:00
Jun Yang 7b87ea82d3 feat: JSON format by space in json filter 2023-03-22 00:08:24 +08:00
allcontributors[bot]andJun Yang 8037f7b4a4 docs: update .all-contributorsrc [skip ci] 2023-03-20 23:10:49 +08:00
allcontributors[bot]andJun Yang 75aba92733 docs: update README.md [skip ci] 2023-03-20 23:10:49 +08:00
Jun Yang b9f8d85c65 chore: add PR title checker 2023-03-20 23:09:19 +08:00
BaNganandJun Yang e50267feaa Update differences.md
- Shopify also has `json` filter, I think it is equivalent to liquidJS `json`
2023-03-20 22:58:46 +08:00
Harttle 04d62f070a docs: update docs pipeline 2023-03-20 00:56:44 +08:00
semantic-release-bot d04ccd79c9 chore(release): 10.6.2 [skip ci]
## [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))
2023-03-19 16:43:24 +00:00
HarttleandJun Yang 9d823937cc chore: upload npm errors for failed pipeline 2023-03-20 00:41:06 +08:00
HarttleandJun Yang da93102c1c chore: upgrade API doc to latest typedoc, fixes #593 2023-03-20 00:41:06 +08:00
HarttleandJun Yang c6cde9cd10 chore: migrate test cases from Chai to Jest 2023-03-20 00:41:06 +08:00
allcontributors[bot]andJun Yang dccb90c591 docs: update .all-contributorsrc [skip ci] 2023-03-19 23:44:13 +08:00
allcontributors[bot]andJun Yang 228a5c3bed docs: update README.md [skip ci] 2023-03-19 23:44:13 +08:00
bobgubkoandGitHub 4542ddcfc3 fix: sample FS in render-file.md (#594) 2023-03-19 23:42:41 +08:00
Jun Yang 2def145cf6 docs: update docs for ownPropertyOnly, #588 2023-03-04 00:21:41 +08:00
semantic-release-bot 14e059c933 chore(release): 10.6.1 [skip ci]
## [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))
2023-03-02 16:17:49 +00:00
Harttle 771b9b9eba style: fix code style 2023-03-03 00:14:38 +08:00
Harttle 9c0dc5fa39 fix: [expression] apply value equal for arrays, #589 2023-03-02 23:44:56 +08:00
Harttle 42d25902e8 fix: strip_html for multi line <script>/<style>/comments, #70 2023-03-02 23:01:15 +08:00
Jun Yang d4e519c4a6 chore: update build badge, coverage to 100%, mv DEFAULT_FMT to defaultOptions 2023-02-23 01:05:54 +08:00
semantic-release-bot 5f4a004e90 chore(release): 10.6.0 [skip ci]
# [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))
2023-02-22 16:00:10 +00:00
prassieandGitHub 3fb66465c6 feat: LiquidOptions.dateFormat to override default date format (#587)
doc: updates related to LiquidOptions.dateFormat
doc: revamped the date filter doc for easier reference
2023-02-22 23:56:33 +08:00
semantic-release-bot d9cac4efca chore(release): 10.5.0 [skip ci]
# [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))
2023-02-14 15:06:52 +00:00
Harttle 8ef920928c docs: add slavivanov and DaRosenberg into contributor list 2023-02-14 22:57:25 +08:00
Slav IvanovandHarttle d489916231 fix: "ownPropertyOnly" not respected when passed via "renderOptions" 2023-02-14 22:39:38 +08:00
24c8a1e372 feat: Adds support for options to CLI and improves usability (#586)
* Improved UX of CLI

* Updated docs and setup tutorial

* Corrected version number in TODO comments

* Downgraded lock file version

* Restored previous lock file

* Removed --keep-output-type option

* Switch to using async IO to avoid problems stdin in some scenarios

https://stackoverflow.com/questions/40362369/stdin-read-fails-on-some-input

https://stackoverflow.com/questions/40362369/stdin-read-fails-on-some-input

* Addressed feedback from code review

* Changed to curl-like systax for specifing inputs as literals, paths or stdin

---------

Co-authored-by: Daniel Rosenberg <[email protected]>
2023-02-14 22:03:00 +08:00
allcontributors[bot]andJun Yang a6618538d1 docs: update .all-contributorsrc [skip ci] 2023-02-04 11:33:02 +08:00
allcontributors[bot]andJun Yang c0c3c07ba1 docs: update README.md [skip ci] 2023-02-04 11:33:02 +08:00
prassieandGitHub a55f44f095 Added documentation for date ordinals support in date filter via %q (#581)
* Added date ordinals support in date filter via %q

* fix: validation regex for default date format

* fix: validation regex for default date format
2023-02-04 11:31:30 +08:00
Jun Yang 7f76e1311f docs: list sponsors & backers separately on liquidjs.com 2023-01-22 21:37:47 +08:00
semantic-release-bot 312000366d chore(release): 10.4.0 [skip ci]
# [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))
2023-01-02 17:42:18 +00:00
HarttleandHarttle 3f21382d43 feat: support not operator, #575 2023-01-03 01:34:03 +08:00
HarttleandHarttle aafaa0b4f9 feat: support calling date without format string, #573 2023-01-03 00:53:33 +08:00
semantic-release-bot 964e5e8961 chore(release): 10.3.3 [skip ci]
## [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))
2022-12-18 04:58:05 +00:00
Jun Yang fb6a9f8717 fix: type compatible with v9 tag definition, support Context as scope in various render APIs, #570 2022-12-18 12:48:06 +08:00
semantic-release-bot 7526d4062d chore(release): 10.3.2 [skip ci]
## [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))
2022-12-13 18:16:48 +00:00
HarttleandHarttle 2663ee16a0 fix: re-export error classes, #569 2022-12-14 02:14:03 +08:00
HarttleandHarttle d24655887f docs: update docs and demo for Value usage, fixes #568 2022-12-14 02:14:03 +08:00
semantic-release-bot a9f93d7235 chore(release): 10.3.1 [skip ci]
## [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))
2022-12-12 11:48:42 +00:00
HarttleandHarttle 0f4916bc5a fix: support Context as evalValue parameter, #568 2022-12-12 19:41:29 +08:00
semantic-release-bot f4a033ecea chore(release): 10.3.0 [skip ci]
# [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))
2022-12-11 18:35:51 +00:00
Jun Yang 5ac3765612 chore: update liquid options to match raw filters 2022-12-12 02:32:50 +08:00
Jun Yang e6db371519 feat: support disable outputEscape for specific filters, #565 2022-12-12 02:17:18 +08:00
Jun Yang a2d949209d docs: doc for timezone parameter of date filter, #553 2022-12-12 01:35:40 +08:00
dependabot[bot]andJun Yang 08a0c1322c chore(deps): bump decode-uri-component from 0.2.0 to 0.2.2 in /docs
Bumps [decode-uri-component](https://github.com/SamVerschueren/decode-uri-component) from 0.2.0 to 0.2.2.
- [Release notes](https://github.com/SamVerschueren/decode-uri-component/releases)
- [Commits](https://github.com/SamVerschueren/decode-uri-component/compare/v0.2.0...v0.2.2)

---
updated-dependencies:
- dependency-name: decode-uri-component
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <[email protected]>
2022-12-03 00:20:10 +08:00
semantic-release-bot dad75ee877 chore(release): 10.2.0 [skip ci]
# [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))
2022-12-02 16:18:42 +00:00
Jun Yang d17813ef52 fix: case should render multiple when statements 2022-12-03 00:14:47 +08:00
Jun Yang 46ffe036a8 docs: zh-cn translation for replace_last, remove_last 2022-12-02 23:54:58 +08:00
dependabot[bot]andJun Yang f47d91a9a6 chore(deps): bump decode-uri-component from 0.2.0 to 0.2.2
Bumps [decode-uri-component](https://github.com/SamVerschueren/decode-uri-component) from 0.2.0 to 0.2.2.
- [Release notes](https://github.com/SamVerschueren/decode-uri-component/releases)
- [Commits](https://github.com/SamVerschueren/decode-uri-component/compare/v0.2.0...v0.2.2)

---
updated-dependencies:
- dependency-name: decode-uri-component
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <[email protected]>
2022-12-02 23:50:08 +08:00
James PriorandJun Yang 8a1efc0f2e docs: fix remove_first example output 2022-12-02 23:49:59 +08:00
James PriorandJun Yang ff4fd44666 docs: remove_last and replace_last 2022-12-02 23:48:50 +08:00
James PriorandJun Yang 6c3f1c1e0c feat: add remove_last filter 2022-12-02 23:48:50 +08:00
James PriorandJun Yang b4d1e27420 feat: add replace_last filter 2022-12-02 23:48:50 +08:00
semantic-release-bot 6f0a68080c chore(release): 10.1.0 [skip ci]
# [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))
2022-11-29 16:25:22 +00:00
HarttleandHarttle 89c6c7676d feat: timezone name for opts.timezoneOffset and date argument, fixes #553 2022-11-30 00:20:12 +08:00
Jun Yang b7ab357964 docs: update CHANGELOG 2022-11-27 18:02:07 +08:00
semantic-release-bot 9b9ef374a8 chore(release): 10.0.0 [skip ci]
# [10.0.0](https://github.com/harttle/liquidjs/compare/v9.43.0...v10.0.0) (2022-11-27)

### chore

* rename filters to snake style, [#487](https://github.com/harttle/liquidjs/issues/487) ([ff112a4](https://github.com/harttle/liquidjs/commit/ff112a4750f91475e9eccdb301d7a468e895f6ca))

### Code Refactoring

* `_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.
2022-11-27 09:51:43 +00:00
dependabot[bot]andJun Yang 5bbdc08eff chore(deps): bump minimatch from 3.0.4 to 3.1.2
Bumps [minimatch](https://github.com/isaacs/minimatch) from 3.0.4 to 3.1.2.
- [Release notes](https://github.com/isaacs/minimatch/releases)
- [Commits](https://github.com/isaacs/minimatch/compare/v3.0.4...v3.1.2)

---
updated-dependencies:
- dependency-name: minimatch
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <[email protected]>
2022-11-27 17:47:55 +08:00
Jun Yang 1380ac931a refactor: more consistent tags to make it easier to iterate over, #524 2022-11-27 17:29:44 +08:00
Jun Yang 4e1a30a20c refactor: _evalToken renamed to evalToken
BREAKING CHANGE: `evalToken` now returns a generator (LiquidJS async), which is different from `evalToken` in previous LiquidJS versions.
2022-11-27 14:04:02 +08:00
Jun Yang 92992689cd refactor: Tag class support in registerTag() 2022-11-27 14:04:01 +08:00
Jun Yang 1f6ce7c822 perf: target Node.js 14 for cjs bundle (main entry)
BREAKING CHANGE: main entry need Node.js>=14 to run, you can build LiquidJS by your own by using ESM entry.
2022-11-27 14:04:01 +08:00
Jun Yang 7eb621601c refactor: change ownPropertyOnly default value to true
BREAKING CHANGE: `ownPropertyOnly` default value changed to `true`
2022-11-27 14:04:01 +08:00
Jun Yang ffefd91fbc refactor: remove toThenable export
BREAKING CHANGE: `<liquidjs>.toThenable` is removed, use `<liquidjs>.toPromise` instead
2022-11-27 14:04:01 +08:00
Jun Yang b115077e12 refactor: remove use of internal Context class in evalValue argument
BREAKING CHANGE: `evalValue` won't support `Context` as second argument anymore.
2022-11-27 14:04:01 +08:00
Jun Yang bb58d3e549 refactor: delay creation of operatorsTrie and hide this implementation
BREAKING CHANGE: use `operators` instead of `operatorsTrie` as Tokenizer constructor argument, #500
2022-11-27 14:04:01 +08:00
Jun Yang ff112a4750 chore: rename filters to snake style, #487
BREAKING CHANGE: keys in `<liquidjs>.filters` are now in snake case (instead of camel case), identical to that in Liquid template.
2022-11-27 14:04:00 +08:00
semantic-release-bot 907c4dea06 chore(release): 9.43.0 [skip ci]
# [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))
2022-11-27 05:50:17 +00:00
Jun Yang 7a714855df feat: support timezone offset argument for date filter, #553 2022-11-27 13:46:51 +08:00
dependabot[bot]andJun Yang cd918ccb85 chore(deps): bump minimatch from 3.0.4 to 3.1.2 in /docs
Bumps [minimatch](https://github.com/isaacs/minimatch) from 3.0.4 to 3.1.2.
- [Release notes](https://github.com/isaacs/minimatch/releases)
- [Commits](https://github.com/isaacs/minimatch/compare/v3.0.4...v3.1.2)

---
updated-dependencies:
- dependency-name: minimatch
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <[email protected]>
2022-11-14 17:24:50 +08:00
HarttleandHarttle 8061e559ac docs: fix tags sidebar translation 2022-10-23 18:16:55 +08:00
allcontributors[bot]andJun Yang 33e97db903 docs: update .all-contributorsrc [skip ci] 2022-10-22 23:59:12 +08:00
allcontributors[bot]andJun Yang 9cfc8fd2df docs: update README.md [skip ci] 2022-10-22 23:59:12 +08:00
f62b2109f2 docs: add echo and liquid tags Chinese translation (#549)
* docs: add echo and liquid tags chinese translation

* Update docs/source/zh-cn/tags/echo.md

Co-authored-by: Jun Yang <[email protected]>

* Update docs/source/zh-cn/tags/echo.md

Co-authored-by: Jun Yang <[email protected]>

* Update docs/source/zh-cn/tags/echo.md

Co-authored-by: Jun Yang <[email protected]>

* Update Liquid.md

* Update Liquid.md

Co-authored-by: Jun Yang <[email protected]>
2022-10-22 23:56:31 +08:00
semantic-release-bot bf6b5c7da1 chore(release): 9.42.1 [skip ci]
## [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))
2022-10-21 16:58:08 +00:00
dependabot[bot]andJun Yang a58fe449e3 chore(deps): bump minimist and hexo-renderer-swig in /docs
Bumps [minimist](https://github.com/minimistjs/minimist) to 1.2.7 and updates ancestor dependency [hexo-renderer-swig](https://github.com/hexojs/hexo-renderer-swig). These dependencies need to be updated together.


Updates `minimist` from 1.2.5 to 1.2.7
- [Release notes](https://github.com/minimistjs/minimist/releases)
- [Changelog](https://github.com/minimistjs/minimist/blob/main/CHANGELOG.md)
- [Commits](https://github.com/minimistjs/minimist/compare/v1.2.5...v1.2.7)

Updates `hexo-renderer-swig` from 1.1.0 to 2.0.0
- [Release notes](https://github.com/hexojs/hexo-renderer-swig/releases)
- [Commits](https://github.com/hexojs/hexo-renderer-swig/commits)

---
updated-dependencies:
- dependency-name: minimist
  dependency-type: indirect
- dependency-name: hexo-renderer-swig
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <[email protected]>
2022-10-22 00:55:15 +08:00
dependabot[bot]andJun Yang 99516cb75f chore(deps): bump semver-regex from 2.0.0 to 3.1.4
Bumps [semver-regex](https://github.com/sindresorhus/semver-regex) from 2.0.0 to 3.1.4.
- [Release notes](https://github.com/sindresorhus/semver-regex/releases)
- [Commits](https://github.com/sindresorhus/semver-regex/compare/v2.0.0...v3.1.4)

---
updated-dependencies:
- dependency-name: semver-regex
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <[email protected]>
2022-10-22 00:53:04 +08:00
dependabot[bot]andJun Yang 850ab0c749 chore(deps): bump ansi-regex from 3.0.0 to 3.0.1
Bumps [ansi-regex](https://github.com/chalk/ansi-regex) from 3.0.0 to 3.0.1.
- [Release notes](https://github.com/chalk/ansi-regex/releases)
- [Commits](https://github.com/chalk/ansi-regex/compare/v3.0.0...v3.0.1)

---
updated-dependencies:
- dependency-name: ansi-regex
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <[email protected]>
2022-10-22 00:52:53 +08:00
HarttleandHarttle 33c7c8f301 docs: demo for using LiquidJS with webpack 2022-10-22 00:39:18 +08:00
HarttleandHarttle 32f613fb43 fix: truncatewords should use at least one word, #537 2022-10-21 14:40:25 +08:00
Jun YangandGitHub 71a1dc6e72 docs: update README 2022-10-18 03:06:14 +08:00
Jun YangandGitHub 375a19b0fd chore: update funding.yml 2022-10-18 03:01:12 +08:00
Jun YangandGitHub 4e17fdc3b1 docs: update README.md 2022-10-18 02:41:14 +08:00
allcontributors[bot]andJun Yang 01c25044ac docs: update .all-contributorsrc [skip ci] 2022-10-08 23:04:19 +08:00
allcontributors[bot]andJun Yang 4a9b467c1b docs: update README.md [skip ci] 2022-10-08 23:04:19 +08:00
honglandJun Yang 78f2120a85 Update intro-to-liquid.md 2022-10-08 23:02:56 +08:00
dependabot[bot]andJun Yang adfc27c480 chore(deps): bump moment-timezone from 0.5.28 to 0.5.37 in /docs
Bumps [moment-timezone](https://github.com/moment/moment-timezone) from 0.5.28 to 0.5.37.
- [Release notes](https://github.com/moment/moment-timezone/releases)
- [Changelog](https://github.com/moment/moment-timezone/blob/develop/changelog.md)
- [Commits](https://github.com/moment/moment-timezone/compare/0.5.28...0.5.37)

---
updated-dependencies:
- dependency-name: moment-timezone
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <[email protected]>
2022-09-02 23:30:27 +08:00
semantic-release-bot 0075be9e6e chore(release): 9.42.0 [skip ci]
# [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))
2022-08-27 15:23:22 +00:00
HarttleandHarttle bbf00f37bf feat: promise in expression & nested property, #533 #276 2022-08-27 23:19:16 +08:00
semantic-release-bot 0997530bab chore(release): 9.41.0 [skip ci]
# [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))
2022-08-24 12:59:20 +00:00
HarttleandHarttle 071368afe1 feat: use evalValue to parse & render expression, #527 2022-08-24 20:46:22 +08:00
dependabot[bot]andJun Yang 2089b9bb6c chore(deps): bump path-parse and path-parse
Bumps [path-parse](https://github.com/jbgutierrez/path-parse) and [path-parse](https://github.com/jbgutierrez/path-parse). These dependencies needed to be updated together.

Updates `path-parse` from 1.0.7 to 1.0.7
- [Release notes](https://github.com/jbgutierrez/path-parse/releases)
- [Commits](https://github.com/jbgutierrez/path-parse/compare/v1.0.7...v1.0.7)

Updates `path-parse` from 1.0.6 to 1.0.7
- [Release notes](https://github.com/jbgutierrez/path-parse/releases)
- [Commits](https://github.com/jbgutierrez/path-parse/compare/v1.0.7...v1.0.7)

---
updated-dependencies:
- dependency-name: path-parse
  dependency-type: indirect
- dependency-name: path-parse
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <[email protected]>
2022-08-20 23:58:19 +08:00
semantic-release-bot fd7002f6bb chore(release): 9.40.0 [skip ci]
# [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))
2022-08-14 18:43:29 +00:00
HarttleandHarttle 905a6dd149 fix: target ES6 for ESM bundles, fixes #526 2022-08-15 02:34:23 +08:00
HarttleandHarttle e874b4060b feat: export toValueSync & defaultOptions to evaluate expression, see #527 2022-08-15 01:53:48 +08:00
semantic-release-bot 753e8f94c0 chore(release): 9.39.2 [skip ci]
## [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))
2022-07-21 15:04:28 +00:00
dependabot[bot]andJun Yang 0a1d60453e chore(deps): bump terser from 4.6.7 to 4.8.1 in /docs
Bumps [terser](https://github.com/terser/terser) from 4.6.7 to 4.8.1.
- [Release notes](https://github.com/terser/terser/releases)
- [Changelog](https://github.com/terser/terser/blob/master/CHANGELOG.md)
- [Commits](https://github.com/terser/terser/commits)

---
updated-dependencies:
- dependency-name: terser
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <[email protected]>
2022-07-21 23:01:24 +08:00
HarttleandHarttle 4ad383d9be fix: expression support Drop.valueOf, fixes #522 2022-07-21 01:21:58 +08:00
semantic-release-bot 66eb3b842a chore(release): 9.39.1 [skip ci]
## [9.39.1](https://github.com/harttle/liquidjs/compare/v9.39.0...v9.39.1) (2022-07-14)

### Bug Fixes

* throw ParseError instead of RenderError for invalid assign expression, closes [#519](https://github.com/harttle/liquidjs/issues/519) ([c41a5d5](https://github.com/harttle/liquidjs/commit/c41a5d5babf85ccedbcb3b6f9a3cf5c326f72ae1))
2022-07-14 16:45:29 +00:00
Harttle c41a5d5bab fix: throw ParseError instead of RenderError for invalid assign expression, closes #519 2022-07-15 00:41:51 +08:00
semantic-release-bot 0aca2dd8c1 chore(release): 9.39.0 [skip ci]
# [9.39.0](https://github.com/harttle/liquidjs/compare/v9.38.0...v9.39.0) (2022-07-09)

### Bug Fixes

* for tag not respecting Drop#valueOf(), fixes [#515](https://github.com/harttle/liquidjs/issues/515) ([c3e51ca](https://github.com/harttle/liquidjs/commit/c3e51caa701fd4449ed5257e23569a37ef12dea2))

### Features

* iteration protocols ([a19feea](https://github.com/harttle/liquidjs/commit/a19feea7c46fc476139a150bda051f485328afe8))
2022-07-09 16:31:12 +00:00
Harttle 4289b4e804 refactor: rename toValue to toValueSync 2022-07-10 00:24:00 +08:00
Harttle c3e51caa70 fix: for tag not respecting Drop#valueOf(), fixes #515 2022-07-09 22:21:51 +08:00
James PriorandJun Yang a19feea7c4 feat: iteration protocols 2022-07-09 18:21:54 +08:00
semantic-release-bot e87f068067 chore(release): 9.38.0 [skip ci]
# [9.38.0](https://github.com/harttle/liquidjs/compare/v9.37.0...v9.38.0) (2022-07-07)

### Bug Fixes

* stack overflow on large number of templates, [#513](https://github.com/harttle/liquidjs/issues/513) ([3dc4290](https://github.com/harttle/liquidjs/commit/3dc4290b56265cfafbee8d9836e912d9b8492f90))

### Features

* inline comment tag ([#514](https://github.com/harttle/liquidjs/issues/514)) ([2f87708](https://github.com/harttle/liquidjs/commit/2f8770898963e35ac4491f6975a8abd03dc09067))
2022-07-07 19:06:27 +00:00
dependabot[bot]andJun Yang 392b859381 chore(deps): bump moment from 2.29.2 to 2.29.4 in /docs
Bumps [moment](https://github.com/moment/moment) from 2.29.2 to 2.29.4.
- [Release notes](https://github.com/moment/moment/releases)
- [Changelog](https://github.com/moment/moment/blob/develop/CHANGELOG.md)
- [Commits](https://github.com/moment/moment/compare/2.29.2...2.29.4)

---
updated-dependencies:
- dependency-name: moment
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <[email protected]>
2022-07-08 03:00:36 +08:00
Harttle ed95d9a760 chore: update to node 16 2022-07-08 02:56:39 +08:00
Harttle 0f824355fa docs: zh-cn doc for inline comment 2022-07-08 01:59:09 +08:00
Harttle 3dc4290b56 fix: stack overflow on large number of templates, #513 2022-07-08 01:46:51 +08:00
jg-rpandGitHub 2f87708989 feat: inline comment tag (#514)
* style: remove unnecessary intermediate constant

* feat: add inline comment tag

* refactor: use readIdentifier when reading tag names

* docs: add inline comment tag
2022-07-08 01:46:15 +08:00
dependabot[bot]andJun Yang 4a0186d62a chore(deps-dev): bump jsdom from 13.2.0 to 16.5.0
Bumps [jsdom](https://github.com/jsdom/jsdom) from 13.2.0 to 16.5.0.
- [Release notes](https://github.com/jsdom/jsdom/releases)
- [Changelog](https://github.com/jsdom/jsdom/blob/master/Changelog.md)
- [Commits](https://github.com/jsdom/jsdom/compare/13.2.0...16.5.0)

---
updated-dependencies:
- dependency-name: jsdom
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <[email protected]>
2022-07-02 20:59:55 +08:00
dependabot[bot]andJun Yang c9e4220c88 chore(deps-dev): bump semantic-release from 17.2.3 to 19.0.3
Bumps [semantic-release](https://github.com/semantic-release/semantic-release) from 17.2.3 to 19.0.3.
- [Release notes](https://github.com/semantic-release/semantic-release/releases)
- [Commits](https://github.com/semantic-release/semantic-release/compare/v17.2.3...v19.0.3)

---
updated-dependencies:
- dependency-name: semantic-release
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <[email protected]>
2022-06-10 23:49:21 +08:00
Jun YangandGitHub bb8f8f569d docs: update security policy 2022-05-17 23:53:20 +08:00
HarttleandHarttle 2f6d84befc test: cases for async variables 2022-05-03 13:31:25 +08:00
semantic-release-bot 463a165e5e chore(release): 9.37.0 [skip ci]
# [9.37.0](https://github.com/harttle/liquidjs/compare/v9.36.2...v9.37.0) (2022-04-21)

### Bug Fixes

* support integer arithmetic for `divided_by`, closes [#465](https://github.com/harttle/liquidjs/issues/465) ([e69a510](https://github.com/harttle/liquidjs/commit/e69a51025efa7dec7d60d0067200a1466988ebbc))

### Features

* automatic output escaping, closes [#500](https://github.com/harttle/liquidjs/issues/500) ([f88490c](https://github.com/harttle/liquidjs/commit/f88490cd3cd0b5316c43c3ca76837544d99ce0b0))
2022-04-21 18:23:02 +00:00
Harttle f88490cd3c feat: automatic output escaping, closes #500 2022-04-22 02:19:36 +08:00
Harttle e69a51025e fix: support integer arithmetic for divided_by, closes #465 2022-04-22 02:19:36 +08:00
allcontributors[bot]andJun Yang ace5309c08 docs: update .all-contributorsrc [skip ci] 2022-04-19 23:55:10 +08:00
allcontributors[bot]andJun Yang 5a90c5bf74 docs: update README.md [skip ci] 2022-04-19 23:55:10 +08:00
semantic-release-bot f6e047867e chore(release): 9.36.2 [skip ci]
## [9.36.2](https://github.com/harttle/liquidjs/compare/v9.36.1...v9.36.2) (2022-04-19)

### Bug Fixes

* lazy createRequire to allow exceptions being catched, fixes [#497](https://github.com/harttle/liquidjs/issues/497) ([b377dad](https://github.com/harttle/liquidjs/commit/b377dad9e34c3de3e0eedc1ee6f17a0e9d919669))
2022-04-19 15:51:00 +00:00
Yahang WuandGitHub c467630e0b docs: fix a broken link for abstract file interface (#498) 2022-04-19 23:48:25 +08:00
Harttle b377dad9e3 fix: lazy createRequire to allow exceptions being catched, fixes #497 2022-04-19 23:44:14 +08:00
semantic-release-bot ecc04c99c5 chore(release): 9.36.1 [skip ci]
## [9.36.1](https://github.com/harttle/liquidjs/compare/v9.36.0...v9.36.1) (2022-04-17)

### Bug Fixes

* contains operator does not support Drop, fixes [#492](https://github.com/harttle/liquidjs/issues/492) ([9e024ff](https://github.com/harttle/liquidjs/commit/9e024ff2bcf17e7ac19c718389d4cef39b8a51f7))
* responsive header ([a56af6b](https://github.com/harttle/liquidjs/commit/a56af6bbfb5b698db55fbeb87e8e0872688fbe19))
* use `createRequire` for ESM, fixes [#334](https://github.com/harttle/liquidjs/issues/334) ([eec381e](https://github.com/harttle/liquidjs/commit/eec381ec72db3858452799b7a3264e240be3044d))
2022-04-17 16:45:54 +00:00
Harttle 9e024ff2bc fix: contains operator does not support Drop, fixes #492 2022-04-18 00:43:18 +08:00
Harttle eec381ec72 fix: use createRequire for ESM, fixes #334 2022-04-18 00:43:17 +08:00
dependabot[bot]andJun Yang c7216c6358 chore(deps): bump ansi-regex from 4.1.0 to 4.1.1 in /docs
Bumps [ansi-regex](https://github.com/chalk/ansi-regex) from 4.1.0 to 4.1.1.
- [Release notes](https://github.com/chalk/ansi-regex/releases)
- [Commits](https://github.com/chalk/ansi-regex/compare/v4.1.0...v4.1.1)

---
updated-dependencies:
- dependency-name: ansi-regex
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <[email protected]>
2022-04-18 00:43:02 +08:00
dependabot[bot]andJun Yang fe78890d35 chore(deps): bump minimist from 1.2.5 to 1.2.6
Bumps [minimist](https://github.com/substack/minimist) from 1.2.5 to 1.2.6.
- [Release notes](https://github.com/substack/minimist/releases)
- [Commits](https://github.com/substack/minimist/compare/1.2.5...1.2.6)

---
updated-dependencies:
- dependency-name: minimist
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <[email protected]>
2022-04-17 23:54:16 +08:00
dependabot[bot]andJun Yang d5771ba42c chore(deps): bump moment from 2.24.0 to 2.29.2 in /docs
Bumps [moment](https://github.com/moment/moment) from 2.24.0 to 2.29.2.
- [Release notes](https://github.com/moment/moment/releases)
- [Changelog](https://github.com/moment/moment/blob/develop/CHANGELOG.md)
- [Commits](https://github.com/moment/moment/compare/2.24.0...2.29.2)

---
updated-dependencies:
- dependency-name: moment
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <[email protected]>
2022-04-17 22:02:49 +08:00
dependabot[bot]andJun Yang 776d235fca chore(deps): bump async from 3.1.0 to 3.2.3
Bumps [async](https://github.com/caolan/async) from 3.1.0 to 3.2.3.
- [Release notes](https://github.com/caolan/async/releases)
- [Changelog](https://github.com/caolan/async/blob/master/CHANGELOG.md)
- [Commits](https://github.com/caolan/async/compare/v3.1.0...v3.2.3)

---
updated-dependencies:
- dependency-name: async
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <[email protected]>
2022-04-17 21:55:18 +08:00
Harttle a56af6bbfb fix: responsive header 2022-03-17 16:19:57 +08:00
semantic-release-bot 1af8553651 chore(release): 9.36.0 [skip ci]
# [9.36.0](https://github.com/harttle/liquidjs/compare/v9.35.2...v9.36.0) (2022-03-05)

### Features

* Access array item by negative index, closes [#486](https://github.com/harttle/liquidjs/issues/486) ([049685b](https://github.com/harttle/liquidjs/commit/049685b9a0271ba03875e24ff2f6c7870cae62a7))
* allow strip filter with specified char, closes [#390](https://github.com/harttle/liquidjs/issues/390) ([c503cb2](https://github.com/harttle/liquidjs/commit/c503cb23dfbdd6f146d6dea16a84eab3df1f7aa9))
* appropriate error for malformed filters, fixes [#271](https://github.com/harttle/liquidjs/issues/271) ([01014ed](https://github.com/harttle/liquidjs/commit/01014edc491e12d38981045442da9faee598cdf7))
2022-03-05 16:56:21 +00:00
Harttle 049685b9a0 feat: Access array item by negative index, closes #486 2022-03-06 00:52:22 +08:00
Harttle c503cb23df feat: allow strip filter with specified char, closes #390 2022-03-06 00:20:51 +08:00
Harttle 01014edc49 feat: appropriate error for malformed filters, fixes #271 2022-03-05 23:24:16 +08:00
Harttle 27e579e0e2 test: case for {% assign %} invalid value, closes #446 2022-03-05 22:09:36 +08:00
semantic-release-bot d3e3fecf53 chore(release): 9.35.2 [skip ci]
## [9.35.2](https://github.com/harttle/liquidjs/compare/v9.35.1...v9.35.2) (2022-03-02)

### Bug Fixes

* corner case for concat filter without argument, [#481](https://github.com/harttle/liquidjs/issues/481) ([aa95517](https://github.com/harttle/liquidjs/commit/aa955173d4c7adc585e862934429f1f4c5f64969))
* export all builtin tags from LiquidJS, [#464](https://github.com/harttle/liquidjs/issues/464) ([33009bb](https://github.com/harttle/liquidjs/commit/33009bb988eb74c58f390992750d91b967cb3428))
2022-03-02 13:26:07 +00:00
Harttle 33009bb988 fix: export all builtin tags from LiquidJS, #464 2022-03-02 21:21:45 +08:00
Harttle aa955173d4 fix: corner case for concat filter without argument, #481 2022-03-02 21:21:25 +08:00
semantic-release-bot 15b78ebd9d chore(release): 9.35.1 [skip ci]
## [9.35.1](https://github.com/harttle/liquidjs/compare/v9.35.0...v9.35.1) (2022-02-26)

### Bug Fixes

* some filters throw on nil input, see [#481](https://github.com/harttle/liquidjs/issues/481) ([7dfb620](https://github.com/harttle/liquidjs/commit/7dfb620d30f8818685e1cfb8e7492313a0d036ab))
2022-02-26 18:12:38 +00:00
Harttle 575f3e2338 docs: add missing tag/filter links on sidebar/table, #482 2022-02-27 02:07:59 +08:00
Harttle 7dfb620d30 fix: some filters throw on nil input, see #481 2022-02-27 02:07:59 +08:00
dependabot[bot]andJun Yang 21b78d9ba0 chore(deps): bump prismjs from 1.25.0 to 1.27.0 in /docs
Bumps [prismjs](https://github.com/PrismJS/prism) from 1.25.0 to 1.27.0.
- [Release notes](https://github.com/PrismJS/prism/releases)
- [Changelog](https://github.com/PrismJS/prism/blob/master/CHANGELOG.md)
- [Commits](https://github.com/PrismJS/prism/compare/v1.25.0...v1.27.0)

---
updated-dependencies:
- dependency-name: prismjs
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <[email protected]>
2022-02-27 02:06:04 +08:00
Harttle 5d077f461a chore: add liquid.min.js into Github release 2022-02-24 01:39:27 +08:00
semantic-release-bot 13343040c6 chore(release): 9.35.0 [skip ci]
# [9.35.0](https://github.com/harttle/liquidjs/compare/v9.34.1...v9.35.0) (2022-02-23)

### Bug Fixes

* `url_encode` throws on undefined value, fixes [#479](https://github.com/harttle/liquidjs/issues/479) ([ca3240c](https://github.com/harttle/liquidjs/commit/ca3240c2c4d157095d2ebe0024d0c71bc5e435f8))

### Features

* expose all tags/filters and TimezoneDate, closes [#464](https://github.com/harttle/liquidjs/issues/464) ([dab8a29](https://github.com/harttle/liquidjs/commit/dab8a29070b2508f2e6532717b7663966f610bec))
2022-02-23 17:20:40 +00:00
Harttle ca3240c2c4 fix: url_encode throws on undefined value, fixes #479 2022-02-24 01:14:46 +08:00
Harttle 2b0c5696bc docs: introduce JS script to escape for Hexo, fixes #480 2022-02-24 01:04:50 +08:00
Harttle dab8a29070 feat: expose all tags/filters and TimezoneDate, closes #464 2022-02-23 23:38:21 +08:00
semantic-release-bot f395295721 chore(release): 9.34.1 [skip ci]
## [9.34.1](https://github.com/harttle/liquidjs/compare/v9.34.0...v9.34.1) (2022-02-20)

### Bug Fixes

* array output now join with "" instead of "," ([ab5e245](https://github.com/harttle/liquidjs/commit/ab5e245fba9a0f6936275319d4e5e25aadb0f7c1))
* sort filter unexpectedly modifies original array, [#475](https://github.com/harttle/liquidjs/issues/475) ([dbc0497](https://github.com/harttle/liquidjs/commit/dbc049738633b1b6f578d9d20f830b548ba67a22))
2022-02-20 07:59:53 +00:00
Harttle 200f6648aa style: fix lint 2022-02-20 15:56:23 +08:00
dependabot[bot]andJun Yang 31aa4ec318 chore(deps): bump ssri from 6.0.1 to 6.0.2
Bumps [ssri](https://github.com/npm/ssri) from 6.0.1 to 6.0.2.
- [Release notes](https://github.com/npm/ssri/releases)
- [Changelog](https://github.com/npm/ssri/blob/v6.0.2/CHANGELOG.md)
- [Commits](https://github.com/npm/ssri/compare/v6.0.1...v6.0.2)

---
updated-dependencies:
- dependency-name: ssri
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <[email protected]>
2022-02-20 13:04:22 +08:00
dependabot[bot]andJun Yang 231574903f chore(deps): bump y18n from 3.2.1 to 3.2.2
Bumps [y18n](https://github.com/yargs/y18n) from 3.2.1 to 3.2.2.
- [Release notes](https://github.com/yargs/y18n/releases)
- [Changelog](https://github.com/yargs/y18n/blob/master/CHANGELOG.md)
- [Commits](https://github.com/yargs/y18n/commits)

---
updated-dependencies:
- dependency-name: y18n
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <[email protected]>
2022-02-20 13:04:12 +08:00
Harttle dbc0497386 fix: sort filter unexpectedly modifies original array, #475 2022-02-20 13:03:40 +08:00
Harttle ab5e245fba fix: array output now join with "" instead of "," 2022-02-20 13:03:40 +08:00
dependabot[bot]andJun Yang 78ce5662df chore(deps): bump ini from 1.3.5 to 1.3.8
Bumps [ini](https://github.com/isaacs/ini) from 1.3.5 to 1.3.8.
- [Release notes](https://github.com/isaacs/ini/releases)
- [Commits](https://github.com/isaacs/ini/compare/v1.3.5...v1.3.8)

---
updated-dependencies:
- dependency-name: ini
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <[email protected]>
2022-02-20 12:53:30 +08:00
dependabot[bot]andJun Yang 8b880f65a2 chore(deps): bump hosted-git-info from 2.8.8 to 2.8.9
Bumps [hosted-git-info](https://github.com/npm/hosted-git-info) from 2.8.8 to 2.8.9.
- [Release notes](https://github.com/npm/hosted-git-info/releases)
- [Changelog](https://github.com/npm/hosted-git-info/blob/v2.8.9/CHANGELOG.md)
- [Commits](https://github.com/npm/hosted-git-info/compare/v2.8.8...v2.8.9)

---
updated-dependencies:
- dependency-name: hosted-git-info
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <[email protected]>
2022-02-20 12:30:08 +08:00
dependabot[bot]andJun Yang d605158f96 chore(deps): bump tar from 4.4.13 to 4.4.19
Bumps [tar](https://github.com/npm/node-tar) from 4.4.13 to 4.4.19.
- [Release notes](https://github.com/npm/node-tar/releases)
- [Changelog](https://github.com/npm/node-tar/blob/main/CHANGELOG.md)
- [Commits](https://github.com/npm/node-tar/compare/v4.4.13...v4.4.19)

---
updated-dependencies:
- dependency-name: tar
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <[email protected]>
2022-02-20 12:29:48 +08:00
dependabot[bot]andJun Yang 1a44b908ce chore(deps): bump npm-user-validate from 1.0.0 to 1.0.1
Bumps [npm-user-validate](https://github.com/npm/npm-user-validate) from 1.0.0 to 1.0.1.
- [Release notes](https://github.com/npm/npm-user-validate/releases)
- [Commits](https://github.com/npm/npm-user-validate/compare/v1.0.0...v1.0.1)

---
updated-dependencies:
- dependency-name: npm-user-validate
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <[email protected]>
2022-02-20 12:29:42 +08:00
Santi AlboandJun Yang a0817e5dd7 docs: fix uniq filter example in the docs 2022-02-18 19:06:01 +08:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
703675e1e0 chore(deps): bump pathval from 1.1.0 to 1.1.1 (#467)
Bumps [pathval](https://github.com/chaijs/pathval) from 1.1.0 to 1.1.1.
- [Release notes](https://github.com/chaijs/pathval/releases)
- [Changelog](https://github.com/chaijs/pathval/blob/master/CHANGELOG.md)
- [Commits](https://github.com/chaijs/pathval/compare/v1.1.0...v1.1.1)

---
updated-dependencies:
- dependency-name: pathval
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <[email protected]>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-02-16 17:57:12 +08:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
819d060a92 chore(deps): bump ajv from 6.12.0 to 6.12.6 in /docs (#468)
Bumps [ajv](https://github.com/ajv-validator/ajv) from 6.12.0 to 6.12.6.
- [Release notes](https://github.com/ajv-validator/ajv/releases)
- [Commits](https://github.com/ajv-validator/ajv/compare/v6.12.0...v6.12.6)

---
updated-dependencies:
- dependency-name: ajv
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <[email protected]>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-02-16 17:57:00 +08:00
allcontributors[bot]GitHuballcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com>
c3d7ecbde1 docs: add santialbo as a contributor for doc (#470)
* docs: update README.md [skip ci]

* docs: update .all-contributorsrc [skip ci]

Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com>
2022-02-16 17:56:46 +08:00
Jun YangandGitHub 8bdb70878f Merge pull request #469 from santialbo/patch-1
docs: fix example in main docs page
2022-02-16 17:54:10 +08:00
Santi AlboandGitHub 2e1537d50c docs: fix example in main docs page 2022-02-16 10:13:41 +01:00
HarttleandHarttle d4afbc038f docs: add support button on navbar 2022-02-13 15:12:16 +08:00
Damian NowakandGitHub 58d03890b4 docs: whitespace-control: correct typo (#462) 2022-01-29 11:50:37 +08:00
semantic-release-bot e3fb47a90b chore(release): 9.34.0 [skip ci]
# [9.34.0](https://github.com/harttle/liquidjs/compare/v9.33.1...v9.34.0) (2022-01-28)

### Bug Fixes

* where-filter null handling ([#457](https://github.com/harttle/liquidjs/issues/457)) ([9da41c8](https://github.com/harttle/liquidjs/commit/9da41c8a37d9c49ee4a16d5bd520fd6ae01c14ec))

### Features

* `ownPropertyOnly` option to protect prototype, [#454](https://github.com/harttle/liquidjs/issues/454) ([7e99efc](https://github.com/harttle/liquidjs/commit/7e99efc5131e20cf3f59e1fc2c371a15aa4109db))
2022-01-28 17:37:13 +00:00
dependabot[bot]andJun Yang e4ad93ee8c chore(deps): bump node-fetch from 2.6.1 to 2.6.7
Bumps [node-fetch](https://github.com/node-fetch/node-fetch) from 2.6.1 to 2.6.7.
- [Release notes](https://github.com/node-fetch/node-fetch/releases)
- [Commits](https://github.com/node-fetch/node-fetch/compare/v2.6.1...v2.6.7)

---
updated-dependencies:
- dependency-name: node-fetch
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <[email protected]>
2022-01-29 01:32:26 +08:00
HarttleandHarttle 0bdf6792d1 docs: add @tbdrz as contributor 2022-01-29 01:30:48 +08:00
HarttleandHarttle 7e99efc513 feat: ownPropertyOnly option to protect prototype, #454 2022-01-29 01:22:34 +08:00
HarttleandHarttle 527858fc14 docs: better PWA, more responsive, better description 2022-01-29 00:37:43 +08:00
Martin SchusterandGitHub 9da41c8a37 fix: where-filter null handling (#457) 2022-01-28 22:43:38 +08:00
tbdrzandJun Yang 2717dae127 Clear unusefull comments 2022-01-28 22:41:11 +08:00
Harttle 8db6c7b28d docs: tutorial for render tag content 2022-01-23 14:24:58 +08:00
dependabot[bot]andJun Yang 298db97b84 chore(deps): bump shelljs from 0.8.4 to 0.8.5
Bumps [shelljs](https://github.com/shelljs/shelljs) from 0.8.4 to 0.8.5.
- [Release notes](https://github.com/shelljs/shelljs/releases)
- [Changelog](https://github.com/shelljs/shelljs/blob/master/CHANGELOG.md)
- [Commits](https://github.com/shelljs/shelljs/compare/v0.8.4...v0.8.5)

---
updated-dependencies:
- dependency-name: shelljs
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <[email protected]>
2022-01-23 00:02:46 +08:00
dependabot[bot]andJun Yang bd8e2b0f96 chore(deps): bump trim-off-newlines from 1.0.1 to 1.0.3
Bumps [trim-off-newlines](https://github.com/stevemao/trim-off-newlines) from 1.0.1 to 1.0.3.
- [Release notes](https://github.com/stevemao/trim-off-newlines/releases)
- [Commits](https://github.com/stevemao/trim-off-newlines/compare/v1.0.1...v1.0.3)

---
updated-dependencies:
- dependency-name: trim-off-newlines
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <[email protected]>
2022-01-23 00:02:32 +08:00
HarttleandHarttle 117eaf57c3 docs: add additional filters/tags as differences, closes #331 2022-01-22 23:24:06 +08:00
HarttleandHarttle 1e69d86b0c chore: build docs on master push 2022-01-22 21:59:02 +08:00
HarttleandHarttle cc6b66216d docs: support dark mode 2022-01-22 21:51:49 +08:00
HarttleandHarttle ca82416dea docs: apply network-first cache strategy 2022-01-22 19:04:12 +08:00
HarttleandHarttle 394d5a1ae2 docs: add tutorials for custom filters and tags 2022-01-22 18:52:37 +08:00
HarttleandHarttle 371da3da74 docs: add jekyllInclude to tutorials 2022-01-20 02:04:54 +08:00
semantic-release-bot 7814285479 chore(release): 9.33.1 [skip ci]
## [9.33.1](https://github.com/harttle/liquidjs/compare/v9.33.0...v9.33.1) (2022-01-19)

### Bug Fixes

* liquidjs.version on npm package ([53824a2](https://github.com/harttle/liquidjs/commit/53824a2d00f978214fcd83a48118b7900cf97449))
2022-01-19 17:19:58 +00:00
HarttleandHarttle 53824a2d00 fix: liquidjs.version on npm package 2022-01-20 01:16:52 +08:00
semantic-release-bot 9966d846b5 chore(release): 9.33.0 [skip ci]
# [9.33.0](https://github.com/harttle/liquidjs/compare/v9.32.1...v9.33.0) (2022-01-19)

### Features

* support `offset:continue`, see [#439](https://github.com/harttle/liquidjs/issues/439) ([8c27a84](https://github.com/harttle/liquidjs/commit/8c27a84059384ae730eb0fa1524df04e122e27a0))
* support Jekyll-like include syntax, see [#441](https://github.com/harttle/liquidjs/issues/441) ([388d0fb](https://github.com/harttle/liquidjs/commit/388d0fbbc42fe8cd69faba61c1dc29e9bb5ec2d0))
2022-01-19 16:56:49 +00:00
HarttleandHarttle 8c27a84059 feat: support offset:continue, see #439 2022-01-20 00:12:18 +08:00
HarttleandHarttle 388d0fbbc4 feat: support Jekyll-like include syntax, see #441 2022-01-19 23:07:25 +08:00
semantic-release-bot d71d0a0c20 chore(release): 9.32.1 [skip ci]
## [9.32.1](https://github.com/harttle/liquidjs/compare/v9.32.0...v9.32.1) (2022-01-12)

### Bug Fixes

* remove limit on operator char length ([7677f84](https://github.com/harttle/liquidjs/commit/7677f848c0c57335dd1c4f1e3ec251fbf9b1663f))
2022-01-12 13:27:40 +00:00
allcontributors[bot]andJun Yang 191a0130d2 docs: update .all-contributorsrc [skip ci] 2022-01-12 21:25:24 +08:00
allcontributors[bot]andJun Yang 2c3ebaca0c docs: update README.md [skip ci] 2022-01-12 21:25:24 +08:00
Ameya ApteandJun Yang 7677f848c0 fix: remove limit on operator char length
The matchOperator function has a default value of str.length for the end parameter
2022-01-12 21:24:08 +08:00
semantic-release-bot c7d2e1f1f4 chore(release): 9.32.0 [skip ci]
# [9.32.0](https://github.com/harttle/liquidjs/compare/v9.31.0...v9.32.0) (2022-01-02)

### Features

* support allow_false for `default` filter, see [#435](https://github.com/harttle/liquidjs/issues/435) ([c756191](https://github.com/harttle/liquidjs/commit/c756191f49f9c2b823048367abfdf0adf2bdb875))
2022-01-02 08:35:53 +00:00
HarttleandHarttle c756191f49 feat: support allow_false for default filter, see #435 2022-01-02 16:31:21 +08:00
HarttleandHarttle e94e386c46 docs: update liquidjs.com and README for demo link 2021-12-31 17:49:27 +08:00
semantic-release-bot b7c782b10a chore(release): 9.31.0 [skip ci]
# [9.31.0](https://github.com/harttle/liquidjs/compare/v9.30.0...v9.31.0) (2021-12-19)

### Features

* implement `liquid` and `echo` tags, see [#428](https://github.com/harttle/liquidjs/issues/428) ([fde9924](https://github.com/harttle/liquidjs/commit/fde9924ee622efae4c013d2aa01c6d705c8d5f46))
2021-12-19 14:35:13 +00:00
HarttleandHarttle 49d3f64873 docs: echo & liquid tags 2021-12-19 22:31:02 +08:00
HarttleandHarttle be3463c5f9 docs: add jg-rp as contributor 2021-12-19 21:42:46 +08:00
James PriorandJun Yang fde9924ee6 feat: implement liquid and echo tags, see #428 2021-12-19 21:09:26 +08:00
semantic-release-bot 5b2ea63b14 chore(release): 9.30.0 [skip ci]
# [9.30.0](https://github.com/harttle/liquidjs/compare/v9.29.0...v9.30.0) (2021-12-18)

### Features

* support jekyll-like include, see [#433](https://github.com/harttle/liquidjs/issues/433) ([23279a8](https://github.com/harttle/liquidjs/commit/23279a816a0582ade7f3b15c1c65c74bc147d134))
2021-12-18 07:31:17 +00:00
HarttleandHarttle 23279a816a feat: support jekyll-like include, see #433 2021-12-18 15:26:15 +08:00
HarttleandHarttle 2c14a9541d chore: update node to 14 for check pipeline 2021-12-12 20:10:15 +08:00
HarttleandHarttle c474649748 chore: update node to 14 on pipeline 2021-12-12 11:11:03 +08:00
HarttleandHarttle fad17cfbb3 docs: fix apidoc generation for typescript@4 2021-12-11 21:30:19 +08:00
semantic-release-bot 6322acb88c chore(release): 9.29.0 [skip ci]
# [9.29.0](https://github.com/harttle/liquidjs/compare/v9.28.6...v9.29.0) (2021-12-11)

### Features

* customize globals & strictVariables when calling render, see [#432](https://github.com/harttle/liquidjs/issues/432) ([6801552](https://github.com/harttle/liquidjs/commit/6801552fe6829770cbbfdda051731c8b466ed9ec))
2021-12-11 12:32:58 +00:00
HarttleandHarttle 95fc705b5d chore: upgrade typescript 2021-12-11 20:23:09 +08:00
HarttleandHarttle 6801552fe6 feat: customize globals & strictVariables when calling render, see #432 2021-12-11 20:22:58 +08:00
HarttleandHarttle 6023d9ba10 docs: path traversal vulnerabilities when customizing FS 2021-12-11 12:31:08 +08:00
semantic-release-bot cc4628d804 chore(release): 9.28.6 [skip ci]
## [9.28.6](https://github.com/harttle/liquidjs/compare/v9.28.5...v9.28.6) (2021-12-07)

### Bug Fixes

* size filter does not respect Objects, fixes [#385](https://github.com/harttle/liquidjs/issues/385) ([6c11426](https://github.com/harttle/liquidjs/commit/6c114267a526ef764dfd9bd94de199d2932ad91a))
* throws when using `preserveTimezones` on Node.js, fixes [#431](https://github.com/harttle/liquidjs/issues/431) ([e2ef236](https://github.com/harttle/liquidjs/commit/e2ef236f68273b72a0b1293b0d13728cdb9aa4b8))
2021-12-07 15:50:25 +00:00
HarttleandHarttle 69286c6909 test: coverage to 100% 2021-12-07 23:34:53 +08:00
HarttleandHarttle 6c114267a5 fix: size filter does not respect Objects, fixes #385 2021-12-07 23:05:46 +08:00
HarttleandHarttle e2ef236f68 fix: throws when using preserveTimezones on Node.js, fixes #431 2021-12-07 22:43:47 +08:00
400 changed files with 16328 additions and 18170 deletions
+127
View File
@@ -450,6 +450,133 @@
"contributions": [
"code"
]
},
{
"login": "jg-rp",
"name": "jg-rp",
"avatar_url": "https://avatars.githubusercontent.com/u/72664870?v=4",
"profile": "https://github.com/jg-rp",
"contributions": [
"code"
]
},
{
"login": "ameyaapte1",
"name": "Ameya Apte",
"avatar_url": "https://avatars.githubusercontent.com/u/16054747?v=4",
"profile": "https://github.com/ameyaapte1",
"contributions": [
"code"
]
},
{
"login": "tbdrz",
"name": "tbdrz",
"avatar_url": "https://avatars.githubusercontent.com/u/50599116?v=4",
"profile": "https://github.com/tbdrz",
"contributions": [
"doc"
]
},
{
"login": "santialbo",
"name": "Santi Albo",
"avatar_url": "https://avatars.githubusercontent.com/u/1557563?v=4",
"profile": "http://santialbo.com",
"contributions": [
"doc"
]
},
{
"login": "YahangWu",
"name": "Yahang Wu",
"avatar_url": "https://avatars.githubusercontent.com/u/12295975?v=4",
"profile": "https://github.com/YahangWu",
"contributions": [
"doc"
]
},
{
"login": "hongl-1",
"name": "hongl",
"avatar_url": "https://avatars.githubusercontent.com/u/101576612?v=4",
"profile": "https://github.com/hongl-1",
"contributions": [
"doc"
]
},
{
"login": "zxx-457",
"name": "zxx-457",
"avatar_url": "https://avatars.githubusercontent.com/u/114141362?v=4",
"profile": "https://github.com/zxx-457",
"contributions": [
"doc"
]
},
{
"login": "prassie",
"name": "prassie",
"avatar_url": "https://avatars.githubusercontent.com/u/1357831?v=4",
"profile": "https://github.com/prassie",
"contributions": [
"doc"
]
},
{
"login": "slavivanov",
"name": "Slav Ivanov",
"avatar_url": "https://avatars.githubusercontent.com/u/713329?v=4",
"profile": "http://slavv.com/",
"contributions": [
"code"
]
},
{
"login": "DaRosenberg",
"name": "Daniel Rosenberg",
"avatar_url": "https://avatars.githubusercontent.com/u/3889090?v=4",
"profile": "http://www.orgflow.io/",
"contributions": [
"code"
]
},
{
"login": "bobgubko",
"name": "bobgubko",
"avatar_url": "https://avatars.githubusercontent.com/u/733312?v=4",
"profile": "https://github.com/bobgubko",
"contributions": [
"code"
]
},
{
"login": "bangank36",
"name": "BaNgan",
"avatar_url": "https://avatars.githubusercontent.com/u/10071857?v=4",
"profile": "https://github.com/bangank36",
"contributions": [
"doc"
]
},
{
"login": "mahyar-pasarzangene",
"name": "Mahyar Pasarzangene",
"avatar_url": "https://avatars.githubusercontent.com/u/16485039?v=4",
"profile": "https://github.com/mahyar-pasarzangene",
"contributions": [
"doc"
]
},
{
"login": "TomasHubelbauer",
"name": "Tomáš Hübelbauer",
"avatar_url": "https://avatars.githubusercontent.com/u/6831144?v=4",
"profile": "https://hubelbauer.net/",
"contributions": [
"code",
"doc"
]
}
],
"contributorsPerLine": 7,
+1
View File
@@ -3,3 +3,4 @@ dist
demo
coverage
docs
private.*
+16 -1
View File
@@ -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
View File
@@ -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
+40
View File
@@ -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
-30
View File
@@ -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@v1
with:
node-version: 10
- 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
+28
View File
@@ -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
+29
View File
@@ -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
+31
View File
@@ -0,0 +1,31 @@
name: Docs
on: [workflow_dispatch, workflow_call]
jobs:
docs:
name: Docs
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: Build
run: |
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
- name: Archive npm failure logs
uses: actions/upload-artifact@v3
if: failure()
with:
name: npm-logs
path: ~/.npm/_logs
+25
View File
@@ -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
+33
View File
@@ -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
+22
View File
@@ -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
+14
View File
@@ -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 }}
+33 -21
View File
@@ -1,37 +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@v1
uses: actions/setup-node@v3
with:
node-version: 12
- name: Build
run: |
npm ci
npm run build
- 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
- name: Publish Docs
uses: JamesIves/[email protected]
with:
branch: gh-pages
folder: docs/public
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
+34
View File
@@ -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
+3
View File
@@ -9,6 +9,9 @@ coverage/
# modules
node_modules/
# tmp
docs/public/js/liquid.browser.min.js
dist/
demo/*/package-lock.json
demo/*/yarn.json
+388
View File
@@ -1,3 +1,391 @@
## [10.8.2](https://github.com/harttle/liquidjs/compare/v10.8.1...v10.8.2) (2023-06-04)
### Bug Fixes
* sample filter randomness and count=1 case ([fcb930f](https://github.com/harttle/liquidjs/commit/fcb930f0ddf2489fa74cd323f24398d7e9f7717f))
## [10.8.1](https://github.com/harttle/liquidjs/compare/v10.8.0...v10.8.1) (2023-06-04)
### Bug Fixes
* incorrect error message for browser UMD bundle ([3a67eb7](https://github.com/harttle/liquidjs/commit/3a67eb7f1cc7e54d2ec94a985eca4c1f147cdd61))
# [10.8.0](https://github.com/harttle/liquidjs/compare/v10.7.1...v10.8.0) (2023-06-03)
### Bug Fixes
* proper error message for filter syntax error, [#610](https://github.com/harttle/liquidjs/issues/610) ([0480d33](https://github.com/harttle/liquidjs/commit/0480d3317d0e46519ad2adf4ac43f53cddf467c6))
* sed invocations to work out of the box on macOS ([#615](https://github.com/harttle/liquidjs/issues/615)) ([87d4cc7](https://github.com/harttle/liquidjs/commit/87d4cc7e14ece14161285a740be63afc8a88b63c))
### Features
* Add support for the Jekyll sample filter ([#612](https://github.com/harttle/liquidjs/issues/612)) ([ba8b842](https://github.com/harttle/liquidjs/commit/ba8b84245266589e43c0e70d99e12b981d349809))
* Add support for the Jekyll push filter ([#611](https://github.com/harttle/liquidjs/issues/611))
* introduce a matrix with latest Ubuntu and macOS to test the build on macOS as well ([82ba548](https://github.com/harttle/liquidjs/commit/82ba54845f4cd4e1e7660c1557e3cfaa22d68924)), closes [#615](https://github.com/harttle/liquidjs/issues/615)
* precise line/col for tokenization Error, [#613](https://github.com/harttle/liquidjs/issues/613) ([e347e60](https://github.com/harttle/liquidjs/commit/e347e603d76c039cec191d417deab34e7ef1f9a7))
## [10.7.1](https://github.com/harttle/liquidjs/compare/v10.7.0...v10.7.1) (2023-04-24)
### Bug Fixes
* incorrect timezone correction for DST dates, fixes [#604](https://github.com/harttle/liquidjs/issues/604) ([33b3c01](https://github.com/harttle/liquidjs/commit/33b3c010af0cd17a303621331feab0119ca840ce))
* timezoneOffset ignored in date when preserveTimezones is enabled, fixes [#605](https://github.com/harttle/liquidjs/issues/605) ([21ee27b](https://github.com/harttle/liquidjs/commit/21ee27b57503f9d57f228973e1699972484e6089))
# [10.7.0](https://github.com/harttle/liquidjs/compare/v10.6.2...v10.7.0) (2023-03-21)
### Bug Fixes
* update remove.md ([#601](https://github.com/harttle/liquidjs/issues/601)) ([1bddd60](https://github.com/harttle/liquidjs/commit/1bddd60b0191032d324526292027bc7fcd190dc1))
### Features
* JSON format by `space` in `json` filter ([7b87ea8](https://github.com/harttle/liquidjs/commit/7b87ea82d3d63420e548743c5a84a073f0cdad22))
## [10.6.2](https://github.com/harttle/liquidjs/compare/v10.6.1...v10.6.2) (2023-03-19)
### Bug Fixes
* sample FS in render-file.md ([#594](https://github.com/harttle/liquidjs/issues/594)) ([4542ddc](https://github.com/harttle/liquidjs/commit/4542ddcfc3d5e245112a119bf22f0e00cb925791))
## [10.6.1](https://github.com/harttle/liquidjs/compare/v10.6.0...v10.6.1) (2023-03-02)
### Bug Fixes
* [expression] apply value equal for arrays, [#589](https://github.com/harttle/liquidjs/issues/589) ([9c0dc5f](https://github.com/harttle/liquidjs/commit/9c0dc5fa39a31d477a5c5a2c5212034174bf0516))
* strip_html for multi line <script>/<style>/comments, [#70](https://github.com/harttle/liquidjs/issues/70) ([42d2590](https://github.com/harttle/liquidjs/commit/42d25902e855d3c06d5ead071bf55604f495c205))
# [10.6.0](https://github.com/harttle/liquidjs/compare/v10.5.0...v10.6.0) (2023-02-22)
### Features
* LiquidOptions.dateFormat to override default date format ([#587](https://github.com/harttle/liquidjs/issues/587)) ([3fb6646](https://github.com/harttle/liquidjs/commit/3fb66465c6fe1bf4dc2e1ace9157c23d0fc8f859))
# [10.5.0](https://github.com/harttle/liquidjs/compare/v10.4.0...v10.5.0) (2023-02-14)
### Bug Fixes
* "ownPropertyOnly" not respected when passed via "renderOptions" ([d489916](https://github.com/harttle/liquidjs/commit/d489916231779149e110183400e3e597b8ee02ba))
### Features
* Adds support for options to CLI and improves usability ([#586](https://github.com/harttle/liquidjs/issues/586)) ([24c8a1e](https://github.com/harttle/liquidjs/commit/24c8a1e3722e5359f02934e2814f9abfa888ee86))
# [10.4.0](https://github.com/harttle/liquidjs/compare/v10.3.3...v10.4.0) (2023-01-02)
### Features
* support `not` operator, [#575](https://github.com/harttle/liquidjs/issues/575) ([3f21382](https://github.com/harttle/liquidjs/commit/3f21382d43cafa1e32162e58adabd22d5c3709ed))
* support calling `date` without format string, [#573](https://github.com/harttle/liquidjs/issues/573) ([aafaa0b](https://github.com/harttle/liquidjs/commit/aafaa0b4f9e84f466fbcc2cb2ae37fe8704c5272))
## [10.3.3](https://github.com/harttle/liquidjs/compare/v10.3.2...v10.3.3) (2022-12-18)
### Bug Fixes
* type compatible with v9 tag definition, support `Context` as scope in various render APIs, [#570](https://github.com/harttle/liquidjs/issues/570) ([fb6a9f8](https://github.com/harttle/liquidjs/commit/fb6a9f8717cd57522d53687da7e4718b28a7f68a))
## [10.3.2](https://github.com/harttle/liquidjs/compare/v10.3.1...v10.3.2) (2022-12-13)
### Bug Fixes
* re-export error classes, [#569](https://github.com/harttle/liquidjs/issues/569) ([2663ee1](https://github.com/harttle/liquidjs/commit/2663ee16a066c74cbd387fe40154fdeb2136f35a))
## [10.3.1](https://github.com/harttle/liquidjs/compare/v10.3.0...v10.3.1) (2022-12-12)
### Bug Fixes
* support `Context` as `evalValue` parameter, [#568](https://github.com/harttle/liquidjs/issues/568) ([0f4916b](https://github.com/harttle/liquidjs/commit/0f4916bc5a93f5e744e4246336c68f2e89774272))
# [10.3.0](https://github.com/harttle/liquidjs/compare/v10.2.0...v10.3.0) (2022-12-11)
### Features
* support disable outputEscape for specific filters, [#565](https://github.com/harttle/liquidjs/issues/565) ([e6db371](https://github.com/harttle/liquidjs/commit/e6db371519f0fb3b0068347cfb2016aed386c8fa))
# [10.2.0](https://github.com/harttle/liquidjs/compare/v10.1.0...v10.2.0) (2022-12-02)
### Bug Fixes
* `case` should render multiple `when` statements ([d17813e](https://github.com/harttle/liquidjs/commit/d17813ef5217264bd08f741b0e1f713bedf2d464))
### Features
* add remove_last filter ([6c3f1c1](https://github.com/harttle/liquidjs/commit/6c3f1c1e0c0c5d30ef77eaf20df65e149e51e693))
* add replace_last filter ([b4d1e27](https://github.com/harttle/liquidjs/commit/b4d1e27420fcf36ae6d5dbc92cfe4a26299690f2))
# [10.1.0](https://github.com/harttle/liquidjs/compare/v10.0.0...v10.1.0) (2022-11-29)
### Features
* timezone name for `opts.timezoneOffset` and `date` argument, fixes [#553](https://github.com/harttle/liquidjs/issues/553) ([89c6c76](https://github.com/harttle/liquidjs/commit/89c6c7676d40f23090472a28cbf2fb22f93daad3))
# [10.0.0](https://github.com/harttle/liquidjs/compare/v9.43.0...v10.0.0) (2022-11-27)
### Code Refactoring
* rename filters to snake style, [#487](https://github.com/harttle/liquidjs/issues/487) ([ff112a4](https://github.com/harttle/liquidjs/commit/ff112a4750f91475e9eccdb301d7a468e895f6ca))
* `_evalToken` renamed to `evalToken` ([4e1a30a](https://github.com/harttle/liquidjs/commit/4e1a30a20c579408c87f2d28b9b6ec8e1dda65cc))
* change `ownPropertyOnly` default value to `true` ([7eb6216](https://github.com/harttle/liquidjs/commit/7eb621601c2b05d6e379e5ce42219f2b1f556208))
* delay creation of `operatorsTrie` and hide this implementation ([bb58d3e](https://github.com/harttle/liquidjs/commit/bb58d3e549dc5a5e067895ec4a0b3257b434f225))
* remove `toThenable` export ([ffefd91](https://github.com/harttle/liquidjs/commit/ffefd91fbc0195c589c8c34ae80f2017acfe557c))
* remove use of internal `Context` class in `evalValue` argument ([b115077](https://github.com/harttle/liquidjs/commit/b115077e122a7b90e7972d58174d68aea8edd7bf))
### Performance Improvements
* target Node.js 14 for cjs bundle (main entry) ([1f6ce7c](https://github.com/harttle/liquidjs/commit/1f6ce7c8224123cea318d1aa6c12aa091d6e0518))
### BREAKING CHANGES
* `evalToken` now returns a generator (LiquidJS async), which is different from `evalToken` in previous LiquidJS versions.
* main entry need Node.js>=14 to run, you can build LiquidJS by your own by using ESM entry.
* `ownPropertyOnly` default value changed to `true`
* `<liquidjs>.toThenable` is removed, use `<liquidjs>.toPromise` instead
* `evalValue` won't support `Context` as second argument anymore.
* use `operators` instead of `operatorsTrie` as Tokenizer constructor argument, #500
* keys in `<liquidjs>.filters` are now in snake case (instead of camel case), identical to that in Liquid template.
# [9.43.0](https://github.com/harttle/liquidjs/compare/v9.42.1...v9.43.0) (2022-11-27)
### Features
* support timezone offset argument for date filter, [#553](https://github.com/harttle/liquidjs/issues/553) ([7a71485](https://github.com/harttle/liquidjs/commit/7a714855df9ba188e2e82839d248f6623ce94a87))
## [9.42.1](https://github.com/harttle/liquidjs/compare/v9.42.0...v9.42.1) (2022-10-21)
### Bug Fixes
* truncatewords should use at least one word, [#537](https://github.com/harttle/liquidjs/issues/537) ([32f613f](https://github.com/harttle/liquidjs/commit/32f613fb43e90f97364ee6a020589992dbb553cf))
# [9.42.0](https://github.com/harttle/liquidjs/compare/v9.41.0...v9.42.0) (2022-08-27)
### Features
* promise in expression & nested property, [#533](https://github.com/harttle/liquidjs/issues/533) [#276](https://github.com/harttle/liquidjs/issues/276) ([bbf00f3](https://github.com/harttle/liquidjs/commit/bbf00f37bf6080d38ebc258d1921d3ff0d504186))
# [9.41.0](https://github.com/harttle/liquidjs/compare/v9.40.0...v9.41.0) (2022-08-24)
### Features
* use evalValue to parse & render expression, [#527](https://github.com/harttle/liquidjs/issues/527) ([071368a](https://github.com/harttle/liquidjs/commit/071368afe1c4fd36ebdb0e1d300c367db1766f7f))
# [9.40.0](https://github.com/harttle/liquidjs/compare/v9.39.2...v9.40.0) (2022-08-14)
### Bug Fixes
* target ES6 for ESM bundles, fixes [#526](https://github.com/harttle/liquidjs/issues/526) ([905a6dd](https://github.com/harttle/liquidjs/commit/905a6dd1491705c1154b6679a67c1eb1ffe7eef5))
### Features
* export toValueSync & defaultOptions to evaluate expression, see [#527](https://github.com/harttle/liquidjs/issues/527) ([e874b40](https://github.com/harttle/liquidjs/commit/e874b4060b46195e05a5cc6690626bdaa532154c))
## [9.39.2](https://github.com/harttle/liquidjs/compare/v9.39.1...v9.39.2) (2022-07-21)
### Bug Fixes
* expression support Drop.valueOf, fixes [#522](https://github.com/harttle/liquidjs/issues/522) ([4ad383d](https://github.com/harttle/liquidjs/commit/4ad383d9beb57f5683805decc1851778db64aea4))
## [9.39.1](https://github.com/harttle/liquidjs/compare/v9.39.0...v9.39.1) (2022-07-14)
### Bug Fixes
* throw ParseError instead of RenderError for invalid assign expression, closes [#519](https://github.com/harttle/liquidjs/issues/519) ([c41a5d5](https://github.com/harttle/liquidjs/commit/c41a5d5babf85ccedbcb3b6f9a3cf5c326f72ae1))
# [9.39.0](https://github.com/harttle/liquidjs/compare/v9.38.0...v9.39.0) (2022-07-09)
### Bug Fixes
* for tag not respecting Drop#valueOf(), fixes [#515](https://github.com/harttle/liquidjs/issues/515) ([c3e51ca](https://github.com/harttle/liquidjs/commit/c3e51caa701fd4449ed5257e23569a37ef12dea2))
### Features
* iteration protocols ([a19feea](https://github.com/harttle/liquidjs/commit/a19feea7c46fc476139a150bda051f485328afe8))
# [9.38.0](https://github.com/harttle/liquidjs/compare/v9.37.0...v9.38.0) (2022-07-07)
### Bug Fixes
* stack overflow on large number of templates, [#513](https://github.com/harttle/liquidjs/issues/513) ([3dc4290](https://github.com/harttle/liquidjs/commit/3dc4290b56265cfafbee8d9836e912d9b8492f90))
### Features
* inline comment tag ([#514](https://github.com/harttle/liquidjs/issues/514)) ([2f87708](https://github.com/harttle/liquidjs/commit/2f8770898963e35ac4491f6975a8abd03dc09067))
# [9.37.0](https://github.com/harttle/liquidjs/compare/v9.36.2...v9.37.0) (2022-04-21)
### Bug Fixes
* support integer arithmetic for `divided_by`, closes [#465](https://github.com/harttle/liquidjs/issues/465) ([e69a510](https://github.com/harttle/liquidjs/commit/e69a51025efa7dec7d60d0067200a1466988ebbc))
### Features
* automatic output escaping, closes [#500](https://github.com/harttle/liquidjs/issues/500) ([f88490c](https://github.com/harttle/liquidjs/commit/f88490cd3cd0b5316c43c3ca76837544d99ce0b0))
## [9.36.2](https://github.com/harttle/liquidjs/compare/v9.36.1...v9.36.2) (2022-04-19)
### Bug Fixes
* lazy createRequire to allow exceptions being catched, fixes [#497](https://github.com/harttle/liquidjs/issues/497) ([b377dad](https://github.com/harttle/liquidjs/commit/b377dad9e34c3de3e0eedc1ee6f17a0e9d919669))
## [9.36.1](https://github.com/harttle/liquidjs/compare/v9.36.0...v9.36.1) (2022-04-17)
### Bug Fixes
* contains operator does not support Drop, fixes [#492](https://github.com/harttle/liquidjs/issues/492) ([9e024ff](https://github.com/harttle/liquidjs/commit/9e024ff2bcf17e7ac19c718389d4cef39b8a51f7))
* responsive header ([a56af6b](https://github.com/harttle/liquidjs/commit/a56af6bbfb5b698db55fbeb87e8e0872688fbe19))
* use `createRequire` for ESM, fixes [#334](https://github.com/harttle/liquidjs/issues/334) ([eec381e](https://github.com/harttle/liquidjs/commit/eec381ec72db3858452799b7a3264e240be3044d))
# [9.36.0](https://github.com/harttle/liquidjs/compare/v9.35.2...v9.36.0) (2022-03-05)
### Features
* Access array item by negative index, closes [#486](https://github.com/harttle/liquidjs/issues/486) ([049685b](https://github.com/harttle/liquidjs/commit/049685b9a0271ba03875e24ff2f6c7870cae62a7))
* allow strip filter with specified char, closes [#390](https://github.com/harttle/liquidjs/issues/390) ([c503cb2](https://github.com/harttle/liquidjs/commit/c503cb23dfbdd6f146d6dea16a84eab3df1f7aa9))
* appropriate error for malformed filters, fixes [#271](https://github.com/harttle/liquidjs/issues/271) ([01014ed](https://github.com/harttle/liquidjs/commit/01014edc491e12d38981045442da9faee598cdf7))
## [9.35.2](https://github.com/harttle/liquidjs/compare/v9.35.1...v9.35.2) (2022-03-02)
### Bug Fixes
* corner case for concat filter without argument, [#481](https://github.com/harttle/liquidjs/issues/481) ([aa95517](https://github.com/harttle/liquidjs/commit/aa955173d4c7adc585e862934429f1f4c5f64969))
* export all builtin tags from LiquidJS, [#464](https://github.com/harttle/liquidjs/issues/464) ([33009bb](https://github.com/harttle/liquidjs/commit/33009bb988eb74c58f390992750d91b967cb3428))
## [9.35.1](https://github.com/harttle/liquidjs/compare/v9.35.0...v9.35.1) (2022-02-26)
### Bug Fixes
* some filters throw on nil input, see [#481](https://github.com/harttle/liquidjs/issues/481) ([7dfb620](https://github.com/harttle/liquidjs/commit/7dfb620d30f8818685e1cfb8e7492313a0d036ab))
# [9.35.0](https://github.com/harttle/liquidjs/compare/v9.34.1...v9.35.0) (2022-02-23)
### Bug Fixes
* `url_encode` throws on undefined value, fixes [#479](https://github.com/harttle/liquidjs/issues/479) ([ca3240c](https://github.com/harttle/liquidjs/commit/ca3240c2c4d157095d2ebe0024d0c71bc5e435f8))
### Features
* expose all tags/filters and TimezoneDate, closes [#464](https://github.com/harttle/liquidjs/issues/464) ([dab8a29](https://github.com/harttle/liquidjs/commit/dab8a29070b2508f2e6532717b7663966f610bec))
## [9.34.1](https://github.com/harttle/liquidjs/compare/v9.34.0...v9.34.1) (2022-02-20)
### Bug Fixes
* array output now join with "" instead of "," ([ab5e245](https://github.com/harttle/liquidjs/commit/ab5e245fba9a0f6936275319d4e5e25aadb0f7c1))
* sort filter unexpectedly modifies original array, [#475](https://github.com/harttle/liquidjs/issues/475) ([dbc0497](https://github.com/harttle/liquidjs/commit/dbc049738633b1b6f578d9d20f830b548ba67a22))
# [9.34.0](https://github.com/harttle/liquidjs/compare/v9.33.1...v9.34.0) (2022-01-28)
### Bug Fixes
* where-filter null handling ([#457](https://github.com/harttle/liquidjs/issues/457)) ([9da41c8](https://github.com/harttle/liquidjs/commit/9da41c8a37d9c49ee4a16d5bd520fd6ae01c14ec))
### Features
* `ownPropertyOnly` option to protect prototype, [#454](https://github.com/harttle/liquidjs/issues/454) ([7e99efc](https://github.com/harttle/liquidjs/commit/7e99efc5131e20cf3f59e1fc2c371a15aa4109db))
## [9.33.1](https://github.com/harttle/liquidjs/compare/v9.33.0...v9.33.1) (2022-01-19)
### Bug Fixes
* liquidjs.version on npm package ([53824a2](https://github.com/harttle/liquidjs/commit/53824a2d00f978214fcd83a48118b7900cf97449))
# [9.33.0](https://github.com/harttle/liquidjs/compare/v9.32.1...v9.33.0) (2022-01-19)
### Features
* support `offset:continue`, see [#439](https://github.com/harttle/liquidjs/issues/439) ([8c27a84](https://github.com/harttle/liquidjs/commit/8c27a84059384ae730eb0fa1524df04e122e27a0))
* support Jekyll-like include syntax, see [#441](https://github.com/harttle/liquidjs/issues/441) ([388d0fb](https://github.com/harttle/liquidjs/commit/388d0fbbc42fe8cd69faba61c1dc29e9bb5ec2d0))
## [9.32.1](https://github.com/harttle/liquidjs/compare/v9.32.0...v9.32.1) (2022-01-12)
### Bug Fixes
* remove limit on operator char length ([7677f84](https://github.com/harttle/liquidjs/commit/7677f848c0c57335dd1c4f1e3ec251fbf9b1663f))
# [9.32.0](https://github.com/harttle/liquidjs/compare/v9.31.0...v9.32.0) (2022-01-02)
### Features
* support allow_false for `default` filter, see [#435](https://github.com/harttle/liquidjs/issues/435) ([c756191](https://github.com/harttle/liquidjs/commit/c756191f49f9c2b823048367abfdf0adf2bdb875))
# [9.31.0](https://github.com/harttle/liquidjs/compare/v9.30.0...v9.31.0) (2021-12-19)
### Features
* implement `liquid` and `echo` tags, see [#428](https://github.com/harttle/liquidjs/issues/428) ([fde9924](https://github.com/harttle/liquidjs/commit/fde9924ee622efae4c013d2aa01c6d705c8d5f46))
# [9.30.0](https://github.com/harttle/liquidjs/compare/v9.29.0...v9.30.0) (2021-12-18)
### Features
* support jekyll-like include, see [#433](https://github.com/harttle/liquidjs/issues/433) ([23279a8](https://github.com/harttle/liquidjs/commit/23279a816a0582ade7f3b15c1c65c74bc147d134))
# [9.29.0](https://github.com/harttle/liquidjs/compare/v9.28.6...v9.29.0) (2021-12-11)
### Features
* customize globals & strictVariables when calling render, see [#432](https://github.com/harttle/liquidjs/issues/432) ([6801552](https://github.com/harttle/liquidjs/commit/6801552fe6829770cbbfdda051731c8b466ed9ec))
## [9.28.6](https://github.com/harttle/liquidjs/compare/v9.28.5...v9.28.6) (2021-12-07)
### Bug Fixes
* size filter does not respect Objects, fixes [#385](https://github.com/harttle/liquidjs/issues/385) ([6c11426](https://github.com/harttle/liquidjs/commit/6c114267a526ef764dfd9bd94de199d2932ad91a))
* throws when using `preserveTimezones` on Node.js, fixes [#431](https://github.com/harttle/liquidjs/issues/431) ([e2ef236](https://github.com/harttle/liquidjs/commit/e2ef236f68273b72a0b1293b0d13728cdb9aa4b8))
## [9.28.5](https://github.com/harttle/liquidjs/compare/v9.28.4...v9.28.5) (2021-11-05)
+56
View File
@@ -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
+116 -69
View File
@@ -2,7 +2,7 @@
[![npm version](https://img.shields.io/npm/v/liquidjs.svg?logo=npm&style=flat-square)](https://www.npmjs.org/package/liquidjs)
[![npm downloads](https://img.shields.io/npm/dm/liquidjs.svg?style=flat-square)](https://www.npmjs.org/package/liquidjs)
[![Coverage](https://img.shields.io/coveralls/harttle/liquidjs.svg?style=flat-square)](https://coveralls.io/github/harttle/liquidjs?branch=master)
[![Build Status](https://img.shields.io/github/workflow/status/harttle/liquidjs/Check/master.svg?style=flat-square)](https://github.com/harttle/liquidjs/actions/workflows/check.yml?query=branch%3Amaster)
[![Build Status](https://img.shields.io/github/actions/workflow/status/harttle/liquidjs/check.yml?branch=master&style=flat-square)](https://github.com/harttle/liquidjs/actions/workflows/check.yml?query=branch%3Amaster)
[![DUB license](https://img.shields.io/dub/l/vibe-d.svg?style=flat-square)](https://github.com/harttle/liquidjs/blob/master/LICENSE)
[![semantic-release](https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg?style=flat-square)](https://github.com/harttle/liquidjs)
@@ -15,12 +15,25 @@ A simple, expressive and safe [Shopify][shopify/liquid] / Github Pages compatibl
<p align="center"><a href="https://liquidjs.com"><img height="155px" width="155px" src="https://liquidjs.com/icon/mstile-310x310.png" alt="logo"></a></p>
## What's it like?
Basically there're two types of Liquid syntax: tags enclosed by `{% %}` and outputs enclosed by `{{ }}`. A Liquid template looks like:
```liquid
{% if username %}
{{ username | append: ", welcome to LiquidJS!" | capitalize }}
{% endif %}
```
[A live demo](https://liquidjs.com/playground.html) is also available and here's a [quick tutorial](https://liquidjs.com/tutorials/intro-to-liquid.html) for Liquid syntax.
## Installation
Install from npm in Node.js:
```bash
npm install --save liquidjs
npm install liquidjs
```
Or use the UMD bundle from jsDelivr:
@@ -29,20 +42,34 @@ Or use the UMD bundle from jsDelivr:
<script src="https://cdn.jsdelivr.net/npm/liquidjs/dist/liquid.browser.min.js"></script>
```
More details, refer to [The Setup Guide][setup].
Or render directly from CLI using npx:
## Related Packages
```bash
npx liquidjs --template 'Hello, {{ name }}!' --context '{"name": "Snake"}'
```
For more details, refer to the [Setup Guide][setup].
## Related Projects
* [@11ty/eleventy](https://www.npmjs.com/package/@11ty/eleventy): A simpler static site generator. An alternative to Jekyll. Written in JavaScript. Transforms a directory of templates (of varying types) into HTML.
* [gulp-liquidjs](https://www.npmjs.com/package/@tuanpham-dev/gulp-liquidjs): A shopify compatible Liquid template engine for Gulp using liquidjs.
* [grunt-liquify](https://www.npmjs.com/package/grunt-liquify): A Grunt task to process Liquid using liquidjs. Use it to add Liquid magic to your scripts and css assets.
* [react-liquid](https://github.com/aquibm/react-liquid#readme): Liquid templating language component for React
* [@11ty/eleventy](https://www.npmjs.com/package/@11ty/eleventy): A simpler static site generator. An alternative to Jekyll. Written in JavaScript. Transforms a directory of templates (of varying types) into HTML.
## Backers
## Financial Support
If you love LiquidJS or your company is using LiquidJS? Please consider [support us on Open Collective or Patreon][financial-support].
![backers from open-collective](https://opencollective.com/liquidjs/tiers/backer.svg?avatarHeight=97)
### Backers
If you personally like LiquidJS and find it useful to you, you can buy me a coffee!
<img src="https://opencollective.com/liquidjs/backers.svg?avatarHeight=72">
### Sponsors
If LiquidJS is benefiting your business/company, please sponsor us to contribute to our effort!
<img src="https://opencollective.com/liquidjs/sponsors.svg?avatarHeight=72">
## Contributors ✨
@@ -52,68 +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>
</tr>
<tbody>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://harttle.land"><img src="https://avatars3.githubusercontent.com/u/4427974?v=4?s=100" width="100px;" alt="Jun Yang"/><br /><sub><b>Jun Yang</b></sub></a><br /><a href="#maintenance-harttle" title="Maintenance">🚧</a> <a href="https://github.com/harttle/liquidjs/commits?author=harttle" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/chenos"><img src="https://avatars0.githubusercontent.com/u/2993310?v=4?s=100" width="100px;" alt="chenos"/><br /><sub><b>chenos</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=chenos" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://zachleat.com/"><img src="https://avatars2.githubusercontent.com/u/39355?v=4?s=100" width="100px;" alt="Zach Leatherman"/><br /><sub><b>Zach Leatherman</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/issues?q=author%3Azachleat" title="Bug reports">🐛</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/thardy"><img src="https://avatars3.githubusercontent.com/u/120636?v=4?s=100" width="100px;" alt="Tim Hardy"/><br /><sub><b>Tim Hardy</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=thardy" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://paulrobertlloyd.com/"><img src="https://avatars3.githubusercontent.com/u/813383?v=4?s=100" width="100px;" alt="Paul Robert Lloyd"/><br /><sub><b>Paul Robert Lloyd</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=paulrobertlloyd" title="Code">💻</a> <a href="https://github.com/harttle/liquidjs/issues?q=author%3Apaulrobertlloyd" title="Bug reports">🐛</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://twitter.com/alecdotbiz"><img src="https://avatars2.githubusercontent.com/u/1925840?v=4?s=100" width="100px;" alt="Alec Larson"/><br /><sub><b>Alec Larson</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=aleclarson" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/pmalouin"><img src="https://avatars1.githubusercontent.com/u/1411117?v=4?s=100" width="100px;" alt="Patrick Malouin"/><br /><sub><b>Patrick Malouin</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=pmalouin" title="Code">💻</a> <a href="https://github.com/harttle/liquidjs/commits?author=pmalouin" title="Documentation">📖</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://jaswrks.com"><img src="https://avatars3.githubusercontent.com/u/1563559?v=4?s=100" width="100px;" alt="jaswrks"/><br /><sub><b>jaswrks</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=jaswrks" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://oott123.com"><img src="https://avatars2.githubusercontent.com/u/905663?v=4?s=100" width="100px;" alt="三三"/><br /><sub><b>三三</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=oott123" title="Code">💻</a> <a href="#ideas-oott123" title="Ideas, Planning, & Feedback">🤔</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/ssendev"><img src="https://avatars0.githubusercontent.com/u/450793?v=4?s=100" width="100px;" alt="ssendev"/><br /><sub><b>ssendev</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=ssendev" title="Code">💻</a> <a href="https://github.com/harttle/liquidjs/commits?author=ssendev" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/wojtask9"><img src="https://avatars3.githubusercontent.com/u/6099236?v=4?s=100" width="100px;" alt="wojtask9"/><br /><sub><b>wojtask9</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=wojtask9" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/thelornenelson"><img src="https://avatars3.githubusercontent.com/u/24596583?v=4?s=100" width="100px;" alt="Andrew Barclay"/><br /><sub><b>Andrew Barclay</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=thelornenelson" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://www.stam.pr/"><img src="https://avatars2.githubusercontent.com/u/142338?v=4?s=100" width="100px;" alt="Cory Mawhorter"/><br /><sub><b>Cory Mawhorter</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=cmawhorter" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/thehappybug"><img src="https://avatars0.githubusercontent.com/u/3393530?v=4?s=100" width="100px;" alt="Mehdi Jaffery"/><br /><sub><b>Mehdi Jaffery</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=thehappybug" title="Code">💻</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/robinbijlani"><img src="https://avatars0.githubusercontent.com/u/2503108?v=4?s=100" width="100px;" alt="Robin Bijlani"/><br /><sub><b>Robin Bijlani</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=robinbijlani" title="Code">💻</a> <a href="https://github.com/harttle/liquidjs/issues?q=author%3Arobinbijlani" title="Bug reports">🐛</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://www.rmkennedy.com"><img src="https://avatars3.githubusercontent.com/u/8356669?v=4?s=100" width="100px;" alt="Ryan Kennedy"/><br /><sub><b>Ryan Kennedy</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=ryaninvents" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/strax"><img src="https://avatars2.githubusercontent.com/u/587213?v=4?s=100" width="100px;" alt="Sami Kukkonen"/><br /><sub><b>Sami Kukkonen</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=strax" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://ScottFreeCode.github.io/"><img src="https://avatars3.githubusercontent.com/u/16506071?v=4?s=100" width="100px;" alt="Scott Santucci"/><br /><sub><b>Scott Santucci</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=ScottFreeCode" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="http://stevenrescigno.com"><img src="https://avatars3.githubusercontent.com/u/8505293?v=4?s=100" width="100px;" alt="Steven "/><br /><sub><b>Steven </b></sub></a><br /><a href="#example-stevenanthonyrevo" title="Examples">💡</a> <a href="https://github.com/harttle/liquidjs/commits?author=stevenanthonyrevo" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://efcl.info/"><img src="https://avatars1.githubusercontent.com/u/19714?v=4?s=100" width="100px;" alt="azu"/><br /><sub><b>azu</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=azu" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/wyozi"><img src="https://avatars3.githubusercontent.com/u/4894573?v=4?s=100" width="100px;" alt="Joonas"/><br /><sub><b>Joonas</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=wyozi" title="Code">💻</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/jamelait"><img src="https://avatars1.githubusercontent.com/u/14369255?v=4?s=100" width="100px;" alt="Jamel A."/><br /><sub><b>Jamel A.</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=jamelait" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://brandonpittman.net"><img src="https://avatars0.githubusercontent.com/u/967145?v=4?s=100" width="100px;" alt="Brandon Pittman"/><br /><sub><b>Brandon Pittman</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=brandonpittman" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/tgrandgent"><img src="https://avatars3.githubusercontent.com/u/17069042?v=4?s=100" width="100px;" alt="tgrandgent"/><br /><sub><b>tgrandgent</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=tgrandgent" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/mastodon0"><img src="https://avatars1.githubusercontent.com/u/7924332?v=4?s=100" width="100px;" alt="Martin Schuster"/><br /><sub><b>Martin Schuster</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=mastodon0" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="http://js.chenlei.me"><img src="https://avatars0.githubusercontent.com/u/6339390?v=4?s=100" width="100px;" alt="Ray"/><br /><sub><b>Ray</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=richardo2016" title="Tests">⚠️</a> <a href="https://github.com/harttle/liquidjs/commits?author=richardo2016" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/CriGoT"><img src="https://avatars0.githubusercontent.com/u/1936786?v=4?s=100" width="100px;" alt="Cristofer Gonzales"/><br /><sub><b>Cristofer Gonzales</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=CriGoT" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://www.raymondcamden.com"><img src="https://avatars3.githubusercontent.com/u/393660?v=4?s=100" width="100px;" alt="Raymond Camden"/><br /><sub><b>Raymond Camden</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=cfjedimaster" title="Documentation">📖</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://stedman.dev"><img src="https://avatars1.githubusercontent.com/u/183122?v=4?s=100" width="100px;" alt="Steve Stedman"/><br /><sub><b>Steve Stedman</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=stedman" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://ciccarello.me"><img src="https://avatars0.githubusercontent.com/u/11273838?v=4?s=100" width="100px;" alt="Anthony Ciccarello"/><br /><sub><b>Anthony Ciccarello</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=aciccarello" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://twitter.com/IAmTrySound"><img src="https://avatars0.githubusercontent.com/u/5635476?v=4?s=100" width="100px;" alt="Bogdan Chadkin"/><br /><sub><b>Bogdan Chadkin</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=TrySound" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://hightouch.io"><img src="https://avatars0.githubusercontent.com/u/5959235?v=4?s=100" width="100px;" alt="Tejas Manohar"/><br /><sub><b>Tejas Manohar</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=tejasmanohar" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="http://about.me/peterdehaan"><img src="https://avatars2.githubusercontent.com/u/557895?v=4?s=100" width="100px;" alt="Peter deHaan"/><br /><sub><b>Peter deHaan</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=pdehaan" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/amit777"><img src="https://avatars0.githubusercontent.com/u/2703309?v=4?s=100" width="100px;" alt="amit777"/><br /><sub><b>amit777</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=amit777" title="Code">💻</a> <a href="#financial-amit777" title="Financial">💵</a></td>
<td align="center" valign="top" width="14.28%"><a href="http://www.ifi.uzh.ch/en/ce/people/schuldenzucker.html"><img src="https://avatars3.githubusercontent.com/u/1100776?v=4?s=100" width="100px;" alt="Steffen Schuldenzucker"/><br /><sub><b>Steffen Schuldenzucker</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=sschuldenzucker" title="Code">💻</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Pixcell"><img src="https://avatars0.githubusercontent.com/u/4005291?v=4?s=100" width="100px;" alt="Pixcell"/><br /><sub><b>Pixcell</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=Pixcell" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://jasonet.co"><img src="https://avatars.githubusercontent.com/u/10660468?v=4?s=100" width="100px;" alt="Jason Etcovitch"/><br /><sub><b>Jason Etcovitch</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=JasonEtco" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/kayuapi"><img src="https://avatars.githubusercontent.com/u/10304328?v=4?s=100" width="100px;" alt="ZC"/><br /><sub><b>ZC</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=kayuapi" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://memmie.lenglet.name"><img src="https://avatars.githubusercontent.com/u/729275?v=4?s=100" width="100px;" alt="Memmie Lenglet"/><br /><sub><b>Memmie Lenglet</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=mems" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/ilhamdev0"><img src="https://avatars.githubusercontent.com/u/57636145?v=4?s=100" width="100px;" alt="ilhamdev0"/><br /><sub><b>ilhamdev0</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=ilhamdev0" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/c412216887"><img src="https://avatars.githubusercontent.com/u/29691650?v=4?s=100" width="100px;" alt="一饮一啄皆是人生"/><br /><sub><b>一饮一啄皆是人生</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=c412216887" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://digitalinspiration.com/"><img src="https://avatars.githubusercontent.com/u/1344071?v=4?s=100" width="100px;" alt="Amit Agarwal"/><br /><sub><b>Amit Agarwal</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=labnol" title="Documentation">📖</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://n1ru4l.cloud/"><img src="https://avatars.githubusercontent.com/u/14338007?v=4?s=100" width="100px;" alt="Laurin Quast"/><br /><sub><b>Laurin Quast</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=n1ru4l" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/mattvague"><img src="https://avatars.githubusercontent.com/u/64985?v=4?s=100" width="100px;" alt="Matt Vague"/><br /><sub><b>Matt Vague</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=mattvague" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/bglw"><img src="https://avatars.githubusercontent.com/u/40188355?v=4?s=100" width="100px;" alt="Liam Bigelow"/><br /><sub><b>Liam Bigelow</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=bglw" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://about.me/jasonkurian"><img src="https://avatars.githubusercontent.com/u/2642545?v=4?s=100" width="100px;" alt="Jason Kurian"/><br /><sub><b>Jason Kurian</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=JaKXz" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/dphm"><img src="https://avatars.githubusercontent.com/u/1707217?v=4?s=100" width="100px;" alt="d pham (they/them)"/><br /><sub><b>d pham (they/them)</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=dphm" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://www.aleksandrhovhannisyan.com/"><img src="https://avatars.githubusercontent.com/u/19352442?v=4?s=100" width="100px;" alt="Aleksandr Hovhannisyan"/><br /><sub><b>Aleksandr Hovhannisyan</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=AleksandrHovhannisyan" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/jg-rp"><img src="https://avatars.githubusercontent.com/u/72664870?v=4?s=100" width="100px;" alt="jg-rp"/><br /><sub><b>jg-rp</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=jg-rp" title="Code">💻</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/ameyaapte1"><img src="https://avatars.githubusercontent.com/u/16054747?v=4?s=100" width="100px;" alt="Ameya Apte"/><br /><sub><b>Ameya Apte</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=ameyaapte1" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/tbdrz"><img src="https://avatars.githubusercontent.com/u/50599116?v=4?s=100" width="100px;" alt="tbdrz"/><br /><sub><b>tbdrz</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=tbdrz" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="http://santialbo.com"><img src="https://avatars.githubusercontent.com/u/1557563?v=4?s=100" width="100px;" alt="Santi Albo"/><br /><sub><b>Santi Albo</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=santialbo" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/YahangWu"><img src="https://avatars.githubusercontent.com/u/12295975?v=4?s=100" width="100px;" alt="Yahang Wu"/><br /><sub><b>Yahang Wu</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=YahangWu" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/hongl-1"><img src="https://avatars.githubusercontent.com/u/101576612?v=4?s=100" width="100px;" alt="hongl"/><br /><sub><b>hongl</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=hongl-1" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/zxx-457"><img src="https://avatars.githubusercontent.com/u/114141362?v=4?s=100" width="100px;" alt="zxx-457"/><br /><sub><b>zxx-457</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=zxx-457" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/prassie"><img src="https://avatars.githubusercontent.com/u/1357831?v=4?s=100" width="100px;" alt="prassie"/><br /><sub><b>prassie</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=prassie" title="Documentation">📖</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="http://slavv.com/"><img src="https://avatars.githubusercontent.com/u/713329?v=4?s=100" width="100px;" alt="Slav Ivanov"/><br /><sub><b>Slav Ivanov</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=slavivanov" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="http://www.orgflow.io/"><img src="https://avatars.githubusercontent.com/u/3889090?v=4?s=100" width="100px;" alt="Daniel Rosenberg"/><br /><sub><b>Daniel Rosenberg</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=DaRosenberg" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/bobgubko"><img src="https://avatars.githubusercontent.com/u/733312?v=4?s=100" width="100px;" alt="bobgubko"/><br /><sub><b>bobgubko</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=bobgubko" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/bangank36"><img src="https://avatars.githubusercontent.com/u/10071857?v=4?s=100" width="100px;" alt="BaNgan"/><br /><sub><b>BaNgan</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=bangank36" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/mahyar-pasarzangene"><img src="https://avatars.githubusercontent.com/u/16485039?v=4?s=100" width="100px;" alt="Mahyar Pasarzangene"/><br /><sub><b>Mahyar Pasarzangene</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=mahyar-pasarzangene" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://hubelbauer.net/"><img src="https://avatars.githubusercontent.com/u/6831144?v=4?s=100" width="100px;" alt="Tomáš Hübelbauer"/><br /><sub><b>Tomáš Hübelbauer</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=TomasHubelbauer" title="Code">💻</a> <a href="https://github.com/harttle/liquidjs/commits?author=TomasHubelbauer" title="Documentation">📖</a></td>
</tr>
</tbody>
</table>
<!-- markdownlint-restore -->
+4 -4
View File
@@ -6,8 +6,8 @@ Only the latest major version is supported with security updates. It can be chan
## Reporting a Vulnerability
Please contact yangjvn@126.com to report a vulnerability.
Please contact yangjvn@126.com to report a vulnerability or change request.
- It will be fixed very soon (maybe within 1 week or couple of days) if that vulnerability obviously affects common use cases.
- Otherwise, it'll be scheduled with a priority just like requested features (which is lower than bugs).
- If it's declined, you'll receive an email (more oftenly there will be a discuss).
- If the vulnerability in question affects common use cases, it will be treated as a bug and fixed very soon (typically within 1 week).
- Otherwise, it'll be scheduled in the same priority of feature request (which is lower than bugs).
- If the request is declined, you'll receive a reply email anyway (most likely there will be a discussion).
-11
View File
@@ -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 -24
View File
@@ -1,26 +1,4 @@
#!/usr/bin/env bash
rm -rf docs/source/api docs/source/zh-cn/api
typedoc ./src --gitRevision master --out docs/source/api --plugin typedoc-plugin-markdown --theme vuepress
rm docs/source/api/README.md
for file in $(find docs/source/api -name "*.md"); do
sed -i \
-e 's/\(\]([^_)]*\)\/_/\1\//g' \
-e 's/\(\]([^)]*\.\)md/\1html/g' \
-e 's/\](_/\](/g' \
-e 's/{%/{% raw %}{%{% endraw %}/g' \
-e 's/{{/{% raw %}{{{% endraw %}/g' \
-e '1 s/"/\&quot;/g' \
-e '1 s/</\&lt;/g' \
-e '1 s/>/\&gt;/g' \
-e '1 s/\*//g' \
-e '1 s/^# \(.*\)/---\ntitle: "\1"\nauto: true\n---/' \
$file
target=${file/\/_/\/}
if [ "$file" != "$target" ]; then
mv $file $target
fi
done
cp -r docs/source/api docs/source/zh-cn/api
rm -rf docs/source/api
typedoc ./src --gitRevision master --out docs/source/api
+14 -3
View File
@@ -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/"/\&quot;/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
+14 -5
View File
@@ -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
+6
View File
@@ -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/
+3
View File
@@ -1,5 +1,8 @@
#!/usr/bin/env bash
set -ex
./bin/build-docs-liquid.sh
./bin/build-contributors.sh
./bin/build-apidoc.sh
./bin/build-changelog.sh
+18
View File
@@ -0,0 +1,18 @@
#!/usr/bin/env node
// In Hexo, content inside markdown code/code fences,
// will not go through nunjucks.
// So we're escaping special chars outside code only.
let backTick = 0
process.stdin.on('data', (buffer) => {
for (const c of buffer.toString()) {
if (c === '`') {
backTick++
}
const shouldEscape = '{%%}'.includes(c) && backTick % 2 === 0
if (shouldEscape) {
const code = c.charCodeAt(0).toString(16)
process.stdout.write(`&#x${code};`)
} else process.stdout.write(c)
}
})
+130 -15
View File
@@ -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
}
-4
View File
@@ -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
+9
View File
@@ -0,0 +1,9 @@
# Using LiquidJS in ESM
## Get Started
```bash
cd demo/nodejs
npm install
npm start
```
+30
View File
@@ -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()
+7
View File
@@ -0,0 +1,7 @@
<html>
<head><meta name="title" content="{{title}}"></head>
<body>
{% block %}{% endblock %}
{% render "footer.liquid" %}
</body>
</html>
+13
View File
@@ -0,0 +1,13 @@
{
"name": "liquidjs-demo-nodejs",
"description": "Node.js demo for liquidjs",
"private": true,
"main": "index.mjs",
"scripts": {
"start": "node index.mjs"
},
"dependencies": {
"hello-liquid": "^1.0.0",
"liquidjs": "^9.28.3"
}
}
+1
View File
@@ -0,0 +1 @@
<small>{{title}}</small>
+1
View File
@@ -0,0 +1 @@
<li>{{index}} - {{todo}}</li>
+7
View File
@@ -0,0 +1,7 @@
{% layout 'html.liquid' %}
<h1>{% include "hello-liquid" %}</h1>
<ul>
{% for todo in todos %}
{% render 'todo.liquid' with todo, index: forloop.index%}
{% endfor %}
</ul>
+1 -1
View File
@@ -1,4 +1,4 @@
# LiquidJS for Express.js
# Using LiquidJS with Express.js
## Get Started
+8 -8
View File
@@ -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 -1
View File
@@ -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%}
+9
View File
@@ -0,0 +1,9 @@
# LiquidJS for Node.js
## Get Started
```bash
cd demo/nodejs
npm install
npm start
```
+25
View File
@@ -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
}
}
}
+16
View File
@@ -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}`)
}
+17
View File
@@ -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"
}
}
+13
View File
@@ -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>
+8
View File
@@ -0,0 +1,8 @@
{
"compilerOptions": {
"downlevelIteration": true,
"types": [
"node"
]
}
}
+33
View File
@@ -0,0 +1,33 @@
import { LayoutTag, ForTag, LiquidTag, CaptureTag, CaseTag, UnlessTag, TablerowTag, Tag, IfTag } from 'liquidjs'
export function isIfTag (tag: Tag): tag is IfTag {
return tag.name === 'if'
}
export function isUnlessTag (tag: Tag): tag is UnlessTag {
return tag.name === 'unless'
}
export function isLiquidTag (tag: Tag): tag is LiquidTag {
return tag.name === 'liquid'
}
export function isCaseTag (tag: Tag): tag is CaseTag {
return tag.name === 'case'
}
export function isCaptureTag (tag: Tag): tag is CaptureTag {
return tag.name === 'capture'
}
export function isTablerowTag (tag: Tag): tag is TablerowTag {
return tag.name === 'tablerow'
}
export function isForTag (tag: Tag): tag is ForTag {
return tag.name === 'for'
}
export function isLayoutTag (tag: Tag): tag is LayoutTag {
return tag.name === 'layout'
}
+11 -11
View File
@@ -1,25 +1,25 @@
import { Liquid, TagToken, Context, Emitter } from 'liquidjs'
import { Value, Liquid, TagToken, Context, Emitter, Tag, TopLevelToken } from 'liquidjs'
const engine = new Liquid({
root: __dirname,
extname: '.liquid'
})
engine.registerTag('header', {
parse: function (token: TagToken) {
const [key, val] = token.args.split(':')
this[key] = val
},
render: async function (context: Context, emitter: Emitter) {
const title = await this.liquid.evalValue(this['content'], context)
engine.registerTag('header', class HeaderTag extends Tag {
private value: Value
constructor (token: TagToken, remainTokens: TopLevelToken[], liquid: Liquid) {
super(token, remainTokens, liquid)
this.value = new Value(token.args, liquid)
}
* render (ctx: Context, emitter: Emitter) {
const title = yield this.value.value(ctx)
emitter.write(`<h1>${title}</h1>`)
}
})
const ctx = {
const scope = {
todos: ['fork and clone', 'make it better', 'make a pull request'],
title: 'Welcome to liquidjs!'
}
// console.log('isTruthy:', isTruthy('a string here'));
engine.renderFile('todolist', ctx).then(console.log)
engine.renderFile('todolist', scope).then(console.log)
+1 -1
View File
@@ -1,4 +1,4 @@
{%header content: title | capitalize%}
{%header title | capitalize%}
<ul>
{% for todo in todos %}
+5 -3
View File
@@ -1,7 +1,9 @@
{
"compilerOptions": {
"types": [
"node"
]
"target": "es6",
"moduleResolution": "node",
"types": [
"node"
]
}
}
+10
View File
@@ -0,0 +1,10 @@
# Using LiquidJS with Webpack
## Get Started
```bash
cd demo/nodejs
npm install
npm run build
npm start
```
+7
View File
@@ -0,0 +1,7 @@
<html>
<head><meta name="title" content="{{title}}"></head>
<body>
{% block %}{% endblock %}
{% render "footer.liquid" %}
</body>
</html>
+18
View File
@@ -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"
}
}
+1
View File
@@ -0,0 +1 @@
<small>{{title}}</small>
+1
View File
@@ -0,0 +1 @@
<li>{{index}} - {{todo}}</li>
+30
View File
@@ -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()
+6
View File
@@ -0,0 +1,6 @@
{% layout 'html.liquid' %}
<ul>
{% for todo in todos %}
{% render 'todo.liquid' with todo, index: forloop.index%}
{% endfor %}
</ul>
+15
View File
@@ -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'),
},
};
View File
+9 -3
View File
@@ -2,7 +2,9 @@ title: LiquidJS
subtitle: "A simple, expressive and safe template engine."
description: "LiquidJS is a simple, expressive and safe Shopify / Github Pages compatible template engine in pure JavaScript."
author: Harttle
language: en
language:
- en
- zh-cn
timezone: UTC
url: https://liquidjs.com
@@ -17,10 +19,14 @@ pretty_urls:
trailing_html: false
theme: navy
skip_render: "api/**/*"
highlight:
enable: false
prismjs:
enable: true
line_number: false
preprocess: true
line_number: true
tab_replace: ''
algolia:
applicationID: 0X19J927JZ
+706 -388
View File
File diff suppressed because it is too large Load Diff
+2 -2
View File
@@ -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 -2
View File
@@ -1,5 +1,5 @@
tutorials: /tutorials/setup.html
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
+13
View File
@@ -9,6 +9,10 @@ tutorials:
advanced:
caching: caching.html
registeration: register-filters-tags.html
access_scope_in_filters: access-scope-in-filters.html
parse_parameters: parse-parameters.html
render_tag_content: render-tag-content.html
sync_and_async: sync-and-async.html
whitespace: whitespace-control.html
plugins: plugins.html
operators: operators.html
@@ -47,10 +51,13 @@ filters:
newline_to_br: newline_to_br.html
plus: plus.html
prepend: prepend.html
raw: raw.html
remove: remove.html
remove_first: remove_first.html
remove_last: remove_last.html
replace: replace.html
replace_first: replace_first.html
replace_last: replace_last.html
reverse: reverse.html
round: round.html
rstrip: rstrip.html
@@ -73,21 +80,27 @@ filters:
tags:
overview: overview.html
"#": inline_comment.html
assign: assign.html
capture: capture.html
case: case.html
comment: comment.html
cycle: cycle.html
decrement: decrement.html
echo: echo.html
else: if.html
elsif: if.html
for: for.html
if: if.html
include: include.html
increment: increment.html
layout: layout.html
liquid: liquid.html
raw: raw.html
render: render.html
tablerow: tablerow.html
unless: unless.html
when: case.html
api:
quick_entry:
+43 -40
View File
@@ -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
+19
View File
@@ -44,4 +44,23 @@ Output
2.99
```
## Allowing `false`
{% since %}v9.32.0{% endsince %}
To allow variables to return `false` instead of the default value, you can use the `allow_false` parameter.
Input
```liquid
{% assign display_price = false %}
{{ display_price | default: true, allow_false: true }}
```
Output
```text
false
```
[falsy]: ../tutorials/truthy-and-falsy.html
+18 -1
View File
@@ -26,6 +26,23 @@ Output
1.6666666666666667
```
{% note info Integer Arithmetic %}Since JavaScript doesn't differentiate integers and floats, LiquidJS is not capable of integer arithmetic and the return type is always `number`, the string representation of which depends on its value.{% endnote %}
In JavaScript, float and integer shares the same type `number` and we cannot tell the difference. For example:
```javascript
// always true
5.0 === 5
```
You'll need to pass another `integerArithmetic` argument to enforce integer divide:
Input
```liquid
{{ 5 | divided_by: 3, true }}
```
Output
```text
1
```
[floor]: ./floor.html
+5 -3
View File
@@ -1,5 +1,6 @@
---
title: Filters
description: Description and demo for each Liquid filter
---
LiquidJS implements business-logic independent filters that are typically implemented in [shopify/liquid][shopify/liquid]. This section contains the specification and demoes for all the filters implemented by LiquidJS.
@@ -8,10 +9,11 @@ There's 40+ filters supported by LiquidJS. These filters can be categorized into
Categories | Filters
--- | ---
Math | plus, minus, modulo, times, floor, ceil, round, divided_by, abs
String | append, prepend, capitalize, upcase, downcase, strip, lstrip, rstrip, strip_newlines, split, replace, replace_first, remove, remove_first, truncate, truncatewords
Math | plus, minus, modulo, times, floor, ceil, round, divided_by, abs, at_least, at_most
String | append, prepend, capitalize, upcase, downcase, strip, lstrip, rstrip, strip_newlines, split, replace, replace_first, replace_last,remove, remove_first, remove_last, truncate, truncatewords
HTML/URI | escape, escape_once, url_encode, url_decode, strip_html, newline_to_br
Array | slice, map, sort, sort_natural, uniq, where, first, last, join, reverse, concat
Array | slice, map, sort, sort_natural, uniq, where, first, last, join, reverse, concat, compact, size
Date | date
Misc | default, json, raw
[shopify/liquid]: https://github.com/Shopify/liquid
+51
View File
@@ -0,0 +1,51 @@
---
title: raw
---
{% since %}v9.37.0{% endsince %}
Liquid filter that directly returns the value of the variable. Useful when [outputEscape](/api/interfaces/LiquidOptions.html#outputEscape) is set.
{% note info Auto escape %}
By default `outputEscape` is not set. That means LiquidJS output is not escaped by default, thus `raw` filter is not useful until `outputEscape` is set.
{% endnote %}
Input (`outputEscape` not set)
```liquid
{{ "<" }}
```
Output
```text
<
```
Input (`outputEscape="escape"`)
```liquid
{{ "<" }}
```
Output
```text
&lt;
```
Input (`outputEscape="json"`)
```liquid
{{ "<" }}
```
Output
```text
"<"
```
Input (`outputEscape="escape"`)
```liquid
{{ "<" | raw }}
```
Output
```text
<
```
+1 -1
View File
@@ -13,5 +13,5 @@ Input
Output
```text
I strained to see the t through the
I sted to see the t through the
```
+1 -1
View File
@@ -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
```
+17
View File
@@ -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
```
+17
View File
@@ -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
```
+2 -2
View File
@@ -14,5 +14,5 @@ Input
Output
```text
ants, bugs, bees```
ants, bugs, bees
```
+28
View File
@@ -1,6 +1,7 @@
{
"short_name": "LiquidJS",
"name": "LiquidJS",
"description": "A simple, expressive and safe Shopify / Github Pages compatible template engine in pure JavaScript.",
"icons": [
{
"src": "/icon/apple-touch-icon-57x57.png",
@@ -23,6 +24,33 @@
"sizes": "512x512"
}
],
"shortcuts" : [
{
"name": "Tutorials",
"url": "/tutorials/intro-to-liquid.html",
"description": "A set of articles describing how to use LiquidJS"
},
{
"name": "Tags",
"url": "/tags/overview.html",
"description": "Description and demo for each Liquid tag"
},
{
"name": "Filters",
"url": "/filters/overview.html",
"description": "Description and demo for each Liquid filter"
},
{
"name": "Playground",
"url": "/playground.html",
"description": "An online code editor to try out and share Liquid templates"
},
{
"name": "API",
"url": "/api/classes/Liquid.html",
"description": "TypeScript doc for LiquidJS classes and interfaces"
}
],
"start_url": "/",
"display": "standalone",
"theme_color": "#0f83ce",
+2
View File
@@ -1,3 +1,5 @@
---
layout: playground
title: Playground
description: An online code editor to try out and share Liquid templates
---
+9 -2
View File
@@ -9,6 +9,7 @@ const urlsToCache = [
'/fonts/icomoon.ttf?e8nnma'
]
const blackList = [
/chrome-extension:/,
/google-analytics.com.*collect/
]
@@ -29,8 +30,14 @@ self.addEventListener('fetch', event => {
if (
event.request.method !== 'GET' || blackList.some(regex => regex.exec(event.request.url))
) return network(event.request)
const pn = networkAndSave(event.request)
event.respondWith(cache(event.request).then(res => res || pn).catch(() => pn))
if (event.request.url.match(/\.githubusercontent\.com/)) {
// cache first
const pn = networkAndSave(event.request)
event.respondWith(cache(event.request).then(res => res || pn).catch(() => pn))
} else {
// network first
event.respondWith(networkAndSave(event.request).catch(() => cache(event.request)))
}
})
function cache (req) {
+20
View File
@@ -0,0 +1,20 @@
---
title: Echo
---
{% since %}v9.31.0{% endsince %}
Outputs an expression in the rendered HTML. This is identical to wrapping an expression in `{{` and `}}`, but works inside liquid tags and supports filters.
## echo
Input
```liquid
{% assign username = 'Bob' %}
{% echo username | append: ", welcome to LiquidJS!" | capitalize %}
```
Output
```text
Bob, welcome to LiquidJS!
```
+62 -20
View File
@@ -66,17 +66,17 @@ Causes the loop to stop iterating when it encounters the `break` tag.
Input
```liquid
{% for i in (1..5) %}
{% if i == 4 %}
{%- if i == 4 -%}
{% break %}
{% else %}
{%- else -%}
{{ i }}
{% endif %}
{%- endif -%}
{% endfor %}
```
Output
```text
1 2 3
123
```
### continue
@@ -86,17 +86,17 @@ Causes the loop to skip the current iteration when it encounters the `continue`
Input
```liquid
{% for i in (1..5) %}
{% if i == 4 %}
{% continue %}
{% else %}
{%- if i == 4 -%}
{%- continue -%}
{%- else -%}
{{ i }}
{% endif %}
{%- endif -%}
{% endfor %}
```
Output
```text
1 2 3 5
1235
```
### forloop
@@ -152,15 +152,15 @@ Limits the loop to the specified number of iterations.
Input
```liquid
<!-- if array = [1,2,3,4,5,6] -->
<!-- for array = [1,2,3,4,5,6] -->
{% for item in array limit:2 %}
{{ item }}
{{- item -}}
{% endfor %}
```
Output
```text
1 2
12
```
### offset
@@ -169,15 +169,57 @@ Begins the loop at the specified index.
Input
```liquid
<!-- if array = [1,2,3,4,5,6] -->
<!-- for array = [1,2,3,4,5,6] -->
{% for item in array offset:2 %}
{{ item }}
{{- item -}}
{% endfor %}
```
Output
```text
3 4 5 6
3456
```
#### offset:continue
{% since %}v9.33.0{% endsince %}
Offset value can be `continue` to continue previous loop. For example:
Input
```liquid
<!-- for array = [1,2,3,4,5,6] -->
{% for item in array limit:2 %}
{{- item -}}
{% endfor%}
{% for item in array offset:continue %}
{{- item -}}
{% endfor%}
```
Output
```text
12
3456
```
For the same variable name (`"item"` in this case) and same collection (`"array"` in this case), there's one position record. That means you can start a new loop with a different variable name:
Input
```liquid
<!-- for array = [1,2,3,4,5,6] -->
{% for item in array limit:2 %}
{{- item -}}
{% endfor%}
{% for item2 in array offset:continue %}
{{- item2 -}}
{% endfor%}
```
Output
```text
12
123456
```
### range
@@ -187,19 +229,19 @@ Defines a range of numbers to loop through. The range can be defined by both lit
Input
```liquid
{% for i in (3..5) %}
{{ i }}
{% endfor %}
{{- i -}}
{% endfor-%}
{% assign num = 4 %}
{% for i in (1..num) %}
{{ i }}
{{- i -}}
{% endfor %}
```
Output
```text
3 4 5
1 2 3 4
345
1234
```
### reversed
+66 -4
View File
@@ -5,7 +5,7 @@ title: Include
{% since %}v1.9.1{% endsince %}
{% note warn Deprecated %}
This tag is deprecated, use <a href="./render.html">render</a> tag instead for better encapsulation.
This tag is deprecated, use <a href="./render.html">render</a> tag instead, which contains all the features of `include` and provides better encapsulation.
{% endnote %}
## Include a Template
@@ -16,7 +16,7 @@ Renders a partial template from the template [roots][root].
{% include 'footer.liquid' %}
```
When the [extname][extname] option is set, the above `.liquid` extension can be omitted and writes:
If [extname][extname] option is set, the above `.liquid` extension becomes optional:
```liquid
{% include 'footer' %}
@@ -44,5 +44,67 @@ A single object can be passed to a snippet by using the `with...as` syntax:
In the example above, the `product` variable in the partial template will hold the value of `featured_product` in the parent template.
[extname]: ../api/interfaces/liquid_options_.liquidoptions.html#Optional-extname
[root]: ../api/interfaces/liquid_options_.liquidoptions.html#Optional-root
## Outputs & Filters
When filename is specified as literal string, it supports Liquid output and filter syntax. Useful when concatenating strings for a complex filename.
```liquid
{% include "prefix/{{name | append: \".html\"}}" %}
```
{% note info Escaping %}
In LiquidJS, `"` within quoted string literals need to be escaped by adding a slash before the quote, e.g. `\"`. Using Jekyll-like filenames can make this easier, see below.
{% endnote %}
## Jekyll-like filenames
Setting [dynamicPartials][dynamicPartials] to `false` will enable Jekyll-like filenames, where file names are specified as literal string without surrounding quotes. Liquid outputs and filters are also supported within that, for example:
```liquid
{% include prefix/{{ page.my_variable }}/suffix %}
```
This way, you don't need to escape `"` in the filename expression.
```liquid
{% include prefix/{{name | append: ".html"}} %}
```
## Jekyll include
{% since %}v9.33.0{% endsince %}
[jekyllInclude][jekyllInclude] is used to enable Jekyll-like include syntax. Defaults to `false`, when set to `true`:
- Filename will be static: `dynamicPartials` now defaults to `false` (instead of `true`). And you can set `dynamicPartials` back to `true`.
- Use `=` instead of `:` to separate parameter key-values.
- Parameters are under `include` variable instead of current scope.
For example, the following template:
```liquid
{% include article.html header="HEADER" content="CONTENT" %}
```
`article.html` with following content:
```liquid
<article>
<header>{{include.header}}</header>
{{include.content}}
</article>
```
Note that we're referencing the first parameter by `include.header` instead of `header`. Will output following:
```html
<article>
<header>HEADER</header>
CONTENT
</article>
```
[extname]: /api/interfaces/LiquidOptions.html#extname
[root]: /api/interfaces/LiquidOptions.html#root
[dynamicPartials]: /api/interfaces/LiquidOptions.html#dynamicPartials
[jekyllInclude]: /api/interfaces/LiquidOptions.html#jekyllInclude
+50
View File
@@ -0,0 +1,50 @@
---
title: "# (inline comment)"
---
{% since %}v9.38.0{% endsince %}
Add comments to a Liquid template using an inline tag. Text enclosed in an inline comment tag will not be printed.
Input
```liquid
Anything inside an inline comment tag will not be printed.
{% # this is an inline comment %}
But every line must start with a '#'.
{%
# this is a comment
# that spans multiple lines
%}
```
Output
```text
Anything inside an inline comment tag will not be printed.
But every line must start with a '#'.
```
Inline comments are useful inside <a href="./liquid.html">`liquid`</a> tags too.
```liquid
{% liquid
# required args
assign product = collection.products.first
# optional args
assign should_show_border = should_show_border | default: true
assign should_highlight = should_highlight | default: false
%}
```
But they don't work well for commenting out blocks of Liquid code. The <a href="./comment.html">`comment`</a> block tag is the better option when you need to temporarily stop other tags from being executed.
Input
```liquid
{%- # {% echo 'Welcome to LiquidJS!' %} -%}
{% comment %}{% echo 'Welcome to LiquidJS!' %}{% endcomment %}
```
Output
```text
-%}
```
+76 -35
View File
@@ -4,21 +4,67 @@ title: Layout
{% since %}v1.9.1{% endsince %}
## Using a Layout Template
## Using a Layout
Renders current template inside a layout template from the template [roots][root].
Introduce a layout template for the current template to render in. The directory for layout files are defined by [layouts][layouts] or [root][root].
```liquid
{% layout 'footer.liquid' %}
// default-layout.liquid
Header
{% block %}{% endblock %}
Footer
// page.liquid
{% layout "default-layout.liquid" %}
{% block %}My page content{% endblock %}
// result
Header
My page content
Footer
```
When the [extname][extname] option is set, the above `.liquid` extension can be omitted and writes:
If [extname][extname] option is set, the `.liquid` extension becomes optional:
```liquid
{% layout 'footer' %}
{% layout 'default-layout' %}
```
When a partial template is rendered by `layout`, the code inside it can access its caller's variables but its parent cannot access variables defined inside a included template.
{% note info Scoping %}
When a partial template is rendered by <code>layout</code>, its template have access for its caller's variables but not vice versa. Variables defined in layout will be popped out before control returning to its caller.
{% endnote %}
## Multiple Blocks
The layout file can contain multiple blocks, each with a specified name. The following snippets yield same result as in the above example.
```liquid
// default-layout.liquid
{% block header %}{% endblock %}
{% block content %}{% endblock %}
{% block footer %}{% endblock %}
// page.liquid
{% layout "default-layout.liquid" %}
{% block header %}Header{% endblock %}
{% block content %}My page content{% endblock %}
{% block footer %}Footer{% endblock %}
```
## Default Block Contents
In the above layout files, blocks has empty contents. But it's not necessarily be empty, in which case, the block contents in layout files will be used as default templates. The following snippets are also equivalent to the above examples:
```liquid
// default-layout.liquid
{% block header %}Header{% endblock %}
{% block content %}{% endblock %}
{% block footer %}Footer{% endblock %}
// page.liquid
{% layout "default-layout.liquid" %}
{% block content %}My page content{% endblock %}
```
## Passing Variables
@@ -29,38 +75,33 @@ Variables defined in current template can be passed to a the layout template by
{% layout 'name', my_variable: my_variable, my_other_variable: 'oranges' %}
```
## Blocks
## Outputs & Filters
The layout file can contain multiple `block`s which will be populated by the child template (the caller). For example we have a `default-layout.liquid` file with the following contents:
When filename is specified as literal string, it supports Liquid output and filter syntax. Useful when concatenating strings for a complex filename.
```
Header
{% block content %}My default content{% endblock %}
Footer
```liquid
{% layout "prefix/{{name | append: \".html\"}}" %}
```
And it's called by a `page.liquid` file with `layout` tag:
```
{% layout "default-layout" %}
{% block content %}My page content{% endblock %}
```
The render result of `page.liquid` will be :
```
Header
My page content
Footer
```
{% note tip Block %}
<ul>
<li>Multiple blocks can be defined within a layout template;</li>
<li>The block name is optional when there's only one block.</li>
<li>The block contents will fallback to parent's corresponding block if not provided by child template.</li>
</ul>
{% note info Escaping %}
In LiquidJS, `"` within quoted string literals need to be escaped. Adding a slash before the quote, e.g. `\"`. Using Jekyll-like filenames can make this easier, see below.
{% endnote %}
[extname]: ../api/interfaces/liquid_options_.liquidoptions.html#Optional-extname
[root]: ../api/interfaces/liquid_options_.liquidoptions.html#Optional-root
## Jekyll-like Filenames
Setting [dynamicPartials][dynamicPartials] to `false` will enable Jekyll-like filenames, file names are specified as literal string. And it also supports Liquid outputs and filters.
```liquid
{% layout prefix/{{ page.my_variable }}/suffix %}
```
This way, you don't need to escape `"` in the filename expression.
```liquid
{% layout prefix/{{name | append: ".html"}} %}
```
[extname]: /api/interfaces/LiquidOptions.html#extname
[root]: /api/interfaces/LiquidOptions.html#root
[layouts]: /api/interfaces/LiquidOptions.html#layouts
[dynamicPartials]: /api/interfaces/LiquidOptions.html#dynamicPartials
+28
View File
@@ -0,0 +1,28 @@
---
title: Liquid
---
{% since %}v9.31.0{% endsince %}
Encloses multiple tags within one set of delimiters, to allow writing Liquid logic more concisely.
## liquid
Input
```liquid
{% liquid
assign names = 'Bob, Sally' | split: ', '
for name in names
echo 'Hello, ' | append: name
unless forloop.last
echo ', '
endunless
endfor
%}
```
Output
```text
Hello, Bob, Hello Sally
```
+3 -2
View File
@@ -1,5 +1,6 @@
---
title: Tags
description: Description and demo for each Liquid tag
---
LiquidJS implements business-logic independent tags that are typically implemented in [shopify/liquid][shopify/liquid]. This section contains the specification and demoes for all the tags implemented by LiquidJS.
@@ -10,8 +11,8 @@ Category | Purpose | Tags
--- | --- | ---
Iteration | iterate over a collection | for, cycle, tablerow
Control Flow | control the execution branch of template rendering | if, unless, elsif, else, case, when
Variable | define and alter variables | assign, increment, decrement
Variable | define and alter variables | assign, increment, decrement, capture, echo
File | include another template or extend a layout template | render, include, layout
Language | temporarily disable LiquidJS syntax | raw, comment
Language | temporarily disable LiquidJS syntax | # (inline comment), raw, comment, liquid
[shopify/liquid]: https://github.com/Shopify/liquid
+45 -10
View File
@@ -4,26 +4,33 @@ title: Render
{% since %}v9.2.0{% endsince %}
## Basic Usage
## Render a Template
### Render a Template
Renders a partial template from the template [root][root]s.
Render a partial template from partials directory specified by [partials][partials] or [root][root].
```liquid
// index.liquid
Contents
{% render 'footer.liquid' %}
// footer.liquid
Footer
// result
Contents
Footer
```
When the [extname][extname] option is set, the above `.liquid` extension can be omitted and writes:
If [extname][extname] option is set, the above `.liquid` extension becomes optional:
```liquid
{% render 'footer' %}
```
{% note info Variable Scope %}
When a partial template is rendered, the code inside it can't access its parent's variables and its variables won't be accessible by its parent. This encapsulation helps make theme code easier to understand and maintain.{% endnote %}
When a partial template is rendered, the code inside it can't access its parent's variables and its variables won't be accessible by its parent. This encapsulation makes partials easier to understand and maintain.{% endnote %}
### Passing Variables
## Passing Variables
Variables defined in parent's scope can be passed to a the partial template by listing them as parameters on the render tag:
@@ -34,6 +41,32 @@ Variables defined in parent's scope can be passed to a the partial template by l
[globals][globals] don't need to be passed down. They are accessible from all files.
## Outputs & Filters
When filename is specified as literal string, it supports Liquid output and filter syntax. Useful when concatenating strings for a complex filename.
```liquid
{% render "prefix/{{name | append: \".html\"}}" %}
```
{% note info Escaping %}
In LiquidJS, `"` within quoted string literals need to be escaped. Adding a slash before the quote, e.g. `\"`. Using Jekyll-like filenames can make this easier, see below.
{% endnote %}
## Jekyll-like Filenames
Setting [dynamicPartials][dynamicPartials] to `false` will enable Jekyll-like filenames, file names are specified as literal string. And it also supports Liquid outputs and filters.
```liquid
{% render prefix/{{ page.my_variable }}/suffix %}
```
This way, you don't need to escape `"` in the filename expression.
```liquid
{% render prefix/{{name | append: ".html"}} %}
```
## Parameters
### The `with` Parameter
@@ -61,6 +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
[globals]: ../api/interfaces/liquid_options_.liquidoptions.html#Optional-globals
[extname]: /api/interfaces/LiquidOptions.html#extname
[root]: /api/interfaces/LiquidOptions.html#root
[partials]: /api/interfaces/LiquidOptions.html#partials
[globals]: /api/interfaces/LiquidOptions.html#globals
[dynamicPartials]: /api/interfaces/LiquidOptions.html#dynamicPartials
@@ -0,0 +1,32 @@
---
title: Access Scope in Filters
---
As covered in [Register Filters/Tags][register-filters], we can access filter arguments directly in filter function like:
```javascript
// Usage: {{ 1 | add: 2, 3 }}
// Output: 6
engine.registerFilter('add', (initial, arg1, arg2) => initial + arg1 + arg2)
```
When it comes to stateful filters, for example transform a URL path to full URL, we'll need to access a `origin` in current scope:
```javascript
// Usage: {{ '/index.html' | fullURL }}
// Scope: { origin: "https://liquidjs.com" }
// Output: https://liquidjs.com/index.html
engine.registerFilter('fullURL', function (path) {
const origin = this.context.get(['origin'])
return new URL(path, origin).toString()
})
```
See this JSFiddle: <http://jsfiddle.net/ctj364up/1/>
{% note warn Arrow Functions %}
<code>this</code> in arrow functions is bound to current JavaScript context, you'll need to use <code>function(){}</code> instead of <code>()=>{}</code> syntax to access <code>this.context</code> correctly.
{% endnote %}
[register-filters]: /tutorials/register-filters-tags.html
+6 -6
View File
@@ -47,9 +47,9 @@ engine.renderFileSync('hello', {name: 'alice'})
engine.renderFileSync('hello', {name: 'bob'})
```
[parse]: ../api/classes/liquid_.liquid.html#parse
[cache]: ../api/interfaces/liquid_options_.liquidoptions.html#Optional-cache
[parseFile]: ../api/classes/liquid_.liquid.html#parseFile
[parseFileSync]: ../api/classes/liquid_.liquid.html#parseFileSync
[renderFile]: ../api/classes/liquid_.liquid.html#renderFile
[renderFileSync]: ../api/classes/liquid_.liquid.html#renderFilesync
[parse]: /api/classes/Liquid.html#parse
[cache]: /api/interfaces/LiquidOptions.html#cache
[parseFile]: /api/classes/Liquid.html#parseFile
[parseFileSync]: /api/classes/Liquid.html#parseFileSync
[renderFile]: /api/classes/Liquid.html#renderFile
[renderFileSync]: /api/classes/Liquid.html#renderFileSync
@@ -2,23 +2,17 @@
title: Contribution Guideline
---
## Star on Github 👉 [![harttle/liquidjs](https://img.shields.io/github/stars/harttle/liquidjs?style=flat-square)][liquidjs]
## 👉👉👉 Star LiquidJS [![harttle/liquidjs](https://img.shields.io/github/stars/harttle/liquidjs?style=flat-square)][liquidjs]
Starring LiquidJS is the most important and easiest way to support us: boost its rank and expose it to more people, which in turn makes it better.
## Show Me Your Code
**Code Style**: LiquidJS applies [standard](https://github.com/standard/eslint-config-standard) and [@typescript-eslint/recommended](https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/eslint-plugin/src/configs/recommended.json) rules, make sure it's still valid before commit:
Getting started and building is described in [CONTRIBUTING.md](https://github.com/harttle/liquidjs/blob/master/CONTRIBUTING.md).
```bash
npm run lint
```
**Code Style**: LiquidJS applies [standard](https://github.com/standard/eslint-config-standard) and [@typescript-eslint/recommended](https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/eslint-plugin/src/configs/recommended.json) rules.
**Testing**: Make sure test cases pass with your patch merged:
```bash
npm test
```
**Testing**: Make sure test cases pass with your patch merged by running `npm test`
**Commit Message**: Please align to [the Angular Commit Message Guidelines](https://github.com/angular/angular.js/blob/master/DEVELOPERS.md#commits), especially note the [type identifier](https://github.com/angular/angular.js/blob/master/DEVELOPERS.md#type), on which semantic-release bot depends.
@@ -26,14 +20,19 @@ npm test
## Financial Support
LiquidJS is Open Source and Free and **without** capitalists support and **without** any ADs. To help it live and thrive, consider contribute on [Open Collective][oc] or [Patreon][pt]. To acknowledge your contribution, your name and avatar will be listed here and on [Github README][liquidjs].
LiquidJS is Open Source and Free. To help it live and thrive, please consider contribute on [Open Collective][oc]. To acknowledge your contribution, your name and avatar will be listed here, on LiquidJS [homepage](https://liquidjs.com/) and on [Github README][liquidjs]. Please provide your Github ID by openning an issue or contacting me through Twitter (harttleharttle), I can help add you into [the contributors table](https://github.com/harttle/liquidjs#contributors-).
<object type="image/svg+xml" data="https://opencollective.com/liquidjs/tiers/backer.svg?avatarHeight=72"></object>
### Backers
If you personally like LiquidJS and find it's useful to you, you can become a backer!
[![Become a Patron!](../icon/[email protected])](https://www.patreon.com/bePatron?u=32321060)
<object type="image/svg+xml" data="https://opencollective.com/liquidjs/backers.svg?avatarHeight=72"></object>
[oc]: https://opencollective.com/liquidjs/
[pt]: https://www.patreon.com/harttle
### Sponsors
If LiquidJS is benefiting your business/company, please sponsor us to make it better!
<object type="image/svg+xml" data="https://opencollective.com/liquidjs/sponsors.svg?avatarHeight=72"></object>
[oc]: https://opencollective.com/liquidjs/contribute/backer-10665/checkout
[shopify/liquid]: https://shopify.github.io/liquid/
[caniuse-promises]: http://caniuse.com/#feat=promises
[pp]: https://github.com/taylorhakes/promise-polyfill
+29 -1
View File
@@ -2,7 +2,25 @@
title: Differences with Shopify/liquid
---
All filters and tags in [shopify/liquid](https://github.com/Shopify/liquid) are supposed to be built in LiquidJS, but not those business-logic specific tags/filters which are typically from Shopify themes (see [Plugins List][plugins] in case you're looking for them and feel free to add yours to the list). Though being compatible the Ruby version is one of our priorities, there are still some differences:
## Compatibility
Being compatible the Ruby version is one of our priorities. Liquid language is originally [implemented in Ruby][ruby-liquid] and used by Shopify, Jekyll and thus Github Pages, as you can see it's one of the most popular template engines in Ruby. There're lots of people using LiquidJS to serve their templates originally written for Shopify themes and Jekyll sites.
So "being compatible" means serve developers from Shopify and Jekyll well:
- **Well-formed Liquid template should work just fine in LiquidJS**. For example, `forloop.index` should be 1-indexed, `nil` should be rendered as empty string rather than `undefined`, etc. Although some features (e.g. [#236][#236]) are not feasible in JavaScript, at least we're trying to implement all the semantics of Liquid language.
- **All filters and tags in [shopify/liquid][ruby-liquid] are supposed to be built in LiquidJS**. But not those business-logic specific tags/filters typically defined by Shopify platform. Those features should be maintained as [plugins][plugins]. For filters/tags that are not business-logic specific, like `{% layout %}`, and extremely useful, feel free to file an issue.
In the meantime, it's now implemented in JavaScript, that means it has to be more powerful:
* **Async as first-class citizen**. Filters and tags can be implemented asynchronously by return a `Promise`.
* **Also can be sync**. For scenarios that are not I/O intensive, render synchronously can be much faster. You can call synchronous APIs like `.renderSync()` as long as all the filters and tags in template support to be rendered synchronously. All builtin filters/tags support both sync and async render.
* **[Abstract file system][afs]**. Along with async feature, LiquidJS can be used to serve templates stored in Databases [#414][#414], on remote HTTP server [#485][#485], and so on.
* **Additional tags and filters** like `layout` and `json`.
## Differences
Though we're trying to be compatible with the Ruby version, there are still some differences:
* Truthy and Falsy. All values except `undefined`, `null`, `false` are truthy, whereas in Ruby Liquid all except `nil` and `false` are truthy. See [#26][#26].
* Number. In JavaScript we cannot distinguish or convert between `float` and `integer`, see [#59][#59]. And when applied `size` filter, numbers always return 0, which is 8 for integer in ruby, cause they do not have a `length` property.
@@ -11,11 +29,21 @@ All filters and tags in [shopify/liquid](https://github.com/Shopify/liquid) are
* Iteration order for objects. The iteration order of JavaScript objects, and thus LiquidJS objects, is a combination of the insertion order for string keys, and ascending order for number-like keys, while the iteration order of Ruby Hash is simply the insertion order.
* Sort stability. The [sort][sort] stability is also not defined in both shopify/liquid and LiquidJS, but it's [considered stable][stable-sort] for LiquidJS in Node.js 12+ and Google Chrome 70+.
* Trailing unmatched characters inside filters are allowed in shopify/liquid but not in LiquidJS. It means filter arguments without a colon like `{%raw%}{{ "a b" | split " "}}{%endraw%}` will throw an error in LiquidJS. This is intended to improve Liquid usability, see [#208][#208] and [#212][#212].
* LiquidJS has additional tags: [layout][layout] and corresponding `block` tag.
* LiquidJS [date][date] filter supports `%q` for date ordinals like `{{ '2023/02/02' | date: '%d%q of %b'}}` => `02nd of Feb`
[date]: https://liquidjs.com/filters/date.html
[layout]: https://liquidjs.com/tags/layout.html
[json]: https://liquidjs.com/filters/json.html
[#26]: https://github.com/harttle/liquidjs/pull/26
[#59]: https://github.com/harttle/liquidjs/issues/59
[#208]: https://github.com/harttle/liquidjs/issues/208
[#212]: https://github.com/harttle/liquidjs/issues/212
[#236]: https://github.com/harttle/liquidjs/issues/236
[#414]: https://github.com/harttle/liquidjs/discussions/414
[#485]: https://github.com/harttle/liquidjs/discussions/485
[sort]: https://liquidjs.com/filters/sort.html
[stable-sort]: https://v8.dev/features/stable-sort
[plugins]: ./plugins.html#Plugin-List
[ruby-liquid]: https://github.com/Shopify/liquid
[afs]: https://liquidjs.com/tutorials/render-file.html#Abstract-File-System
+6 -1
View File
@@ -1,5 +1,6 @@
---
title: Introduction to Liquid Template Language
title: The Liquid Template Language
describe: A short introduction to the Liquid template language and some simple demos.
---
LiquidJS is a simple, expressive and safe [Shopify][shopify/liquid] / Github Pages compatible template engine in pure JavaScript. The purpose of this repo is to provide a standard Liquid implementation for the JavaScript community. Liquid is originally implemented in Ruby and used by Github Pages, Jekyll and Shopify, see [Differences with Shopify/liquid][diff].
@@ -9,6 +10,10 @@ LiquidJS syntax is relatively simple. There're 2 types of markups in LiquidJS:
- **Tags**. A tag consists of a tag name and optional arguments wrapped between `{%raw%}{%{%endraw%}` and `%}`.
- **Outputs**. An output consists of a value and a list of filters, which is optional, wrapped between `{%raw%}{{{%endraw%}` and `}}`.
{% note info Live Demo %}
Before going into the details, here's a live demo to play around: <https://liquidjs.com/playground.html>.
{% endnote %}
## Outputs
**Outputs** are used to output variables, which can be transformed by filters, into HTML. The following template will insert the value of `username` into the input's value:
+30 -2
View File
@@ -12,7 +12,7 @@ const engine = new Liquid({
```
{% note info API Document %}
Following is an overview for all the options, for exact types and signatures please refer to <a href="https://liquidjs.com/api/interfaces/liquid_options_.liquidoptions.html" target="_self">LiquidOptions | API</a>.
Following is an overview for all the options, for exact types and signatures please refer to <a href="https://liquidjs.com/api/interfaces/LiquidOptions.html" target="_self">LiquidOptions | API</a>.
{% endnote %}
## cache
@@ -52,6 +52,29 @@ Setting `dynamicPartials: false`, LiquidJS will try to include the file named `f
{% note warn Common Pitfall %}
LiquidJS defaults this option to <code>true</code> to be compatible with shopify/liquid, but if you're from <a href="https://github.com/11ty/eleventy" target="_blank">eleventy</a> it's set to <code>false</code> by default (see <a href="https://www.11ty.dev/docs/languages/liquid/#quoted-include-paths" target="_blank">Quoted Include Paths</a>) which I believe is trying to be compatible with Jekyll.{% endnote %}
## Jekyll include
{% since %}v9.33.0{% endsince %}
[jekyllInclude][jekyllInclude] is used to enable Jekyll-like include syntax. Defaults to `false`, when set to `true`:
- Filename will be static: `dynamicPartials` now defaults to `false` (instead of `true`). And you can set `dynamicPartials` back to `true`.
- Use `=` instead of `:` to separate parameter key-values.
- Parameters are under `include` variable instead of current scope.
For example in the following template, `name.html` is not quoted, `header` and `"HEADER"` are separated by `=`, and the `header` parameter is referenced by `include.header`. More details please check out [include][include].
```liquid
// entry template
{% include article.html header="HEADER" content="CONTENT" %}
// article.html
<article>
<header>{{include.header}}</header>
{{include.content}}
</article>
```
## extname
**extname** defines the default extension name to be appended into filenames if the filename has no extension name. Defaults to `''` which means it's disabled by default. By setting it to `.liquid`:
@@ -85,6 +108,8 @@ it defaults to false. For example, when set to true, a blank string would evalu
**preserveTimezones** is a boolean effects only literal timestamps. When set to `true`, all literal timestamps will remain the same when output. This is a parser option, so Date objects passed to LiquidJS as data will not be affected. Note that `preserveTimezones` has a higher priority than `timezoneOffset`.
**dateFormat** is used to specify a default format to output dates. `%A, %B %-e, %Y at %-l:%M %P %z` will be used if not specified. For example, set `dateFormat: %Y-%m-%dT%H:%M:%S:%LZ` to output all dates in [JavaScript Date.toJson()][https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toJSON] format.
## Trimming
**greedy**, **trimOutputLeft**, **trimOutputRight**, **trimTagLeft**, **trimTagRight** options are used to eliminate extra newlines and indents in templates around Liquid Constructs. See [Whitespace Control][wc] for details.
@@ -105,6 +130,8 @@ it defaults to false. For example, when set to true, a blank string would evalu
**lenientIf** modifies the behavior of `strictVariables` to allow handling optional variables. If set to `true`, an undefined variable will *not* cause an exception in the following two situations: a) it is the condition to an `if`, `elsif`, or `unless` tag; b) it occurs right before a `default` filter. Irrelevant if `strictVariables` is not set. Defaults to `false`.
**ownPropertyOnly** hides scope variables from prototypes, useful when you're passing a not sanitized object into LiquidJS or need to hide prototypes from templates. Defaults to `true`.
{% note info Non-existent Tags %}
Non-existent tags always throw errors during parsing and this behavior can not be customized.
{% endnote %}
@@ -113,7 +140,7 @@ Non-existent tags always throw errors during parsing and this behavior can not b
Parameter orders are ignored by default, for ea `{% for i in (1..8) reversed limit:3 %}` will always perform `limit` before `reversed`, even if `reversed` occurs before `limit`. To make parameter order respected, set **orderedFilterParameters** to `true`. Its default value is `false`.
[liquid]: ../api/classes/liquid_.liquid.html
[liquid]: /api/classes/Liquid.html
[caching]: ./caching.html
[abstract-fs]: ./render-file.html#Abstract-File-System
[render-file]: ./render-file.html
@@ -123,3 +150,4 @@ Parameter orders are ignored by default, for ea `{% for i in (1..8) reversed lim
[layout]: ../tags/layout.html
[wc]: ./whitespace-control.html
[intro]: ./intro-to-liquid.html
[jekyllInclude]: /api/interfaces/LiquidOptions.html#jekyllInclude
+100
View File
@@ -0,0 +1,100 @@
---
title: Parse Parameters
---
## Access Raw Parameters
As covered in [Register Filters/Tags][register-tags], tag parameters is available on `tagToken.args` as a raw string. For example:
```javascript
// Usage: {% random foo bar coo %}
// Output: "foo", "bar" or "coo"
engine.registerTag('random', {
parse(tagToken) {
// tagToken.args === "foo bar coo"
this.items = tagToken.args.split(' ')
},
render(context, emitter) {
// get a random index
const index = Math.floor(this.items.length * Math.random())
// output that item
emitter.write(this.items[index])
}
})
```
Here's a JSFiddle version: <http://jsfiddle.net/ctj364up/2/>
## Parse Parameters as Values
Sometimes we need more dynamic tags and want to pass values to the custom tag instead of static strings. Variables in LiquidJS can be literal (string, number, etc.) or a variable from current context scope.
The following modified template also contains 3 values to random from, but they're values instead of static strings. The first one is string literal, second one is an identifier, third one is a property access sequence containing two identifiers.
```liquid
{% random "foo" bar obj.coo %}
```
It can be tricky to parse all these cases manually, but there's a [Tokenizer][Tokenizer] class in LiquidJS you can make use of.
```javascript
const { Liquid, Tokenizer, evalToken } = require('liquidjs')
engine.registerTag('random', {
parse(tagToken) {
const tokenizer = new Tokenizer(tagToken.args)
this.items = []
while (!tokenizer.end()) {
// here readValue() returns a LiteralToken or PropertyAccessToken
this.items.push(tokenizer.readValue())
}
},
* render(context, emitter) {
const index = Math.floor(this.items.length * Math.random())
const token = this.items[index]
// in LiquidJS, we use yield to wait for async call
const value = yield evalToken(token, context)
emitter.write(value)
}
})
```
Calling this tag in scope `{ bar: "bar", obj: { coo: "coo" } }` yields exactly the same result as the first example. See this JSFiddle: <http://jsfiddle.net/ctj364up/3/>
{% note info Async ans Promises %}
Async calls in LiquidJS are implemented by generators directly, for we can call generators in synchronous manner so this tag implementation is also valid for `renderSync()`, `parseAndRenderSync()`, `renderFileSync()`. If you need to await a promise in tag implementation, simply replace `await somePromise` with `yield somePromise` and keep `* render()` instead of `async render()` will do the trick. See <a href="/tutorials/sync-and-async.html">Sync and Async</a> for more details.
{% endnote %}
## Parse Key-Value Pairs as Named Parameters
Named parameters become very handy when there're optional parameters or lots of parameters, in which case the order of parameters is not important. This is exactly what [Hash][Hash] class is invented for.
```liquid
{% random from:2, to:max %}
```
In the above example, we're trying to generate a random number in the range [2, max]. We'll use `Hash` to parse `from` and `to` parameters.
```javascript
const { Liquid, Hash } = require('liquidjs')
engine.registerTag('random', {
parse(tagToken) {
// parse the parameters structure into `this.args`
this.args = new Hash(tagToken.args)
},
* render(context, emitter) {
// evaluate the parameters in `context`
const {from, to} = yield this.args.render(context)
const length = to - from + 1
const value = from + Math.floor(length * Math.random())
emitter.write(value)
}
})
```
Rendering `{% random from:2, to:max %}` in scope `{ max: 10 }` will generate a random number in the range [2, 10]. See this JSFiddle: <http://jsfiddle.net/ctj364up/4/>
[register-tags]: /tutorials/register-filters-tags.html
[Tokenizer]: /api/classes/Tokenizer.html
[Hash]: /api/classes/Hash.html
+1 -1
View File
@@ -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
+26 -7
View File
@@ -6,14 +6,14 @@ title: Register Filters/Tags
```typescript
// Usage: {% upper name %}
import { TagToken, Context, Emitter, TopLevelToken } from 'liquidjs'
import { Value, TagToken, Context, Emitter, TopLevelToken } from 'liquidjs'
engine.registerTag('upper', {
parse: function(tagToken: TagToken, remainTokens: TopLevelToken[]) {
this.str = tagToken.args; // name
this.value = new Value(token.args, liquid)
},
render: async function(ctx: Context) {
var str = await this.liquid.evalValue(this.str, ctx); // 'alice'
render: function*(ctx: Context) {
const str = yield this.value.value(ctx); // 'alice'
return str.toUpperCase() // 'ALICE'
}
});
@@ -22,7 +22,26 @@ engine.registerTag('upper', {
* `parse`: Read tokens from `remainTokens` until your end token.
* `render`: Combine scope data with your parsed tokens into HTML string.
See existing tag implementations here: <https://github.com/harttle/liquidjs/tree/master/src/builtin/tags>
For complex tag implementation, you can also provide a tag class:
```typescript
// Usage: {% upper name:"alice" %}
import { Hash, Tag, TagToken, Context, Emitter, TopLevelToken, Liquid } from 'liquidjs'
engine.registerTag('upper', class UpperTag extends Tag {
private hash: Hash
constructor(tagToken: TagToken, remainTokens: TopLevelToken[], liquid: Liquid) {
super(tagToken, remainTokens, liquid)
this.hash = new Hash(tagToken.args)
}
* render(ctx: Context) {
const hash = yield this.hash.render();
return hash.name.toUpperCase() // 'ALICE'
}
});
```
See existing tag implementations here: <https://github.com/harttle/liquidjs/tree/master/src/tags>
See demo example here: https://github.com/harttle/liquidjs/blob/master/demo/typescript/index.ts
## Register Filters
@@ -39,7 +58,7 @@ Filter arguments will be passed to the registered filter function, for example:
engine.registerFilter('add', (initial, arg1, arg2) => initial + arg1 + arg2)
```
See existing filter implementations here: <https://github.com/harttle/liquidjs/tree/master/src/builtin/filters>
See existing filter implementations here: <https://github.com/harttle/liquidjs/tree/master/src/filters>
## Unregister Tags/Filters
@@ -61,4 +80,4 @@ function disabledFilter(name) {
}
}
engine.registerFilter('plus', disabledFilter('plus'));
```
```
+16 -11
View File
@@ -68,7 +68,7 @@ Here's a demo for browsers: [demo/browser](https://github.com/harttle/liquidjs/t
## Abstract File System
LiquidJS defines an abstract file system interface in [src/fs/ifs.ts][ifs] and the default implementation is [src/fs/node.ts][fs-node] for Node.js and [src/fs/browser.ts][fs-browser] for the browser bundle.
LiquidJS defines an abstract file system interface in [src/fs/fs.ts][ifs] and the default implementation is [src/fs/fs-impl.ts][fs-node] for Node.js and [src/build/fs-impl-browser.ts][fs-browser] for the browser bundle.
The `Liquid` constructor provides a [fs][fs] option to specify the file system implementation. It's supposed to be used to define customized template fetching logic, i.e. fetch template from a database table, like:
@@ -85,7 +85,10 @@ var engine = new Liquid({
existsSync () {
return true
},
exists () {
async exists () {
return true
},
contains () {
return true
},
resolve(root, file, ext) {
@@ -95,14 +98,16 @@ var 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
{% 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/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
+137
View File
@@ -0,0 +1,137 @@
---
title: Render Tag Content
---
Custom tags can have content template and can be nested. This article describes how to implement custom tags that consists of a *begin tag*, an *end tag*, and template content between them.
## Render Tag Content
We'll start with a simple tag `wrap` which wraps its content into a `<div class="wrapper"></div>` element:
```liquid
{% wrap %}
{{ "hello world!" | capitalize }}
{% endwrap %}
```
Expected output:
```html
<div class='wrapper'>
Hello world!
</div>
```
Firstly, [register][register-tags] a tag with name `wrap` and parse the content into `this.tpls`. Here in `parse(tagToken, remainTokens)`,
- `tagToken` is current token `{% wrap %}`, and
- `remainTokens` is an array of all tokens following `{% wrap %}` until the end of this template file.
Basically, what we need to do is take/`.shift()` enough tags from `remainTokens` until we got a `endwrap` token (the name can be arbitrary, but in convention, we need it to be `endwrap`). And if there's no `endwrap` until the end of template file, we need to throw an tag-not-closed `Error`.
```javascript
engine.registerTag('wrap', {
parse(tagToken, remainTokens) {
this.tpls = []
let closed = false
while(remainTokens.length) {
let token = remainTokens.shift()
// we got the end tag! stop taking tokens
if (token.name === 'endwrap') {
closed = true
break
}
// parse token into template
// parseToken() may consume more than 1 tokens
// e.g. {% if %}...{% endif %}
let tpl = this.liquid.parser.parseToken(token, remainTokens)
this.tpls.push(tpl)
}
if (!closed) throw new Error(`tag ${tagToken.getText()} not closed`)
},
* render(context, emitter) {
emitter.write("<div class='wrapper'>")
yield this.liquid.renderer.renderTemplates(this.tpls, context, emitter)
emitter.write("</div>")
}
})
```
`.renderTemplates()` can be async, we need `yield` to wait it complete. More details on async in LiquidJS, please refer to [Sync and Async][async]. Other parts of `render()` method is quite straightforward. Here's a JSFiddle version: <http://jsfiddle.net/por0zcn1/3/>
## Using ParseStream
When it comes to complex tags like [for][for] and [if][if], the `parse()` can be very complicated. There's a [ParseStream][ParseStream] utility to organize the `parse()` in event-based style. Following is a re-written `parse()` using `ParseStream` and does exactly the same as above example.
```javascript
parse(tagToken, remainTokens) {
this.tpls = []
this.liquid.parser.parseStream(remainTokens)
.on('template', tpl => this.tpls.push(tpl))
// note that we cannot use arrow function because we need `this`
.on('tag:endwrap', function () { this.stop() })
.on('end', () => { throw new Error(`tag ${tagToken.getText()} not closed`) })
.start()
}
```
Here's a JSFiddle version: <http://jsfiddle.net/por0zcn1/4/>. For simplicity, the following examples are implemented using `ParseStream`.
## Manipulate the Context
The `wrap` tag above doesn't seem to be very useful, without using that tag we can render the content anyway. Now we're going to implement a `repeat` tag to render the content 2 times (we can also add a [parameter][parameter] to render arbitrary times).
```liquid
{% repeat %}
{{ repeat.i }}. {{ "hello world!" | capitalize }}
{% endrepeat %}`
```
Expected outputs:
```html
1. Hello world!
2. Hello world!
```
As you've noticed, there's an additional `repeat.i` in the context of `repeat`. That is implemented by manipulating the *Context*.
{% note info Context %}
<em>Context</em> defines the value of each variable in Liquid template. In LiquidJS, a `Context` consists of a stack of `Scope`s. A *Scope* is a plain object like the one specified in `engine.render(tpl, scope)`.
{% endnote %}
Each time we enter a new *Context*, we need to push a new *Scope*. And when we finish rendering and exit the *Context*, we pop the *Scope* from the *Context*. As you can see in the following implementation:
```javascript
engine.registerTag('repeat', {
parse(tagToken, remainTokens) {
this.tpls = []
this.liquid.parser.parseStream(remainTokens)
.on('template', tpl => this.tpls.push(tpl))
.on('tag:endrepeat', function () { this.stop() })
.on('end', () => { throw new Error(`tag ${tagToken.getText()} not closed`) })
.start()
},
* render(context, emitter) {
const repeat = { i: 1 }
context.push({ repeat })
yield this.liquid.renderer.renderTemplates(this.tpls, context, emitter)
repeat.i++
yield this.liquid.renderer.renderTemplates(this.tpls, context, emitter)
context.pop()
}
})
```
The `parse()` is exactly the same as `wrap` tag, we repeat the content simply by calling `.renderTemplates(this.tpls)` twice during `render()`. Here's the JSFiddle: <http://jsfiddle.net/por0zcn1/2/>
{% note warn Use Push & Pop in Pairs %}
`context.push()` and `context.pop()` have to be used in pairs. Failing to `pop()` the *Scope* you pushed will leak the *Scope* to latter templates and may corrupt the *Context* stack.
{% endnote %}
[register-tags]: ./register-filters-tags.html
[async]: ./sync-and-async.html
[for]: ../tags/for.html
[if]: ../tags/if.html
[ParseStream]: /api/classes/ParseStream.html
[parameter]: ./parse-parameters.html
+35 -4
View File
@@ -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
+116
View File
@@ -0,0 +1,116 @@
---
title: Sync and Async
---
LiquidJS supports both sync and async evaluate, and can be used with Promises. To reuse the same set of tag/filter implementations in both sync and async, LiquidJS tags are implemented as generators.
## Sync and Async API
All major methods on [Liquid][Liquid] supports both sync and async. These methods return Promises:
- `render()`
- `renderFile()`
- `parseFile()`
- `parseAndRender()`
- `evalValue()`
The synchronous version of methods contains a `Sync` suffix:
- `renderSync()`
- `renderFileSync()`
- `parseFileSync()`
- `parseAndRenderSync()`
- `evalValueSync()`
## Implement Sync-Compatible Tags
LiquidJS uses a generator-based async implementation to support both async and sync in one piece of tag implementation. For example, below `UpperTag` can be used in both `engine.renderSync()` and `engine.render()`.
```typescript
import { TagToken, Context, Emitter, TopLevelToken, Value, Tag, Liquid } from 'liquidjs'
// Usage: {% upper "alice" %}
// Output: ALICE
engine.registerTag('upper', class UpperTag extends Tag {
private value: Value
constructor (token: TagToken, remainTokens: TopLevelToken[], liquid: Liquid) {
super(token, remainTokens, liquid)
this.value = new Value(token.args, liquid)
}
* render (ctx: Context, emitter: Emitter) {
const title = yield this.value.value(ctx)
emitter.write(title.toUpperCase())
}
})
```
All builtin tags are implemented this way and safe to use in both sync and async (I'll call it *sync-compatible*). To make your custom tag *sync-compatible*, you'll need to:
- declare render function as `* render()`, in which
- do not directly `return <Promise>`, and
- do not call any APIs that returns a Promise.
## Call APIs that return a Promise
But LiquidJS is Promise-friendly, right? You can still call Promise-based functions and wait for that Promise within tag implementations. Just replace `await` with `yield`. e.g. we're calling `fs.readFile()` which returns a `Promise`:
```typescript
* render (ctx: Context, emitter: Emitter) {
const file = yield this.value.value(ctx)
const title = yield fs.readFile(file, 'utf8')
emitter.write(title.toUpperCase())
}
```
Now that this `* render()` calls an API that returns a Promise, so it's no longer *sync-compatible*.
{% note info Non Sync-Compatible Tags %}
Non <em>sync-compatible</em> tags are also valid tags, will work just fine for asynchronous API calls. When called synchronously, tags that return a <code>Promise</code> will be rendered as <code>[object Promise]</code>.
{% endnote %}
## Convert LiquidJS async Generator to Promise
You can convert a Generator to Promise by [toPromise][toPromise], for example:
```typescript
import { TagToken, Context, Emitter, TopLevelToken, Value, Tag, Liquid, toPromise } from 'liquidjs'
// Usage: {% upper "alice" %}
// Output: ALICE
engine.registerTag('upper', class UpperTag extends Tag {
private value: Value
constructor (token: TagToken, remainTokens: TopLevelToken[], liquid: Liquid) {
super(token, remainTokens, liquid)
this.value = new Value(token.args, liquid)
}
async render (ctx: Context, emitter: Emitter) {
const title = await toPromise(this.value.value(ctx))
emitter.write(title.toUpperCase())
}
})
```
## Async only Tags
If your tag is intend to be used only asynchronously, it can be declared as `async render()` so you can use `await` in its implementation directly:
```typescript
import { toPromise, TagToken, Context, Emitter, TopLevelToken, Value, Tag, Liquid } from 'liquidjs'
// Usage: {% upper "alice" %}
// Output: ALICE
engine.registerTag('upper', class UpperTag extends Tag {
private value: Value
constructor (token: TagToken, remainTokens: TopLevelToken[], liquid: Liquid) {
super(token, remainTokens, liquid)
this.value = new Value(token.args, liquid)
}
async render (ctx: Context, emitter: Emitter) {
const title = await toPromise(this.value.value(ctx))
emitter.write(`<h1>${title}</h1>`)
}
})
```
[Liquid]: /api/classes/Liquid.html
[toPromise]: /api/functions/toPromise.html
+4 -4
View File
@@ -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
+3 -3
View File
@@ -41,7 +41,7 @@ Alternatively, LiquidJS provides these per engine options to enable whitespace c
* `trimTagLeft`
* `trimTagRight`
* `trimValueRight`
* `trimValueLeft`
* `trimValueRight`
[LiquidJS][liquidjs] will **NOT** trim any whitespace by default, aka. above options all default to `false`. For details of these options, see the [options][options].
@@ -52,5 +52,5 @@ In greedy mode (enabled by the [greedy option][greedy]), all consecutive whitesp
[shopify/liquid]: https://github.com/Shopify/liquid
[liquidjs]: https://github.com/harttle/liquidjs
[options]: ../api/interfaces/liquid_options_.liquidoptions.html
[greedy]: ../api/interfaces/liquid_options_.liquidoptions.html#Optional-greedy
[options]: /api/interfaces/LiquidOptions.html
[greedy]: /api/interfaces/LiquidOptions.html#greedy
+16 -1
View File
@@ -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

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