From 72ee7b4c1e78528561ecd2b6b09095ac67242799 Mon Sep 17 00:00:00 2001 From: harttle Date: Thu, 8 Oct 2020 12:53:54 +0800 Subject: [PATCH] feat: support jsTruthy, #255 #257 --- docs/source/tutorials/truthy-and-falsy.md | 19 ++++++++++ docs/source/zh-cn/tutorials/options.md | 6 +++ .../zh-cn/tutorials/truthy-and-falsy.md | 20 +++++++++- src/liquid-options.ts | 2 +- test/integration/liquid/liquid.ts | 2 +- test/unit/render/boolean.ts | 37 +++++++++++-------- 6 files changed, 68 insertions(+), 18 deletions(-) diff --git a/docs/source/tutorials/truthy-and-falsy.md b/docs/source/tutorials/truthy-and-falsy.md index eb1625694f..8ad705d151 100644 --- a/docs/source/tutorials/truthy-and-falsy.md +++ b/docs/source/tutorials/truthy-and-falsy.md @@ -22,6 +22,25 @@ value | truthy | falsy `array` | ✔️ | `empty array` | ✔️ | +## Use JavaScript Truthy + +Note that liquidjs use Shopify's truthiness by default. But it can be toggled to used standard JavaScript truthiness by setting the **jsTruthy** option to `true`. + +value | truthy | falsy +--- | --- | --- +`true` | ✔️ | +`false` | | ✔️ +`null` | | ✔️ +`undefined` | | ✔️ +`string` | ✔️ | +`empty string` | | ✔️ +`0` | | ✔️ +`integer` | ✔️ | +`float` | ✔️ | +`array` | ✔️ | +`empty array` | ✔️ | + + [ruby]: https://shopify.github.io/liquid [sl]: https://www.npmjs.com/package/liquidjs [diff]: https://github.com/harttle/liquidjs#differences-and-limitations \ No newline at end of file diff --git a/docs/source/zh-cn/tutorials/options.md b/docs/source/zh-cn/tutorials/options.md index 18c143913d..50663180da 100644 --- a/docs/source/zh-cn/tutorials/options.md +++ b/docs/source/zh-cn/tutorials/options.md @@ -63,6 +63,12 @@ LiquidJS 把这个选项默认值设为 true 以兼容于 shopify/l **globals** 用来定义对所有模板可见的全局变量。包括 [render tag][render] 引入的子模板,见 [3185][185]。 +## jsTruthy + +**jsTruthy** 用来使用 Javascript 的真值判断,默认为 `false` 使用 Shopify 方式。 + +例如,空字符串在 JavaScript 中为假(`jsTruthy` 为 `true` 时),在 Shopify 真值表中为真。 + ## 换行和缩进 **greedy**, **trimOutputLeft**, **trimOutputRight**, **trimTagLeft**, **trimTagRight** 选项用来移除 Liquid 语法周围的换行和缩进,详情请参考 [Whitespace Control][wc]。 diff --git a/docs/source/zh-cn/tutorials/truthy-and-falsy.md b/docs/source/zh-cn/tutorials/truthy-and-falsy.md index 1571dd7e86..b7571af32f 100644 --- a/docs/source/zh-cn/tutorials/truthy-and-falsy.md +++ b/docs/source/zh-cn/tutorials/truthy-and-falsy.md @@ -8,7 +8,7 @@ title: 真和假 根据 [Shopify 的文档](https://shopify.github.io/liquid/basics/truthy-and-falsy/),Ruby 版本除了 `false` 和 `nil` 之外的所有值都是真,但 JavaScript 有完全不同的类型系统,比如我们有 `undefined` 类型,以及不区分 `integer` 和 `float`,因此有些不同: -value | truthy | falsy +值 | 真 | 假 --- | --- | --- `true` | ✔️ | `false` | | ✔️ @@ -22,6 +22,24 @@ value | truthy | falsy `array` | ✔️ | `empty array` | ✔️ | +## 使用 JavaScript 真值 + +liquidjs 默认使用 Shopify 的真值表,但可以通过设置 **jsTruthy** 选项为 `true` 来使用标准的 JavaScript 真值。 + +值 | 真 | 假 +--- | --- | --- +`true` | ✔️ | +`false` | | ✔️ +`null` | | ✔️ +`undefined` | | ✔️ +`string` | ✔️ | +`empty string` | | ✔️ +`0` | | ✔️ +`integer` | ✔️ | +`float` | ✔️ | +`array` | ✔️ | +`empty array` | ✔️ | + [ruby]: https://shopify.github.io/liquid [sl]: https://www.npmjs.com/package/liquidjs [diff]: https://github.com/harttle/liquidjs#differences-and-limitations \ No newline at end of file diff --git a/src/liquid-options.ts b/src/liquid-options.ts index 735c067c3a..40e59d135a 100644 --- a/src/liquid-options.ts +++ b/src/liquid-options.ts @@ -11,7 +11,7 @@ export interface LiquidOptions { extname?: string; /** Whether or not to cache resolved templates. Defaults to `false`. */ cache?: boolean | number | Cache; - /** Use Javascript Truthiness.Defaults to `false`. */ + /** Use Javascript Truthiness. Defaults to `false`. */ jsTruthy?: boolean; /** If set, treat the `filepath` parameter in `{%include filepath %}` and `{%layout filepath%}` as a variable, otherwise as a literal value. Defaults to `true`. */ dynamicPartials?: boolean; diff --git a/test/integration/liquid/liquid.ts b/test/integration/liquid/liquid.ts index 00a245a170..1a2465e459 100644 --- a/test/integration/liquid/liquid.ts +++ b/test/integration/liquid/liquid.ts @@ -19,7 +19,7 @@ describe('Liquid', function () { it('should call plugin with Liquid', async function () { const engine = new Liquid() engine.plugin(function () { - this.registerFilter('t', isFalsy) + this.registerFilter('t', function (v) { return isFalsy(v, this.context) }) }) const html = await engine.parseAndRender('{{false|t}}') expect(html).to.equal('true') diff --git a/test/unit/render/boolean.ts b/test/unit/render/boolean.ts index 4115a4912b..ab4df22a35 100644 --- a/test/unit/render/boolean.ts +++ b/test/unit/render/boolean.ts @@ -1,38 +1,45 @@ import { isTruthy, isFalsy } from '../../../src/render/boolean' +import { Context } from '../../../src/context/context' import { expect } from 'chai' describe('boolean Shopify', async function () { describe('.isTruthy()', async function () { + const ctx = { + opts: { + jsTruthy: false + } + } as unknown as Context + // // Spec: https://shopify.github.io/liquid/basics/truthy-and-falsy/ it('true is truthy', function () { - expect(isTruthy(true)).to.be.true + expect(isTruthy(true, ctx)).to.be.true }) it('false is falsy', function () { - expect(isTruthy(false)).to.be.false + expect(isTruthy(false, ctx)).to.be.false }) it('null is falsy', function () { - expect(isTruthy(null)).to.be.false + expect(isTruthy(null, ctx)).to.be.false }) it('"foo" is truthy', function () { - expect(isTruthy('foo')).to.be.true + expect(isTruthy('foo', ctx)).to.be.true }) it('"" is truthy', function () { - expect(isTruthy('')).to.be.true + expect(isTruthy('', ctx)).to.be.true }) it('0 is truthy', function () { - expect(isTruthy(0)).to.be.true + expect(isTruthy(0, ctx)).to.be.true }) it('1 is truthy', function () { - expect(isTruthy(1)).to.be.true + expect(isTruthy(1, ctx)).to.be.true }) it('1.1 is truthy', function () { - expect(isTruthy(1.1)).to.be.true + expect(isTruthy(1.1, ctx)).to.be.true }) it('[1] is truthy', function () { - expect(isTruthy([1])).to.be.true + expect(isTruthy([1], ctx)).to.be.true }) it('[] is truthy', function () { - expect(isTruthy([])).to.be.true + expect(isTruthy([], ctx)).to.be.true }) }) }) @@ -42,11 +49,11 @@ describe('boolean jsTruthy', async function () { opts: { jsTruthy: true } - } + } as unknown as Context describe('.isFalsy()', async function () { it('null is always falsy', function () { - expect(isFalsy(null, ctx)).to.be.false + expect(isFalsy(null, ctx)).to.be.true }) }) @@ -58,7 +65,7 @@ describe('boolean jsTruthy', async function () { expect(isTruthy(false, ctx)).to.be.false }) it('null is always falsy', function () { - expect(isTruthy(null, ctx)).to.be.true + expect(isTruthy(null, ctx)).to.be.false }) it('null is always falsy', function () { expect(isTruthy(null, ctx)).to.be.false @@ -81,8 +88,8 @@ describe('boolean jsTruthy', async function () { it('[1] is truthy', function () { expect(isTruthy([1], ctx)).to.be.true }) - it('[] is falsy', function () { - expect(isTruthy([], ctx)).to.be.false + it('[] is truthy', function () { + expect(isTruthy([], ctx)).to.be.true }) }) })