Fixes
- Fixed comparison of strings in logical expressions. Previously we only supported comparing strings for equality with
==
and!=
, now we support<
,>
,<=
and>=
too. - Fixed handling of superfluous expressions in
{% else %}
tags. We now silently ignore anything betweenelse
and%}
, matching the behavior of Shopify/Liquid. - Fixed handling of extra
{% else %}
and{% elsif %}
blocks after the first{% else %}
block. We now silently ignore extraneous blocks, matching the behavior of Shopify/Liquid.
Fixes
- Fixed the
split
filter. Previously, when thesplit
filter's argument string was equal to its input string, we returned an array with empty strings. Now we return an empty array.
Fixes
- Fixed comparison of simple arrays with
{% if %}
,{% unless %}
and{% case %}
tags. Previously, two simple arrays with the same elements would not be considered equal. - Fixed the standard
map
filters handling of nested input arrays. We now automatically flatten nested input arrays and coerce non-iterable inputs to a single element array, just like Ruby Liquid. - Fixed the
{% liquid %}
tag's handling of some corner cases involving nestedliquid
tags.
Features
- Added the standard
sum
filter, which returns the sum of any numeric values in its input array (docs, source). - Added optional
{% extends %}
and{% block %}
tags that add template inheritance features to Liquid templates (docs, source). - Added
filter
andtag
properties to the result ofTemplate.analyze()
, containing the locations of filters and tags found during static analysis (docs).
Features
- Allow customization of local namespace limits by overriding
RenderContext.assignScore
. See #5. - New
macro
andcall
tags. Define parameterized Liquid snippets with themacro
tag and call them using thecall
tag.macro
andcall
are optional extra tags that need to be explicitly registered with aliquidscript.Environment
. (docs, source) - New drop-in replacements for the standard output statement (
{{ output }}
),assign
tag andecho
tag that support inline conditional expressions, optionally including a logicalnot
operator and grouping terms with parentheses. (docs, source)
Compatibility
- Allow whitespace control from
raw
tags. See Shopify/liquid #1683. - Support bracketed variables without a leading identifier. See Shopify/liquid 1680.
Fixes
- Fixed the string representation of variable paths that contain bracketed string elements with a dot. Previously
foo["x.y"].bar
would be represented asfoo.x.y.bar
. Now we retain the quoted property namefoo["x.y"].bar
. It is this string representation that is exposed in the results ofTemplate.analyze()
. See #9. - Fixed
{% cycle %}
tag behavior when given a cycle group name. See Python Liquid/#43. - Fixed the
round
filter when given non-integer arguments. See Shopify/liquid#1590. - Allow string literals to be used as a
{% for %}
tag iterable. See Python Liquid/#102.
Features
- Include comment text in a template's abstract syntax tree. We used to strip comment text out, as a space saving measure, but static analysis of comment text will be required when implementing translation message extraction.
Fixes
- Fixed static template analysis fails with
{% break %}
and{% continue %}
.
Fixes
- Fixed
case
/when
tag expression parsing.when
expressions no longer fail when presented with a string containing a comma. Handling of comma andor
separated "sub-expressions" is now consistent with the reference implementation.
Compatibility
for
tag arguments can now be separated by commas as well as whitespace. See Shopify/liquid#1658.
Fixes
- The
truncatewords
filter now trims leading and trailing whitespace from its output. - The built-in
for
andtablerow
tags now accept string arguments as well as integer literals and variables that resolve to integers.
Fixes
- The
tablerowloop
drop now exposes itsrow
property, being the current row in the table. - The
truncatewords
filter no longer throws aFilterArgumentError
if its word count argument is greater than2147483647
. If the word count argument is greater than2147483647
, the input string is returned. - The
slice
filter now clamps its arguments to betweenNumber.MIN_SAFE_INTEGER
andNumber.MAX_SAFE_INTEGER
. A smaller range than the reference implementation, but close enough while avoidingBigInt
and custom slicing.
Features
- Resource limits. Optionally set limits on memory usage per template render to mitigate the impact of malicious templates. (docs)
Fixes
- Fixed a range expression bug where the length of a range would be incorrectly calculated if both start and stop values were the same.
Breaking Changes
- Objects returned from
ast.Node.children
must now include atoken
property, being the token representing the start of the AST node.
Features
- Template static analysis. Report template variable usage using
Template.analyze()
andTemplate.analyzeSync()
. (docs)
Features
- New general purpose argument list parser. Parse Liquid expressions containing any number of named or keyword arguments, with a choice of key/value separator. See
src/expressions/arguments/parse.ts
. - New inline comment tag
{% # .. %}
. See Shopify Liquid PR #1498.
Fixes
- Fixed a bug with the
assign
tag where it would incorrectly throw aLiquidSyntaxError
when parts of its expression were split over multiple lines. - Fixed a bug with the
where
filter. It is now consistent with the reference implementation when givennil
orUndefined
as its second argument. - Fixed a bug with the
sort
filter. It now raises aLiquidTypeError
at render time if the items to be sorted are incompatible. The reference implementation raises an equivalentLiquid::ArgumentError
in this situation.
Docs
- New example Jekyll-style
include
tag.
- New "if not" tag. A drop-in replacement for the standard
if
tag that supports logicalnot
and grouping with parentheses. - Moved some module-level constants to static class variables for easier subclassing of tags.
- Allow
ObjectChain
to containpush
,pop
andsize
properties. This is potentially a breaking change for early adopters writing custom tags usingcontext.scope.push
andcontext.scope.pop
. The symbolschainPush
andchainPop
would be needed instead. - Enforce
maxContextDepth
when extending a render context scope as well as copying aRenderContext
. - New
FalsyStrictUndefined
type.FalsyStrictUndefined
is similar toStrictUndefined
, but can be tested for truthiness and compared to other values in anif
/unless
expression without throwing an error.
- Breaking Change: Both
Environment.fromString()
andTemplate.fromString()
have been changed to accept a template source string (as before), render context globals as the second argument, and aTemplateContext
object as an optional third argument. - Breaking Change: The
children
method of theNode
interface is now optional. If implemented it should return an array ofChildNode
s, whereas before it would have been an array ofNodes
. - Breaking Change:
TemplateParser.parseBlock()
now accepts an optionaltoken
argument. If given, this token will be assigned to the resulting block. The current token in the stream will be used otherwise. All built-in block tags now pass their initial tag toparseBlock()
instead of the tag for the first node in the block.
- Fixed a bug where the
loaderContext
object passed toRenderContext.getTemplate
andRenderContext.getTemplateSync
would not get passed on to template loaders. - Fixed a bug where the abstract
Loader
class was not passingmatter
,upToDate
andupToDateSync
on toEnvironment.fromString
. - Renamed
TemplateSource.uptoDate
toTemplateSource.upToDate
andTemplateSource.uptoDateSync
toTemplateSource.upToDateSync
.
- Fixed a bug with
NodeFileSystemLoader
andCachingNodeFileSystemLoader
where template authors could escape the template search path.
- Declare DOM types for browser specific loaders.
- Don't remove browser specific loaders in Node builds.
- New
RenderContext.extend()
andRenderContext.extendSync()
helpers for extending the current scope for the duration of a callback function. - New
Environment.addTag()
method for adding custom tags to an environment. - New
makeTokenizer()
functions for reusing built-in expression tokenizers. - New extra
with
tag. Extra tags are not not part of "standard" Liquid and are not registered automatically.
- Parse unix timestamps with the
date
filter. - Renamed
expression.Filter
toExpressionFilter
. This avoids conflicts with The filter implementation type.
- Fixed line numbers in error messages involving tag expressions containing newlines.
- Improved
LiquidSyntaxError
messages.- Error messages now include any offending operators rather than the name of the token that represents the operator.
- The template name and line number of the error is included. Previously this only happened for render-time errors.
- More efficient parsing of
liquid
tag expressions. TheTemplateParser
class now includes aparseLiquid()
method that is similar toparseBlock()
, but does not needlessly check an empty set for the name of an end tag. - Added
toLiquidSync
to the drop protocol.
- New
FetchLoader
. A template loader for web browsers that uses the Fetch API to get templates. - New
XMLHttpRequestLoader
. A template loader for web browsers that usesXMLHttpRequest
to get templates. - Move
src/builtin/loaders/choice.ts
tosrc/builtin/loaders/choice_loader.ts
- Move
src/builtin/loaders/file_system.ts
tosrc/builtin/loaders/file_system_loader.ts
- Change browser tests to use Mocha's "tdd" interface.