Fix package.json.
LiquidScript has had a complete rewrite for version 2. The result is improved performance, better compatibility with Shopify/liquid, and several breaking API changes.
Other than a few corner cases where we now follow Shopify/liquid more closely, there are no significant changes to template rendering behavior.
Breaking API changes
Template.fromString()andEnvironment.fromString()have been replaced withEnvironment.parse(),Environment.render()and top-level convenience functionsparse()andrender(). See https://jg-rp.github.io/liquidscript/#quick-start.- Resource limits and their environment options have been renamed to better match Shopify/liquid. See https://jg-rp.github.io/liquidscript/environment#resource-limits.
- The "drop" API has changed to give runtime objects better access to the render context and support lazy slicing. See https://jg-rp.github.io/liquidscript/data-types-and-drops#user-defined-types.
- Our token stream interface, template AST and tag interface have changed. See https://jg-rp.github.io/liquidscript/guides/custom-tags. Please open an issue if you need assistance migrating tag implementations.
- The template loader interface has changed. See https://jg-rp.github.io/liquidscript/loaders.
- Removed the non-standard
{% macro %}and{% call %}tags. Please open an issue if you need the{% macro %}tag.
Features
- Instance of
Templatenow have convenience methods for statically inspecting a template's variable, tag a filter usage. See https://jg-rp.github.io/liquidscript/static-analysis. - Added the built-in
squishfilter. - Added diagnostic errors with detailed messages. See https://jg-rp.github.io/liquidscript/api/classes/DetailedLiquidError.
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 betweenelseand%}, 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
splitfilter. Previously, when thesplitfilter'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
mapfilters 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 nestedliquidtags.
Features
- Added the standard
sumfilter, 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
filterandtagproperties 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
macroandcalltags. Define parameterized Liquid snippets with themacrotag and call them using thecalltag.macroandcallare optional extra tags that need to be explicitly registered with aliquidscript.Environment. (docs, source) - New drop-in replacements for the standard output statement (
{{ output }}),assigntag andechotag that support inline conditional expressions, optionally including a logicalnotoperator and grouping terms with parentheses. (docs, source)
Compatibility
- Allow whitespace control from
rawtags. 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"].barwould 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
roundfilter 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/whentag expression parsing.whenexpressions no longer fail when presented with a string containing a comma. Handling of comma andorseparated "sub-expressions" is now consistent with the reference implementation.
Compatibility
fortag arguments can now be separated by commas as well as whitespace. See Shopify/liquid#1658.
Fixes
- The
truncatewordsfilter now trims leading and trailing whitespace from its output. - The built-in
forandtablerowtags now accept string arguments as well as integer literals and variables that resolve to integers.
Fixes
- The
tablerowloopdrop now exposes itsrowproperty, being the current row in the table. - The
truncatewordsfilter no longer throws aFilterArgumentErrorif its word count argument is greater than2147483647. If the word count argument is greater than2147483647, the input string is returned. - The
slicefilter now clamps its arguments to betweenNumber.MIN_SAFE_INTEGERandNumber.MAX_SAFE_INTEGER. A smaller range than the reference implementation, but close enough while avoidingBigIntand 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.childrenmust now include atokenproperty, 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
assigntag where it would incorrectly throw aLiquidSyntaxErrorwhen parts of its expression were split over multiple lines. - Fixed a bug with the
wherefilter. It is now consistent with the reference implementation when givennilorUndefinedas its second argument. - Fixed a bug with the
sortfilter. It now raises aLiquidTypeErrorat render time if the items to be sorted are incompatible. The reference implementation raises an equivalentLiquid::ArgumentErrorin this situation.
Docs
- New example Jekyll-style
includetag.
- New "if not" tag. A drop-in replacement for the standard
iftag that supports logicalnotand grouping with parentheses. - Moved some module-level constants to static class variables for easier subclassing of tags.
- Allow
ObjectChainto containpush,popandsizeproperties. This is potentially a breaking change for early adopters writing custom tags usingcontext.scope.pushandcontext.scope.pop. The symbolschainPushandchainPopwould be needed instead. - Enforce
maxContextDepthwhen extending a render context scope as well as copying aRenderContext. - New
FalsyStrictUndefinedtype.FalsyStrictUndefinedis similar toStrictUndefined, but can be tested for truthiness and compared to other values in anif/unlessexpression 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 aTemplateContextobject as an optional third argument. - Breaking Change: The
childrenmethod of theNodeinterface is now optional. If implemented it should return an array ofChildNodes, whereas before it would have been an array ofNodes. - Breaking Change:
TemplateParser.parseBlock()now accepts an optionaltokenargument. 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
loaderContextobject passed toRenderContext.getTemplateandRenderContext.getTemplateSyncwould not get passed on to template loaders. - Fixed a bug where the abstract
Loaderclass was not passingmatter,upToDateandupToDateSyncon toEnvironment.fromString. - Renamed
TemplateSource.uptoDatetoTemplateSource.upToDateandTemplateSource.uptoDateSynctoTemplateSource.upToDateSync.
- Fixed a bug with
NodeFileSystemLoaderandCachingNodeFileSystemLoaderwhere 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
withtag. Extra tags are not not part of "standard" Liquid and are not registered automatically.
- Parse unix timestamps with the
datefilter. - Renamed
expression.FiltertoExpressionFilter. This avoids conflicts with The filter implementation type.
- Fixed line numbers in error messages involving tag expressions containing newlines.
- Improved
LiquidSyntaxErrormessages.- 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
liquidtag expressions. TheTemplateParserclass now includes aparseLiquid()method that is similar toparseBlock(), but does not needlessly check an empty set for the name of an end tag. - Added
toLiquidSyncto 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 usesXMLHttpRequestto get templates. - Move
src/builtin/loaders/choice.tstosrc/builtin/loaders/choice_loader.ts - Move
src/builtin/loaders/file_system.tstosrc/builtin/loaders/file_system_loader.ts - Change browser tests to use Mocha's "tdd" interface.