mirror of
https://gitee.com/nocobase/nocobase.git
synced 2025-05-05 05:29:26 +08:00
feat(json-templates): enhance date filter handling and support non-string types
This commit is contained in:
parent
144534f170
commit
8503080803
@ -8,7 +8,7 @@
|
||||
*/
|
||||
|
||||
import { parse } from '../json-templates';
|
||||
|
||||
import { TokenKind } from 'liquidjs';
|
||||
describe('json-templates', () => {
|
||||
it('parse json with string template', async () => {
|
||||
const template = {
|
||||
@ -29,16 +29,18 @@ describe('json-templates', () => {
|
||||
describe('json-templates filters', () => {
|
||||
it('date filters', async () => {
|
||||
const template = {
|
||||
now: '{{now}}',
|
||||
today: '{{now | date_format: "YYYY-MM-DD"}}',
|
||||
yesterday: '{{now | date_subtract: 1, "day" | date_format: "YYYY-MM-DD"}}',
|
||||
};
|
||||
|
||||
const compiledFn = parse(template);
|
||||
compiledFn.parameters.some((parameter) => parameter.key === 'now');
|
||||
const result = compiledFn({
|
||||
now: new Date('2025-01-01: 12:00:00'),
|
||||
const parsed = parse(template);
|
||||
const now = new Date('2025-01-01: 12:00:00');
|
||||
const result = parsed({
|
||||
now,
|
||||
});
|
||||
expect(result).toEqual({
|
||||
now,
|
||||
today: '2025-01-01',
|
||||
yesterday: '2024-12-31',
|
||||
});
|
||||
@ -61,17 +63,31 @@ describe('json-templates filters', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('when non-string type', async () => {
|
||||
class Form {}
|
||||
const form = new Form();
|
||||
const template = {
|
||||
form: '{{form}}',
|
||||
};
|
||||
const result = parse(template)({
|
||||
form,
|
||||
});
|
||||
expect(result).toEqual({
|
||||
form,
|
||||
});
|
||||
});
|
||||
|
||||
it('when key is undefined, ignore it', async () => {
|
||||
const template = {
|
||||
key1: '{{current.key1}}',
|
||||
key2: '{{current.key2}}',
|
||||
};
|
||||
const result = parse(template)({
|
||||
current: { key1: 'value1', key2: undefined },
|
||||
current: { key1: 'value1' },
|
||||
});
|
||||
expect(result).toEqual({
|
||||
key1: 'value1',
|
||||
key2: '',
|
||||
key2: undefined,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -12,9 +12,12 @@
|
||||
//
|
||||
// Created by Curran Kelleher and Chrostophe Serafin.
|
||||
// Contributions from Paul Brewer and Javier Blanco Martinez.
|
||||
import { get } from 'lodash';
|
||||
import { get, template } from 'lodash';
|
||||
import liquidjsEngine from './liquidjs';
|
||||
import { TokenKind } from 'liquidjs';
|
||||
import engine from './liquidjs';
|
||||
import raw from 'liquidjs/dist/tags/raw';
|
||||
import b from 'packages/core/database/src/__tests__/fixtures/c1/b';
|
||||
|
||||
// An enhanced version of `typeof` that handles arrays and dates as well.
|
||||
function type(value) {
|
||||
@ -30,25 +33,6 @@ function type(value) {
|
||||
return valueType;
|
||||
}
|
||||
|
||||
// Constructs a parameter object from a match result.
|
||||
// e.g. "['{{foo}}']" --> { key: "foo" }
|
||||
// e.g. "['{{foo:bar}}']" --> { key: "foo", defaultValue: "bar" }
|
||||
function Parameter(match) {
|
||||
let param;
|
||||
const matchValue = match.substr(2, match.length - 4).trim();
|
||||
const i = matchValue.indexOf(':');
|
||||
|
||||
if (i !== -1) {
|
||||
param = {
|
||||
key: matchValue.substr(0, i),
|
||||
};
|
||||
} else {
|
||||
param = { key: matchValue };
|
||||
}
|
||||
|
||||
return param;
|
||||
}
|
||||
|
||||
// Constructs a template function with deduped `parameters` property.
|
||||
function Template(fn, parameters) {
|
||||
fn.parameters = Array.from(new Map(parameters.map((parameter) => [parameter.key, parameter])).values());
|
||||
@ -85,10 +69,56 @@ const parseString = (() => {
|
||||
// template parameter syntax such as {{foo}} or {{foo:someDefault}}.
|
||||
|
||||
return (str) => {
|
||||
const rawTemplates = liquidjsEngine.parse(str);
|
||||
// const ref = {};
|
||||
// rawTemplates.forEach((template) => {
|
||||
// if (template.token.kind === TokenKind.Output) {
|
||||
// // @ts-ignore
|
||||
// const variable = template.value?.initial?.postfix;
|
||||
// // @ts-ignore
|
||||
// ref.variableName = variable[0].props[0].content;
|
||||
// // @ts-ignore
|
||||
// ref.filters = template.value?.filters.map(({ name, handler, args }) => ({
|
||||
// name,
|
||||
// handler,
|
||||
// args: args.map((arg) => arg.content),
|
||||
// }));
|
||||
// }
|
||||
// });
|
||||
|
||||
const templates = rawTemplates
|
||||
.filter((rawTemplate) => rawTemplate.token.kind === TokenKind.Output)
|
||||
.map((rawTemplate) => {
|
||||
const fullVariables = liquidjsEngine.fullVariablesSync(rawTemplate.token.input);
|
||||
return {
|
||||
// @ts-ignore
|
||||
variableName: fullVariables[0],
|
||||
tokenBegin: rawTemplate.token.begin,
|
||||
tokenEnd: rawTemplate.token.end,
|
||||
// @ts-ignore
|
||||
filters: rawTemplate.value?.filters.map(({ name, handler, args }) => ({
|
||||
name,
|
||||
handler,
|
||||
args: args.map((arg) => arg.content),
|
||||
})),
|
||||
};
|
||||
});
|
||||
const templateFn = (context) => {
|
||||
return engine.parseAndRenderSync(str, context);
|
||||
if (templates.length === 1 && templates[0].tokenBegin === 0 && templates[0].tokenEnd === str.length) {
|
||||
let value = get(context, templates[0].variableName);
|
||||
if (typeof value === 'function') {
|
||||
value = value();
|
||||
}
|
||||
if (Array.isArray(templates[0].filters)) {
|
||||
return templates[0].filters.reduce((acc, filter) => filter.handler(...[acc, ...filter.args]), value);
|
||||
}
|
||||
}
|
||||
return engine.renderSync(rawTemplates, context);
|
||||
};
|
||||
const parameters = liquidjsEngine.fullVariablesSync(str).map((variable) => ({ key: variable }));
|
||||
|
||||
// Accommodate non-string as original values.
|
||||
|
||||
const parameters = templates.map((template) => ({ key: template.variableName }));
|
||||
|
||||
return Template(templateFn, parameters);
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user