- Notifications
You must be signed in to change notification settings - Fork2
Liquid templates for JavaScript
License
jg-rp/liquidscript
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
Liquid templates for JavaScript.
import{Template}from"liquidscript";consttemplate=Template.fromString("Hello, {{ you }}!");// Syncconsole.log(template.renderSync({you:"World"}));// Hello, World!console.log(template.renderSync({you:"Liquid"}));// Hello, Liquid!// Asynctemplate.render({you:"World"}).then(console.log);// Hello, World!template.render({you:"Liquid"}).then(console.log);// Hello, Liquid!// Or, using await(async()=>{console.log(awaittemplate.render({you:"World"}));// Hello, World!console.log(awaittemplate.render({you:"Liquid"}));// Hello, Liquid!})();
- Documentation:https://jg-rp.github.io/liquidscript/
- API documentation:https://jg-rp.github.io/liquidscript/api
- Filter reference:https://jg-rp.github.io/liquidscript/language/filters
- Tag reference:https://jg-rp.github.io/liquidscript/language/tags
- Change log:https://github.com/jg-rp/liquidscript/blob/main/CHANGELOG.md
- NPM:https://www.npmjs.com/package/liquidscript
- Issue tracker:https://github.com/jg-rp/liquidscript/issues
LiquidScript currently depends onDecimal.js for decimal arithmetic, andluxon for timezone aware date/times and some limited parsing of date and time strings.
Both of these dependencies are considered an implementation detail and might be replace with lighter-weight alternatives later.
LiquidScript is written in TypeScript, compiled to JavaScript usingBabel and bundled usingRollup. The following included bundles targetdefaults, not IE 11, maintained node versions, not node 12
. SeeBrowserslist.
Bundle | Description |
---|---|
liquidscript.cjs.js | A CommonJS formatted bundle |
liquidscript.esm.js | An ECMAScript module formatted bundle |
liquidscript.iife.bundle.js | A bundle formatted as an Immediately Invoked Function Expression, including dependencies. |
liquidscript.iife.bundle.min.js | A minified bundle formatted as an Immediately Invoked Function Expression, including dependencies. |
liquidscript.iife.js | A bundle formatted as an Immediately Invoked Function Expression, excluding dependencies. |
liquidscript.iife.min.js | A minified bundle formatted as an Immediately Invoked Function Expression, excluding dependencies. |
Some excellent JavaScript implementations of Liquid already exist. To meet some rather specific requirements, LiquidScript has been developed with the following goals.
Maintain a very strict policy of compatibility with Ruby Liquid and, by extension,Python Liquid. Given an equivalent render context, a template rendered with LiquidScript should produce the same output as when rendered with Ruby Liquid, and vice versa. Seegolden-liquid. Most notably:
- Floats with a single trailing zero must retain that zero upon output.
- Built-in math filters must handle integers and floats appropriately. For example, the
divided_by
filter should perform integer division if both arguments are integers, and regular division otherwise. - Built-in math filters must do decimal arithmetic. SeeDecimal.js dependency.
- Built-in filters must reject excess or otherwise invalid arguments with an error.
It should be possible to extend LiquidScript (without forking) to include features commonly found in other template languages. Like template inheritance, expressions that use logical
not
and inline conditional statements, for example.Expose a syntax tree for every parsed template, facilitating template static analysis and performance optimizations.
Offer fine-grained control of template context globals. Pin globals to an environment, template or loader.
Offer an asynchronous API, including handling of render context promises and asynchronous drops.
Offer HTML and XML auto-escaping, with facilities to mark text as "safe". SeeAuto Escape.
Drops (arbitrary objects added to a render context) must not expose their methods unless explicitly whitelisted. Seedrop protocol.
You can run the benchmark usingyarn benchmark
from the root of the source tree. On my development machine we get the following results.
templates per iteration: 60rounds (best of): 3simulated IO time: 50msparse ...renderSync ...parse & renderSync ...render ...render + parse with IO ... parse:63.15 i/s - 300 in 4.75s renderSync:213.65 i/s - 1000 in 4.68s parse & renderSync:44.36 i/s - 250 in 5.64s render:109.45 i/s - 500 in 4.57srender + parse with IO:14.91 i/s - 50 in 3.35s
The benchmark workload has been carefully matched to that of thereference implementation, although it's not clear what, if any, overhead their benchmark includes.
When the same benchmark is run usingLiquidJS, it shows that, for parsing templates, LiquidJS is faster than LiquidScript, but LiquidScript is faster at rendering templates.
Compared toPython Liquid, which includes a comparable benchmark, LiquidScript is as much as two or three times faster for synchronous operations. Python Liquid's benchmark does not currently include figures for asynchronously rendering templates.
About
Liquid templates for JavaScript