Skip to content

Commit

Permalink
Merge e110662 into 995392d
Browse files Browse the repository at this point in the history
  • Loading branch information
mathiashsteffensen committed Jan 24, 2022
2 parents 995392d + e110662 commit 553ec75
Show file tree
Hide file tree
Showing 6 changed files with 163 additions and 7 deletions.
18 changes: 16 additions & 2 deletions README.md
Expand Up @@ -311,9 +311,11 @@ i18n.configure({
mustacheConfig: {
tags: ['{{', '}}'],
disable: false
}
})
},

// Parser can be any object that responds to .parse & .stringify
parser: JSON
})
```

The locale itself is gathered directly from the browser by header, cookie or query parameter depending on your setup.
Expand Down Expand Up @@ -376,6 +378,18 @@ i18n.configure({

**NOTE:** Enabling `staticCatalog` disables all other fs realated options such as `updateFiles`, `autoReload` and `syncFiles`

#### Some words on `parser` option

Instead of parsing all file contents as JSON, you can parse them as YAML or any other format you like
```js
const YAML = require('yaml')

i18n.configure({
extension: '.yml',
parser: YAML
})
```

### i18n.init()

When used as middleware in frameworks like express to setup the current environment for each loop. In contrast to configure the `i18n.init()` should be called within each request-response-cycle.
Expand Down
15 changes: 12 additions & 3 deletions i18n.js
Expand Up @@ -47,6 +47,7 @@ const i18n = function I18n(_OPTS = false) {
tags: ['{{', '}}'],
disable: false
}

let mustacheRegex
const pathsep = path.sep // ---> means win support will be available in node 0.8.x and above
let autoReload
Expand All @@ -70,6 +71,7 @@ const i18n = function I18n(_OPTS = false) {
let updateFiles
let syncFiles
let missingKeyFn
let parser

// public exports
const i18n = {}
Expand Down Expand Up @@ -178,6 +180,13 @@ const i18n = function I18n(_OPTS = false) {
missingKeyFn =
typeof opt.missingKeyFn === 'function' ? opt.missingKeyFn : missingKey

parser =
typeof opt.parser === 'object' &&
typeof opt.parser.parse === 'function' &&
typeof opt.parser.stringify === 'function'
? opt.parser
: JSON

// when missing locales we try to guess that from directory
opt.locales = opt.staticCatalog
? Object.keys(opt.staticCatalog)
Expand Down Expand Up @@ -1228,10 +1237,10 @@ const i18n = function I18n(_OPTS = false) {
const file = getStorageFilePath(locale)
try {
logDebug('read ' + file + ' for locale: ' + locale)
localeFile = fs.readFileSync(file)
localeFile = fs.readFileSync(file, 'utf-8')
try {
// parsing filecontents to locales[locale]
locales[locale] = JSON.parse(localeFile)
locales[locale] = parser.parse(localeFile)
} catch (parseError) {
logError(
'unable to parse locales from file (maybe ' +
Expand Down Expand Up @@ -1292,7 +1301,7 @@ const i18n = function I18n(_OPTS = false) {
tmp = target + '.tmp'
fs.writeFileSync(
tmp,
JSON.stringify(locales[locale], null, indent),
parser.stringify(locales[locale], null, indent),
'utf8'
)
stats = fs.statSync(tmp)
Expand Down
106 changes: 106 additions & 0 deletions locales/en.yml
@@ -0,0 +1,106 @@
Empty: ""
Hello: Hello
"Hello %s, how are you today?": Hello %s, how are you today?
weekend: weekend
"Hello %s, how are you today? How was your %s.": Hello %s, how are you today? How was your %s.
Hi: Hi
Howdy: Howdy
"%s cat":
one: "%s cat"
other: "%s cats"
"%f star":
one: "%f star"
other: "%f stars"
"%d star":
one: "%d star"
other: "%d stars"
"%s star":
one: "%s star"
other: "%s stars"
cat:
one: "%s cat"
other: "%s cats"
cats:
n:
one: "%s cat"
other: "%s cats"
nested:
deep:
plural:
one: plural
other: plurals
path:
sub: nested.path.sub
There is one monkey in the %%s:
one: There is one monkey in the %%s
other: There are %d monkeys in the %%s
tree: tree
There is one monkey in the %s:
one: There is one monkey in the %s
other: There are %d monkeys in the %s
There is one monkey in the tree:
one: There is one monkey in the tree
other: There are %d monkeys in the tree
plurals with intervals in string (no object): "[0] a zero rule|[2,5] two to five (included)|and a catchall rule"
plurals with intervals in _other_ missing _one_:
other: "[0] a zero rule|[2,5] two to five (included)|and a catchall rule"
plurals with intervals as string:
one: The default 'one' rule
other: "[0] a zero rule|[2,5] two to five (included)|and a catchall rule"
plurals with intervals as string (excluded):
one: The default 'one' rule
other: "[0] a zero rule|]2,5[ two to five (excluded)|and a catchall rule"
plurals in any order:
one: The default 'one' rule
other: "[0] a zero rule|and a catchall rule|[2,5] two to five (included)"
plurals to eternity: "[0,] this will last forever|but only gt 0"
plurals from eternity: "[,0] this was born long before|but only lt 0"
Hello %s: Hello %s
"Hello {{name}}": Hello {{name}}
"Hello {{name}}, how was your %s?": Hello {{name}}, how was your %s?
format:
date: MM/DD/YYYY
time: h:mm:ss a
greeting:
formal: Hello
informal: Hi
placeholder:
formal: Hello %s
informal: Hi %s
loud: greeting.placeholder.loud
plurals:
one: The default 'one' rule
other: "[0] a zero rule|[2,5] two to five (included)|and a catchall rule"
another:
nested:
extra:
deep:
example:
one: The default 'one' rule
other: "[0] a zero rule|[2,5] two to five (included)|and a catchall rule"
lazy:
example:
other: "[0] a zero rule|[2,5] two to five (included)|and a catchall rule"
mustache:
example: "[0] a zero rule for {{me}}|[2,5] two to five (included) for {{me}}|and
a catchall rule for {{me}}"
mustacheprintf:
example: "[0] %s is zero rule for {{me}}|[2,5] %s is between two and five
(included) for {{me}}|and a catchall rule for {{me}} to get my number
%s"
nested.deep.plural:
one: nested.deep.plural
other: 1
ordered arguments: "%2$s then %1$s"
ordered arguments with numbers: "%2$d then %1$s then %3$.2f"
repeated argument: "%1$s, %1$s, %1$s"
. is first character: Dot is first character
last character is .: last character is Dot
few sentences. with .: few sentences with Dot
"Hello {{{name}}}": Hello {{{name}}}
Standalone | 42 symbol somewhere | in the text | 1| 0: Standalone | 42 symbol somewhere | in the text | 1| 0
"should ignore\ \n standalone | mixed with\ \n new lines 42 | value - 42": |-
should ignore
standalone | mixed with
new lines 42 | value - 42
mftest: "In {lang} there {NUM, plural,one{is one for #}other{others for #}}"
5 changes: 3 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Expand Up @@ -52,6 +52,7 @@
"prettier": "^2.5.1",
"should": "^13.2.3",
"sinon": "^12.0.1",
"yaml": "^1.10.2",
"zombie": "^6.1.4"
},
"engines": {
Expand Down
25 changes: 25 additions & 0 deletions test/i18n.configureParser.js
@@ -0,0 +1,25 @@
const { I18n } = require('..')
const YAML = require('yaml')
require('should')

describe('configure parser', function () {
context('with YAML parser', function () {
const i18n = new I18n({
locales: ['en'],
extension: '.yml',
parser: YAML
})

it('should parse the locale files with the YAML parser', function () {
i18n.__('Hello').should.equal('Hello')
})

it('should write unknown keys to the catalog', function () {
i18n.__('does.not.exist')

const catalog = i18n.getCatalog()
catalog.should.have.property('en')
catalog.en.should.have.property('does.not.exist', 'does.not.exist')
})
})
})

0 comments on commit 553ec75

Please sign in to comment.