vue-i18n
vue-i18n copied to clipboard
Some characters are not allowed in translation keys
Hi, I'm currently dealing with generated translation keys (they come from database values), and some of them have some characters ([ ] ' ") that doesn't work as translation key.
The dot (.) character is used as a separator, but I haven't found any way to escape it to be used as part of a key.
vue & vue-i18n version
2.6.10 and 8.14.0
Reproduction Link
https://jsfiddle.net/67Lx3aqy/
What is Expected?
The keys with special characters ([ ] ' ") should be translated. Is there any way to escape dot characters to be used in keys?
What is actually happening?
The translation key is shown instead.
Hi, same problem here with @. The full key is something like keyPart1.@keyPart2.
Same here
Some special characters are used for features in vue-i18n. Maybe escaping is good to have. Could you tell what is a motivation to use such special chars with escaping, instead of just changing message key into safe one?
@exoego Hi, What I'm doing is to provide a human readable name for several sets of morphosyntactic tags. Tags can contain almost any Latin-1 character.
Sure, I can manually replace these special characters by others, but those characters may be used in other tags, which complicates this process.
When I know the list of tags in advance, I can use characters not present in the tagset to make the replacements, but this is not always true so I will have to use a more complicated approach. With escaping this process will be always the same with predictable rules.
Any news with escaping?
I have translations from json file with keys that contain dot . :
{
"MyApp.UI":{
"Screen1.Label1": "First label on first screen",
"Screen1.Label2": "Second label on first screen",
"Screen2.Label1": "First label on second screen",
...
}
}
That is loaded like :
import VueI18n from 'vue-i18n'
import En from './i18n-en.json'
const messages = {
en: En
}
const i18n = new VueI18n({
locale: 'en',
messages,
})
But $t('MyApp.UI.Screen1.Label1') don't display the text First label on first screen, but display the key MyApp.UI.Screen1.Label1.
A solution is to flat the object from json file :
import VueI18n from 'vue-i18n'
import En from './i18n-en.json'
const messages = {
en: flatObj(En)
}
const i18n = new VueI18n({
locale: 'en',
messages,
})
function flatObj(obj, newObj = {}, parentKey = '') {
for (const key in obj) {
const currKey = parentKey.length > 0 ? `${parentKey}.${key}` : key
if (typeof obj[key] === 'object') {
flatObj(obj[key], newObj, currKey)
} else {
newObj[currKey] = obj[key]
}
}
return newObj
}
But I wish that vue-i18n manage that case.
+1