handlebars-i18n 1.7.1 → 1.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/handlebars-i18n.js +66 -1
- package/dist/handlebars-i18n.min.js +1 -1
- package/examples/browser-example/index.html +17 -9
- package/examples/node-example/simple-example.js +87 -71
- package/examples/typescript/test.hbs +13 -7
- package/package.json +1 -1
- package/readme.md +49 -50
- package/test/handlebars-i18n.test.js +236 -81
package/dist/handlebars-i18n.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* handlebars-i18n.js
|
|
3
3
|
*
|
|
4
4
|
* @author: Florian Walzel
|
|
5
|
-
* @date: 2024-
|
|
5
|
+
* @date: 2024-08
|
|
6
6
|
*
|
|
7
7
|
* handlebars-i18n adds features for localization/
|
|
8
8
|
* internationalization to handlebars.js
|
|
@@ -444,6 +444,71 @@
|
|
|
444
444
|
return dateFormat.format(date);
|
|
445
445
|
}
|
|
446
446
|
);
|
|
447
|
+
handlebars.registerHelper('_dateAdd',
|
|
448
|
+
/**
|
|
449
|
+
* adds a time offset in a given unit to a date
|
|
450
|
+
* -> returns the modified date
|
|
451
|
+
*
|
|
452
|
+
* @param dateInput
|
|
453
|
+
* @param offset
|
|
454
|
+
* @param options
|
|
455
|
+
* @returns {string}
|
|
456
|
+
*/
|
|
457
|
+
function (dateInput, offset, options) {
|
|
458
|
+
|
|
459
|
+
if (typeof dateInput !== 'number' && typeof dateInput !== 'string')
|
|
460
|
+
throw new Error('@ handlebars-i18n: invalid first argument "dateInput" was given for _dateAdd.');
|
|
461
|
+
|
|
462
|
+
if (typeof offset !== 'number')
|
|
463
|
+
throw new Error('@ handlebars-i18n: invalid second argument "offset" was given for _dateAdd.');
|
|
464
|
+
|
|
465
|
+
const date = __createDateObj(dateInput);
|
|
466
|
+
|
|
467
|
+
const opts = __configLookup(options, i18next.language, optionsConf.DateTimeFormat);
|
|
468
|
+
opts.unit = opts.unit || 'hour';
|
|
469
|
+
|
|
470
|
+
switch (opts.unit) {
|
|
471
|
+
case 'second':
|
|
472
|
+
case 'seconds':
|
|
473
|
+
date.setSeconds(date.getSeconds() + offset);
|
|
474
|
+
break;
|
|
475
|
+
case 'minute':
|
|
476
|
+
case 'minutes':
|
|
477
|
+
date.setMinutes(date.getMinutes() + offset);
|
|
478
|
+
break;
|
|
479
|
+
case 'hour':
|
|
480
|
+
case 'hours':
|
|
481
|
+
date.setHours(date.getHours() + offset);
|
|
482
|
+
break;
|
|
483
|
+
case 'day':
|
|
484
|
+
case 'days':
|
|
485
|
+
date.setDate(date.getDate() + offset);
|
|
486
|
+
break;
|
|
487
|
+
case 'week':
|
|
488
|
+
case 'weeks':
|
|
489
|
+
date.setDate(date.getDate() + offset * 7);
|
|
490
|
+
break;
|
|
491
|
+
case 'month':
|
|
492
|
+
case 'months':
|
|
493
|
+
date.setMonth(date.getMonth() + offset);
|
|
494
|
+
break;
|
|
495
|
+
case 'quarter':
|
|
496
|
+
case 'quarters':
|
|
497
|
+
date.setMonth(date.getMonth() + offset * 3);
|
|
498
|
+
break;
|
|
499
|
+
case 'year':
|
|
500
|
+
case 'years':
|
|
501
|
+
date.setFullYear(date.getFullYear() + offset);
|
|
502
|
+
break;
|
|
503
|
+
default:
|
|
504
|
+
throw new Error('@ handlebars-i18n: invalid argument "unit" was given for _dateAdd.' +
|
|
505
|
+
'Unit must be either "second" | "minute" | "hour" | "day" | "week" | "month" | "quarter" | "year".');
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
const dateFormat = new Intl.DateTimeFormat(i18next.language, opts);
|
|
509
|
+
return dateFormat.format(date);
|
|
510
|
+
}
|
|
511
|
+
);
|
|
447
512
|
handlebars.registerHelper('_dateRel',
|
|
448
513
|
/**
|
|
449
514
|
* returns a relative date formatted according the options
|
|
@@ -1 +1 @@
|
|
|
1
|
-
!function(e,
|
|
1
|
+
!function(e,t){if("object"==typeof exports&&"object"==typeof module){const e=require("handlebars"),r=require("i18next"),n=require("intl"),a=require("relative-time-format");module.exports=t(e,r,n,a,"TEST"===process?.env?.NODE_ENV)}else if("function"==typeof define&&define.amd)define(["Handlebars","i18next","Intl"],t);else{if("object"!=typeof e.Handlebars||"object"!=typeof e.i18next||"object"!=typeof e.Intl)return console.error("@ handlebars-i18n: One or more dependencies are missing. Check for Handlebars, i18next and Intl."),!1;e.HandlebarsI18n=t(e.Handlebars,e.i18next,e.Intl)}}(this,(function(e,t,r,n,a){"use strict";const o={DateTimeFormat:{standard:{},custom:{}},RelativeTimeFormat:{standard:{all:{unit:"hours"}},custom:{}},NumberFormat:{standard:{},custom:{}},PriceFormat:{standard:{all:{style:"currency",currency:"EUR"}},custom:{}}};let i=JSON.parse(JSON.stringify(o));const s={};function u(e,t){let r=[null].concat(t);return new(e.bind.apply(e,r))}function l(e,t,r){if("object"==typeof e&&"object"==typeof e.hash&&Object.keys(e.hash).length>0){let n=e.hash;if(void 0===n.format)return n;if(void 0!==r.custom[n.format]&&void 0!==r.custom[n.format][t])return r.custom[n.format][t]}return void 0!==r.standard[t]?r.standard[t]:void 0!==r.standard.all?r.standard.all:{}}function c(e,t,r,n){return"string"!=typeof e?(console.error("@ handlebars-i18n.configure(): Invalid argument <"+e+'> First argument must be a string with language code such as "en".'),!1):["DateTimeFormat","RelativeTimeFormat","NumberFormat","PriceFormat"].includes(t)?"object"!=typeof r?(console.error("@ handlebars-i18n.configure(): Invalid argument <"+r+"> Third argument must be an object containing the configuration parameters."),!1):(null==n||"string"==typeof n)&&""!==n&&" "!==n||(console.error("@ handlebars-i18n.configure(): Invalid argument <"+n+"> Fourth argument (optional) must be a string naming your custom format configuration."),!1):(console.error("@ handlebars-i18n.configure(): Invalid argument <"+t+'>. Second argument must be a string with the options key. Use either "DateTimeFormat", "RelativeTimeFormat", "NumberFormat", or "PriceFormat".'),!1)}function m(e,t,r,n){return null!=n?(void 0===i[t].custom[n]&&(i[t].custom[n]={}),i[t].custom[n][e]=r):i[t].standard[e]=r,!0}function g(e){return"number"==typeof e||"string"==typeof e&&""!==e}function d(e){let t;if("number"==typeof e)t=new Date(e);else if("string"==typeof e)if("["===e.charAt(0)&&"]"===e.slice(-1)){let r=(e=e.substring(1,e.length-1).replace(/ /g,"")).split(",");t=u.bind(null,Date)(r)}else t="now"===e.toLowerCase()||"today"===e.toLowerCase()?new Date:new Date(e);else t=new Date;return t}function f(e,t){if("function"==typeof r.RelativeTimeFormat)return new r.RelativeTimeFormat(e,t);if(void 0===s[e])try{s[e]=require(`relative-time-format/locale/${e}`)}catch(e){console.error(e)}return n.addLocale(s[e]),new n(e,t)}function b(e,t){return t=t||"hour",Math.trunc(e/{second:1e3,seconds:1e3,minute:6e4,minutes:6e4,hour:36e5,hours:36e5,day:864e5,days:864e5,week:6048e5,weeks:6048e5,month:2629746e3,months:2629746e3,quarter:78894e5,quarters:78894e5,year:315576e5,years:315576e5}[t])}return{configure:function(e,t,r,n){if("string"!=typeof e&&!Array.isArray(e))return console.error("@ handlebars-i18n.configure(): Invalid argument <"+e+'> First argument must be a string with language code such as "en" or an array with language parameters.'),!1;if(Array.isArray(e)){if(e.length<1)return console.log("@ handlebars-i18n.configure(): You passed an empty array, no parameters taken."),!1;e.forEach((e=>{if(!c(e[0],e[1],e[2],e[3]))return!1;m(e[0],e[1],e[2],e[3])}))}else{if(!c(e,t,r,n))return!1;m(e,t,r,n)}return!0},reset:function(){return i=JSON.parse(JSON.stringify(o)),!0},init:function(n,a){return"object"==typeof n&&null!==n?e=n:null!=n&&console.error("@ handlebars-i18n.init(): Invalid Argument [1] given for overrideHndlbrs. Argument must be the Handlebars object. Using generic Handlebars object instead."),"object"==typeof a&&null!==a?t=a:null!=a&&console.error("@ handlebars-i18n.init(): Invalid Argument [2] given for overrideI18n. Argument must be the i18next object. Using generic i18next object on module level instead."),e.registerHelper("__",(function(r,n){return new e.SafeString(void 0!==t?t.t(r,n.hash):r)})),e.registerHelper("_locale",(function(){return t.language})),e.registerHelper("localeIs",(function(e){return t.language===e})),e.registerHelper("_date",(function(e,n){const a=d(e),o=l(n,t.language,i.DateTimeFormat);return new r.DateTimeFormat(t.language,o).format(a)})),e.registerHelper("_dateAdd",(function(e,n,a){if("number"!=typeof e&&"string"!=typeof e)throw new Error('@ handlebars-i18n: invalid first argument "dateInput" was given for _dateAdd.');if("number"!=typeof n)throw new Error('@ handlebars-i18n: invalid second argument "offset" was given for _dateAdd.');const o=d(e),s=l(a,t.language,i.DateTimeFormat);switch(s.unit=s.unit||"hour",s.unit){case"second":case"seconds":o.setSeconds(o.getSeconds()+n);break;case"minute":case"minutes":o.setMinutes(o.getMinutes()+n);break;case"hour":case"hours":o.setHours(o.getHours()+n);break;case"day":case"days":o.setDate(o.getDate()+n);break;case"week":case"weeks":o.setDate(o.getDate()+7*n);break;case"month":case"months":o.setMonth(o.getMonth()+n);break;case"quarter":case"quarters":o.setMonth(o.getMonth()+3*n);break;case"year":case"years":o.setFullYear(o.getFullYear()+n);break;default:throw new Error('@ handlebars-i18n: invalid argument "unit" was given for _dateAdd.Unit must be either "second" | "minute" | "hour" | "day" | "week" | "month" | "quarter" | "year".')}return new r.DateTimeFormat(t.language,s).format(o)})),e.registerHelper("_dateRel",(function(e,r){const n=parseInt(e),a=l(r,t.language,i.RelativeTimeFormat);return f(t.language,a).format(n,a.unit)})),e.registerHelper("_dateDiff",(function(e,r,n){let a,o=l(n,t.language,i.RelativeTimeFormat);if(!g(e))return console.error("@ handlebars-i18n: invalid first argument dateInputA was given for _dateDiff."),null;r=r||"now",a=d(e)-d(r);const s=b(a,o.unit);return f(t.language,o).format(s,o.unit)})),e.registerHelper("_num",(function(e,n){let a=l(n,t.language,i.NumberFormat);return new r.NumberFormat(t.language,a).format(e)})),e.registerHelper("_price",(function(e,n){let a=l(n,t.language,i.PriceFormat);"string"!=typeof a.style&&"string"==typeof a.currency&&(a.style="currency");return new r.NumberFormat(t.language,a).format(e)})),e},...a&&{private:{applyToConstructor:u,configLookup:l,validateArgs:c,setArgs:m,isNumOrString:g,createDateObj:d,getRelDateFormatPolyfill:f,getDateDiff:b}}}}));
|
|
@@ -218,6 +218,22 @@
|
|
|
218
218
|
|
|
219
219
|
<button onclick="changeLang()">{{__ "key0"}} {{#if (localeIs "en")}}German {{else}}Englisch {{/if}}</button>
|
|
220
220
|
|
|
221
|
+
<h4>Date with positive time offset:</h4>
|
|
222
|
+
<code>{{{{raw}}}} {{_dateAdd "December 17, 1995" 24 unit="hour"}} {{{{/raw}}}}</code>
|
|
223
|
+
<p>→ {{_dateAdd "December 17, 1995 08:00:00" 24 unit="hour"}}</p>
|
|
224
|
+
|
|
225
|
+
<h4>Date with negative time offset:</h4>
|
|
226
|
+
<code>{{{{raw}}}} {{_dateAdd "December 17, 1995" -10 unit="day"}} {{{{/raw}}}}</code>
|
|
227
|
+
<p>→ {{_dateAdd "December 17, 1995" -10 unit="day"}}</p>
|
|
228
|
+
|
|
229
|
+
<h4>Relative difference between two dates:</h4>
|
|
230
|
+
<code>{{{{raw}}}} {{_dateDiff "1996-12-07T00:00:00" "1996-12-08T00:00:00" unit="day"}} {{{{/raw}}}}</code>
|
|
231
|
+
<p>→ {{_dateDiff "1996-12-07T00:00:00" "1996-12-08T00:00:00" unit="day"}}</p>
|
|
232
|
+
|
|
233
|
+
<h4>Relative difference between two dates with custom configuration (subset "date-rel-spec"):</h4>
|
|
234
|
+
<code>{{{{raw}}}} {{_dateDiff myDate "1995-12-17T00:00:00" format="date-rel-spec"}} {{{{/raw}}}}</code>
|
|
235
|
+
<p>→ {{_dateDiff myDate "1995-12-17T00:00:00" format="date-rel-spec"}}</p>
|
|
236
|
+
|
|
221
237
|
<h4>Relative date event in the future:</h4>
|
|
222
238
|
<code>{{{{raw}}}} {{_dateRel 7 unit="hour"}} {{{{/raw}}}}</code>
|
|
223
239
|
<p>→ {{_dateRel 7 unit="hour"}}</p>
|
|
@@ -226,15 +242,7 @@
|
|
|
226
242
|
<code>{{{{raw}}}} {{_dateRel 7 unit="hour"}} {{{{/raw}}}}</code>
|
|
227
243
|
<p>→ {{_dateRel -7 unit="hour"}}</p>
|
|
228
244
|
|
|
229
|
-
<
|
|
230
|
-
<code>{{{{raw}}}} {{_dateDiff "1996-12-07T00:00:00" "1996-12-08T00:00:00" unit="day"}} {{{{/raw}}}}</code>
|
|
231
|
-
<p>→ {{_dateDiff "1996-12-07T00:00:00" "1996-12-08T00:00:00" unit="day"}}</p>
|
|
232
|
-
|
|
233
|
-
<h4>Date difference by custom configuration (subset "date-rel-spec"):</h4>
|
|
234
|
-
<code>{{{{raw}}}} {{_dateDiff mydate "1995-12-17T00:00:00" format="date-rel-spec"}} {{{{/raw}}}}</code>
|
|
235
|
-
<p>→ {{_dateDiff mydate "1995-12-17T00:00:00" format="date-rel-spec"}}</p>
|
|
236
|
-
|
|
237
|
-
<p> </p><button onclick="changeLang()">{{__ "key0"}} {{#if (localeIs "en")}}German {{else}}Englisch {{/if}}</button>`;
|
|
245
|
+
<button onclick="changeLang()">{{__ "key0"}} {{#if (localeIs "en")}}German {{else}}Englisch {{/if}}</button>`;
|
|
238
246
|
|
|
239
247
|
// -- Ignore this. It’s just a helper to display un-rendered {{handlebars code}} between the <code> Tags
|
|
240
248
|
Handlebars.registerHelper('raw', function(options) {
|
|
@@ -18,9 +18,9 @@ const htmlEntities = require('html-entities');
|
|
|
18
18
|
// -- The translation phrases for i18next
|
|
19
19
|
i18next
|
|
20
20
|
.init({
|
|
21
|
-
resources
|
|
22
|
-
'en'
|
|
23
|
-
translation
|
|
21
|
+
resources: {
|
|
22
|
+
'en': {
|
|
23
|
+
translation: {
|
|
24
24
|
'key0': 'Change Language to',
|
|
25
25
|
'key1': 'What is good?',
|
|
26
26
|
'key2': '{{what}} is good.',
|
|
@@ -29,7 +29,7 @@ i18next
|
|
|
29
29
|
'key4': 'Selected Language is:'
|
|
30
30
|
}
|
|
31
31
|
},
|
|
32
|
-
'de'
|
|
32
|
+
'de': {
|
|
33
33
|
translation: {
|
|
34
34
|
'key0': 'Sprache wechseln zu',
|
|
35
35
|
'key1': 'Was ist gut?',
|
|
@@ -40,16 +40,16 @@ i18next
|
|
|
40
40
|
}
|
|
41
41
|
}
|
|
42
42
|
},
|
|
43
|
-
lng
|
|
43
|
+
lng: 'en',
|
|
44
44
|
compatibilityJSON: 'v2'
|
|
45
45
|
});
|
|
46
46
|
|
|
47
47
|
// -- Handlebars' example data object
|
|
48
48
|
let data = {
|
|
49
|
-
sayWhat
|
|
50
|
-
holdKey3
|
|
51
|
-
holdKey4
|
|
52
|
-
mynumber
|
|
49
|
+
sayWhat: 'handlebars-i18n',
|
|
50
|
+
holdKey3: 'key3WithCount',
|
|
51
|
+
holdKey4: 'key4',
|
|
52
|
+
mynumber: 33.333,
|
|
53
53
|
myMmaxDigits: 1,
|
|
54
54
|
myPrice: 12.99,
|
|
55
55
|
myDate: '2020-03-11T03:24:00'
|
|
@@ -59,23 +59,30 @@ let data = {
|
|
|
59
59
|
HandlebarsI18n.init();
|
|
60
60
|
HandlebarsI18n.configure([
|
|
61
61
|
// generic configuration for all languages for number representation:
|
|
62
|
-
['all', 'NumberFormat', {
|
|
62
|
+
['all', 'NumberFormat', {minimumFractionDigits: 2}],
|
|
63
63
|
// generic configurations per language for price representation:
|
|
64
|
-
['en', 'PriceFormat', {
|
|
65
|
-
['de', 'PriceFormat', {
|
|
64
|
+
['en', 'PriceFormat', {currency: 'USD'}],
|
|
65
|
+
['de', 'PriceFormat', {currency: 'EUR'}],
|
|
66
66
|
// generic configurations per language for date representation:
|
|
67
|
-
['en', 'DateTimeFormat', {
|
|
68
|
-
['de', 'DateTimeFormat', {
|
|
67
|
+
['en', 'DateTimeFormat', {year: 'numeric', month: 'long', day: 'numeric', hour: 'numeric', minute: 'numeric'}],
|
|
68
|
+
['de', 'DateTimeFormat', {
|
|
69
|
+
year: 'numeric',
|
|
70
|
+
month: 'numeric',
|
|
71
|
+
day: 'numeric',
|
|
72
|
+
hour: 'numeric',
|
|
73
|
+
minute: 'numeric',
|
|
74
|
+
hour12: false
|
|
75
|
+
}],
|
|
69
76
|
// configurations per language with custom formats for date:
|
|
70
|
-
['en', 'DateTimeFormat', {
|
|
71
|
-
['de', 'DateTimeFormat', {
|
|
72
|
-
['en', 'DateTimeFormat', {
|
|
73
|
-
['de', 'DateTimeFormat', {
|
|
74
|
-
['en', 'DateTimeFormat', {
|
|
75
|
-
['de', 'DateTimeFormat', {
|
|
77
|
+
['en', 'DateTimeFormat', {year: 'numeric'}, 'custom-year-only'],
|
|
78
|
+
['de', 'DateTimeFormat', {year: 'numeric'}, 'custom-year-only'],
|
|
79
|
+
['en', 'DateTimeFormat', {year: 'numeric', month: 'numeric', day: 'numeric'}, 'custom-date-short'],
|
|
80
|
+
['de', 'DateTimeFormat', {year: 'numeric', month: 'numeric', day: 'numeric'}, 'custom-date-short'],
|
|
81
|
+
['en', 'DateTimeFormat', {hour: 'numeric', minute: 'numeric', second: 'numeric', hour12: false}, 'custom-time'],
|
|
82
|
+
['de', 'DateTimeFormat', {hour: 'numeric', minute: 'numeric', second: 'numeric', hour12: false}, 'custom-time'],
|
|
76
83
|
// custom formats for relative dates:
|
|
77
|
-
['en', 'RelativeTimeFormat', {
|
|
78
|
-
['de', 'RelativeTimeFormat', {
|
|
84
|
+
['en', 'RelativeTimeFormat', {style: 'short', unit: 'year'}, 'date-rel-spec'],
|
|
85
|
+
['de', 'RelativeTimeFormat', {style: 'short', unit: 'year'}, 'date-rel-spec']
|
|
79
86
|
]);
|
|
80
87
|
|
|
81
88
|
let template;
|
|
@@ -120,107 +127,116 @@ template += '{{__ "key1" lng="de"}}';
|
|
|
120
127
|
// ----------------------------------------
|
|
121
128
|
|
|
122
129
|
// Translation key given through handlebars variable and _locale output:
|
|
123
|
-
template += raw('{{__ holdKey4}} {{_locale}}');
|
|
124
|
-
template += '{{__ holdKey4}} {{_locale}}';
|
|
130
|
+
template += raw('{{__ holdKey4}} {{_locale}}');
|
|
131
|
+
template += '{{__ holdKey4}} {{_locale}}';
|
|
125
132
|
|
|
126
133
|
// Check against selected language:
|
|
127
|
-
template += raw('{{#if (localeIs "en")}}English {{else}}Deutsch {{/if}}');
|
|
128
|
-
template += '{{#if (localeIs "en")}}English {{else}}Deutsch {{/if}}';
|
|
134
|
+
template += raw('{{#if (localeIs "en")}}English {{else}}Deutsch {{/if}}');
|
|
135
|
+
template += '{{#if (localeIs "en")}}English {{else}}Deutsch {{/if}}';
|
|
129
136
|
|
|
130
137
|
|
|
131
138
|
// Number representation
|
|
132
139
|
// ----------------------------------------
|
|
133
140
|
|
|
134
141
|
// Number representation as configured for all languages:
|
|
135
|
-
template += raw('{{_num 7000}}');
|
|
136
|
-
template += '{{_num 7000}}';
|
|
142
|
+
template += raw('{{_num 7000}}');
|
|
143
|
+
template += '{{_num 7000}}';
|
|
137
144
|
|
|
138
145
|
// Number representation with specific format attribute:
|
|
139
|
-
template += raw('{{_num 3.1415926 maximumFractionDigits=0}}');
|
|
140
|
-
template += '{{_num 3.1415926 maximumFractionDigits=0}}';
|
|
146
|
+
template += raw('{{_num 3.1415926 maximumFractionDigits=0}}');
|
|
147
|
+
template += '{{_num 3.1415926 maximumFractionDigits=0}}';
|
|
141
148
|
|
|
142
149
|
// Number and attribute given through handlebars variables:
|
|
143
|
-
template += raw('{{_num mynumber maximumFractionDigits=myMaxDigits}}');
|
|
144
|
-
template += '{{_num mynumber maximumFractionDigits=myMaxDigits}}';
|
|
150
|
+
template += raw('{{_num mynumber maximumFractionDigits=myMaxDigits}}');
|
|
151
|
+
template += '{{_num mynumber maximumFractionDigits=myMaxDigits}}';
|
|
145
152
|
|
|
146
153
|
|
|
147
154
|
// Price representation
|
|
148
155
|
// ----------------------------------------
|
|
149
156
|
|
|
150
157
|
// Price representation as configured per language:
|
|
151
|
-
template += raw('{{_price 9999.99}}');
|
|
152
|
-
template += '{{_price 9999.99}}';
|
|
158
|
+
template += raw('{{_price 9999.99}}');
|
|
159
|
+
template += '{{_price 9999.99}}';
|
|
153
160
|
|
|
154
161
|
// Price representation with specific format attributes:
|
|
155
|
-
template += raw('{{_price 1000.99 currency="JPY" minimumFractionDigits=0}}');
|
|
156
|
-
template += '{{_price 1000.99 currency="JPY" minimumFractionDigits=0}}';
|
|
162
|
+
template += raw('{{_price 1000.99 currency="JPY" minimumFractionDigits=0}}');
|
|
163
|
+
template += '{{_price 1000.99 currency="JPY" minimumFractionDigits=0}}';
|
|
157
164
|
|
|
158
165
|
// Price given through handlebars variable and with specific format attribute:
|
|
159
|
-
template += raw('{{_price myPrice currency="DKK"}}');
|
|
160
|
-
template += '{{_price myPrice currency="DKK"}}';
|
|
166
|
+
template += raw('{{_price myPrice currency="DKK"}}');
|
|
167
|
+
template += '{{_price myPrice currency="DKK"}}';
|
|
161
168
|
|
|
162
169
|
|
|
163
170
|
// Date representation
|
|
164
171
|
// ----------------------------------------
|
|
165
172
|
|
|
166
173
|
// Todays’ date as configured per language:
|
|
167
|
-
template += raw('{{_date}}');
|
|
168
|
-
template += '{{_date}}';
|
|
174
|
+
template += raw('{{_date}}');
|
|
175
|
+
template += '{{_date}}';
|
|
169
176
|
|
|
170
177
|
// Date given as date string:
|
|
171
|
-
template += raw('{{_date "2020-03-11T03:24:00"}}');
|
|
172
|
-
template += '{{_date "2020-03-11T03:24:00"}}';
|
|
178
|
+
template += raw('{{_date "2020-03-11T03:24:00"}}');
|
|
179
|
+
template += '{{_date "2020-03-11T03:24:00"}}';
|
|
173
180
|
|
|
174
181
|
// Date given in milliseconds since begin of unix epoch:
|
|
175
|
-
template += raw('{{_date 1583922952743}}');
|
|
176
|
-
template += '{{_date 1583922952743}}';
|
|
182
|
+
template += raw('{{_date 1583922952743}}');
|
|
183
|
+
template += '{{_date 1583922952743}}';
|
|
177
184
|
|
|
178
185
|
// Date given as javascript date parameter array:
|
|
179
|
-
template += raw('{{_date "[2012, 11, 20, 3, 0, 0]"}}');
|
|
180
|
-
template += '{{_date "[2012, 11, 20, 3, 0, 0]"}}';
|
|
186
|
+
template += raw('{{_date "[2012, 11, 20, 3, 0, 0]"}}');
|
|
187
|
+
template += '{{_date "[2012, 11, 20, 3, 0, 0]"}}';
|
|
181
188
|
|
|
182
189
|
// Todays’ date with specific format attributes:
|
|
183
|
-
template += raw('{{_date "today" year="2-digit" month="2-digit" day="2-digit"}}');
|
|
184
|
-
template += '{{_date "today" year="2-digit" month="2-digit" day="2-digit"}}';
|
|
190
|
+
template += raw('{{_date "today" year="2-digit" month="2-digit" day="2-digit"}}');
|
|
191
|
+
template += '{{_date "today" year="2-digit" month="2-digit" day="2-digit"}}';
|
|
185
192
|
|
|
186
193
|
// Date given through handlebars variable:
|
|
187
|
-
template += raw('{{_date myDate}}');
|
|
188
|
-
template += '{{_date myDate}}';
|
|
194
|
+
template += raw('{{_date myDate}}');
|
|
195
|
+
template += '{{_date myDate}}';
|
|
189
196
|
|
|
190
197
|
// Date formatted by custom configuration (subset "custom-year-only"):
|
|
191
|
-
template += raw('{{_date myDate format="custom-year-only"}}');
|
|
192
|
-
template += '{{_date myDate format="custom-year-only"}}';
|
|
198
|
+
template += raw('{{_date myDate format="custom-year-only"}}');
|
|
199
|
+
template += '{{_date myDate format="custom-year-only"}}';
|
|
193
200
|
|
|
194
201
|
// Date formatted by custom configuration (subset "custom-date-short"):
|
|
195
|
-
template += raw('{{_date myDate format="custom-date-short"}}');
|
|
196
|
-
template += '{{_date myDate format="custom-date-short"}}';
|
|
202
|
+
template += raw('{{_date myDate format="custom-date-short"}}');
|
|
203
|
+
template += '{{_date myDate format="custom-date-short"}}';
|
|
197
204
|
|
|
198
205
|
// Date formatted by custom configuration (subset "custom-date-short"):
|
|
199
|
-
template += raw('{{_date myDate format="custom-time"}}');
|
|
200
|
-
template += '{{_date myDate format="custom-time"}}';
|
|
206
|
+
template += raw('{{_date myDate format="custom-time"}}');
|
|
207
|
+
template += '{{_date myDate format="custom-time"}}';
|
|
201
208
|
|
|
202
209
|
// Relative date representation
|
|
203
210
|
// ----------------------------------------
|
|
204
211
|
|
|
212
|
+
// Date with positive time offset:
|
|
213
|
+
template += raw('{{_dateAdd "December 17, 1995 08:00:00" 24 unit="hour"}}');
|
|
214
|
+
template += '{{_dateAdd "December 17, 1995 08:00:00" 24 unit="hour"}}';
|
|
215
|
+
|
|
216
|
+
// Date with negative time offset:
|
|
217
|
+
template += raw('{{_dateAdd "December 17, 1995" -10 unit="day"}}');
|
|
218
|
+
template += '{{_dateAdd "December 17, 1995" -10 unit="day"}}';
|
|
219
|
+
|
|
220
|
+
// Relative difference between two dates:
|
|
221
|
+
template += raw('{{_dateDiff "1996-12-07T00:00:00" "1996-12-08T00:00:00" unit="day"}}');
|
|
222
|
+
template += '{{_dateDiff "1996-12-07T00:00:00" "1996-12-08T00:00:00" unit="day"}}';
|
|
223
|
+
|
|
224
|
+
// Relative difference between two dates with custom configuration (subset "date-rel-spec"):
|
|
225
|
+
template += raw('{{_dateDiff myDate "1995-12-17T00:00:00" format="date-rel-spec"}}');
|
|
226
|
+
template += '{{_dateDiff myDate "1995-12-17T00:00:00" format="date-rel-spec"}}';
|
|
227
|
+
|
|
205
228
|
// Relative date event in the future:
|
|
206
|
-
template += raw('{{_dateRel 7 unit="hour"}}');
|
|
207
|
-
template += '{{_dateRel 7 unit="hour"}}';
|
|
229
|
+
template += raw('{{_dateRel 7 unit="hour"}}');
|
|
230
|
+
template += '{{_dateRel 7 unit="hour"}}';
|
|
208
231
|
|
|
209
232
|
// Relative date event in the past:
|
|
210
|
-
template += raw('{{_dateRel -7 unit="hour"}}');
|
|
211
|
-
template += '{{_dateRel -7 unit="hour"}}';
|
|
212
|
-
|
|
213
|
-
// Date difference:
|
|
214
|
-
template += raw('{{_dateDiff "1996-12-07T00:00:00" "1996-12-08T00:00:00" unit="day"}}');
|
|
215
|
-
template += '{{_dateDiff "1996-12-07T00:00:00" "1996-12-08T00:00:00" unit="day"}}';
|
|
233
|
+
template += raw('{{_dateRel -7 unit="hour"}}');
|
|
234
|
+
template += '{{_dateRel -7 unit="hour"}}';
|
|
216
235
|
|
|
217
|
-
|
|
218
|
-
template += raw('{{_dateDiff mydate "1995-12-17T00:00:00" format="date-rel-spec"}}');
|
|
219
|
-
template += '{{_dateDiff mydate "1995-12-17T00:00:00" format="date-rel-spec"}}';
|
|
236
|
+
const compiled = Handlebars.compile(template);
|
|
220
237
|
|
|
238
|
+
i18next.changeLanguage('de'); // --> Test the changes by replacing 'de' with 'en'
|
|
221
239
|
|
|
222
|
-
const
|
|
223
|
-
i18next.changeLanguage('de'); // --> Test the changes by replacing 'de' with 'en'
|
|
224
|
-
const decoded = htmlEntities.decode(compiled(data));
|
|
240
|
+
const decoded = htmlEntities.decode(compiled(data));
|
|
225
241
|
|
|
226
|
-
console.log('\x1b[36m%s\x1b[0m', decoded);
|
|
242
|
+
console.log('\x1b[36m%s\x1b[0m', decoded);
|
|
@@ -86,14 +86,20 @@ HandlebarsI18n example output from TS:
|
|
|
86
86
|
// Relative date representation
|
|
87
87
|
// ----------------------------------------
|
|
88
88
|
|
|
89
|
-
//
|
|
90
|
-
{{
|
|
89
|
+
// Date with positive time offset:
|
|
90
|
+
{{_dateAdd "December 17, 1995 08:00:00" 24 unit="hour"}}
|
|
91
91
|
|
|
92
|
-
//
|
|
93
|
-
{{
|
|
92
|
+
// Date with negative time offset:
|
|
93
|
+
{{_dateAdd "December 17, 1995" -10 unit="day"}}
|
|
94
94
|
|
|
95
|
-
//
|
|
95
|
+
// Relative difference between two dates:
|
|
96
96
|
{{_dateDiff "1996-12-07T00:00:00" "1996-12-08T00:00:00" unit="day"}}
|
|
97
97
|
|
|
98
|
-
//
|
|
99
|
-
{{_dateDiff
|
|
98
|
+
// Relative difference between two dates with custom configuration (subset "date-rel-spec"):
|
|
99
|
+
{{_dateDiff myDate "1995-12-17T00:00:00" format="date-rel-spec"}}
|
|
100
|
+
|
|
101
|
+
// Relative date event in the future:
|
|
102
|
+
{{_dateRel 7 unit="hour"}}
|
|
103
|
+
|
|
104
|
+
// Relative date event in the past:
|
|
105
|
+
{{_dateRel -7 unit="hour"}}
|
package/package.json
CHANGED
package/readme.md
CHANGED
|
@@ -28,16 +28,8 @@ If you use handlebars-i18n in a professional context, you could
|
|
|
28
28
|
|
|
29
29
|
## Install
|
|
30
30
|
|
|
31
|
-
If you use version npm >= 7:
|
|
32
|
-
|
|
33
|
-
```bash
|
|
34
|
-
$ npm i handlebars-i18n
|
|
35
|
-
```
|
|
36
|
-
|
|
37
|
-
For older versions do:
|
|
38
|
-
|
|
39
31
|
```bash
|
|
40
|
-
|
|
32
|
+
npm i handlebars-i18n
|
|
41
33
|
```
|
|
42
34
|
|
|
43
35
|
## Usage
|
|
@@ -147,7 +139,7 @@ Finally use in template:
|
|
|
147
139
|
|
|
148
140
|
* returns for "en" → **$1,200.99**
|
|
149
141
|
|
|
150
|
-
##
|
|
142
|
+
## Detailed examples
|
|
151
143
|
|
|
152
144
|
:point_right: See the *examples folder* in the repo for more use cases and details.
|
|
153
145
|
|
|
@@ -197,13 +189,9 @@ Template usage:
|
|
|
197
189
|
The i18next resource:
|
|
198
190
|
|
|
199
191
|
```javascript
|
|
200
|
-
"en"
|
|
201
|
-
:
|
|
202
|
-
{
|
|
192
|
+
"en" : {
|
|
203
193
|
translation : {
|
|
204
|
-
"whatIsWhat"
|
|
205
|
-
:
|
|
206
|
-
"{{a}} is {{b}}."
|
|
194
|
+
"whatIsWhat" : "{{a}} is {{b}}."
|
|
207
195
|
}
|
|
208
196
|
}
|
|
209
197
|
```
|
|
@@ -215,19 +203,12 @@ The i18next resource:
|
|
|
215
203
|
```
|
|
216
204
|
|
|
217
205
|
```javascript
|
|
218
|
-
"en"
|
|
219
|
-
:
|
|
220
|
-
{
|
|
206
|
+
"en" : {
|
|
221
207
|
translation : {
|
|
222
|
-
"keyWithCount"
|
|
223
|
-
|
|
224
|
-
"{{count}} item",
|
|
225
|
-
"keyWithCount_plural"
|
|
226
|
-
:
|
|
227
|
-
"{{count}} items"
|
|
208
|
+
"keyWithCount" : "{{count}} item",
|
|
209
|
+
"keyWithCount_plural" : "{{count}} items"
|
|
228
210
|
}
|
|
229
|
-
}
|
|
230
|
-
, ...
|
|
211
|
+
},
|
|
231
212
|
```
|
|
232
213
|
|
|
233
214
|
**Override globally selected language**
|
|
@@ -311,51 +292,67 @@ in [handlebars-i18n.d.ts](./dist/handlebars-i18n.d.ts).
|
|
|
311
292
|
|
|
312
293
|
---
|
|
313
294
|
|
|
314
|
-
###
|
|
295
|
+
### _dateAdd :tada: new in 1.8
|
|
315
296
|
|
|
316
|
-
|
|
297
|
+
Adds a time offset in a given unit to a date, returns the modified date.
|
|
317
298
|
|
|
318
299
|
```
|
|
319
|
-
{{
|
|
300
|
+
{{_dateAdd "1996-12-17" 24 unit="hour"}}
|
|
320
301
|
```
|
|
321
302
|
|
|
322
|
-
Will output for "en" → **
|
|
303
|
+
Will output for "en" → **12/18/1996**
|
|
304
|
+
|
|
305
|
+
The first argument is a date (see function **_date** for valid date inputs). The second argument is a time amount given
|
|
306
|
+
as number. The option **unit** specifies the time amount. Possible units
|
|
307
|
+
are `"second"` | `"minute"` | `"hour"` | `"day"` | `"week"` | `"month"` | `"quarter"` |`"year"` (default is `"hour"`).
|
|
308
|
+
Further options as for function **_date** can be applied.
|
|
309
|
+
|
|
310
|
+
---
|
|
311
|
+
|
|
312
|
+
### _dateDiff
|
|
313
|
+
|
|
314
|
+
Outputs the relative time difference between two given dates.
|
|
323
315
|
|
|
324
316
|
```
|
|
325
|
-
{{
|
|
317
|
+
{{_dateDiff "1996-12-17T00:00:00" "1995-12-17T00:00:00" unit="year"}}
|
|
326
318
|
```
|
|
327
319
|
|
|
328
|
-
Will output for "en" → **
|
|
320
|
+
Will output for "en" → **in 1 year**
|
|
329
321
|
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
see [Intl.RelativeTimeFormat Constructor](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/RelativeTimeFormat/RelativeTimeFormat).
|
|
334
|
-
Alternatively check this repo’s TS types
|
|
335
|
-
in [handlebars-i18n.d.ts](./dist/handlebars-i18n.d.ts).
|
|
322
|
+
The second date argument is subtracted from the first. If the difference is a positive value, a future event statement
|
|
323
|
+
is made. A negative value refers to a past date. (If no second argument is given, the default date is the present moment).
|
|
324
|
+
Allowed date input formats are similar to **_date**, options equal **_dateRel**. Default unit is `"hour"`.
|
|
336
325
|
|
|
337
326
|
---
|
|
338
327
|
|
|
339
|
-
###
|
|
328
|
+
### _dateRel
|
|
340
329
|
|
|
341
|
-
Outputs
|
|
330
|
+
Outputs a string with a relative date statement, formatted according to the language specific conventions.
|
|
342
331
|
|
|
343
332
|
```
|
|
344
|
-
{{
|
|
333
|
+
{{_dateRel 7 unit="hour"}}
|
|
345
334
|
```
|
|
346
335
|
|
|
347
|
-
Will output for "en" → **in
|
|
336
|
+
Will output for "en" → **in 7 hours**
|
|
348
337
|
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
338
|
+
```
|
|
339
|
+
{{_dateRel -7 unit="hour"}}
|
|
340
|
+
```
|
|
341
|
+
|
|
342
|
+
Will output for "en" → **7 hours ago**
|
|
343
|
+
|
|
344
|
+
A positive number argument leads to a future event statement, a negative refers to a past date. Possible units
|
|
345
|
+
are `"second"` | `"minute"` | `"hour"` | `"day"` | `"week"` | `"month"` | `"quarter"` |`"year"` (default is `"hour"`).
|
|
346
|
+
For a complete set of options (such as `numberingSystem` or `localeMatcher`)
|
|
347
|
+
see [Intl.RelativeTimeFormat Constructor](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/RelativeTimeFormat/RelativeTimeFormat).
|
|
348
|
+
Alternatively check this repo’s TS types in [handlebars-i18n.d.ts](./dist/handlebars-i18n.d.ts).
|
|
352
349
|
|
|
353
350
|
---
|
|
354
351
|
|
|
355
352
|
### _num
|
|
356
353
|
|
|
357
|
-
Outputs a formatted number according to the language specific conventions of number representation, e.g.
|
|
358
|
-
|
|
354
|
+
Outputs a formatted number according to the language specific conventions of number representation, e.g.
|
|
355
|
+
**4,100,000.8314** for "**en**", but **4.100.000,8314** for "**de**".
|
|
359
356
|
|
|
360
357
|
```
|
|
361
358
|
{{_num 4100000.8314 }}
|
|
@@ -378,8 +375,8 @@ Will output **3.14** for "**en**", but **3,14** for "**de**".
|
|
|
378
375
|
|
|
379
376
|
### _price
|
|
380
377
|
|
|
381
|
-
Outputs a formatted currency string according to the language specific conventions of price representation, e.g.
|
|
382
|
-
|
|
378
|
+
Outputs a formatted currency string according to the language specific conventions of price representation, e.g.
|
|
379
|
+
**€9,999.99** for "**en**", but **9.999,99 €** for "**de**".
|
|
383
380
|
|
|
384
381
|
```
|
|
385
382
|
{{_price 9999.99}}
|
|
@@ -451,6 +448,8 @@ Call a subset in template with the parameter format="custom-name", like:
|
|
|
451
448
|
{{_date myDate format="year-only"}}
|
|
452
449
|
```
|
|
453
450
|
|
|
451
|
+
Subsets must be defined per language, a subset for "all" is invalid.
|
|
452
|
+
|
|
454
453
|
### The lookup cascade
|
|
455
454
|
|
|
456
455
|
The general lookup cascade is:
|