liquidts
v0.1.4
Published
A Liquid template engine for modern Node.js, with all shopify/liquid features.
Downloads
638
Maintainers
Readme
liquidts
This originated as a typescriptification of harttle/liquidjs, itself based on liquid-node and huge thanks are offered breaking the back of implementing liquid in javascript. As I started work, it was obvious that it wasn't going to remain analogous with the original project, and hence making this a hard fork
The original work, of course, comes from shopify/liquid - and thanks to them for such a great platform to work from.
Installation:
npm install --save liquidts
Concerns
- [ ] Performance with large numbers of blocks needs to be investigated, especially in loop situations
Filesystems
By default, liquidts
won't attempt to load any files for Engine#renderFile
or {% include %}
tags. If you want to use
file loading, then you can either use the provided file-system based engine, or implement your own.
Rendering
Performance with strings in Node is atrocious, so we try and avoid manipulating them wherever possible. There is a naive
implementation of a "write buffer" in this library that concatenates all writes into an array and then joins it when the
consumer reads it. This is a lot faster than working on a "state" string, but still could be better. The options object
that .render
accepts as its third argument allows you to pass a writer: Writeable
in to allow you to implement this
yourself.
Render from String
Parse and Render:
const Liquid = require('liquidts');
const engine = Liquid();
engine.parseAndRender('{{name | capitalize}}', {name: 'alice'})
.then(output => {
// output.read() === 'Alice'
});
Caching templates:
const tpl = engine.parse('{{name | capitalize}}');
engine.render(tpl, {name: 'alice'})
.then(output => {
// output.read() === 'Alice'
});
Options
The full list of options for Liquid()
is listed as following:
fileSystem
needs to be an object implementingFileSystem
if you wish to render files rather than ad-hoc strings, or to useinclude
tagsregisters
are a globally availableMap
of settings and the like that can be consumed by tags but not templatesstrictFilters
is used to enable strict filter existence. If set tofalse
, undefined filters will be rendered as empty string. Otherwise, undefined filters will cause an exception. Defaults tofalse
.strictVariables
is used to enable strict variable derivation. If set tofalse
, undefined variables will be rendered as empty string. Otherwise, undefined variables will cause an exception. Defaults tofalse
.trimRight
is used to strip blank characters (including\t
, and\r
) from the right of tags ({% %}
) until\n
(inclusive). Defaults tofalse
.trimLeft
is similiar totrimRight
, whereas the\n
is exclusive. Defaults tofalse
.greedy
is used to specify whethertrimLeft
/trimRight
is greedy. When set totrue
, all successive blank characters including\n
will be trimed regardless of line breaks. Defaults tofalse
.
Includes
// file: color.liquid
color: '{{ color }}' shape: '{{ shape }}'
// file: theme.liquid
{% assign shape = 'circle' %}
{% include 'color' %}
{% include 'color' with 'red' %}
{% include 'color', color: 'yellow', shape: 'square' %}
The output will be:
color: '' shape: 'circle'
color: 'red' shape: 'circle'
color: 'yellow' shape: 'square'
Layouts
// file: default-layout.liquid
Header
{% block content %}My default content{% endblock %}
Footer
// file: page.liquid
{% layout "default-layout" %}
{% block content %}My page content{% endblock %}
The output of page.liquid
:
Header
My page content
Footer
- It's possible to define multiple blocks.
- block name is optional when there's only one block.
Register Filters
// Usage: {{ name | uppper }}
engine.registerFilter('upper', function(v){
return v.toUpperCase();
});
See existing filter implementations: https://github.com/musicglue/liquidts/blob/master/filters.js
Register Tags
// Usage: {% upper name%}
engine.registerTag('upper', {
parse: function(tagToken, remainTokens) {
this.str = tagToken.args; // name
},
render: function(scope, hash) {
var str = Liquid.evalValue(this.str, scope); // 'alice'
return Promise.resolve(str.toUpperCase()); // 'Alice'
}
});
See existing tag implementations: https://github.com/musicglue/liquidts/blob/master/tags/
Contribution Guide
- Write a test to define the feature you want.
- File an issue, or optionally:
- Get your test pass and make a pull request.