diff --git a/public/app/features/templating/formatRegistry.ts b/public/app/features/templating/formatRegistry.ts index 6256c4259ff..0196a44f0aa 100644 --- a/public/app/features/templating/formatRegistry.ts +++ b/public/app/features/templating/formatRegistry.ts @@ -33,6 +33,7 @@ export enum FormatRegistryID { glob = 'glob', text = 'text', queryParam = 'queryparam', + jsonWithoutQuote = 'jsonwithoutquote', } export const formatRegistry = new Registry(() => { @@ -254,6 +255,14 @@ export const formatRegistry = new Registry(() => { return formatQueryParameter(name, value); }, }, + { + id: FormatRegistryID.jsonWithoutQuote, + name: 'JSON Without Quote', + description: 'JSON stringify value, but the double quotation marks around it are removed.', + formatter: ({ value }) => { + return JSON.stringify(value).replace(/^"|"$/g, ''); + }, + }, ]; return formats; diff --git a/public/app/features/templating/template_srv.test.ts b/public/app/features/templating/template_srv.test.ts index 25e9528ab35..78d7d0e477f 100644 --- a/public/app/features/templating/template_srv.test.ts +++ b/public/app/features/templating/template_srv.test.ts @@ -426,6 +426,26 @@ describe('templateSrv', () => { const result = _templateSrv.formatValue("'test\n", 'raw'); expect(result).toBe("'test\n"); }); + + it('single value and pipeline should render the string value processed by all functions in turn', () => { + const result = _templateSrv.formatValue('Test Value"', 'json|percentencode'); + expect(result).toBe('%22Test%20Value%5C%22%22'); + }); + + it('multi value and pipeline should render the string value processed by all functions in turn', () => { + const result = _templateSrv.formatValue(['test', 'test"2'], 'json|percentencode'); + expect(result).toBe('%5B%22test%22%2C%22test%5C%222%22%5D'); + }); + + it('single value and jsonwithoutquote format should render JSON format string, But the double quotation marks around it have been removed', () => { + const result = _templateSrv.formatValue('Test Value"', 'jsonwithoutquote'); + expect(result).toBe('Test Value\\"'); + }); + + it('multi value and jsonwithoutquote format should render JSON format string, like json', () => { + const result = _templateSrv.formatValue(['test', 'test"2'], 'jsonwithoutquote'); + expect(result).toBe('["test","test\\"2"]'); + }); }); describe('can check if variable exists', () => { diff --git a/public/app/features/templating/template_srv.ts b/public/app/features/templating/template_srv.ts index 7a06912ddfc..e58b68df5af 100644 --- a/public/app/features/templating/template_srv.ts +++ b/public/app/features/templating/template_srv.ts @@ -143,24 +143,25 @@ export class TemplateSrv implements BaseTemplateSrv { format = FormatRegistryID.glob; } - // some formats have arguments that come after ':' character - let args = format.split(':'); - if (args.length > 1) { - format = args[0]; - args = args.slice(1); - } else { - args = []; + const formats = format.split('|'); + for (let fmt of formats) { + // some formats have arguments that come after ':' character + let args = fmt.split(':'); + if (args.length > 1) { + fmt = args[0]; + args = args.slice(1); + } else { + args = []; + } + let formatItem = formatRegistry.getIfExists(fmt); + if (!formatItem) { + console.error(`Variable format ${fmt} not found. Using glob format as fallback.`); + formatItem = formatRegistry.get(FormatRegistryID.glob); + } + const options: FormatOptions = { value, args, text: text ?? value }; + value = formatItem.formatter(options, variable); } - - let formatItem = formatRegistry.getIfExists(format); - - if (!formatItem) { - console.error(`Variable format ${format} not found. Using glob format as fallback.`); - formatItem = formatRegistry.get(FormatRegistryID.glob); - } - - const options: FormatOptions = { value, args, text: text ?? value }; - return formatItem.formatter(options, variable); + return value; } setGrafanaVariable(name: string, value: any) {