Skip to content
Snippets Groups Projects
Commit b509588a authored by Winnie Hellmann's avatar Winnie Hellmann
Browse files

Add basic sprintf implementation to JavaScript

parent 92173ac5
No related branches found
No related tags found
No related merge requests found
import Jed from 'jed';
 
import sprintf from './sprintf';
/**
This is required to require all the translation folders in the current directory
this saves us having to do this manually & keep up to date with new languages
Loading
Loading
@@ -67,4 +69,5 @@ export { lang };
export { gettext as __ };
export { ngettext as n__ };
export { pgettext as s__ };
export { sprintf };
export default locale;
import _ from 'underscore';
/**
Very limited implementation of sprintf supporting only named parameters.
@param input (translated) text with parameters (e.g. '%{num_users} users use us')
@param parameters object mapping parameter names to values (e.g. { num_users: 5 })
@param escapeParameters whether parameter values should be escaped (see http://underscorejs.org/#escape)
@returns {String} the text with parameters replaces (e.g. '5 users use us')
@see https://ruby-doc.org/core-2.3.3/Kernel.html#method-i-sprintf
@see https://gitlab.com/gitlab-org/gitlab-ce/issues/37992
**/
export default (input, parameters, escapeParameters = true) => {
let output = input;
if (parameters) {
Object.keys(parameters).forEach((parameterName) => {
const parameterValue = parameters[parameterName];
const escapedParameterValue = escapeParameters ? _.escape(parameterValue) : parameterValue;
output = output.replace(new RegExp(`%{${parameterName}}`, 'g'), escapedParameterValue);
});
}
return output;
}
Loading
Loading
@@ -2,6 +2,7 @@ import {
__,
n__,
s__,
sprintf,
} from '../locale';
 
export default (Vue) => {
Loading
Loading
@@ -37,6 +38,7 @@ export default (Vue) => {
@returns {String} Translated context based text
**/
s__,
sprintf,
},
});
};
---
title: Add basic sprintf implementation to JavaScript
merge_request: 14506
author:
type: other
Loading
Loading
@@ -183,13 +183,20 @@ aren't in the message with id `1 pipeline`.
 
### Interpolation
 
- In Ruby/HAML:
- In Ruby/HAML (see [sprintf]):
 
```ruby
_("Hello %{name}") % { name: 'Joe' }
```
 
- In JavaScript: Not supported at this moment.
- In JavaScript: Only named parameters are supported (see also [#37992]):
```javascript
__("Hello %{name}") % { name: 'Joe' }
```
[sprintf]: http://ruby-doc.org/core/Kernel.html#method-i-sprintf
[#37992]: https://gitlab.com/gitlab-org/gitlab-ce/issues/37992
 
### Plurals
 
Loading
Loading
import sprintf from '~/locale/sprintf';
describe('locale', () => {
describe('sprintf', () => {
it('does not modify string without parameters', () => {
const input = 'No parameters';
const output = sprintf(input);
expect(output).toBe(input);
});
it('ignores extraneous parameters', () => {
const input = 'No parameters';
const output = sprintf(input, { ignore: 'this' });
expect(output).toBe(input);
});
it('ignores extraneous placeholders', () => {
const input = 'No %{parameters}';
const output = sprintf(input);
expect(output).toBe(input);
});
it('replaces parameters', () => {
const input = '%{name} has %{count} parameters';
const parameters = {
name: 'this',
count: 2,
};
const output = sprintf(input, parameters);
expect(output).toBe('this has 2 parameters');
});
it('replaces multiple occurrences', () => {
const input = 'to %{verb} or not to %{verb}';
const parameters = {
verb: 'be',
};
const output = sprintf(input, parameters);
expect(output).toBe('to be or not to be');
});
it('escapes parameters', () => {
const input = 'contains %{userContent}';
const parameters = {
userContent: '<script>alert("malicious!")</script>',
};
const output = sprintf(input, parameters);
expect(output).toBe('contains &lt;script&gt;alert(&quot;malicious!&quot;)&lt;/script&gt;');
});
it('does not escape parameters for escapeParameters = false', () => {
const input = 'contains %{safeContent}';
const parameters = {
safeContent: '<strong>bold attempt</strong>',
};
const output = sprintf(input, parameters, false);
expect(output).toBe('contains <strong>bold attempt</strong>');
});
});
});
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment