feat(liquidjs): add date filters and enhance json-templates parsing

This commit is contained in:
Sheldon Guo 2025-02-15 21:38:09 +08:00
parent 693d193a84
commit 2014ca321e
6 changed files with 80 additions and 36 deletions

View File

@ -14,7 +14,8 @@
"graphlib": "^2.1.8", "graphlib": "^2.1.8",
"handlebars": "^4.7.8", "handlebars": "^4.7.8",
"multer": "^1.4.5-lts.1", "multer": "^1.4.5-lts.1",
"object-path": "^0.11.8" "object-path": "^0.11.8",
"liquidjs": "^10.20.3"
}, },
"gitHead": "d0b4efe4be55f8c79a98a331d99d9f8cf99021a1" "gitHead": "d0b4efe4be55f8c79a98a331d99d9f8cf99021a1"
} }

View File

@ -25,3 +25,17 @@ describe('json-templates', () => {
}); });
}); });
}); });
describe('json-templates filters', () => {
it('format filters', async () => {
const template = {
today: '{{now | date_format: "YYYY-MM-DD"}}',
};
const result = parse(template)({
now: new Date('2025-01-01: 12:00:00'),
});
expect(result).toEqual({
today: '2025-01-01',
});
});
});

View File

@ -13,6 +13,8 @@
// Created by Curran Kelleher and Chrostophe Serafin. // Created by Curran Kelleher and Chrostophe Serafin.
// Contributions from Paul Brewer and Javier Blanco Martinez. // Contributions from Paul Brewer and Javier Blanco Martinez.
import { get } from 'lodash'; import { get } from 'lodash';
import liquidjsEngine from './liquidjs';
import engine from './liquidjs';
// An enhanced version of `typeof` that handles arrays and dates as well. // An enhanced version of `typeof` that handles arrays and dates as well.
function type(value) { function type(value) {
@ -39,7 +41,6 @@ function Parameter(match) {
if (i !== -1) { if (i !== -1) {
param = { param = {
key: matchValue.substr(0, i), key: matchValue.substr(0, i),
defaultValue: matchValue.substr(i + 1),
}; };
} else { } else {
param = { key: matchValue }; param = { key: matchValue };
@ -82,43 +83,14 @@ export function parse(value) {
const parseString = (() => { const parseString = (() => {
// This regular expression detects instances of the // This regular expression detects instances of the
// template parameter syntax such as {{foo}} or {{foo:someDefault}}. // template parameter syntax such as {{foo}} or {{foo:someDefault}}.
const regex = /{{(\w|:|[\s-+.,@/()?=*_$])+}}/g; const regex = /{{(\w|:|[\s-+.,@/()?=*_$|])+}}/g;
return (str) => { return (str) => {
let parameters = []; const templateFn = (context) => {
let templateFn = (context) => str; return engine.parseAndRenderSync(str, context);
};
const parameters = liquidjsEngine.fullVariablesSync(str).map((variable) => ({ key: variable }));
const matches = str.match(regex); const matches = str.match(regex);
if (matches) {
parameters = matches.map(Parameter);
templateFn = (context) => {
context = context || {};
return matches.reduce((result, match, i) => {
const parameter = parameters[i];
let value = get(context, parameter.key);
if (typeof value === 'undefined') {
value = parameter.defaultValue;
}
if (typeof value === 'function') {
value = value();
}
// Accommodate non-string as original values.
if (matches.length === 1 && str.startsWith('{{') && str.endsWith('}}')) {
return value;
}
// Treat Date value inside string to ISO string.
if (value instanceof Date) {
value = value.toISOString();
}
return result.replace(match, value == null ? '' : value);
}, str);
};
}
return Template(templateFn, parameters); return Template(templateFn, parameters);
}; };

View File

@ -0,0 +1,25 @@
/**
* This file is part of the NocoBase (R) project.
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
* Authors: NocoBase Team.
*
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
* For more information, please refer to: https://www.nocobase.com/agreement.
*/
import { dayjs } from '../../dayjs';
import { QUnitType } from 'dayjs';
export function dateFormat(initialValue: any, format: string) {
return dayjs.isDayjs(initialValue) ? initialValue.format(format) : dayjs(initialValue).format(format);
}
export function dateAdd(initialValue: any, number: number, unit: any) {
const value = dayjs.isDayjs(initialValue) ? initialValue : dayjs(initialValue);
return value.add(number, unit);
}
export function dateSubtract(initialValue: any, number: number, unit: any) {
const value = dayjs.isDayjs(initialValue) ? initialValue : dayjs(initialValue);
return value.subtract(number, unit);
}

View File

@ -0,0 +1,16 @@
/**
* This file is part of the NocoBase (R) project.
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
* Authors: NocoBase Team.
*
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
* For more information, please refer to: https://www.nocobase.com/agreement.
*/
import { Liquid } from 'liquidjs';
import { dateFormat, dateAdd, dateSubtract } from './date';
export function registerFilters(liquid: Liquid) {
liquid.registerFilter('date_format', dateFormat);
liquid.registerFilter('date_add', dateFormat);
liquid.registerFilter('date_subtract', dateFormat);
}

View File

@ -0,0 +1,16 @@
/**
* This file is part of the NocoBase (R) project.
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
* Authors: NocoBase Team.
*
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
* For more information, please refer to: https://www.nocobase.com/agreement.
*/
import { Liquid } from 'liquidjs';
import { registerFilters } from './filters';
const engine = new Liquid();
registerFilters(engine);
export default engine;