feat: support Jekyll style where, #768

This commit is contained in:
Harttle
2024-11-17 21:33:38 +08:00
committed by Jun Yang
parent 11f013bf24
commit 9107eb1b93
9 changed files with 95 additions and 4 deletions
+3
View File
@@ -8,4 +8,7 @@ export class BlankDrop extends EmptyDrop {
if (isString(value)) return /^\s*$/.test(value)
return super.equals(value)
}
static is (value: unknown) {
return value instanceof BlankDrop
}
}
+3
View File
@@ -25,4 +25,7 @@ export class EmptyDrop extends Drop implements Comparable {
public valueOf () {
return ''
}
static is (value: unknown) {
return value instanceof EmptyDrop
}
}
+6 -2
View File
@@ -1,8 +1,9 @@
import { toArray, argumentsToValue, toValue, stringify, caseInsensitiveCompare, isArray, isNil, last as arrayLast } from '../util'
import { equals, evalToken, isTruthy } from '../render'
import { arrayIncludes, equals, evalToken, isTruthy } from '../render'
import { Value, FilterImpl } from '../template'
import { Tokenizer } from '../parser'
import type { Scope } from '../context'
import { EmptyDrop } from '../drop'
export const join = argumentsToValue(function (this: FilterImpl, v: any[], arg: string) {
const array = toArray(v)
@@ -124,9 +125,12 @@ export function * where<T extends object> (this: FilterImpl, arr: T[], property:
for (const item of arr) {
values.push(yield evalToken(token, this.context.spawn(item)))
}
const matcher = this.context.opts.jekyllWhere
? (v: any) => EmptyDrop.is(expected) ? equals(v, expected) : (isArray(v) ? arrayIncludes(v, expected) : equals(v, expected))
: (v: any) => equals(v, expected)
return arr.filter((_, i) => {
if (expected === undefined) return isTruthy(values[i], this.context)
return equals(values[i], expected)
return matcher(values[i])
})
}
+2
View File
@@ -22,6 +22,8 @@ export interface LiquidOptions {
relativeReference?: boolean;
/** Use jekyll style include, pass parameters to `include` variable of current scope. Defaults to `false`. */
jekyllInclude?: boolean;
/** Use jekyll style where filter, enables array item match. Defaults to `false`. */
jekyllWhere?: boolean;
/** Add a extname (if filepath doesn't include one) before template file lookup. Eg: setting to `".html"` will allow including file by basename. Defaults to `""`. */
extname?: string;
/** Whether or not to cache resolved templates. Defaults to `false`. */
+4
View File
@@ -58,3 +58,7 @@ function arrayEquals (lhs: any[], rhs: any[]): boolean {
if (lhs.length !== rhs.length) return false
return !lhs.some((value, i) => !equals(value, rhs[i]))
}
export function arrayIncludes (arr: any[], item: any): boolean {
return arr.some(value => equals(value, item))
}