Commit Graph
48 Commits
Author SHA1 Message Date
afa5f54004 feat: Add support of inner expressions enclosed by parentheses (#863)
* Add support of inner expressions enclosed by parentheses

* Add support of inner expressions enclosed by parentheses

Made-with: Cursor

* simplify implementation

* fix lint

* fix test

* Enhance tests for parenthesized filter chains in Liquid tags. Added scenarios for enabled and disabled grouped expressions in case, for, if, unless tags, ensuring proper handling of expressions and error throwing for invalid syntax.

* test: remove duplicate readGroupedExpression test block

The readGroupedExpression() test suite was duplicated twice in the spec file. Removed the duplicate block to avoid redundant test execution.

* refactor: extract extractGroupedExpressionTokenVariables helper

Extract inline grouped expression variable extraction logic into a dedicated
function for consistency with other extractors (extractFilteredValueVariables,
extractPropertyAccessVariable).

This addresses PR #863 comment 7 - improves code organization and
maintainability.

* refactor(types): explicit type for collection in for tag

collection: ValueToken | GroupedExpressionToken

Addresses PR #863 comment 5.

* refactor: evaluate grouped expressions at render time with resolvedFilters

Addresses PR review comments 4, 6, 8, 9 - moves grouped expression evaluation
from parse-time resolution to render-time lazy evaluation following the
generator-based async/sync duality pattern used throughout liquidjs.

Key changes:
- Replace resolvedValue (Value instance) with resolvedFilters (Filter[])
- Rename resolveGroupedExpressions() to resolveGroupedExpressionFilters()
- Move evaluation logic to evalGroupedExpressionToken() at render time
- Build Filter instances at parse time (carry liquid reference for render)
- Evaluate expression and apply filters lazily via generators
- Add support for tablerow tag with grouped expressions
- Remove duplicate getFilter() method in Value class

Maintains proper layering (tokens → render → templates) and consistency
with Value.value() pattern. Filter resolution still happens at parse time
since it requires liquid.filters access, but actual evaluation is deferred
to render time.

Tags that store raw ValueToken (for, case when-values, tablerow) still need
explicit resolveGroupedExpressionFilters() calls. Tags that wrap with
new Value() get automatic recursive resolution via Value constructor.

* refactor: reuse FilteredValueToken and fix architectural layering

Replace GroupedExpressionToken with existing FilteredValueToken to avoid
code duplication and fix layering violation where tokens depended on
templates (Filter instances).

Key changes:
- Reuse FilteredValueToken instead of GroupedExpressionToken
- Simplify readGroupOrRange() to return FilteredValueToken | RangeToken
- Add liquid reference to Context for runtime filter resolution
- Build Filter instances at render time in evalFilteredValueToken()
- Remove resolveGroupedExpressionFilters() and parse-time resolution
- Remove explicit resolution calls from tag constructors

This maintains proper architectural layering (tokens → render → templates)
with no backward dependencies, as requested in PR review feedback.

All 1537 tests pass.

* revert redundant'

* refactor: make getFilter private and improve code organization

* test: fix test name in case.spec.ts for when disabled block

* refactor: no need for Deprecated flag

* test: fix test name and logic to properly test if tag with nested expressions

* feat: support real parenthesis grouping in grouped expressions

Allow arbitrary expressions inside parentheses (e.g. ((a | upcase) > 3)
and (1 < 3)) when groupedExpressions is enabled, reusing readFilteredValue
for the general case while keeping range and filter-chain fast paths.

* feat: enhance expression tokenization with new generator methods

Added `readExpressionTokensFromHere` and `readGroupedExpressionTokens` methods to improve the handling of expression tokens. This refactor simplifies the token reading process and maintains compatibility with existing grouped expressions, ensuring proper evaluation and filtering.

* add tests

* address comments

---------

Co-authored-by: Omri Rosner <[email protected]>
2026-08-01 18:15:54 +08:00
499b221f33 docs: remove translations & update homepage (#904)
* docs: add GitHub buttons and improve option docs

* chore: replace husky with prepush check

* docs: revamp homepage and switch to custom GitHub buttons

- Make the docs English-only by removing all zh-cn content, the language switcher UI, and related JS/config

- Rework homepage feature cards (Safe & Typed, Pure JavaScript, Shopify & Jekyll, Streaming) and refresh section colors/layout

- Replace buttons.github.io with custom Star/Sponsor buttons featuring a live star count and dark-mode support

- Drop the buttons.js script and tidy banner, header, footer, and share partials

Co-authored-by: Cursor <[email protected]>

* fix: restore tsconfig settings and changelog build

Re-add suppressImplicitAnyIndexErrors and downlevelIteration removed in
a75033e2c, which broke the rollup TypeScript build on CI. Drop zh-cn
changelog output now that translations were removed.

Co-authored-by: Cursor <[email protected]>

* fix: resolve TS errors without deprecated tsconfig options

Co-authored-by: Cursor <[email protected]>

---------

Co-authored-by: Cursor <[email protected]>
2026-06-07 01:37:51 +08:00
Loo Rong JieandGitHub 955b7971c0 Support having new line and other whitespace after include filename (#834) 2025-11-11 13:58:12 +08:00
HarttleandJun Yang a490a70da1 fix: consistent range syntax parsing, #791 2025-01-19 17:58:00 +08:00
Yang Jun d705888c8d feat: expose FilterToken to filter this, #762 2024-10-16 22:07:25 +08:00
Yang JunandJun Yang 6aeed2586a feat: support custom key-value separator, #752 2024-09-22 21:55:44 +08:00
Jun YangandGitHub e4aeb023fd feat: locale support for date filter, #567 (#723) 2024-07-22 00:39:44 +08:00
Jun Yang 2b713b721d feat: group_by/group_by_exp/find/find_exp from Jekyll, #443 2024-04-14 19:34:07 +08:00
Harttle dd7616acb9 fix: allow unicode to be identifiers, fixes #655 2023-11-04 21:33:29 +08:00
Jun YangandGitHub 660d9be55f feat: more flexible squared property read expression, fixes #643 (#646)
* fix: more flexible squared property read expression, fixes #643

* fix: unecessary error wrapping in browser bundles

* style: update code style and types

* perf: use token.value when evalToken
2023-08-23 00:45:49 +08:00
Jun YangandGitHub bf425c3adb fix: allow quotes in inline comment tag, fixes #628 2023-07-07 22:48:55 +08: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
HarttleandJun Yang c6cde9cd10 chore: migrate test cases from Chai to Jest 2023-03-20 00:41:06 +08:00
HarttleandHarttle 3f21382d43 feat: support not operator, #575 2023-01-03 01:34:03 +08:00
Jun Yang 92992689cd refactor: Tag class support in registerTag() 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
HarttleandHarttle e874b4060b feat: export toValueSync & defaultOptions to evaluate expression, see #527 2022-08-15 01:53:48 +08:00
jg-rpandGitHub 2f87708989 feat: inline comment tag (#514)
* style: remove unnecessary intermediate constant

* feat: add inline comment tag

* refactor: use readIdentifier when reading tag names

* docs: add inline comment tag
2022-07-08 01:46:15 +08:00
Harttle 01014edc49 feat: appropriate error for malformed filters, fixes #271 2022-03-05 23:24:16 +08:00
HarttleandHarttle 388d0fbbc4 feat: support Jekyll-like include syntax, see #441 2022-01-19 23:07:25 +08:00
Ameya ApteandJun Yang 7677f848c0 fix: remove limit on operator char length
The matchOperator function has a default value of str.length for the end parameter
2022-01-12 21:24:08 +08:00
James PriorandJun Yang fde9924ee6 feat: implement liquid and echo tags, see #428 2021-12-19 21:09:26 +08:00
HarttleandHarttle 23279a816a feat: support jekyll-like include, see #433 2021-12-18 15:26:15 +08:00
harttle 8273c17dab perf: parse filenames in parse() insteadof render() 2021-09-30 22:15:09 +08:00
harttle 2f059f6a25 feat: support filters in if/unless/case, see #287 2021-02-12 22:22:41 +08:00
Jason EtcovitchandJun Yang befc33c4eb feat: create trie programmatically in options 2021-02-04 09:11:28 +08:00
harttle 9c40da7369 fix: allow string literals contain delimiters, fixes #288 2021-01-24 12:49:19 +08:00
harttle a492d8e23d fix: raw block not ignoring {% characters, fixes #263 2020-12-08 00:12:20 +08:00
wyoziandJun Yang e67c3c6924 Make end brace peek stricter and fix the test 2020-10-09 21:18:40 +08:00
wyoziandJun Yang 18a807ea2e fix: braced property access 2020-10-09 21:18:40 +08:00
harttle 8daf281fca fix: throw an error if : omitted unintentionally, #212, #208 2020-03-31 14:05:38 +08:00
harttle d2d6a38235 perf: introduce AST to avoid reparse 2020-03-15 02:51:25 +08:00
harttle f7ef9b61c1 refactor: remove src/render/value.ts 2020-03-14 19:04:18 +08:00
harttle 3dfdf982c9 perf: remove transient strings to reduce memory 2020-03-14 19:04:18 +08:00
harttle 6ea6881f08 feat: with & for in render tag, closes #195 2020-03-04 07:08:54 +08:00
Patrick MalouinandJun Yang 3ad512c51c perf: add string flattening to reduce retained memory (node only)
add a memory footprint benchmark
2019-10-10 09:35:15 +08:00
harttle ae45c4622e fix: break/continue omitting output before them, #123
BREAKING CHANGE: remove default export, now should be used like import
{Liquid} from 'liquidjs'
2019-08-26 10:15:43 -05:00
harttle 88c89fe3b3 style: introduce @typescript-eslint/recommended 2019-07-06 14:33:34 +08:00
harttle 82d7673554 perf: use polymophism instead duck test 2019-03-25 20:11:23 +08:00
harttle 7bee9fc92d feat: exported Drop interface for #107
Deprecate snake_cased options and APIs, sed #109
2019-02-28 00:05:08 +08:00
harttle 53a835ab54 fix(#108): remove absolute path in emitted d.ts 2019-02-26 00:43:30 +08:00
harttle 5b6100d12b refactor: strictly typed 2019-02-23 00:49:54 +08:00
harttle d20a043fbb feat: override output/tag delimiter, fixes #54 2019-02-21 01:07:32 +08:00
harttle 3dbab238ae BREAKING CHANGE: trim_value_* -> trim_output_* 2019-02-21 01:07:32 +08:00
harttle c33d8f6828 feat: throw an Error if delimiter not matched 2019-02-20 22:40:09 +08:00
harttle fc9ebdb90f chore(TypeScript): fix linting and generate .d.ts 2019-02-17 18:20:04 +08:00
harttle 677e8511e6 chore(TypeScript): refactor objects into classes
fix: `Nil`(null, undefined) now renders as empty string
change: `parser.parseValue()` renamed to `parser.parseOutput`
change: registered tags/filters become static and shared across different liquid instances
2019-02-17 04:55:30 +08:00