diff --git a/README.md b/README.md index e81e14735..a0871454b 100644 --- a/README.md +++ b/README.md @@ -25,6 +25,7 @@ Though being compatible with [Ruby Liquid](https://github.com/shopify/liquid) is * Dynamic file locating (enabled by default), which means layout/partial name can be an variable in liquidjs. See [#51](https://github.com/harttle/liquidjs/issues/51). * Truthy and Falsy. All values except `undefined`, `null`, `false` are truthy, whereas in Ruby Liquid all except `nil` and `false` are truthy. See [#26](https://github.com/harttle/liquidjs/pull/26). * Number Rendering. Since JavaScript do not distinguish `float` and `integer`, we cannot either convert between them nor render regarding to their type. See [#59](https://github.com/harttle/liquidjs/issues/59). +* Along with [.to_liquid()](https://github.com/Shopify/liquid/wiki/Introduction-to-Drops), we provide an alias `.toLiquid()` to align with your code styles. ## TOC diff --git a/src/scope.js b/src/scope.js index 09795f630..1634eae26 100644 --- a/src/scope.js +++ b/src/scope.js @@ -63,7 +63,10 @@ var Scope = { } else { if (typeof obj.to_liquid === 'function') { obj = obj.to_liquid() + } else if (typeof obj.toLiquid === 'function') { + obj = obj.toLiquid() } + if (key === 'size' && (_.isArray(obj) || _.isString(obj))) { val = obj.length } else { diff --git a/src/util/underscore.js b/src/util/underscore.js index 32b0b75fc..f77828b08 100644 --- a/src/util/underscore.js +++ b/src/util/underscore.js @@ -11,8 +11,12 @@ function isString (value) { } function stringify (value) { - if (value && typeof value.to_liquid === 'function') { - return stringify(value.to_liquid()) + if (!isNil(value)) { + if (typeof value.to_liquid === 'function') { + return stringify(value.to_liquid()) + } else if (typeof value.toLiquid === 'function') { + return stringify(value.toLiquid()) + } } if (isString(value)) { return value diff --git a/test/scope.js b/test/scope.js index 7bce0783e..5c0009676 100644 --- a/test/scope.js +++ b/test/scope.js @@ -96,6 +96,14 @@ describe('scope', function () { expect(scope.get('foo.bar')).to.equal('BAR') }) + it('should respect to toLiquid', function () { + let scope = Scope.factory({foo: { + toLiquid: () => ({bar: 'BAR'}), + bar: 'bar' + }}) + expect(scope.get('foo.bar')).to.equal('BAR') + }) + it('should access child property via dot syntax', function () { expect(scope.get('bar.zoo')).to.equal('coo') expect(scope.get('bar.arr')).to.deep.equal(['a', 'b']) diff --git a/test/util/underscore.js b/test/util/underscore.js index 4375ebe5a..8cfa8b897 100644 --- a/test/util/underscore.js +++ b/test/util/underscore.js @@ -34,6 +34,17 @@ describe('util/underscore', function () { expect(_.isString(123)).to.be.false }) }) + describe('.stringify()', function () { + it('should respect to to_liquid() method', function () { + expect(_.stringify({to_liquid: () => 'foo'})).to.equal('foo') + }) + it('should respect to toLiquid() method', function () { + expect(_.stringify({toLiquid: () => 'foo'})).to.equal('foo') + }) + it('should recursively call toLiquid()', function () { + expect(_.stringify({toLiquid: () => ({toLiquid: () => 'foo'})})).to.equal('foo') + }) + }) describe('.forOwn()', function () { it('should iterate all properties', function () { var spy = sinon.spy()