mirror of
https://github.com/harttle/liquidjs.git
synced 2026-10-03 00:55:13 -07:00
raw and comment
This commit is contained in:
@@ -89,6 +89,8 @@ Documentation: <https://shopify.github.io/liquid/basics/introduction/#tags>
|
|||||||
- [x] capture [Document](https://shopify.github.io/liquid/tags/variable/) [Source](https://github.com/harttle/shopify-liquid/blob/master/tags/capture.js) [Test][tt]
|
- [x] capture [Document](https://shopify.github.io/liquid/tags/variable/) [Source](https://github.com/harttle/shopify-liquid/blob/master/tags/capture.js) [Test][tt]
|
||||||
- [x] increment [Document](https://shopify.github.io/liquid/tags/variable/) [Source](https://github.com/harttle/shopify-liquid/blob/master/tags/increment.js) [Test][tt]
|
- [x] increment [Document](https://shopify.github.io/liquid/tags/variable/) [Source](https://github.com/harttle/shopify-liquid/blob/master/tags/increment.js) [Test][tt]
|
||||||
- [x] decrement [Document](https://shopify.github.io/liquid/tags/variable/) [Source](https://github.com/harttle/shopify-liquid/blob/master/tags/decrement.js) [Test][tt]
|
- [x] decrement [Document](https://shopify.github.io/liquid/tags/variable/) [Source](https://github.com/harttle/shopify-liquid/blob/master/tags/decrement.js) [Test][tt]
|
||||||
|
- [x] raw [Document](https://help.shopify.com/themes/liquid/tags/theme-tags#raw) [Source](https://github.com/harttle/shopify-liquid/blob/master/tags/raw.js) [Test][tt]
|
||||||
|
- [x] comment [Document](https://help.shopify.com/themes/liquid/tags/theme-tags#comment) [Source](https://github.com/harttle/shopify-liquid/blob/master/tags/comment.js) [Test][tt]
|
||||||
|
|
||||||
|
|
||||||
## Filters
|
## Filters
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "shopify-liquid",
|
"name": "shopify-liquid",
|
||||||
"version": "1.1.1",
|
"version": "1.1.2",
|
||||||
"description": "A Shopify Liquid Implementation in Node.js",
|
"description": "A Shopify Liquid Implementation in Node.js",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ module.exports = function(Tag, Filter) {
|
|||||||
start: function() {
|
start: function() {
|
||||||
this.trigger('start');
|
this.trigger('start');
|
||||||
while (!this.stopRequested && (token = this.tokens.shift())) {
|
while (!this.stopRequested && (token = this.tokens.shift())) {
|
||||||
|
if (this.trigger('token', token)) continue;
|
||||||
if (token.type == 'tag' &&
|
if (token.type == 'tag' &&
|
||||||
this.trigger(`tag:${token.name}`, token)) {
|
this.trigger(`tag:${token.name}`, token)) {
|
||||||
continue;
|
continue;
|
||||||
@@ -37,18 +38,6 @@ module.exports = function(Tag, Filter) {
|
|||||||
stop: function() {
|
stop: function() {
|
||||||
this.stopRequested = true;
|
this.stopRequested = true;
|
||||||
return this;
|
return this;
|
||||||
},
|
|
||||||
onStart: function(cb) {
|
|
||||||
return this.on('start', cb);
|
|
||||||
},
|
|
||||||
onEnd: function(cb) {
|
|
||||||
return this.on('end', cb);
|
|
||||||
},
|
|
||||||
onTag: function(name, cb) {
|
|
||||||
return this.on(`tag:${name}`, cb);
|
|
||||||
},
|
|
||||||
onTemplate: function(cb) {
|
|
||||||
return this.on('template', cb);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ module.exports = function() {
|
|||||||
var reg = register[this.name];
|
var reg = register[this.name];
|
||||||
if(!reg) reg = register[this.name] = {};
|
if(!reg) reg = register[this.name] = {};
|
||||||
var obj = hash(this.token.args, scope);
|
var obj = hash(this.token.args, scope);
|
||||||
return this.tagImpl.render(scope, obj, reg) || '';
|
return this.tagImpl.render && this.tagImpl.render(scope, obj, reg) || '';
|
||||||
},
|
},
|
||||||
parse: function(token, tokens){
|
parse: function(token, tokens){
|
||||||
this.type = 'tag';
|
this.type = 'tag';
|
||||||
@@ -38,9 +38,6 @@ module.exports = function() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
function register(name, tag) {
|
function register(name, tag) {
|
||||||
if (typeof tag.render !== 'function') {
|
|
||||||
throw new Error(`expect ${name}.render to be a function`);
|
|
||||||
}
|
|
||||||
tagImpls[name] = tag;
|
tagImpls[name] = tag;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+3
-3
@@ -13,9 +13,9 @@ module.exports = function(liquid) {
|
|||||||
this.templates = [];
|
this.templates = [];
|
||||||
|
|
||||||
var stream = liquid.parser.parseStream(remainTokens);
|
var stream = liquid.parser.parseStream(remainTokens);
|
||||||
stream.onTag('endcapture', token => stream.stop())
|
stream.on('tag:endcapture', token => stream.stop())
|
||||||
.onTemplate(tpl => this.templates.push(tpl))
|
.on('template', tpl => this.templates.push(tpl))
|
||||||
.onEnd(x => {
|
.on('end', x => {
|
||||||
throw new Error(`tag ${tagToken.raw} not closed`);
|
throw new Error(`tag ${tagToken.raw} not closed`);
|
||||||
});
|
});
|
||||||
stream.start();
|
stream.start();
|
||||||
|
|||||||
+5
-5
@@ -11,7 +11,7 @@ module.exports = function(liquid) {
|
|||||||
|
|
||||||
var p = [],
|
var p = [],
|
||||||
stream = liquid.parser.parseStream(remainTokens)
|
stream = liquid.parser.parseStream(remainTokens)
|
||||||
.onTag('when', token => {
|
.on('tag:when', token => {
|
||||||
if (!this.cases[token.args]) {
|
if (!this.cases[token.args]) {
|
||||||
this.cases.push({
|
this.cases.push({
|
||||||
val: token.args,
|
val: token.args,
|
||||||
@@ -19,10 +19,10 @@ module.exports = function(liquid) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.onTag('else', token => p = this.elseTemplates)
|
.on('tag:else', token => p = this.elseTemplates)
|
||||||
.onTag('endcase', token => stream.stop())
|
.on('tag:endcase', token => stream.stop())
|
||||||
.onTemplate(tpl => p.push(tpl))
|
.on('template', tpl => p.push(tpl))
|
||||||
.onEnd(x => {
|
.on('end', x => {
|
||||||
throw new Error(`tag ${tagToken.raw} not closed`);
|
throw new Error(`tag ${tagToken.raw} not closed`);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,21 @@
|
|||||||
|
var Liquid = require('..');
|
||||||
|
var lexical = Liquid.lexical;
|
||||||
|
var re = new RegExp(`(${lexical.identifier.source})`);
|
||||||
|
|
||||||
|
module.exports = function(liquid) {
|
||||||
|
|
||||||
|
liquid.registerTag('comment', {
|
||||||
|
parse: function(tagToken, remainTokens) {
|
||||||
|
var stream = liquid.parser.parseStream(remainTokens);
|
||||||
|
stream
|
||||||
|
.on('token', token => {
|
||||||
|
if(token.name === 'endcomment') stream.stop();
|
||||||
|
})
|
||||||
|
.on('end', x => {
|
||||||
|
throw new Error(`tag ${tagToken.raw} not closed`);
|
||||||
|
});
|
||||||
|
stream.start();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
};
|
||||||
+5
-5
@@ -19,11 +19,11 @@ module.exports = function(liquid) {
|
|||||||
this.elseTemplates = [];
|
this.elseTemplates = [];
|
||||||
|
|
||||||
var p, stream = liquid.parser.parseStream(remainTokens)
|
var p, stream = liquid.parser.parseStream(remainTokens)
|
||||||
.onStart(x => p = this.templates)
|
.on('start', x => p = this.templates)
|
||||||
.onTag('else', token => p = this.elseTemplates)
|
.on('tag:else', token => p = this.elseTemplates)
|
||||||
.onTag('endfor', token => stream.stop())
|
.on('tag:endfor', token => stream.stop())
|
||||||
.onTemplate(tpl => p.push(tpl))
|
.on('template', tpl => p.push(tpl))
|
||||||
.onEnd(x => {
|
.on('end', x => {
|
||||||
throw new Error(`tag ${tagToken.raw} not closed`);
|
throw new Error(`tag ${tagToken.raw} not closed`);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
+6
-6
@@ -10,11 +10,11 @@ module.exports = function(liquid) {
|
|||||||
this.elseTemplates = [];
|
this.elseTemplates = [];
|
||||||
|
|
||||||
var p, stream = liquid.parser.parseStream(remainTokens)
|
var p, stream = liquid.parser.parseStream(remainTokens)
|
||||||
.onStart(x => this.branches.push({
|
.on('start', x => this.branches.push({
|
||||||
cond: tagToken.args,
|
cond: tagToken.args,
|
||||||
templates: p = []
|
templates: p = []
|
||||||
}))
|
}))
|
||||||
.onTag('elsif', token => {
|
.on('tag:elsif', token => {
|
||||||
if (!this.branches[token.args]) {
|
if (!this.branches[token.args]) {
|
||||||
this.branches.push({
|
this.branches.push({
|
||||||
cond: token.args,
|
cond: token.args,
|
||||||
@@ -22,10 +22,10 @@ module.exports = function(liquid) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.onTag('else', token => p = this.elseTemplates)
|
.on('tag:else', token => p = this.elseTemplates)
|
||||||
.onTag('endif', token => stream.stop())
|
.on('tag:endif', token => stream.stop())
|
||||||
.onTemplate(tpl => p.push(tpl))
|
.on('template', tpl => p.push(tpl))
|
||||||
.onEnd(x => {
|
.on('end', x => {
|
||||||
throw new Error(`tag ${tagToken.raw} not closed`);
|
throw new Error(`tag ${tagToken.raw} not closed`);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
+27
@@ -0,0 +1,27 @@
|
|||||||
|
var Liquid = require('..');
|
||||||
|
var lexical = Liquid.lexical;
|
||||||
|
var re = new RegExp(`(${lexical.identifier.source})`);
|
||||||
|
|
||||||
|
module.exports = function(liquid) {
|
||||||
|
|
||||||
|
liquid.registerTag('raw', {
|
||||||
|
parse: function(tagToken, remainTokens) {
|
||||||
|
this.tokens = [];
|
||||||
|
|
||||||
|
var stream = liquid.parser.parseStream(remainTokens);
|
||||||
|
stream
|
||||||
|
.on('token', token => {
|
||||||
|
if(token.name === 'endraw') stream.stop();
|
||||||
|
else this.tokens.push(token);
|
||||||
|
})
|
||||||
|
.on('end', x => {
|
||||||
|
throw new Error(`tag ${tagToken.raw} not closed`);
|
||||||
|
});
|
||||||
|
stream.start();
|
||||||
|
},
|
||||||
|
render: function(scope, hash) {
|
||||||
|
return this.tokens.map(token => token.raw).join('');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
};
|
||||||
+4
-4
@@ -16,10 +16,10 @@ module.exports = function(liquid) {
|
|||||||
this.templates = [];
|
this.templates = [];
|
||||||
|
|
||||||
var p, stream = liquid.parser.parseStream(remainTokens)
|
var p, stream = liquid.parser.parseStream(remainTokens)
|
||||||
.onStart(x => p = this.templates)
|
.on('start', x => p = this.templates)
|
||||||
.onTag('endtablerow', token => stream.stop())
|
.on('tag:endtablerow', token => stream.stop())
|
||||||
.onTemplate(tpl => p.push(tpl))
|
.on('template', tpl => p.push(tpl))
|
||||||
.onEnd(x => {
|
.on('end', x => {
|
||||||
throw new Error(`tag ${tagToken.raw} not closed`);
|
throw new Error(`tag ${tagToken.raw} not closed`);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
+5
-5
@@ -5,14 +5,14 @@ module.exports = function(liquid) {
|
|||||||
liquid.registerTag('unless', {
|
liquid.registerTag('unless', {
|
||||||
parse: function(tagToken, remainTokens) {
|
parse: function(tagToken, remainTokens) {
|
||||||
var p, stream = liquid.parser.parseStream(remainTokens)
|
var p, stream = liquid.parser.parseStream(remainTokens)
|
||||||
.onStart(x => {
|
.on('start', x => {
|
||||||
p = this.templates = [];
|
p = this.templates = [];
|
||||||
this.cond = tagToken.args;
|
this.cond = tagToken.args;
|
||||||
})
|
})
|
||||||
.onTag('else', token => this.elseTemplates = p = [])
|
.on('tag:else', token => this.elseTemplates = p = [])
|
||||||
.onTag('endunless', token => stream.stop())
|
.on('tag:endunless', token => stream.stop())
|
||||||
.onTemplate(tpl => p.push(tpl))
|
.on('template', tpl => p.push(tpl))
|
||||||
.onEnd(x => {
|
.on('end', x => {
|
||||||
throw new Error(`tag ${tagToken.raw} not closed`);
|
throw new Error(`tag ${tagToken.raw} not closed`);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -27,12 +27,6 @@ describe('tag', function() {
|
|||||||
}).to.throw(/tag foo not found/);
|
}).to.throw(/tag foo not found/);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should throw when render method not defined', function() {
|
|
||||||
expect(function() {
|
|
||||||
tag.register('foo', {});
|
|
||||||
}).to.throw(/expect foo.render to be a function/);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should register simple tag', function() {
|
it('should register simple tag', function() {
|
||||||
expect(
|
expect(
|
||||||
function() {
|
function() {
|
||||||
|
|||||||
@@ -34,6 +34,18 @@ describe('tags', function() {
|
|||||||
test('{% assign foo="a b" | capitalize | split: " " | first %}{{foo}}', 'A');
|
test('{% assign foo="a b" | capitalize | split: " " | first %}{{foo}}', 'A');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should support raw', function() {
|
||||||
|
testThrow('{% raw%}', /{% raw%} not closed/);
|
||||||
|
test('{% raw %}{{ 5 | plus: 6 }}{% endraw %} is equal to 11.', '{{ 5 | plus: 6 }} is equal to 11.');
|
||||||
|
test('{% raw %}\n{{ foo}} \n{% endraw %}', '\n{{ foo}} \n');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should support comment', function() {
|
||||||
|
testThrow('{% comment %}{% raw%}', /{% comment %} not closed/);
|
||||||
|
test('My name is {% comment %}super{% endcomment %} Shopify.', 'My name is Shopify.');
|
||||||
|
test('{% comment %}\n{{ foo}} \n{% endcomment %}', '');
|
||||||
|
});
|
||||||
|
|
||||||
it('should support case', function() {
|
it('should support case', function() {
|
||||||
testThrow('{% case "foo"%}', /{% case "foo"%} not closed/);
|
testThrow('{% case "foo"%}', /{% case "foo"%} not closed/);
|
||||||
test('{% case "foo"%}' +
|
test('{% case "foo"%}' +
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
var chai = require("chai");
|
var chai = require("chai");
|
||||||
var should = chai.should();
|
var should = chai.should();
|
||||||
|
var expect = chai.expect;
|
||||||
|
|
||||||
var tokenizer = require('../tokenizer.js');
|
var tokenizer = require('../tokenizer.js');
|
||||||
|
|
||||||
@@ -39,4 +40,13 @@ describe('tokenizer', function() {
|
|||||||
tokens[1].value.should.equal('bar');
|
tokens[1].value.should.equal('bar');
|
||||||
tokens[2].value.should.equal('foo');
|
tokens[2].value.should.equal('foo');
|
||||||
});
|
});
|
||||||
|
it('should keep white spaces and newlines', function(){
|
||||||
|
var html = '{{foo}}\n{%bar %} \n {{alice}}';
|
||||||
|
var tokens = tokenizer.parse(html);
|
||||||
|
expect(tokens.length).to.equal(5);
|
||||||
|
expect(tokens[1].type).to.equal('html');
|
||||||
|
expect(tokens[1].raw).to.equal('\n');
|
||||||
|
expect(tokens[3].type).to.equal('html');
|
||||||
|
expect(tokens[3].raw).to.equal(' \n ');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ function parse(html) {
|
|||||||
htmlFragment = html.slice(idx, result.index);
|
htmlFragment = html.slice(idx, result.index);
|
||||||
tokens.push({
|
tokens.push({
|
||||||
type: 'html',
|
type: 'html',
|
||||||
|
raw: htmlFragment,
|
||||||
value: htmlFragment
|
value: htmlFragment
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -47,6 +48,7 @@ function parse(html) {
|
|||||||
htmlFragment = html.slice(idx, html.length);
|
htmlFragment = html.slice(idx, html.length);
|
||||||
tokens.push({
|
tokens.push({
|
||||||
type: 'html',
|
type: 'html',
|
||||||
|
raw: htmlFragment,
|
||||||
value: htmlFragment
|
value: htmlFragment
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user