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
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
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;

View File

@ -493,6 +493,27 @@ Example config:
max_file_size: 512000 # in bytes, only for default media library
```
## Summary string template transformations
You can apply transformations on fields in a summary string template using filter notation syntax.
Example config:
```yaml
collections:
- name: 'posts'
label: 'Posts'
folder: '_posts'
summary: "{{title | upper}} - {{date | date('YYYY-MM-DD')}}"
fields:
- { label: 'Title', name: 'title', widget: 'string' }
- { label: 'Publish Date', name: 'date', widget: 'datetime' }
```
The above config will transform the title field to uppercase and format the date field using `YYYY-MM-DD` format.
Available transformations are `upper`, `lower` and `date('<format>')`
## Registering to CMS Events
You can execute a function when a specific CMS event occurs.