14 KiB
shopify-liquid
Liquid implementation for Node.js. All tags and filters listed in Shopify Documentation shall be implemented.
Shopify liquid is used by Jekyll and Github Pages.
Installation:
npm install --save shopify-liquid
Render from String
Parse and Render:
var Liquid = require('shopify-liquid');
var engine = Liquid();
engine.parseAndRender('{{name | capitalize}}', {name: 'alice'}); // Alice
Caching templates:
var tpl = engine.parse('{{name | capitalize}}');
engine.render(tpl, {name: 'alice'}); // Alice
Render from File
var engine = Liquid({
root: path.resolve(__dirname, 'views/'), // for layouts and partials
extname: '.liquid',
cache: false
});
// equivalent to: engine.renderFile("hello", {name: 'alice'});
var html = engine.renderFile("hello.html", {name: 'alice'});
cache default to false, extname default to .liquid, root default to "".
Use with Express.js
app.engine('liquid', engine.express());
app.set('views', './views'); // specify the views directory
app.set('view engine', 'liquid'); // register the template engine
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.html
Header
{% block content %}My default content{% endblock %}
Footer
// file: page.html
{% layout "default-layout" %}
{% block content %}My page content{% endblock %}
The output of page.html:
Header
My page content
Footer
- It's possible to define multiple blocks.
- block name is optional when there's only one block.
Extension
Register Filters:
// Usage: {{ name | uppper }}
engine.registerFilter('upper', function(v){
return v.toUpperCase();
});
See existing filter implementations: https://github.com/harttle/shopify-liquid/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 str.toUpperCase(); // 'Alice'
}
});
See existing tag implementations: https://github.com/harttle/shopify-liquid/blob/master/tags/
Operators
Documentation: https://shopify.github.io/liquid/basics/operators/
==, !=, >, <, >=, <=, or, and, contains.
Tags
Documentation: https://shopify.github.io/liquid/basics/introduction/#tags
| Tag | Document | Source | Test |
|---|---|---|---|
case/when |
Document | Source | Test |
if |
Document | Source | Test |
unless |
Document | Source | Test |
elsif/else |
Document | Source | Test |
for |
Document | Source | Test |
break |
Document | Source | Test |
continue |
Document | Source | Test |
for: limit,offset,range,reversed |
Document | Source | Test |
cycle |
Document | Source | Test |
cycle: group |
Document | Source | Test |
tablerow |
Document | Source | Test |
tablerow: cols,limit,offset,range |
Document | Source | Test |
assign |
Document | Source | Test |
capture |
Document | Source | Test |
increment |
Document | Source | Test |
decrement |
Document | Source | Test |
raw |
Document | Source | Test |
comment |
Document | Source | Test |
include |
Document | Source | Test |
layout, block |
Document | Source | Test |
Filters
Documentation: https://shopify.github.io/liquid/basics/introduction/#filters
Async Support
harttle/shopify-liquid do NOT support async rendering, this is by design.
The primary principle of harttle/shopify-liquid is EASY TO EXTEND. Async rendering introduces extra complexity in both implementation and extension.
For template-driven projects, checkout these Liquid-like engines:
- liquid-node: https://github.com/sirlantis/liquid-node
- nunjucks: http://mozilla.github.io/nunjucks/
