feat: Support filters for template strings #3677 (#4396)

This commit is contained in:
KoljaTM
2020-10-25 16:29:59 +01:00
committed by GitHub
parent a690e467fa
commit 1fa108ee67
3 changed files with 80 additions and 4 deletions

View File

@ -107,6 +107,28 @@ describe('stringTemplate', () => {
compileStringTemplate('{{slug}}', date, 'slug', fromJS({}), value => value.toUpperCase()),
).toBe('SLUG');
});
it('return apply filter to values', () => {
expect(
compileStringTemplate(
'{{slug | upper}}-{{title | lower}}-{{year}}',
date,
'backendSlug',
fromJS({ slug: 'entrySlug', title: 'Title', date }),
),
).toBe('BACKENDSLUG-title-2020');
});
it('return apply filter to date field', () => {
expect(
compileStringTemplate(
"{{slug | upper}}-{{title | lower}}-{{published | date('MM-DD')}}-{{year}}",
date,
'backendSlug',
fromJS({ slug: 'entrySlug', title: 'Title', published: date, date }),
),
).toBe('BACKENDSLUG-title-01-02-2020');
});
});
describe('expandPath', () => {

View File

@ -1,11 +1,24 @@
import moment from 'moment';
import { Map } from 'immutable';
import { basename, extname, dirname } from 'path';
import { basename, dirname, extname } from 'path';
import { get, trimEnd } from 'lodash';
const filters = [
{ pattern: /^upper$/, transform: (str: string) => str.toUpperCase() },
{
pattern: /^lower$/,
transform: (str: string) => str.toLowerCase(),
},
{
pattern: /^date\('(.+)'\)$/,
transform: (str: string, match: RegExpMatchArray) => moment(str).format(match[1]),
},
];
const FIELD_PREFIX = 'fields.';
const templateContentPattern = '[^}{]+';
const templateVariablePattern = `{{(${templateContentPattern})}}`;
const templateContentPattern = '([^}{|]+)';
const filterPattern = '( \\| ([^}{]+))?';
const templateVariablePattern = `{{${templateContentPattern}${filterPattern}}}`;
// prepends a Zero if the date has only 1 digit
function formatDate(date: number) {
@ -110,6 +123,21 @@ function getExplicitFieldReplacement(key: string, data: Map<string, unknown>) {
return value;
}
function getFilterFunction(filterStr: string) {
if (filterStr) {
let match: RegExpMatchArray | null = null;
const filter = filters.find(filter => {
match = filterStr.match(filter.pattern);
return !!match;
});
if (filter) {
return (str: string) => filter.transform(str, match as RegExpMatchArray);
}
}
return null;
}
export function compileStringTemplate(
template: string,
date: Date | undefined | null,
@ -125,7 +153,7 @@ export function compileStringTemplate(
const compiledString = template.replace(
RegExp(templateVariablePattern, 'g'),
(_, key: string) => {
(_full, key: string, _part, filter: string) => {
let replacement;
const explicitFieldReplacement = getExplicitFieldReplacement(key, data);
@ -144,6 +172,11 @@ export function compileStringTemplate(
if (processor) {
return processor(replacement);
} else {
const filterFunction = getFilterFunction(filter);
if (filterFunction) {
replacement = filterFunction(replacement);
}
}
return replacement;