Compare commits

...
122 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
343 changed files with 11820 additions and 35803 deletions
+82
View File
@@ -495,6 +495,88 @@
"contributions": [
"doc"
]
},
{
"login": "hongl-1",
"name": "hongl",
"avatar_url": "https://avatars.githubusercontent.com/u/101576612?v=4",
"profile": "https://github.com/hongl-1",
"contributions": [
"doc"
]
},
{
"login": "zxx-457",
"name": "zxx-457",
"avatar_url": "https://avatars.githubusercontent.com/u/114141362?v=4",
"profile": "https://github.com/zxx-457",
"contributions": [
"doc"
]
},
{
"login": "prassie",
"name": "prassie",
"avatar_url": "https://avatars.githubusercontent.com/u/1357831?v=4",
"profile": "https://github.com/prassie",
"contributions": [
"doc"
]
},
{
"login": "slavivanov",
"name": "Slav Ivanov",
"avatar_url": "https://avatars.githubusercontent.com/u/713329?v=4",
"profile": "http://slavv.com/",
"contributions": [
"code"
]
},
{
"login": "DaRosenberg",
"name": "Daniel Rosenberg",
"avatar_url": "https://avatars.githubusercontent.com/u/3889090?v=4",
"profile": "http://www.orgflow.io/",
"contributions": [
"code"
]
},
{
"login": "bobgubko",
"name": "bobgubko",
"avatar_url": "https://avatars.githubusercontent.com/u/733312?v=4",
"profile": "https://github.com/bobgubko",
"contributions": [
"code"
]
},
{
"login": "bangank36",
"name": "BaNgan",
"avatar_url": "https://avatars.githubusercontent.com/u/10071857?v=4",
"profile": "https://github.com/bangank36",
"contributions": [
"doc"
]
},
{
"login": "mahyar-pasarzangene",
"name": "Mahyar Pasarzangene",
"avatar_url": "https://avatars.githubusercontent.com/u/16485039?v=4",
"profile": "https://github.com/mahyar-pasarzangene",
"contributions": [
"doc"
]
},
{
"login": "TomasHubelbauer",
"name": "Tomáš Hübelbauer",
"avatar_url": "https://avatars.githubusercontent.com/u/6831144?v=4",
"profile": "https://hubelbauer.net/",
"contributions": [
"code",
"doc"
]
}
],
"contributorsPerLine": 7,
+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@v2
with:
node-version: '14'
- name: Build
run: |
npm ci
npm run build
- name: Test
run: |
npm run lint
npm run test
- name: Coverage
uses: coverallsapp/[email protected]
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
- name: Performance
run: |
npm run perf:diff
+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
+12 -8
View File
@@ -1,19 +1,16 @@
name: Docs
on:
push:
branches:
- master
on: [workflow_dispatch, workflow_call]
jobs:
docs:
name: Docs
runs-on: ubuntu-18.04
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Setup Node.js
uses: actions/setup-node@v2
uses: actions/setup-node@v3
with:
node-version: '14'
- name: Build
@@ -21,7 +18,14 @@ jobs:
npm ci
npm run build:docs
- name: Publish
if: github.ref == 'refs/heads/master'
uses: JamesIves/[email protected]
with:
branch: gh-pages
folder: docs/public
folder: docs/public
- name: Archive npm failure logs
uses: actions/upload-artifact@v3
if: failure()
with:
name: npm-logs
path: ~/.npm/_logs
+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 -16
View File
@@ -1,32 +1,49 @@
name: Release
on: workflow_dispatch
jobs:
build:
strategy:
matrix:
os: [ubuntu-latest, macos-latest]
uses: ./.github/workflows/build.yml
with:
os: ${{ matrix.os }}
test:
needs: build
uses: ./.github/workflows/test.yml
release:
name: Release
runs-on: ubuntu-18.04
needs: [build, test]
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Setup Node.js
uses: actions/setup-node@v2
uses: actions/setup-node@v3
with:
node-version: '14'
- name: Build
run: |
npm ci
npm run build:dist
- name: Test
run: |
npm run lint
npm run test
- name: Coverage
uses: coverallsapp/[email protected]
node-version: '18'
- name: Install Dependencies
run: npm ci
- name: Download artifacts
uses: actions/download-artifact@v3
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
name: dist-ubuntu-latest
path: dist
- name: Release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
run: npx semantic-release
run: |
if [ ${{ github.ref == 'refs/heads/master' }} ]; then
npx semantic-release
else
npx semantic-release --dry-run
fi
- name: Archive npm failure logs
uses: actions/upload-artifact@v3
if: failure()
with:
name: npm-logs
path: ~/.npm/_logs
+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
+215
View File
@@ -1,3 +1,218 @@
## [10.8.2](https://github.com/harttle/liquidjs/compare/v10.8.1...v10.8.2) (2023-06-04)
### Bug Fixes
* sample filter randomness and count=1 case ([fcb930f](https://github.com/harttle/liquidjs/commit/fcb930f0ddf2489fa74cd323f24398d7e9f7717f))
## [10.8.1](https://github.com/harttle/liquidjs/compare/v10.8.0...v10.8.1) (2023-06-04)
### Bug Fixes
* incorrect error message for browser UMD bundle ([3a67eb7](https://github.com/harttle/liquidjs/commit/3a67eb7f1cc7e54d2ec94a985eca4c1f147cdd61))
# [10.8.0](https://github.com/harttle/liquidjs/compare/v10.7.1...v10.8.0) (2023-06-03)
### Bug Fixes
* proper error message for filter syntax error, [#610](https://github.com/harttle/liquidjs/issues/610) ([0480d33](https://github.com/harttle/liquidjs/commit/0480d3317d0e46519ad2adf4ac43f53cddf467c6))
* sed invocations to work out of the box on macOS ([#615](https://github.com/harttle/liquidjs/issues/615)) ([87d4cc7](https://github.com/harttle/liquidjs/commit/87d4cc7e14ece14161285a740be63afc8a88b63c))
### Features
* Add support for the Jekyll sample filter ([#612](https://github.com/harttle/liquidjs/issues/612)) ([ba8b842](https://github.com/harttle/liquidjs/commit/ba8b84245266589e43c0e70d99e12b981d349809))
* Add support for the Jekyll push filter ([#611](https://github.com/harttle/liquidjs/issues/611))
* introduce a matrix with latest Ubuntu and macOS to test the build on macOS as well ([82ba548](https://github.com/harttle/liquidjs/commit/82ba54845f4cd4e1e7660c1557e3cfaa22d68924)), closes [#615](https://github.com/harttle/liquidjs/issues/615)
* precise line/col for tokenization Error, [#613](https://github.com/harttle/liquidjs/issues/613) ([e347e60](https://github.com/harttle/liquidjs/commit/e347e603d76c039cec191d417deab34e7ef1f9a7))
## [10.7.1](https://github.com/harttle/liquidjs/compare/v10.7.0...v10.7.1) (2023-04-24)
### Bug Fixes
* incorrect timezone correction for DST dates, fixes [#604](https://github.com/harttle/liquidjs/issues/604) ([33b3c01](https://github.com/harttle/liquidjs/commit/33b3c010af0cd17a303621331feab0119ca840ce))
* timezoneOffset ignored in date when preserveTimezones is enabled, fixes [#605](https://github.com/harttle/liquidjs/issues/605) ([21ee27b](https://github.com/harttle/liquidjs/commit/21ee27b57503f9d57f228973e1699972484e6089))
# [10.7.0](https://github.com/harttle/liquidjs/compare/v10.6.2...v10.7.0) (2023-03-21)
### Bug Fixes
* update remove.md ([#601](https://github.com/harttle/liquidjs/issues/601)) ([1bddd60](https://github.com/harttle/liquidjs/commit/1bddd60b0191032d324526292027bc7fcd190dc1))
### Features
* JSON format by `space` in `json` filter ([7b87ea8](https://github.com/harttle/liquidjs/commit/7b87ea82d3d63420e548743c5a84a073f0cdad22))
## [10.6.2](https://github.com/harttle/liquidjs/compare/v10.6.1...v10.6.2) (2023-03-19)
### Bug Fixes
* sample FS in render-file.md ([#594](https://github.com/harttle/liquidjs/issues/594)) ([4542ddc](https://github.com/harttle/liquidjs/commit/4542ddcfc3d5e245112a119bf22f0e00cb925791))
## [10.6.1](https://github.com/harttle/liquidjs/compare/v10.6.0...v10.6.1) (2023-03-02)
### Bug Fixes
* [expression] apply value equal for arrays, [#589](https://github.com/harttle/liquidjs/issues/589) ([9c0dc5f](https://github.com/harttle/liquidjs/commit/9c0dc5fa39a31d477a5c5a2c5212034174bf0516))
* strip_html for multi line <script>/<style>/comments, [#70](https://github.com/harttle/liquidjs/issues/70) ([42d2590](https://github.com/harttle/liquidjs/commit/42d25902e855d3c06d5ead071bf55604f495c205))
# [10.6.0](https://github.com/harttle/liquidjs/compare/v10.5.0...v10.6.0) (2023-02-22)
### Features
* LiquidOptions.dateFormat to override default date format ([#587](https://github.com/harttle/liquidjs/issues/587)) ([3fb6646](https://github.com/harttle/liquidjs/commit/3fb66465c6fe1bf4dc2e1ace9157c23d0fc8f859))
# [10.5.0](https://github.com/harttle/liquidjs/compare/v10.4.0...v10.5.0) (2023-02-14)
### Bug Fixes
* "ownPropertyOnly" not respected when passed via "renderOptions" ([d489916](https://github.com/harttle/liquidjs/commit/d489916231779149e110183400e3e597b8ee02ba))
### Features
* Adds support for options to CLI and improves usability ([#586](https://github.com/harttle/liquidjs/issues/586)) ([24c8a1e](https://github.com/harttle/liquidjs/commit/24c8a1e3722e5359f02934e2814f9abfa888ee86))
# [10.4.0](https://github.com/harttle/liquidjs/compare/v10.3.3...v10.4.0) (2023-01-02)
### Features
* support `not` operator, [#575](https://github.com/harttle/liquidjs/issues/575) ([3f21382](https://github.com/harttle/liquidjs/commit/3f21382d43cafa1e32162e58adabd22d5c3709ed))
* support calling `date` without format string, [#573](https://github.com/harttle/liquidjs/issues/573) ([aafaa0b](https://github.com/harttle/liquidjs/commit/aafaa0b4f9e84f466fbcc2cb2ae37fe8704c5272))
## [10.3.3](https://github.com/harttle/liquidjs/compare/v10.3.2...v10.3.3) (2022-12-18)
### Bug Fixes
* type compatible with v9 tag definition, support `Context` as scope in various render APIs, [#570](https://github.com/harttle/liquidjs/issues/570) ([fb6a9f8](https://github.com/harttle/liquidjs/commit/fb6a9f8717cd57522d53687da7e4718b28a7f68a))
## [10.3.2](https://github.com/harttle/liquidjs/compare/v10.3.1...v10.3.2) (2022-12-13)
### Bug Fixes
* re-export error classes, [#569](https://github.com/harttle/liquidjs/issues/569) ([2663ee1](https://github.com/harttle/liquidjs/commit/2663ee16a066c74cbd387fe40154fdeb2136f35a))
## [10.3.1](https://github.com/harttle/liquidjs/compare/v10.3.0...v10.3.1) (2022-12-12)
### Bug Fixes
* support `Context` as `evalValue` parameter, [#568](https://github.com/harttle/liquidjs/issues/568) ([0f4916b](https://github.com/harttle/liquidjs/commit/0f4916bc5a93f5e744e4246336c68f2e89774272))
# [10.3.0](https://github.com/harttle/liquidjs/compare/v10.2.0...v10.3.0) (2022-12-11)
### Features
* support disable outputEscape for specific filters, [#565](https://github.com/harttle/liquidjs/issues/565) ([e6db371](https://github.com/harttle/liquidjs/commit/e6db371519f0fb3b0068347cfb2016aed386c8fa))
# [10.2.0](https://github.com/harttle/liquidjs/compare/v10.1.0...v10.2.0) (2022-12-02)
### Bug Fixes
* `case` should render multiple `when` statements ([d17813e](https://github.com/harttle/liquidjs/commit/d17813ef5217264bd08f741b0e1f713bedf2d464))
### Features
* add remove_last filter ([6c3f1c1](https://github.com/harttle/liquidjs/commit/6c3f1c1e0c0c5d30ef77eaf20df65e149e51e693))
* add replace_last filter ([b4d1e27](https://github.com/harttle/liquidjs/commit/b4d1e27420fcf36ae6d5dbc92cfe4a26299690f2))
# [10.1.0](https://github.com/harttle/liquidjs/compare/v10.0.0...v10.1.0) (2022-11-29)
### Features
* timezone name for `opts.timezoneOffset` and `date` argument, fixes [#553](https://github.com/harttle/liquidjs/issues/553) ([89c6c76](https://github.com/harttle/liquidjs/commit/89c6c7676d40f23090472a28cbf2fb22f93daad3))
# [10.0.0](https://github.com/harttle/liquidjs/compare/v9.43.0...v10.0.0) (2022-11-27)
### Code Refactoring
* rename filters to snake style, [#487](https://github.com/harttle/liquidjs/issues/487) ([ff112a4](https://github.com/harttle/liquidjs/commit/ff112a4750f91475e9eccdb301d7a468e895f6ca))
* `_evalToken` renamed to `evalToken` ([4e1a30a](https://github.com/harttle/liquidjs/commit/4e1a30a20c579408c87f2d28b9b6ec8e1dda65cc))
* change `ownPropertyOnly` default value to `true` ([7eb6216](https://github.com/harttle/liquidjs/commit/7eb621601c2b05d6e379e5ce42219f2b1f556208))
* delay creation of `operatorsTrie` and hide this implementation ([bb58d3e](https://github.com/harttle/liquidjs/commit/bb58d3e549dc5a5e067895ec4a0b3257b434f225))
* remove `toThenable` export ([ffefd91](https://github.com/harttle/liquidjs/commit/ffefd91fbc0195c589c8c34ae80f2017acfe557c))
* remove use of internal `Context` class in `evalValue` argument ([b115077](https://github.com/harttle/liquidjs/commit/b115077e122a7b90e7972d58174d68aea8edd7bf))
### Performance Improvements
* target Node.js 14 for cjs bundle (main entry) ([1f6ce7c](https://github.com/harttle/liquidjs/commit/1f6ce7c8224123cea318d1aa6c12aa091d6e0518))
### BREAKING CHANGES
* `evalToken` now returns a generator (LiquidJS async), which is different from `evalToken` in previous LiquidJS versions.
* main entry need Node.js>=14 to run, you can build LiquidJS by your own by using ESM entry.
* `ownPropertyOnly` default value changed to `true`
* `<liquidjs>.toThenable` is removed, use `<liquidjs>.toPromise` instead
* `evalValue` won't support `Context` as second argument anymore.
* use `operators` instead of `operatorsTrie` as Tokenizer constructor argument, #500
* keys in `<liquidjs>.filters` are now in snake case (instead of camel case), identical to that in Liquid template.
# [9.43.0](https://github.com/harttle/liquidjs/compare/v9.42.1...v9.43.0) (2022-11-27)
### Features
* support timezone offset argument for date filter, [#553](https://github.com/harttle/liquidjs/issues/553) ([7a71485](https://github.com/harttle/liquidjs/commit/7a714855df9ba188e2e82839d248f6623ce94a87))
## [9.42.1](https://github.com/harttle/liquidjs/compare/v9.42.0...v9.42.1) (2022-10-21)
### Bug Fixes
* truncatewords should use at least one word, [#537](https://github.com/harttle/liquidjs/issues/537) ([32f613f](https://github.com/harttle/liquidjs/commit/32f613fb43e90f97364ee6a020589992dbb553cf))
# [9.42.0](https://github.com/harttle/liquidjs/compare/v9.41.0...v9.42.0) (2022-08-27)
### Features
* promise in expression & nested property, [#533](https://github.com/harttle/liquidjs/issues/533) [#276](https://github.com/harttle/liquidjs/issues/276) ([bbf00f3](https://github.com/harttle/liquidjs/commit/bbf00f37bf6080d38ebc258d1921d3ff0d504186))
# [9.41.0](https://github.com/harttle/liquidjs/compare/v9.40.0...v9.41.0) (2022-08-24)
### Features
* use evalValue to parse & render expression, [#527](https://github.com/harttle/liquidjs/issues/527) ([071368a](https://github.com/harttle/liquidjs/commit/071368afe1c4fd36ebdb0e1d300c367db1766f7f))
# [9.40.0](https://github.com/harttle/liquidjs/compare/v9.39.2...v9.40.0) (2022-08-14)
### Bug Fixes
* target ES6 for ESM bundles, fixes [#526](https://github.com/harttle/liquidjs/issues/526) ([905a6dd](https://github.com/harttle/liquidjs/commit/905a6dd1491705c1154b6679a67c1eb1ffe7eef5))
### Features
* export toValueSync & defaultOptions to evaluate expression, see [#527](https://github.com/harttle/liquidjs/issues/527) ([e874b40](https://github.com/harttle/liquidjs/commit/e874b4060b46195e05a5cc6690626bdaa532154c))
## [9.39.2](https://github.com/harttle/liquidjs/compare/v9.39.1...v9.39.2) (2022-07-21)
### Bug Fixes
* expression support Drop.valueOf, fixes [#522](https://github.com/harttle/liquidjs/issues/522) ([4ad383d](https://github.com/harttle/liquidjs/commit/4ad383d9beb57f5683805decc1851778db64aea4))
## [9.39.1](https://github.com/harttle/liquidjs/compare/v9.39.0...v9.39.1) (2022-07-14)
+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
+97 -77
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)
@@ -42,28 +42,35 @@ Or use the UMD bundle from jsDelivr:
<script src="https://cdn.jsdelivr.net/npm/liquidjs/dist/liquid.browser.min.js"></script>
```
More details, refer to [The Setup Guide][setup].
Or render directly from CLI using npx:
## Related Packages
```bash
npx liquidjs --template 'Hello, {{ name }}!' --context '{"name": "Snake"}'
```
For more details, refer to the [Setup Guide][setup].
## Related Projects
* [@11ty/eleventy](https://www.npmjs.com/package/@11ty/eleventy): A simpler static site generator. An alternative to Jekyll. Written in JavaScript. Transforms a directory of templates (of varying types) into HTML.
* [gulp-liquidjs](https://www.npmjs.com/package/@tuanpham-dev/gulp-liquidjs): A shopify compatible Liquid template engine for Gulp using liquidjs.
* [grunt-liquify](https://www.npmjs.com/package/grunt-liquify): A Grunt task to process Liquid using liquidjs. Use it to add Liquid magic to your scripts and css assets.
* [react-liquid](https://github.com/aquibm/react-liquid#readme): Liquid templating language component for React
* [@11ty/eleventy](https://www.npmjs.com/package/@11ty/eleventy): A simpler static site generator. An alternative to Jekyll. Written in JavaScript. Transforms a directory of templates (of varying types) into HTML.
## Financial Support
If you love LiquidJS or your company is using LiquidJS? Please consider [support us on Open Collective or Patreon][financial-support].
### Backers
If you personally like LiquidJS and find it's useful to you, you can become a backer!
If you personally like LiquidJS and find it useful to you, you can buy me a coffee!
<object type="image/svg+xml" data="https://opencollective.com/liquidjs/backers.svg?avatarHeight=72"></object>
<img src="https://opencollective.com/liquidjs/backers.svg?avatarHeight=72">
### Sponsors
If LiquidJS is benefiting your business/company, please sponsor us to make it better!
If LiquidJS is benefiting your business/company, please sponsor us to contribute to our effort!
<img src="https://opencollective.com/liquidjs/sponsors.svg?avatarHeight=72">
<object type="image/svg+xml" data="https://opencollective.com/liquidjs/sponsors.svg?avatarHeight=72"></object>
## Contributors ✨
Want to contribute? see [Contribution Guidelines][contribution]. Thanks goes to these wonderful people:
@@ -72,75 +79,88 @@ Want to contribute? see [Contribution Guidelines][contribution]. Thanks goes to
<!-- prettier-ignore-start -->
<!-- markdownlint-disable -->
<table>
<tr>
<td align="center"><a href="https://harttle.land"><img src="https://avatars3.githubusercontent.com/u/4427974?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Jun Yang</b></sub></a><br /><a href="#maintenance-harttle" title="Maintenance">🚧</a> <a href="https://github.com/harttle/liquidjs/commits?author=harttle" title="Code">💻</a></td>
<td align="center"><a href="https://github.com/chenos"><img src="https://avatars0.githubusercontent.com/u/2993310?v=4?s=100" width="100px;" alt=""/><br /><sub><b>chenos</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=chenos" title="Code">💻</a></td>
<td align="center"><a href="https://zachleat.com/"><img src="https://avatars2.githubusercontent.com/u/39355?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Zach Leatherman</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/issues?q=author%3Azachleat" title="Bug reports">🐛</a></td>
<td align="center"><a href="https://github.com/thardy"><img src="https://avatars3.githubusercontent.com/u/120636?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Tim Hardy</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=thardy" title="Code">💻</a></td>
<td align="center"><a href="https://paulrobertlloyd.com/"><img src="https://avatars3.githubusercontent.com/u/813383?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Paul Robert Lloyd</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=paulrobertlloyd" title="Code">💻</a> <a href="https://github.com/harttle/liquidjs/issues?q=author%3Apaulrobertlloyd" title="Bug reports">🐛</a></td>
<td align="center"><a href="https://twitter.com/alecdotbiz"><img src="https://avatars2.githubusercontent.com/u/1925840?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Alec Larson</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=aleclarson" title="Code">💻</a></td>
<td align="center"><a href="https://github.com/pmalouin"><img src="https://avatars1.githubusercontent.com/u/1411117?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Patrick Malouin</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=pmalouin" title="Code">💻</a> <a href="https://github.com/harttle/liquidjs/commits?author=pmalouin" title="Documentation">📖</a></td>
</tr>
<tr>
<td align="center"><a href="https://jaswrks.com"><img src="https://avatars3.githubusercontent.com/u/1563559?v=4?s=100" width="100px;" alt=""/><br /><sub><b>jaswrks</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=jaswrks" title="Code">💻</a></td>
<td align="center"><a href="https://oott123.com"><img src="https://avatars2.githubusercontent.com/u/905663?v=4?s=100" width="100px;" alt=""/><br /><sub><b>三三</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=oott123" title="Code">💻</a> <a href="#ideas-oott123" title="Ideas, Planning, & Feedback">🤔</a></td>
<td align="center"><a href="https://github.com/ssendev"><img src="https://avatars0.githubusercontent.com/u/450793?v=4?s=100" width="100px;" alt=""/><br /><sub><b>ssendev</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=ssendev" title="Code">💻</a> <a href="https://github.com/harttle/liquidjs/commits?author=ssendev" title="Documentation">📖</a></td>
<td align="center"><a href="https://github.com/wojtask9"><img src="https://avatars3.githubusercontent.com/u/6099236?v=4?s=100" width="100px;" alt=""/><br /><sub><b>wojtask9</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=wojtask9" title="Code">💻</a></td>
<td align="center"><a href="https://github.com/thelornenelson"><img src="https://avatars3.githubusercontent.com/u/24596583?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Andrew Barclay</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=thelornenelson" title="Code">💻</a></td>
<td align="center"><a href="https://www.stam.pr/"><img src="https://avatars2.githubusercontent.com/u/142338?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Cory Mawhorter</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=cmawhorter" title="Code">💻</a></td>
<td align="center"><a href="https://github.com/thehappybug"><img src="https://avatars0.githubusercontent.com/u/3393530?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Mehdi Jaffery</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=thehappybug" title="Code">💻</a></td>
</tr>
<tr>
<td align="center"><a href="https://github.com/robinbijlani"><img src="https://avatars0.githubusercontent.com/u/2503108?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Robin Bijlani</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=robinbijlani" title="Code">💻</a> <a href="https://github.com/harttle/liquidjs/issues?q=author%3Arobinbijlani" title="Bug reports">🐛</a></td>
<td align="center"><a href="https://www.rmkennedy.com"><img src="https://avatars3.githubusercontent.com/u/8356669?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Ryan Kennedy</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=ryaninvents" title="Code">💻</a></td>
<td align="center"><a href="https://github.com/strax"><img src="https://avatars2.githubusercontent.com/u/587213?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Sami Kukkonen</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=strax" title="Code">💻</a></td>
<td align="center"><a href="https://ScottFreeCode.github.io/"><img src="https://avatars3.githubusercontent.com/u/16506071?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Scott Santucci</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=ScottFreeCode" title="Code">💻</a></td>
<td align="center"><a href="http://stevenrescigno.com"><img src="https://avatars3.githubusercontent.com/u/8505293?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Steven </b></sub></a><br /><a href="#example-stevenanthonyrevo" title="Examples">💡</a> <a href="https://github.com/harttle/liquidjs/commits?author=stevenanthonyrevo" title="Code">💻</a></td>
<td align="center"><a href="https://efcl.info/"><img src="https://avatars1.githubusercontent.com/u/19714?v=4?s=100" width="100px;" alt=""/><br /><sub><b>azu</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=azu" title="Documentation">📖</a></td>
<td align="center"><a href="https://github.com/wyozi"><img src="https://avatars3.githubusercontent.com/u/4894573?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Joonas</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=wyozi" title="Code">💻</a></td>
</tr>
<tr>
<td align="center"><a href="https://github.com/jamelait"><img src="https://avatars1.githubusercontent.com/u/14369255?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Jamel A.</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=jamelait" title="Code">💻</a></td>
<td align="center"><a href="https://brandonpittman.net"><img src="https://avatars0.githubusercontent.com/u/967145?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Brandon Pittman</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=brandonpittman" title="Code">💻</a></td>
<td align="center"><a href="https://github.com/tgrandgent"><img src="https://avatars3.githubusercontent.com/u/17069042?v=4?s=100" width="100px;" alt=""/><br /><sub><b>tgrandgent</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=tgrandgent" title="Code">💻</a></td>
<td align="center"><a href="https://github.com/mastodon0"><img src="https://avatars1.githubusercontent.com/u/7924332?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Martin Schuster</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=mastodon0" title="Code">💻</a></td>
<td align="center"><a href="http://js.chenlei.me"><img src="https://avatars0.githubusercontent.com/u/6339390?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Ray</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=richardo2016" title="Tests">⚠️</a> <a href="https://github.com/harttle/liquidjs/commits?author=richardo2016" title="Code">💻</a></td>
<td align="center"><a href="https://github.com/CriGoT"><img src="https://avatars0.githubusercontent.com/u/1936786?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Cristofer Gonzales</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=CriGoT" title="Code">💻</a></td>
<td align="center"><a href="https://www.raymondcamden.com"><img src="https://avatars3.githubusercontent.com/u/393660?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Raymond Camden</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=cfjedimaster" title="Documentation">📖</a></td>
</tr>
<tr>
<td align="center"><a href="https://stedman.dev"><img src="https://avatars1.githubusercontent.com/u/183122?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Steve Stedman</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=stedman" title="Documentation">📖</a></td>
<td align="center"><a href="https://ciccarello.me"><img src="https://avatars0.githubusercontent.com/u/11273838?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Anthony Ciccarello</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=aciccarello" title="Documentation">📖</a></td>
<td align="center"><a href="https://twitter.com/IAmTrySound"><img src="https://avatars0.githubusercontent.com/u/5635476?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Bogdan Chadkin</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=TrySound" title="Code">💻</a></td>
<td align="center"><a href="https://hightouch.io"><img src="https://avatars0.githubusercontent.com/u/5959235?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Tejas Manohar</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=tejasmanohar" title="Code">💻</a></td>
<td align="center"><a href="http://about.me/peterdehaan"><img src="https://avatars2.githubusercontent.com/u/557895?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Peter deHaan</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=pdehaan" title="Documentation">📖</a></td>
<td align="center"><a href="https://github.com/amit777"><img src="https://avatars0.githubusercontent.com/u/2703309?v=4?s=100" width="100px;" alt=""/><br /><sub><b>amit777</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=amit777" title="Code">💻</a> <a href="#financial-amit777" title="Financial">💵</a></td>
<td align="center"><a href="http://www.ifi.uzh.ch/en/ce/people/schuldenzucker.html"><img src="https://avatars3.githubusercontent.com/u/1100776?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Steffen Schuldenzucker</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=sschuldenzucker" title="Code">💻</a></td>
</tr>
<tr>
<td align="center"><a href="https://github.com/Pixcell"><img src="https://avatars0.githubusercontent.com/u/4005291?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Pixcell</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=Pixcell" title="Code">💻</a></td>
<td align="center"><a href="https://jasonet.co"><img src="https://avatars.githubusercontent.com/u/10660468?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Jason Etcovitch</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=JasonEtco" title="Code">💻</a></td>
<td align="center"><a href="https://github.com/kayuapi"><img src="https://avatars.githubusercontent.com/u/10304328?v=4?s=100" width="100px;" alt=""/><br /><sub><b>ZC</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=kayuapi" title="Documentation">📖</a></td>
<td align="center"><a href="https://memmie.lenglet.name"><img src="https://avatars.githubusercontent.com/u/729275?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Memmie Lenglet</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=mems" title="Code">💻</a></td>
<td align="center"><a href="https://github.com/ilhamdev0"><img src="https://avatars.githubusercontent.com/u/57636145?v=4?s=100" width="100px;" alt=""/><br /><sub><b>ilhamdev0</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=ilhamdev0" title="Documentation">📖</a></td>
<td align="center"><a href="https://github.com/c412216887"><img src="https://avatars.githubusercontent.com/u/29691650?v=4?s=100" width="100px;" alt=""/><br /><sub><b>一饮一啄皆是人生</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=c412216887" title="Documentation">📖</a></td>
<td align="center"><a href="https://digitalinspiration.com/"><img src="https://avatars.githubusercontent.com/u/1344071?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Amit Agarwal</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=labnol" title="Documentation">📖</a></td>
</tr>
<tr>
<td align="center"><a href="https://n1ru4l.cloud/"><img src="https://avatars.githubusercontent.com/u/14338007?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Laurin Quast</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=n1ru4l" title="Code">💻</a></td>
<td align="center"><a href="https://github.com/mattvague"><img src="https://avatars.githubusercontent.com/u/64985?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Matt Vague</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=mattvague" title="Code">💻</a></td>
<td align="center"><a href="https://github.com/bglw"><img src="https://avatars.githubusercontent.com/u/40188355?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Liam Bigelow</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=bglw" title="Code">💻</a></td>
<td align="center"><a href="https://about.me/jasonkurian"><img src="https://avatars.githubusercontent.com/u/2642545?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Jason Kurian</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=JaKXz" title="Documentation">📖</a></td>
<td align="center"><a href="https://github.com/dphm"><img src="https://avatars.githubusercontent.com/u/1707217?v=4?s=100" width="100px;" alt=""/><br /><sub><b>d pham (they/them)</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=dphm" title="Documentation">📖</a></td>
<td align="center"><a href="https://www.aleksandrhovhannisyan.com/"><img src="https://avatars.githubusercontent.com/u/19352442?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Aleksandr Hovhannisyan</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=AleksandrHovhannisyan" title="Code">💻</a></td>
<td align="center"><a href="https://github.com/jg-rp"><img src="https://avatars.githubusercontent.com/u/72664870?v=4?s=100" width="100px;" alt=""/><br /><sub><b>jg-rp</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=jg-rp" title="Code">💻</a></td>
</tr>
<tr>
<td align="center"><a href="https://github.com/ameyaapte1"><img src="https://avatars.githubusercontent.com/u/16054747?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Ameya Apte</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=ameyaapte1" title="Code">💻</a></td>
<td align="center"><a href="https://github.com/tbdrz"><img src="https://avatars.githubusercontent.com/u/50599116?v=4?s=100" width="100px;" alt=""/><br /><sub><b>tbdrz</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=tbdrz" title="Documentation">📖</a></td>
<td align="center"><a href="http://santialbo.com"><img src="https://avatars.githubusercontent.com/u/1557563?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Santi Albo</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=santialbo" title="Documentation">📖</a></td>
<td align="center"><a href="https://github.com/YahangWu"><img src="https://avatars.githubusercontent.com/u/12295975?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Yahang Wu</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=YahangWu" title="Documentation">📖</a></td>
</tr>
<tbody>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://harttle.land"><img src="https://avatars3.githubusercontent.com/u/4427974?v=4?s=100" width="100px;" alt="Jun Yang"/><br /><sub><b>Jun Yang</b></sub></a><br /><a href="#maintenance-harttle" title="Maintenance">🚧</a> <a href="https://github.com/harttle/liquidjs/commits?author=harttle" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/chenos"><img src="https://avatars0.githubusercontent.com/u/2993310?v=4?s=100" width="100px;" alt="chenos"/><br /><sub><b>chenos</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=chenos" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://zachleat.com/"><img src="https://avatars2.githubusercontent.com/u/39355?v=4?s=100" width="100px;" alt="Zach Leatherman"/><br /><sub><b>Zach Leatherman</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/issues?q=author%3Azachleat" title="Bug reports">🐛</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/thardy"><img src="https://avatars3.githubusercontent.com/u/120636?v=4?s=100" width="100px;" alt="Tim Hardy"/><br /><sub><b>Tim Hardy</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=thardy" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://paulrobertlloyd.com/"><img src="https://avatars3.githubusercontent.com/u/813383?v=4?s=100" width="100px;" alt="Paul Robert Lloyd"/><br /><sub><b>Paul Robert Lloyd</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=paulrobertlloyd" title="Code">💻</a> <a href="https://github.com/harttle/liquidjs/issues?q=author%3Apaulrobertlloyd" title="Bug reports">🐛</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://twitter.com/alecdotbiz"><img src="https://avatars2.githubusercontent.com/u/1925840?v=4?s=100" width="100px;" alt="Alec Larson"/><br /><sub><b>Alec Larson</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=aleclarson" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/pmalouin"><img src="https://avatars1.githubusercontent.com/u/1411117?v=4?s=100" width="100px;" alt="Patrick Malouin"/><br /><sub><b>Patrick Malouin</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=pmalouin" title="Code">💻</a> <a href="https://github.com/harttle/liquidjs/commits?author=pmalouin" title="Documentation">📖</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://jaswrks.com"><img src="https://avatars3.githubusercontent.com/u/1563559?v=4?s=100" width="100px;" alt="jaswrks"/><br /><sub><b>jaswrks</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=jaswrks" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://oott123.com"><img src="https://avatars2.githubusercontent.com/u/905663?v=4?s=100" width="100px;" alt="三三"/><br /><sub><b>三三</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=oott123" title="Code">💻</a> <a href="#ideas-oott123" title="Ideas, Planning, & Feedback">🤔</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/ssendev"><img src="https://avatars0.githubusercontent.com/u/450793?v=4?s=100" width="100px;" alt="ssendev"/><br /><sub><b>ssendev</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=ssendev" title="Code">💻</a> <a href="https://github.com/harttle/liquidjs/commits?author=ssendev" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/wojtask9"><img src="https://avatars3.githubusercontent.com/u/6099236?v=4?s=100" width="100px;" alt="wojtask9"/><br /><sub><b>wojtask9</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=wojtask9" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/thelornenelson"><img src="https://avatars3.githubusercontent.com/u/24596583?v=4?s=100" width="100px;" alt="Andrew Barclay"/><br /><sub><b>Andrew Barclay</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=thelornenelson" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://www.stam.pr/"><img src="https://avatars2.githubusercontent.com/u/142338?v=4?s=100" width="100px;" alt="Cory Mawhorter"/><br /><sub><b>Cory Mawhorter</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=cmawhorter" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/thehappybug"><img src="https://avatars0.githubusercontent.com/u/3393530?v=4?s=100" width="100px;" alt="Mehdi Jaffery"/><br /><sub><b>Mehdi Jaffery</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=thehappybug" title="Code">💻</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/robinbijlani"><img src="https://avatars0.githubusercontent.com/u/2503108?v=4?s=100" width="100px;" alt="Robin Bijlani"/><br /><sub><b>Robin Bijlani</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=robinbijlani" title="Code">💻</a> <a href="https://github.com/harttle/liquidjs/issues?q=author%3Arobinbijlani" title="Bug reports">🐛</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://www.rmkennedy.com"><img src="https://avatars3.githubusercontent.com/u/8356669?v=4?s=100" width="100px;" alt="Ryan Kennedy"/><br /><sub><b>Ryan Kennedy</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=ryaninvents" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/strax"><img src="https://avatars2.githubusercontent.com/u/587213?v=4?s=100" width="100px;" alt="Sami Kukkonen"/><br /><sub><b>Sami Kukkonen</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=strax" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://ScottFreeCode.github.io/"><img src="https://avatars3.githubusercontent.com/u/16506071?v=4?s=100" width="100px;" alt="Scott Santucci"/><br /><sub><b>Scott Santucci</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=ScottFreeCode" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="http://stevenrescigno.com"><img src="https://avatars3.githubusercontent.com/u/8505293?v=4?s=100" width="100px;" alt="Steven "/><br /><sub><b>Steven </b></sub></a><br /><a href="#example-stevenanthonyrevo" title="Examples">💡</a> <a href="https://github.com/harttle/liquidjs/commits?author=stevenanthonyrevo" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://efcl.info/"><img src="https://avatars1.githubusercontent.com/u/19714?v=4?s=100" width="100px;" alt="azu"/><br /><sub><b>azu</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=azu" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/wyozi"><img src="https://avatars3.githubusercontent.com/u/4894573?v=4?s=100" width="100px;" alt="Joonas"/><br /><sub><b>Joonas</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=wyozi" title="Code">💻</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/jamelait"><img src="https://avatars1.githubusercontent.com/u/14369255?v=4?s=100" width="100px;" alt="Jamel A."/><br /><sub><b>Jamel A.</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=jamelait" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://brandonpittman.net"><img src="https://avatars0.githubusercontent.com/u/967145?v=4?s=100" width="100px;" alt="Brandon Pittman"/><br /><sub><b>Brandon Pittman</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=brandonpittman" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/tgrandgent"><img src="https://avatars3.githubusercontent.com/u/17069042?v=4?s=100" width="100px;" alt="tgrandgent"/><br /><sub><b>tgrandgent</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=tgrandgent" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/mastodon0"><img src="https://avatars1.githubusercontent.com/u/7924332?v=4?s=100" width="100px;" alt="Martin Schuster"/><br /><sub><b>Martin Schuster</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=mastodon0" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="http://js.chenlei.me"><img src="https://avatars0.githubusercontent.com/u/6339390?v=4?s=100" width="100px;" alt="Ray"/><br /><sub><b>Ray</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=richardo2016" title="Tests">⚠️</a> <a href="https://github.com/harttle/liquidjs/commits?author=richardo2016" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/CriGoT"><img src="https://avatars0.githubusercontent.com/u/1936786?v=4?s=100" width="100px;" alt="Cristofer Gonzales"/><br /><sub><b>Cristofer Gonzales</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=CriGoT" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://www.raymondcamden.com"><img src="https://avatars3.githubusercontent.com/u/393660?v=4?s=100" width="100px;" alt="Raymond Camden"/><br /><sub><b>Raymond Camden</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=cfjedimaster" title="Documentation">📖</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://stedman.dev"><img src="https://avatars1.githubusercontent.com/u/183122?v=4?s=100" width="100px;" alt="Steve Stedman"/><br /><sub><b>Steve Stedman</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=stedman" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://ciccarello.me"><img src="https://avatars0.githubusercontent.com/u/11273838?v=4?s=100" width="100px;" alt="Anthony Ciccarello"/><br /><sub><b>Anthony Ciccarello</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=aciccarello" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://twitter.com/IAmTrySound"><img src="https://avatars0.githubusercontent.com/u/5635476?v=4?s=100" width="100px;" alt="Bogdan Chadkin"/><br /><sub><b>Bogdan Chadkin</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=TrySound" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://hightouch.io"><img src="https://avatars0.githubusercontent.com/u/5959235?v=4?s=100" width="100px;" alt="Tejas Manohar"/><br /><sub><b>Tejas Manohar</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=tejasmanohar" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="http://about.me/peterdehaan"><img src="https://avatars2.githubusercontent.com/u/557895?v=4?s=100" width="100px;" alt="Peter deHaan"/><br /><sub><b>Peter deHaan</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=pdehaan" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/amit777"><img src="https://avatars0.githubusercontent.com/u/2703309?v=4?s=100" width="100px;" alt="amit777"/><br /><sub><b>amit777</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=amit777" title="Code">💻</a> <a href="#financial-amit777" title="Financial">💵</a></td>
<td align="center" valign="top" width="14.28%"><a href="http://www.ifi.uzh.ch/en/ce/people/schuldenzucker.html"><img src="https://avatars3.githubusercontent.com/u/1100776?v=4?s=100" width="100px;" alt="Steffen Schuldenzucker"/><br /><sub><b>Steffen Schuldenzucker</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=sschuldenzucker" title="Code">💻</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Pixcell"><img src="https://avatars0.githubusercontent.com/u/4005291?v=4?s=100" width="100px;" alt="Pixcell"/><br /><sub><b>Pixcell</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=Pixcell" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://jasonet.co"><img src="https://avatars.githubusercontent.com/u/10660468?v=4?s=100" width="100px;" alt="Jason Etcovitch"/><br /><sub><b>Jason Etcovitch</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=JasonEtco" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/kayuapi"><img src="https://avatars.githubusercontent.com/u/10304328?v=4?s=100" width="100px;" alt="ZC"/><br /><sub><b>ZC</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=kayuapi" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://memmie.lenglet.name"><img src="https://avatars.githubusercontent.com/u/729275?v=4?s=100" width="100px;" alt="Memmie Lenglet"/><br /><sub><b>Memmie Lenglet</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=mems" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/ilhamdev0"><img src="https://avatars.githubusercontent.com/u/57636145?v=4?s=100" width="100px;" alt="ilhamdev0"/><br /><sub><b>ilhamdev0</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=ilhamdev0" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/c412216887"><img src="https://avatars.githubusercontent.com/u/29691650?v=4?s=100" width="100px;" alt="一饮一啄皆是人生"/><br /><sub><b>一饮一啄皆是人生</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=c412216887" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://digitalinspiration.com/"><img src="https://avatars.githubusercontent.com/u/1344071?v=4?s=100" width="100px;" alt="Amit Agarwal"/><br /><sub><b>Amit Agarwal</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=labnol" title="Documentation">📖</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://n1ru4l.cloud/"><img src="https://avatars.githubusercontent.com/u/14338007?v=4?s=100" width="100px;" alt="Laurin Quast"/><br /><sub><b>Laurin Quast</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=n1ru4l" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/mattvague"><img src="https://avatars.githubusercontent.com/u/64985?v=4?s=100" width="100px;" alt="Matt Vague"/><br /><sub><b>Matt Vague</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=mattvague" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/bglw"><img src="https://avatars.githubusercontent.com/u/40188355?v=4?s=100" width="100px;" alt="Liam Bigelow"/><br /><sub><b>Liam Bigelow</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=bglw" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://about.me/jasonkurian"><img src="https://avatars.githubusercontent.com/u/2642545?v=4?s=100" width="100px;" alt="Jason Kurian"/><br /><sub><b>Jason Kurian</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=JaKXz" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/dphm"><img src="https://avatars.githubusercontent.com/u/1707217?v=4?s=100" width="100px;" alt="d pham (they/them)"/><br /><sub><b>d pham (they/them)</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=dphm" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://www.aleksandrhovhannisyan.com/"><img src="https://avatars.githubusercontent.com/u/19352442?v=4?s=100" width="100px;" alt="Aleksandr Hovhannisyan"/><br /><sub><b>Aleksandr Hovhannisyan</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=AleksandrHovhannisyan" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/jg-rp"><img src="https://avatars.githubusercontent.com/u/72664870?v=4?s=100" width="100px;" alt="jg-rp"/><br /><sub><b>jg-rp</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=jg-rp" title="Code">💻</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/ameyaapte1"><img src="https://avatars.githubusercontent.com/u/16054747?v=4?s=100" width="100px;" alt="Ameya Apte"/><br /><sub><b>Ameya Apte</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=ameyaapte1" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/tbdrz"><img src="https://avatars.githubusercontent.com/u/50599116?v=4?s=100" width="100px;" alt="tbdrz"/><br /><sub><b>tbdrz</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=tbdrz" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="http://santialbo.com"><img src="https://avatars.githubusercontent.com/u/1557563?v=4?s=100" width="100px;" alt="Santi Albo"/><br /><sub><b>Santi Albo</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=santialbo" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/YahangWu"><img src="https://avatars.githubusercontent.com/u/12295975?v=4?s=100" width="100px;" alt="Yahang Wu"/><br /><sub><b>Yahang Wu</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=YahangWu" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/hongl-1"><img src="https://avatars.githubusercontent.com/u/101576612?v=4?s=100" width="100px;" alt="hongl"/><br /><sub><b>hongl</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=hongl-1" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/zxx-457"><img src="https://avatars.githubusercontent.com/u/114141362?v=4?s=100" width="100px;" alt="zxx-457"/><br /><sub><b>zxx-457</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=zxx-457" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/prassie"><img src="https://avatars.githubusercontent.com/u/1357831?v=4?s=100" width="100px;" alt="prassie"/><br /><sub><b>prassie</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=prassie" title="Documentation">📖</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="http://slavv.com/"><img src="https://avatars.githubusercontent.com/u/713329?v=4?s=100" width="100px;" alt="Slav Ivanov"/><br /><sub><b>Slav Ivanov</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=slavivanov" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="http://www.orgflow.io/"><img src="https://avatars.githubusercontent.com/u/3889090?v=4?s=100" width="100px;" alt="Daniel Rosenberg"/><br /><sub><b>Daniel Rosenberg</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=DaRosenberg" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/bobgubko"><img src="https://avatars.githubusercontent.com/u/733312?v=4?s=100" width="100px;" alt="bobgubko"/><br /><sub><b>bobgubko</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=bobgubko" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/bangank36"><img src="https://avatars.githubusercontent.com/u/10071857?v=4?s=100" width="100px;" alt="BaNgan"/><br /><sub><b>BaNgan</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=bangank36" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/mahyar-pasarzangene"><img src="https://avatars.githubusercontent.com/u/16485039?v=4?s=100" width="100px;" alt="Mahyar Pasarzangene"/><br /><sub><b>Mahyar Pasarzangene</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=mahyar-pasarzangene" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://hubelbauer.net/"><img src="https://avatars.githubusercontent.com/u/6831144?v=4?s=100" width="100px;" alt="Tomáš Hübelbauer"/><br /><sub><b>Tomáš Hübelbauer</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=TomasHubelbauer" title="Code">💻</a> <a href="https://github.com/harttle/liquidjs/commits?author=TomasHubelbauer" title="Documentation">📖</a></td>
</tr>
</tbody>
</table>
<!-- markdownlint-restore -->
-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 -22
View File
@@ -1,24 +1,4 @@
#!/usr/bin/env bash
set -ex
rm -rf docs/source/api docs/source/zh-cn/api
typedoc ./src --gitRevision master --out docs/source/api --plugin typedoc-plugin-markdown --ignoreCompilerErrors true --theme vuepress
rm docs/source/api/README.md
for file in $(find docs/source/api -name "*.md"); do
sed -i \
-e 's/\(\]([^_)]*\)\/_/\1\//g' \
-e 's/\(\]([^)]*\.\)md/\1html/g' \
-e 's/\](_/\](/g' \
-e '1 s/"/\&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/\/_/\/}
cat $file | ./bin/escape-nunjucks.js > $target
done
cp -r docs/source/api docs/source/zh-cn/api
rm -rf docs/source/api
typedoc ./src --gitRevision master --out docs/source/api
+14 -3
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/
+1
View File
@@ -2,6 +2,7 @@
set -ex
./bin/build-docs-liquid.sh
./bin/build-contributors.sh
./bin/build-apidoc.sh
./bin/build-changelog.sh
+130 -15
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
+1 -1
View File
@@ -1,4 +1,4 @@
# LiquidJS for Node.js
# Using LiquidJS in ESM
## Get Started
+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 -10
View File
@@ -1,24 +1,25 @@
import { Liquid, TagToken, Context, Emitter } from 'liquidjs'
import { Value, Liquid, TagToken, Context, Emitter, Tag, TopLevelToken } from 'liquidjs'
const engine = new Liquid({
root: __dirname,
extname: '.liquid'
})
engine.registerTag('header', {
parse: function (token: TagToken) {
const [key, val] = token.args.split(':')
this[key] = val
},
render: async function (context: Context, emitter: Emitter) {
const title = await this.liquid.evalValue(this['content'], context)
engine.registerTag('header', class HeaderTag extends Tag {
private value: Value
constructor (token: TagToken, remainTokens: TopLevelToken[], liquid: Liquid) {
super(token, remainTokens, liquid)
this.value = new Value(token.args, liquid)
}
* render (ctx: Context, emitter: Emitter) {
const title = yield this.value.value(ctx)
emitter.write(`<h1>${title}</h1>`)
}
})
const ctx = {
const scope = {
todos: ['fork and clone', 'make it better', 'make a pull request'],
title: 'Welcome to liquidjs!'
}
engine.renderFile('todolist', ctx).then(console.log)
engine.renderFile('todolist', scope).then(console.log)
+1 -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'),
},
};
+1 -1
View File
@@ -19,7 +19,7 @@ pretty_urls:
trailing_html: false
theme: navy
skip_render: "api/**/*"
highlight:
enable: false
prismjs:
+669 -358
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"
}
}
}
+1 -1
View File
@@ -2,4 +2,4 @@ tutorials: /tutorials/intro-to-liquid.html
tags: /tags/overview.html
filters: /filters/overview.html
playground: /playground.html
api: /api/classes/liquid_.liquid.html
api: /api/classes/Liquid.html
+3 -1
View File
@@ -54,8 +54,10 @@ filters:
raw: raw.html
remove: remove.html
remove_first: remove_first.html
remove_last: remove_last.html
replace: replace.html
replace_first: replace_first.html
replace_last: replace_last.html
reverse: reverse.html
round: round.html
rstrip: rstrip.html
@@ -78,7 +80,7 @@ filters:
tags:
overview: overview.html
"# (inline comment)": inline_comment.html
"#": inline_comment.html
assign: assign.html
capture: capture.html
case: case.html
+43 -40
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
+1 -1
View File
@@ -10,7 +10,7 @@ There's 40+ filters supported by LiquidJS. These filters can be categorized into
Categories | Filters
--- | ---
Math | plus, minus, modulo, times, floor, ceil, round, divided_by, abs, at_least, at_most
String | append, prepend, capitalize, upcase, downcase, strip, lstrip, rstrip, strip_newlines, split, replace, replace_first, remove, remove_first, truncate, truncatewords
String | append, prepend, capitalize, upcase, downcase, strip, lstrip, rstrip, strip_newlines, split, replace, replace_first, replace_last,remove, remove_first, remove_last, truncate, truncatewords
HTML/URI | escape, escape_once, url_encode, url_decode, strip_html, newline_to_br
Array | slice, map, sort, sort_natural, uniq, where, first, last, join, reverse, concat, compact, size
Date | date
+1 -1
View File
@@ -4,7 +4,7 @@ title: raw
{% since %}v9.37.0{% endsince %}
Liquid filter that directly returns the value of the variable. Useful when [outputEscape](/api/interfaces/liquid_options_.liquidoptions.html#Optional-outputEscape) is set.
Liquid filter that directly returns the value of the variable. Useful when [outputEscape](/api/interfaces/LiquidOptions.html#outputEscape) is set.
{% note info Auto escape %}
By default `outputEscape` is not set. That means LiquidJS output is not escaped by default, thus `raw` filter is not useful until `outputEscape` is set.
+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
```
+1 -1
View File
@@ -47,7 +47,7 @@
},
{
"name": "API",
"url": "/api/classes/liquid_.liquid.html",
"url": "/api/classes/Liquid.html",
"description": "TypeScript doc for LiquidJS classes and interfaces"
}
],
+4 -4
View File
@@ -104,7 +104,7 @@ Note that we're referencing the first parameter by `include.header` instead of `
</article>
```
[extname]: ../api/interfaces/liquid_options_.liquidoptions.html#Optional-extname
[root]: ../api/interfaces/liquid_options_.liquidoptions.html#Optional-root
[dynamicPartials]: ../api/interfaces/liquid_options_.liquidoptions.html#Optional-dynamicPartials
[jekyllInclude]: ../api/interfaces/liquid_options_.liquidoptions.html#Optional-jekyllInclude
[extname]: /api/interfaces/LiquidOptions.html#extname
[root]: /api/interfaces/LiquidOptions.html#root
[dynamicPartials]: /api/interfaces/LiquidOptions.html#dynamicPartials
[jekyllInclude]: /api/interfaces/LiquidOptions.html#jekyllInclude
+4 -4
View File
@@ -101,7 +101,7 @@ This way, you don't need to escape `"` in the filename expression.
{% layout prefix/{{name | append: ".html"}} %}
```
[extname]: ../api/interfaces/liquid_options_.liquidoptions.html#Optional-extname
[root]: ../api/interfaces/liquid_options_.liquidoptions.html#Optional-root
[layouts]: ../api/interfaces/liquid_options_.liquidoptions.html#Optional-layouts
[dynamicPartials]: ../api/interfaces/liquid_options_.liquidoptions.html#dynamicPartials
[extname]: /api/interfaces/LiquidOptions.html#extname
[root]: /api/interfaces/LiquidOptions.html#root
[layouts]: /api/interfaces/LiquidOptions.html#layouts
[dynamicPartials]: /api/interfaces/LiquidOptions.html#dynamicPartials
+5 -5
View File
@@ -94,8 +94,8 @@ In the example above, the partial template will be rendered once for each `varia
{% note tip The forloop object %} When using the for parameter, the <a href="./for.html#forloop">forloop</a> object is accessible within the snippet.{% endnote %}
[forloop]: ./for.html
[extname]: ../api/interfaces/liquid_options_.liquidoptions.html#Optional-extname
[root]: ../api/interfaces/liquid_options_.liquidoptions.html#Optional-root
[partials]: ../api/interfaces/liquid_options_.liquidoptions.html#Optional-partials
[globals]: ../api/interfaces/liquid_options_.liquidoptions.html#Optional-globals
[dynamicPartials]: ../api/interfaces/liquid_options_.liquidoptions.html#dynamicPartials
[extname]: /api/interfaces/LiquidOptions.html#extname
[root]: /api/interfaces/LiquidOptions.html#root
[partials]: /api/interfaces/LiquidOptions.html#partials
[globals]: /api/interfaces/LiquidOptions.html#globals
[dynamicPartials]: /api/interfaces/LiquidOptions.html#dynamicPartials
+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
@@ -8,17 +8,11 @@ Starring LiquidJS is the most important and easiest way to support us: boost its
## Show Me Your Code
**Code Style**: LiquidJS applies [standard](https://github.com/standard/eslint-config-standard) and [@typescript-eslint/recommended](https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/eslint-plugin/src/configs/recommended.json) rules, make sure it's still valid before commit:
Getting started and building is described in [CONTRIBUTING.md](https://github.com/harttle/liquidjs/blob/master/CONTRIBUTING.md).
```bash
npm run lint
```
**Code Style**: LiquidJS applies [standard](https://github.com/standard/eslint-config-standard) and [@typescript-eslint/recommended](https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/eslint-plugin/src/configs/recommended.json) rules.
**Testing**: Make sure test cases pass with your patch merged:
```bash
npm test
```
**Testing**: Make sure test cases pass with your patch merged by running `npm test`
**Commit Message**: Please align to [the Angular Commit Message Guidelines](https://github.com/angular/angular.js/blob/master/DEVELOPERS.md#commits), especially note the [type identifier](https://github.com/angular/angular.js/blob/master/DEVELOPERS.md#type), on which semantic-release bot depends.
@@ -26,7 +20,7 @@ npm test
## Financial Support
LiquidJS is Open Source and Free. To help it live and thrive, please consider contribute on [Open Collective][oc] or [Patreon][pt]. To acknowledge your contribution, your name and avatar will be listed here, on LiquidJS [homepage](https://liquidjs.com/) and on [Github README][liquidjs].
LiquidJS is Open Source and Free. To help it live and thrive, please consider contribute on [Open Collective][oc]. To acknowledge your contribution, your name and avatar will be listed here, on LiquidJS [homepage](https://liquidjs.com/) and on [Github README][liquidjs]. Please provide your Github ID by openning an issue or contacting me through Twitter (harttleharttle), I can help add you into [the contributors table](https://github.com/harttle/liquidjs#contributors-).
### Backers
If you personally like LiquidJS and find it's useful to you, you can become a backer!
@@ -38,8 +32,7 @@ If LiquidJS is benefiting your business/company, please sponsor us to make it be
<object type="image/svg+xml" data="https://opencollective.com/liquidjs/sponsors.svg?avatarHeight=72"></object>
[oc]: https://opencollective.com/liquidjs/contribute/backer-ii-10666/checkout
[pt]: https://www.patreon.com/harttle
[oc]: https://opencollective.com/liquidjs/contribute/backer-10665/checkout
[shopify/liquid]: https://shopify.github.io/liquid/
[caniuse-promises]: http://caniuse.com/#feat=promises
[pp]: https://github.com/taylorhakes/promise-polyfill
+2 -1
View File
@@ -30,8 +30,9 @@ Though we're trying to be compatible with the Ruby version, there are still some
* Sort stability. The [sort][sort] stability is also not defined in both shopify/liquid and LiquidJS, but it's [considered stable][stable-sort] for LiquidJS in Node.js 12+ and Google Chrome 70+.
* Trailing unmatched characters inside filters are allowed in shopify/liquid but not in LiquidJS. It means filter arguments without a colon like `{%raw%}{{ "a b" | split " "}}{%endraw%}` will throw an error in LiquidJS. This is intended to improve Liquid usability, see [#208][#208] and [#212][#212].
* LiquidJS has additional tags: [layout][layout] and corresponding `block` tag.
* LiquidJS has additional filters: [json][json].
* LiquidJS [date][date] filter supports `%q` for date ordinals like `{{ '2023/02/02' | date: '%d%q of %b'}}` => `02nd of Feb`
[date]: https://liquidjs.com/filters/date.html
[layout]: https://liquidjs.com/tags/layout.html
[json]: https://liquidjs.com/filters/json.html
[#26]: https://github.com/harttle/liquidjs/pull/26
+6 -4
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
@@ -108,6 +108,8 @@ it defaults to false. For example, when set to true, a blank string would evalu
**preserveTimezones** is a boolean effects only literal timestamps. When set to `true`, all literal timestamps will remain the same when output. This is a parser option, so Date objects passed to LiquidJS as data will not be affected. Note that `preserveTimezones` has a higher priority than `timezoneOffset`.
**dateFormat** is used to specify a default format to output dates. `%A, %B %-e, %Y at %-l:%M %P %z` will be used if not specified. For example, set `dateFormat: %Y-%m-%dT%H:%M:%S:%LZ` to output all dates in [JavaScript Date.toJson()][https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toJSON] format.
## Trimming
**greedy**, **trimOutputLeft**, **trimOutputRight**, **trimTagLeft**, **trimTagRight** options are used to eliminate extra newlines and indents in templates around Liquid Constructs. See [Whitespace Control][wc] for details.
@@ -128,7 +130,7 @@ it defaults to false. For example, when set to true, a blank string would evalu
**lenientIf** modifies the behavior of `strictVariables` to allow handling optional variables. If set to `true`, an undefined variable will *not* cause an exception in the following two situations: a) it is the condition to an `if`, `elsif`, or `unless` tag; b) it occurs right before a `default` filter. Irrelevant if `strictVariables` is not set. Defaults to `false`.
**ownPropertyOnly** hides scope variables from prototypes, useful when you're passing a not sanitized object into LiquidJS or need to hide prototypes from templates. Defaults to `false`.
**ownPropertyOnly** hides scope variables from prototypes, useful when you're passing a not sanitized object into LiquidJS or need to hide prototypes from templates. Defaults to `true`.
{% note info Non-existent Tags %}
Non-existent tags always throw errors during parsing and this behavior can not be customized.
@@ -138,7 +140,7 @@ Non-existent tags always throw errors during parsing and this behavior can not b
Parameter orders are ignored by default, for ea `{% for i in (1..8) reversed limit:3 %}` will always perform `limit` before `reversed`, even if `reversed` occurs before `limit`. To make parameter order respected, set **orderedFilterParameters** to `true`. Its default value is `false`.
[liquid]: ../api/classes/liquid_.liquid.html
[liquid]: /api/classes/Liquid.html
[caching]: ./caching.html
[abstract-fs]: ./render-file.html#Abstract-File-System
[render-file]: ./render-file.html
@@ -148,4 +150,4 @@ Parameter orders are ignored by default, for ea `{% for i in (1..8) reversed lim
[layout]: ../tags/layout.html
[wc]: ./whitespace-control.html
[intro]: ./intro-to-liquid.html
[jekyllInclude]: ../api/interfaces/liquid_options_.liquidoptions.html#Optional-jekyllInclude
[jekyllInclude]: /api/interfaces/LiquidOptions.html#jekyllInclude
+2 -2
View File
@@ -96,5 +96,5 @@ Rendering `{% random from:2, to:max %}` in scope `{ max: 10 }` will generate a r
[register-tags]: /tutorials/register-filters-tags.html
[Tokenizer]: /api/classes/parser_tokenizer_.tokenizer.html
[Hash]: /api/classes/template_tag_hash_.hash.html
[Tokenizer]: /api/classes/Tokenizer.html
[Hash]: /api/classes/Hash.html
+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
+25 -6
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
+11 -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/fs.ts][ifs] and the default implementation is [src/fs/node.ts][fs-node] for Node.js and [src/fs/browser.ts][fs-browser] for the browser bundle.
LiquidJS defines an abstract file system interface in [src/fs/fs.ts][ifs] and the default implementation is [src/fs/fs-impl.ts][fs-node] for Node.js and [src/build/fs-impl-browser.ts][fs-browser] for the browser bundle.
The `Liquid` constructor provides a [fs][fs] option to specify the file system implementation. It's supposed to be used to define customized template fetching logic, i.e. fetch template from a database table, like:
@@ -85,7 +85,7 @@ var engine = new Liquid({
existsSync () {
return true
},
exists () {
async exists () {
return true
},
contains () {
@@ -100,14 +100,14 @@ var engine = new Liquid({
{% note warn Path Traversal Vulnerability %}The default value of <code>contains()</code> always returns true. That means when specifying an abstract file system, you'll need to provide a proper <code>contains()</code> to avoid expose such vulnerabilities.{% endnote %}
[fs]: ../api/interfaces/liquid_options_.liquidoptions.html#Optional-fs
[ifs]: https://github.com/harttle/liquidjs/blob/master/src/fs/fs.ts
[fs-node]: https://github.com/harttle/liquidjs/blob/master/src/fs/node.ts
[fs-browser]: https://github.com/harttle/liquidjs/blob/master/src/fs/browser.ts
[fs]: /api/interfaces/LiquidOptions.html#fs
[ifs]: /api/interfaces/FS.html
[fs-node]: https://github.com/harttle/liquidjs/blob/master/src/fs/fs-impl.ts
[fs-browser]: https://github.com/harttle/liquidjs/blob/master/src/fs/fs-impl-browser.ts
[layout]: https://help.shopify.com/en/themes/liquid/tags/theme-tags#layout
[include]: https://help.shopify.com/themes/liquid/tags/theme-tags#include
[renderFile]: ../api/classes/liquid_.liquid.html#renderFile
[renderFileSync]: ../api/classes/liquid_.liquid.html#renderFilesync
[parseFile]: ../api/classes/liquid_.liquid.html#parseFile
[parseFileSync]: ../api/classes/liquid_.liquid.html#parseFileSync
[root]: ../api/interfaces/liquid_options_.liquidoptions.html#Optional-root
[renderFile]: /api/classes/Liquid.html#renderFile
[renderFileSync]: /api/classes/Liquid.html#renderFileSync
[parseFile]: /api/classes/Liquid.html#parseFile
[parseFileSync]: /api/classes/Liquid.html#parseFileSync
[root]: /api/interfaces/LiquidOptions.html#root
+1 -1
View File
@@ -133,5 +133,5 @@ The `parse()` is exactly the same as `wrap` tag, we repeat the content simply by
[async]: ./sync-and-async.html
[for]: ../tags/for.html
[if]: ../tags/if.html
[ParseStream]: ../api/classes/parser_parse_stream_.parsestream.html
[ParseStream]: /api/classes/ParseStream.html
[parameter]: ./parse-parameters.html
+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
+67 -41
View File
@@ -24,67 +24,93 @@ The synchronous version of methods contains a `Sync` suffix:
## Implement Sync-Compatible Tags
### Requirements
LiquidJS uses a generator-based async implementation to support both async and sync in one piece of tag implementation. For example, below `UpperTag` can be used in both `engine.renderSync()` and `engine.render()`.
All builtin tags are *sync-compatible* and safe to use for both sync and async APIs. To make your custom tag *sync-compatible*, you'll need to avoid return a `Promise`. That means the `render(context, emitter)`:
```typescript
import { TagToken, Context, Emitter, TopLevelToken, Value, Tag, Liquid } from 'liquidjs'
- Should not directly `return <Promise>`, and
- Should not be declared as `async`.
// Usage: {% upper "alice" %}
// Output: ALICE
engine.registerTag('upper', class UpperTag extends Tag {
private value: Value
constructor (token: TagToken, remainTokens: TopLevelToken[], liquid: Liquid) {
super(token, remainTokens, liquid)
this.value = new Value(token.args, liquid)
}
* render (ctx: Context, emitter: Emitter) {
const title = yield this.value.value(ctx)
emitter.write(title.toUpperCase())
}
})
```
All builtin tags are implemented this way and safe to use in both sync and async (I'll call it *sync-compatible*). To make your custom tag *sync-compatible*, you'll need to:
- declare render function as `* render()`, in which
- do not directly `return <Promise>`, and
- do not call any APIs that returns a Promise.
## Call APIs that return a Promise
But LiquidJS is Promise-friendly, right? You can still call Promise-based functions and wait for that Promise within tag implementations. Just replace `await` with `yield`. e.g. we're calling `fs.readFile()` which returns a `Promise`:
```typescript
* render (ctx: Context, emitter: Emitter) {
const file = yield this.value.value(ctx)
const title = yield fs.readFile(file, 'utf8')
emitter.write(title.toUpperCase())
}
```
Now that this `* render()` calls an API that returns a Promise, so it's no longer *sync-compatible*.
{% note info Non Sync-Compatible Tags %}
Non <em>sync-compatible</em> tags are also valid tags, will work just fine for asynchronous API calls. When called synchronously, tags that return a <code>Promise</code> will be rendered as <code>[object Promise]</code>.
{% endnote %}
### Await Promises
But LiquidJS is Promise-friendly, right? You can still call Promise-based functions and wait for that Promise within tag implementations. Just replace `await` with `yield` and keep `* render()` instead of `async render()`. e.g.
## Convert LiquidJS async Generator to Promise
You can convert a Generator to Promise by [toPromise][toPromise], for example:
```typescript
import { TagToken, Context, Emitter, TopLevelToken } from 'liquidjs'
import { TagToken, Context, Emitter, TopLevelToken, Value, Tag, Liquid, toPromise } from 'liquidjs'
// Usage: {% upper "alice" %}
// Output: ALICE
engine.registerTag('upper', {
parse: function(tagToken: TagToken, remainTokens: TopLevelToken[]) {
this.str = tagToken.args
},
* render: function(ctx: Context) {
// _evalValue will behave synchronously when called by synchronous API
// in which case `ctx.sync == true`
var str = yield this.liquid._evalValue(this.str, ctx)
return str.toUpperCase()
}
engine.registerTag('upper', class UpperTag extends Tag {
private value: Value
constructor (token: TagToken, remainTokens: TopLevelToken[], liquid: Liquid) {
super(token, remainTokens, liquid)
this.value = new Value(token.args, liquid)
}
async render (ctx: Context, emitter: Emitter) {
const title = await toPromise(this.value.value(ctx))
emitter.write(title.toUpperCase())
}
})
```
See this JSFiddle: <http://jsfiddle.net/ctj364up/6/>.
## Async only Tags
## Async-only Tags
For tags that intended to be used only by async API, or those cannot be implemented synchronously, there's no difference between using generator-base syntax or async syntax. I'll call them *async-only tags*.
For example, if the above `this.liquid._evalValue()` doesn't respect `ctx.sync` and always returns a Promise, even if the tag is implemented using `* render()` and `yield this.liquid._evalValue()`, it will be rendered as `<object Promise>` anyway.
For *async-only tags*, you can use async syntax at will. Be careful some APIs in LiquidJS return Promises and others return Generators. You'll need [toPromise][toPromise] API to convert a Generator to a Promise, for example:
If your tag is intend to be used only asynchronously, it can be declared as `async render()` so you can use `await` in its implementation directly:
```typescript
import { TagToken, Context, Emitter, TopLevelToken, toPromise } from 'liquidjs'
import { toPromise, TagToken, Context, Emitter, TopLevelToken, Value, Tag, Liquid } from 'liquidjs'
// Usage: {% upper "alice" %}
// Output: ALICE
engine.registerTag('upper', {
parse: function(tagToken: TagToken, remainTokens: TopLevelToken[]) {
this.str = tagToken.args; // name
},
render: async function(ctx: Context) {
var str = await toPromise(this.liquid._evalValue(this.str, ctx));
// Or use the alternate API that returns a Promise
// var str = await this.liquid.evalValue(this.str, ctx);
return str.toUpperCase()
}
});
engine.registerTag('upper', class UpperTag extends Tag {
private value: Value
constructor (token: TagToken, remainTokens: TopLevelToken[], liquid: Liquid) {
super(token, remainTokens, liquid)
this.value = new Value(token.args, liquid)
}
async render (ctx: Context, emitter: Emitter) {
const title = await toPromise(this.value.value(ctx))
emitter.write(`<h1>${title}</h1>`)
}
})
```
See this JSFiddle: <http://jsfiddle.net/ctj364up/5/>.
[Liquid]: /api/classes/liquid_.liquid.html
[toPromise]: /api/modules/liquid_.html#toPromise
[Liquid]: /api/classes/Liquid.html
[toPromise]: /api/functions/toPromise.html
+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
+2 -2
View File
@@ -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
+1 -1
View File
@@ -10,7 +10,7 @@ LiquidJS 共支持 40+ 个过滤器,可以分为如下几类:
类别 | 过滤器
--- | ---
数学 | plus, minus, modulo, times, floor, ceil, round, divided_by, abs, at_least, at_most
字符串 | append, prepend, capitalize, upcase, downcase, strip, lstrip, rstrip, strip_newlines, split, replace, replace_first, remove, remove_first, truncate, truncatewords
字符串 | append, prepend, capitalize, upcase, downcase, strip, lstrip, rstrip, strip_newlines, split, replace, replace_first, replace_last, remove, remove_first, remove_last, truncate, truncatewords
HTML/URI | escape, escape_once, url_encode, url_decode, strip_html, newline_to_br
数组 | slice, map, sort, sort_natural, uniq, wheres, first, last, join, reverse, concat, compact, size
日期 | date
+1 -1
View File
@@ -4,7 +4,7 @@ title: raw
{% since %}v9.37.0{% endsince %}
直接返回变量的值。配合 [outputEscape](/api/interfaces/liquid_options_.liquidoptions.html#Optional-outputEscape) 参数使用。
直接返回变量的值。配合 [outputEscape](/api/interfaces/LiquidOptions.html#outputEscape) 参数使用。
{% note info 自动转义 %}
默认情况下 `outputEscape``undefined`,这意味着 LiquidJS 输出不会默认转义,因此这时使用 `raw` 没有意义。
+17
View File
@@ -0,0 +1,17 @@
---
title: remove_last
---
{% since %}v10.2.0{% endsince %}
移除字符串中出现的最后一个指定子字符串。
输入
```liquid
{{ "I strained to see the train through the rain" | remove_last: "rain" }}
```
输出
```text
I strained to see the train through the
```
+17
View File
@@ -0,0 +1,17 @@
---
title: replace_last
---
{% since %}v10.2.0{% endsince %}
把字符串中出现的最后一个指定子字符串替换为另一个字符串。
输入
```liquid
{{ "Take my protein pills and put my helmet on" | replace_last: "my", "your" }}
```
输出
```text
Take my protein pills and put your helmet on
```
+1 -1
View File
@@ -47,7 +47,7 @@
},
{
"name": "API",
"url": "/zh-cn/api/classes/liquid_.liquid.html",
"url": "/api/classes/Liquid.html",
"description": "LiquidJS 类和接口的 TypeScript 文档"
}
],
+20
View File
@@ -0,0 +1,20 @@
---
title: Echo
---
{% since %}v9.31.0{% endsince %}
根据表达式输出渲染 HTML。和使用 `{{` expression `}}` 包裹模板效果一样,不同的是 echo 可以在 liquid 标签中使用,同时也支持过滤器。
## echo
输入
```liquid
{% assign username = 'Bob' %}
{% echo username | append: ", welcome to LiquidJS!" | capitalize %}
```
输出
```text
Bob, welcome to LiquidJS!
```
+4 -4
View File
@@ -104,7 +104,7 @@ title: Include
</article>
```
[extname]: ../../api/interfaces/liquid_options_.liquidoptions.html#Optional-extname
[root]: ../../api/interfaces/liquid_options_.liquidoptions.html#Optional-root
[dynamicPartials]: ../../api/interfaces/liquid_options_.liquidoptions.html#Optional-dynamicPartials
[jekyllInclude]: ../../api/interfaces/liquid_options_.liquidoptions.html#Optional-jekyllInclude
[extname]: /api/interfaces/LiquidOptions.html#extname
[root]: /api/interfaces/LiquidOptions.html#root
[dynamicPartials]: /api/interfaces/LiquidOptions.html#dynamicPartials
[jekyllInclude]: /api/interfaces/LiquidOptions.html#jekyllInclude
+2 -2
View File
@@ -62,5 +62,5 @@ Footer
</ul>
{% endnote %}
[extname]: ../../api/interfaces/liquid_options_.liquidoptions.html#Optional-extname
[root]: ../../api/interfaces/liquid_options_.liquidoptions.html#Optional-root
[extname]: /api/interfaces/LiquidOptions.html#extname
[root]: /api/interfaces/LiquidOptions.html#root
+28
View File
@@ -0,0 +1,28 @@
---
title: Liquid
---
{% since %}v9.31.0{% endsince %}
通过 liquid 标签可以在一个分隔符中使用多个标签, 使 Liquid 逻辑书写更简洁。
## liquid
输入
```liquid
{% liquid
assign names = 'Bob, Sally' | split: ', '
for name in names
echo 'Hello, ' | append: name
unless forloop.last
echo ', '
endunless
endfor
%}
```
输出
```text
Hello, Bob, Hello Sally
```
+3 -3
View File
@@ -60,6 +60,6 @@ title: Render
{% note tip forloop 对象 %} 使用 for 参数时,在子模板中可以访问 <a href="./for.html#forloop">forloop</a> 对象。{% endnote %}
[extname]: ../../api/interfaces/liquid_options_.liquidoptions.html#Optional-extname
[root]: ../../api/interfaces/liquid_options_.liquidoptions.html#Optional-root
[globals]: ../../api/interfaces/liquid_options_.liquidoptions.html#Optional-globals
[extname]: /api/interfaces/LiquidOptions.html#extname
[root]: /api/interfaces/LiquidOptions.html#root
[globals]: /api/interfaces/LiquidOptions.html#globals
+6 -5
View File
@@ -47,8 +47,9 @@ engine.renderFileSync('hello', {name: 'alice'})
engine.renderFileSync('hello', {name: 'bob'})
```
[parse]: ../../api/classes/liquid_.liquid.html#parse
[parseFile]: ../../api/classes/liquid_.liquid.html#parseFile
[parseFileSync]: ../../api/classes/liquid_.liquid.html#parseFileSync
[renderFile]: ../../api/classes/liquid_.liquid.html#renderFile
[renderFileSync]: ../../api/classes/liquid_.liquid.html#renderFilesync
[parse]: /api/classes/Liquid.html#parse
[cache]: /api/interfaces/LiquidOptions.html#cache
[parseFile]: /api/classes/Liquid.html#parseFile
[parseFileSync]: /api/classes/Liquid.html#parseFileSync
[renderFile]: /api/classes/Liquid.html#renderFile
[renderFileSync]: /api/classes/Liquid.html#renderFileSync
@@ -8,17 +8,11 @@ Star 是支持 LiquidJS 最重要的方式,也是最简单的方式:通过
## 发起 Pull Request
**代码风格**LiquidJS 采用 [standard](https://github.com/standard/eslint-config-standard) 和 [@typescript-eslint/recommended](https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/eslint-plugin/src/configs/recommended.json) 规则,提交前确保可以通过风格检查:
开发和构建描述在这篇文档里 [CONTRIBUTING.md](https://github.com/harttle/liquidjs/blob/master/CONTRIBUTING.md)。
```bash
npm run lint
```
**代码风格**LiquidJS 采用 [standard](https://github.com/standard/eslint-config-standard) 和 [@typescript-eslint/recommended](https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/eslint-plugin/src/configs/recommended.json) 规则。
**测试**:确保你改动之后测试仍然可以通过
```bash
npm test
```
**测试**:确保你改动之后测试仍然可以通过 `npm test`
**提交消息**:请遵守 [Angular 提交消息规范](https://github.com/angular/angular.js/blob/master/DEVELOPERS.md#commits),尤其注意 [type 标识](https://github.com/angular/angular.js/blob/master/DEVELOPERS.md#type)semantic-release 机器人依赖这个标识自动发布。
@@ -26,7 +20,7 @@ npm test
## 资金支持
LiquidJS 是开源和免费的,但支持 [Open Collective][oc] 或 [Patreon][pt] 赞助,作为感谢你的名字和头像(或 Logo)会展示在这里,[LiquidJS 首页](https://liquidjs.com/)和 [Github README][liquidjs]。
LiquidJS 是开源和免费的,但支持 [Open Collective][oc] 赞助,作为感谢你的名字和头像(或 Logo)会展示在这里,[LiquidJS 首页](https://liquidjs.com/)和 [Github README][liquidjs]。
### 支持者
如果你喜欢 LiquidJS,希望支持我们,你可以成为 Open Collective Backer
@@ -39,7 +33,6 @@ LiquidJS 是开源和免费的,但支持 [Open Collective][oc] 或 [Patreon][p
<object type="image/svg+xml" data="https://opencollective.com/liquidjs/sponsors.svg?avatarHeight=72"></object>
[oc]: https://opencollective.com/liquidjs/
[pt]: https://www.patreon.com/harttle
[shopify/liquid]: https://shopify.github.io/liquid/
[caniuse-promises]: http://caniuse.com/#feat=promises
[pp]: https://github.com/taylorhakes/promise-polyfill
@@ -16,7 +16,7 @@ LiquidJS 语法相对简单。LiquidJS 中有两种标记:
## 输出
**输出** 用于转换和输出变量到 HTMl。下面的模板将会把 `username` 的值插入到 input 的 `value`
**输出** 用于转换和输出变量到 HTML。下面的模板将会把 `username` 的值插入到 input 的 `value`
```liquid
<input type="text" name="user" value="{{username}}">
+4 -3
View File
@@ -12,7 +12,7 @@ const engine = new Liquid({
```
{% note info API 文档 %}
下面的所有选项的概述,希望了解具体的类型和签名,请前往 <a href="https://liquidjs.com/api/interfaces/liquid_options_.liquidoptions.html" target="_self">LiquidOptions | API</a>.
下面的所有选项的概述,希望了解具体的类型和签名,请前往 <a href="https://liquidjs.com/api/interfaces/LiquidOptions.html" target="_self">LiquidOptions | API</a>.
{% endnote %}
## 缓存
@@ -106,6 +106,7 @@ LiquidJS 把这个选项默认值设为 <code>true</code> 以兼容于 shopify/l
**preserveTimezones** 是一个布尔值,只影响时间戳字面量。当设置为 `true` 时,所有字面量的时间戳字符串会在输出时保持原状,即不论输入时采取怎样的时区,输出时仍然采用那一时区(和 Shopify Liquid 的行为一致)。注意这是一个解析器参数,渲染时传入的数据中的日期的输出不会受此参数影响。注意 `preserveTimezones``timezoneOffset` 的优先级更高。
**dateFormat** 用于指定输出日期的默认格式. `%A, %B %-e, %Y at %-l:%M %P %z` 如果未指定,将使用. 例如,设置 `dateFormat: %Y-%m-%dT%H:%M:%S:%LZ` 以输出 [JavaSrcipt Date.toJson()][https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Date/toJSON] 格式.
## 换行和缩进
@@ -135,7 +136,7 @@ LiquidJS 把这个选项默认值设为 <code>true</code> 以兼容于 shopify/l
默认会忽略参数出现的顺序,例如 `{% for i in (1..8) reversed limit:3 %}` 里总是会先执行 `limit` 再执行 `reversed`,虽然 `reversed` 先出现。为了让 LiquidJS 按顺序执行参数,需要设置 **orderedFilterParameters**`true`。它的默认值为 `false`
[liquid]: ../api/classes/liquid_.liquid.html
[liquid]: /api/classes/Liquid.html
[caching]: ./caching.html
[abstract-fs]: ./render-file.html#Abstract-File-System
[render-file]: ./render-file.html
@@ -145,4 +146,4 @@ LiquidJS 把这个选项默认值设为 <code>true</code> 以兼容于 shopify/l
[layout]: ../tags/layout.html
[wc]: ./whitespace-control.html
[intro]: ./intro-to-liquid.html
[jekyllInclude]: ../api/interfaces/liquid_options_.liquidoptions.html#Optional-jekyllInclude
[jekyllInclude]: /api/interfaces/LiquidOptions.html#jekyllInclude
@@ -96,5 +96,5 @@ engine.registerTag('random', {
`{ max: 10 }` 上下文上渲染 `{% random from:2, to:max %}` 将会得到 [2, 10] 范围内的随机数。见这个 JSFiddle<http://jsfiddle.net/ctj364up/4/>。
[register-tags]: /tutorials/register-filters-tags.html
[Tokenizer]: /api/classes/parser_tokenizer_.tokenizer.html
[Hash]: /api/classes/template_tag_hash_.hash.html
[Tokenizer]: /api/classes/Tokenizer.html
[Hash]: /api/classes/Hash.html
+1 -1
View File
@@ -45,5 +45,5 @@ engine.parseAndRender('{{ "foo" | upup }}').then(console.log)
* Sections 标签(开发中): https://github.com/harttle/liquidjs-section-tags
* 颜色过滤器: https://github.com/harttle/liquidjs-color-filters
[liquid]: ../../api/classes/liquid_.liquid.html
[liquid]: /api/classes/Liquid.html
[register]: ./register-filters-tags.html
@@ -8,10 +8,10 @@ title: 注册标签和过滤器
// 使用方式: {% upper name %}
engine.registerTag('upper', {
parse: function(tagToken, remainTokens) {
this.str = tagToken.args; // name
this.value = new Value(token.args, liquid)
},
render: async function(scope, hash) {
var str = await this.liquid.evalValue(this.str, scope); // 'alice'
render: function*(scope, hash) {
const str = yield this.value.value(ctx); // 'alice'
return str.toUpperCase() // 'Alice'
}
});
@@ -20,7 +20,26 @@ engine.registerTag('upper', {
* `parse`: 从 `remainTokens` 中读取后续的标签/输出/HTML,直到找到你期望的结束标签。
* `render`: 把 scope 数据和此前解析得到的 Token 结合,输出 HTML 字符串。
查看已有的标签实现:<https://github.com/harttle/liquidjs/tree/master/src/builtin/tags>
对于更复杂的标签实现,可以提供一个继承自 `Tag` 的类:
```typescript
// Usage: {% upper name:"alice" %}
import { Hash, Tag, TagToken, Context, Emitter, TopLevelToken, Liquid } from 'liquidjs'
engine.registerTag('upper', class UpperTag extends Tag {
private hash: Hash
constructor(tagToken: TagToken, remainTokens: TopLevelToken[], liquid: Liquid) {
super(tagToken, remainTokens, liquid)
this.hash = new Hash(tagToken.args)
}
* render(ctx: Context) {
const hash = yield this.hash.render();
return hash.name.toUpperCase() // 'ALICE'
}
});
```
可以参考已有的标签实现:<https://github.com/harttle/liquidjs/tree/master/src/tags>
## 注册过滤器
@@ -36,7 +55,24 @@ engine.registerFilter('upper', v => v.toUpperCase())
engine.registerFilter('add', (initial, arg1, arg2) => initial + arg1 + arg2)
```
查看已有的过滤器实现:<https://github.com/harttle/liquidjs/tree/master/src/builtin/filters>
查看已有的过滤器实现:<https://github.com/harttle/liquidjs/tree/master/src/filters>。对于复杂的标签,也可以用一个类来实现:
```typescript
// Usage: {% upper name:"alice" %}
import { Hash, Tag, TagToken, Context, Emitter, TopLevelToken, Liquid } from 'liquidjs'
engine.registerTag('upper', class UpperTag extends Tag {
private hash: Hash
constructor(tagToken: TagToken, remainTokens: TopLevelToken[], liquid: Liquid) {
super(tagToken, remainTokens, liquid)
this.hash = new Hash(tagToken.args)
}
* render(ctx: Context) {
const hash = yield this.hash.render();
return hash.name.toUpperCase() // 'ALICE'
}
});
```
## 反注册标签/过滤器
+9 -9
View File
@@ -100,14 +100,14 @@ const engine = new Liquid({
});
```
[fs]: ../../api/interfaces/liquid_options_.liquidoptions.html#Optional-fs
[ifs]: https://github.com/harttle/liquidjs/blob/master/src/fs/ifs.ts
[fs-node]: https://github.com/harttle/liquidjs/blob/master/src/fs/node.ts
[fs-browser]: https://github.com/harttle/liquidjs/blob/master/src/fs/browser.ts
[fs]: /api/interfaces/LiquidOptions.html#fs
[ifs]: /api/interfaces/FS.html
[fs-node]: https://github.com/harttle/liquidjs/blob/master/src/fs/fs-impl.ts
[fs-browser]: https://github.com/harttle/liquidjs/blob/master/src/fs/fs-impl-browser.ts
[layout]: https://help.shopify.com/en/themes/liquid/tags/theme-tags#layout
[include]: https://help.shopify.com/themes/liquid/tags/theme-tags#include
[renderFile]: ../../api/classes/liquid_.liquid.html#renderFile
[renderFileSync]: ../../api/classes/liquid_.liquid.html#renderFilesync
[parseFile]: ../../api/classes/liquid_.liquid.html#parseFile
[parseFileSync]: ../../api/classes/liquid_.liquid.html#parseFileSync
[root]: ../../api/interfaces/liquid_options_.liquidoptions.html#Optional-root
[renderFile]: /api/classes/Liquid.html#renderFile
[renderFileSync]: /api/classes/Liquid.html#renderFileSync
[parseFile]: /api/classes/Liquid.html#parseFile
[parseFileSync]: /api/classes/Liquid.html#parseFileSync
[root]: /api/interfaces/LiquidOptions.html#root
@@ -133,5 +133,5 @@ engine.registerTag('repeat', {
[async]: ./sync-and-async.html
[for]: ../tags/for.html
[if]: ../tags/if.html
[ParseStream]: ../api/classes/parser_parse_stream_.parsestream.html
[ParseStream]: /api/classes/ParseStream.html
[parameter]: ./parse-parameters.html
+67 -44
View File
@@ -24,66 +24,89 @@ LiquidJS 支持同步调用也支持异步调用,支持 Promise。为了同异
## 如何实现兼容同步的标签
### 要求
所有内置标签都兼容同步,可以安全地用于同步或异步 API。为了让你的自定义标签页支持同步,你的标签不能返回 `Promise`,这意味着你的 `render(context, emitter)` 函数:
- 不能直接 `return <Promise>`
- 也不能声明为 `async`
{% note info 不兼容同步的标签 %}
不兼容同步的标签也仍然是合法标签,在异步 API 下也会正常运行。被同步调用时,返回 <code>Promise</code> 的标签会被渲染成 <code>[object Promise]</code>。
{% endnote %}
### 等待 Promise
但 LiquidJS 是支持 `Promise` 的,你仍然可以调用返回 `Promise` 的方法并等它 resolve。只需要把 `await` 换成 `yield` 并保留 `* render()` 不要改成 `async render()`。例如:
LiquidJS 使用基于生成器的异步实现,来让同一份代码支持同步和异步调用。例如下面的 `UpperTag` 既可以用于 `engine.renderSync()` 也可以用于 `engine.render()`
```typescript
import { TagToken, Context, Emitter, TopLevelToken } from 'liquidjs'
import { TagToken, Context, Emitter, TopLevelToken, Value, Tag, Liquid } from 'liquidjs'
// Usage: {% upper "alice" %}
// Output: ALICE
engine.registerTag('upper', {
parse: function(tagToken: TagToken, remainTokens: TopLevelToken[]) {
this.str = tagToken.args
},
* render: function(ctx: Context) {
// 同步调用时 `ctx.sync == true``_evalValue()` 会同步地执行
var str = yield this.liquid._evalValue(this.str, ctx)
return str.toUpperCase()
}
engine.registerTag('upper', class UpperTag extends Tag {
private value: Value
constructor (token: TagToken, remainTokens: TopLevelToken[], liquid: Liquid) {
super(token, remainTokens, liquid)
this.value = new Value(token.args, liquid)
}
* render (ctx: Context, emitter: Emitter) {
const title = yield this.value.value(ctx)
emitter.write(title.toUpperCase())
}
})
```
见这个 JSFiddle<http://jsfiddle.net/ctj364up/6/>。
所有内置标签都兼容同步,可以安全地用于同步或异步 API。实现同时支持同异步的标签,需要:
## 只支持异步的标签
- render 函数声明成 `* render()`,并且在里面
- 不能直接 `return <Promise>`
- 不能调用会返回 Promise 的函数。
对于只用于异步 API 的标签,或者只能实现为异步的标签,使用生成器语法和 async 语法并没有区别。
## 调用返回 Promise 的函数
例如,如果上面的 `this.liquid._evalValue()` 不会检查 `ctx.sync` 而且总是返回一个 `Promise`,那么即使这个标签用 `* render()``yield this.liquid._evalValue()` 实现,最终也会渲染成 `<object Promise>`
这时可以直接使用 async 语法。注意有些 LiquidJS API 会返回 `Promise`,有些会返回生成器。你需要用 [toPromise][toPromise] API 来把生成器转换为 `Promise`,比如:
但 LiquidJS 是支持 `Promise` 的,你仍然可以调用返回 `Promise` 的方法并等它 resolve。只需要把 `await` 换成 `yield`。例如:
```typescript
import { TagToken, Context, Emitter, TopLevelToken, toPromise } from 'liquidjs'
* render (ctx: Context, emitter: Emitter) {
const file = yield this.value.value(ctx)
const title = yield fs.readFile(file, 'utf8')
emitter.write(title.toUpperCase())
}
```
现在 `* render()` 调用了一个返回 Promise 的 API,它就不再兼容同步了。不兼容同步的标签也仍然是合法标签,在异步 API 下也会正常运行。被同步调用时,返回 <code>Promise</code> 的标签会被渲染成 <code>[object Promise]</code>。
## 把 LiquidJS 生成器转换成 Promise
有些 LiquidJS API 会返回 `Promise`,有些会返回生成器。你可以用 [toPromise][toPromise] 来把生成器转换为 `Promise`,比如:
```typescript
import { TagToken, Context, Emitter, TopLevelToken, Value, Tag, Liquid, toPromise } from 'liquidjs'
// Usage: {% upper "alice" %}
// Output: ALICE
engine.registerTag('upper', {
parse: function(tagToken: TagToken, remainTokens: TopLevelToken[]) {
this.str = tagToken.args; // name
},
render: async function(ctx: Context) {
var str = await toPromise(this.liquid._evalValue(this.str, ctx));
// Or use the alternate API that returns a Promise
// var str = await this.liquid.evalValue(this.str, ctx);
return str.toUpperCase()
}
});
engine.registerTag('upper', class UpperTag extends Tag {
private value: Value
constructor (token: TagToken, remainTokens: TopLevelToken[], liquid: Liquid) {
super(token, remainTokens, liquid)
this.value = new Value(token.args, liquid)
}
async render (ctx: Context, emitter: Emitter) {
const title = await toPromise(this.value.value(ctx))
emitter.write(title.toUpperCase())
}
})
```
见这个 JSFiddle<http://jsfiddle.net/ctj364up/5/>。
## 纯异步标签
[Liquid]: /api/classes/liquid_.liquid.html
[toPromise]: /api/modules/liquid_.html#toPromise
如果你的标签就不打算支持同步,可以干脆实现成 `async render()`,这样就可以使用更熟悉的 `await` 了:
```typescript
import { toPromise, TagToken, Context, Emitter, TopLevelToken, Value, Tag, Liquid } from 'liquidjs'
// Usage: {% upper "alice" %}
// Output: ALICE
engine.registerTag('upper', class UpperTag extends Tag {
private value: Value
constructor (token: TagToken, remainTokens: TopLevelToken[], liquid: Liquid) {
super(token, remainTokens, liquid)
this.value = new Value(token.args, liquid)
}
async render (ctx: Context, emitter: Emitter) {
const title = await toPromise(this.value.value(ctx))
emitter.write(`<h1>${title}</h1>`)
}
})
```
[Liquid]: /api/classes/Liquid.html
[toPromise]: /api/functions/toPromise.html
@@ -61,12 +61,12 @@ var engine = new Liquid({
`cache` 还可以是一个数字表示最大缓存的模板数量,也可以是一个自定义的缓存实现,详情请参考 [cache 选项][cache]。
[cache]: ../../api/interfaces/liquid_options_.liquidoptions.html#Optional-cache
[cache]: /api/interfaces/LiquidOptions.html#cache
[express-views]: http://expressjs.com/en/guide/using-template-engines.html
[parseFile]: ../../api/classes/liquid_.liquid.html#parseFile
[parseFileSync]: ../../api/classes/liquid_.liquid.html#parseFileSync
[parseFile]: /api/classes/Liquid.html#parseFile
[parseFileSync]: /api/classes/Liquid.html#parseFileSync
[layout]: https://help.shopify.com/en/themes/liquid/tags/theme-tags#layout
[include]: https://help.shopify.com/themes/liquid/tags/theme-tags#include
[root]: ../../api/interfaces/liquid_options_.liquidoptions.html#Optional-root
[root]: /api/interfaces/LiquidOptions.html#root
[render-a-file]: ./render-a-file.html
[Caching]: ./caching.html

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