skolmer / es2015-i18n-tag Goto Github PK
View Code? Open in Web Editor NEWES2015 template literal tag for i18n and l10n (translation and internationalization)
Home Page: http://i18n-tag.kolmer.net
License: MIT License
ES2015 template literal tag for i18n and l10n (translation and internationalization)
Home Page: http://i18n-tag.kolmer.net
License: MIT License
Pluralisation rules vary between languages, e.g. in English, 0 is plural, 1 is singular, and 2+ are plural, but in French, 0 is singular. Plural rules should instead rely on defaults set in the locale.
I'm okay with continuing to use a nested template, for consistency of the pattern, but rather than simply relying on the count, it would be useful to have a method for checking if a pluralisation rule applies in the current locale. I've seen plural-translate functions in other implementations (e.g. gettext-based libs for PHP that say t2('You have %s apple', 'You have %s apples')
, but the nested approach gives a bit more flexibility without sacrificing readability.
How about:
import t, { isPlural } from 'es2015-i18n-tag';
const appleBasket = ['macintosh', 'red delicious', 'honeycrisp'];
foo(isPlural(appleBasket.length) ? t`You have ${appleBasket.length} apples in your basket.` : t`You have ${appleBasket.length} apple in your basket.`);
I've done a 500-string translation file in 17 languages with different translators, and for the most part this reading is very natural and they were able to understand which pluralisation form to use. It does get a bit sketchy for languages like Russian which can have 3 plural forms, of course. Perhaps isPlural
could return an int
, not a boolean
, which would by truthy enough that the basic ternary above would work, but leave the door open for higher plural forms.
This could be configurable for the singleton, so if they locale doesn't have the plurals available, you could override them.
Thoughts? I could get started on a PR on this right away since I have a project which needs to get some new translations up ASAP. I was looking at i18next before, but I found there approach to be very es5; I wrote a workalike to some translations functions a PHP app was using so they could share translations files ( https://github.com/jkoudys/janeswalk-web/blob/master/modules/janeswalk/utils/translate.js ), but I'd much rather support a lib that helps the community.
I've been struggling to get the i18n-tag-schema working to extract anything, but had a thought about using webpack to do this instead. It's an increasingly common pattern to simply apply a webpack loader via require
(or a transpiled import
, if that tickles your fancy) to build static assets, e.g. require('css!mystyle.css');
in your top-level app.js, which your webpack config would see and bundle up as a static asset. Since translations are yet another static asset, why not let them go in the pipe too?
Building it as a loader would abstract away decisions about building it into a gulp-task, auto-building, how to bundle it, etc., and all that complexity we have no reason to care about. It would also make it a lot easier to deal with different modules and loaders, since we could apply the loader after letting babel concat your modules together.
We'd probably want a couple loaders:
Thoughts?
Hi!
It seems like translate
function lacks of type safety. For instance the following code i18n.translate(null)
or i18n.translate(10)
produces error
TypeError: Cannot read property 'replace' of null
TypeError: str.replace is not a function
355 | // e.g. this._formatStrings('{0} {1}!', 'hello', 'world') == 'hello world!'
356 | _buildMessage(str, ...values) {
> 357 | return str.replace(/\${(\d)}/g, (_, index) => values[Number(index)])
358 | }
359 | }
360 |
I think it's not desired behaviour and this method should treat undefined/null as empty string and convert anything else to string. But of course this behaviour is discussable. I preprepared a PR based on that behaviour assumption.
@skolmer I got a feeling that this will be the next big thing in i18n ;) I would advise a small name change as es2015-i18n-tag is not very "cute". i18n-tag
would do, what do you think?
The idea is that ESLint could show warnings if a string is not translatable and provide autofixing to easily change the string into a tagged template literal.
ESLint prefer-template rule: https://github.com/eslint/eslint/blob/master/lib/rules/prefer-template.js
Codemod to replace concatenated strings by template literals: https://vramana.github.io/blog/2015/12/21/codemod-tutorial/
I found this library while looking for modern and easy ways of adding localization to my Node service. It's pretty much the only one which uses string tag functions and still supports standard variable replacements without inventing a new syntax. Brilliant! However, it doesn't seem to suite my use case as I'll have to handle multiple different translations in parallel, e.g. respond to parallel requests in different languages. Or maybe I just don't really understand how to use it?
I'm looking for something where I can instantiate multiple i18n
string tag functions, each with a different locale and string table. I thus forked this repo locally and built something that works more like this:
import { I18n } from "./i18";
const i18n = I18n.create({ locales: "de" });
console.log(i18n`Hello ${name}, you have ${amount}:c in your bank account.`);
// => Hallo Steffen, Sie haben US$ 1,250.33 auf Ihrem Bankkonto.
I feel this is a cleaner interface and better scoped. Would that be something to consider for a v2 of this lib? What are your thoughts about this?
As suggested in #3 we need an api to extend suffix functions for Strings, DateTime and Numbers.
I've noticed that es2015-i18n-tag does not properly localize dates on node V7.7.1. I'm not sure if it's related to node, but in the browser (chrome & chrome Canary) it works just fine with the same setup.
Setup:
i18nConfig({
locales: 'nl-NL',
number: {currency: 'EUR'},
translations: translations['nl-NL'] || {}
});
In the browser the expected output is for
i18n`${new Date()}:t(D)`
is "maandag 22 mei 2017", which is properly localized in the set locale. In Node v7.7.1 however, the output is till in English. Translating a string in node from my translations object works just fine, giving the suspicion the locale is properly set.
Hi,
it's possible to update the main field value in packages.json to be compatible with the import map system.
"main": "./dist/lib/index.js"
instead of
"main": "./dist/lib"
Branch | Build failing 🚨 |
---|---|
Dependency | eslint-plugin-import |
Current Version | 2.3.0 |
Type | devDependency |
This version is covered by your current version range and after updating it in your project the build failed.
As eslint-plugin-import is “only” a devDependency of this project it might not break production or downstream projects, but “only” your build or test tools – preventing new deploys or publishes.
I recommend you give this issue a high priority. I’m sure you can resolve this 💪
The new version differs by 10 commits.
44ca158
update utils changelog
a3728d7
bump eslint-module-utils to v2.1.0
3e29169
bump v2.4.0
ea9c92c
Merge pull request #737 from kevin940726/master
8f9b403
fix typos, enforce type of array of strings in allow option
95315e0
update CHANGELOG.md
28e1623
eslint-module-utils: filePath in parserOptions (#840)
2f690b4
update CI to build on Node 6+7 (#846)
7d41745
write doc, add two more tests
dedfb11
add allow glob for rule no-unassigned-import, fix #671
See the full diff
There is a collection of frequently asked questions and of course you may always ask my humans.
Your Greenkeeper Bot 🌴
latest package does not contain dist folder so load module failed.
# npm install es2015-i18n-tag
+ [email protected]
added 1 package from 1 contributor in 0.944s
# cd node_modules/es2015-i18n-tag/
# ls -lR
.:
total 272
-rw-r--r--. 1 root root 5268 Jan 19 22:15 benchmark.js
-rw-r--r--. 1 root root 0 Jan 19 22:15 CHANGELOG.md
-rw-r--r--. 1 root root 2528 Jan 19 22:15 CONTRIBUTING.md
-rw-r--r--. 1 root root 1081 Jan 19 22:15 LICENSE
-rw-r--r--. 1 root root 4469 Jan 20 14:00 package.json
-rw-r--r--. 1 root root 20006 Jan 19 22:15 README.md
-rw-r--r--. 1 root root 233307 Jan 19 22:15 yarn.lock
To see what happens to your code in Node.js 10, Greenkeeper has created a branch with the following changes:
.travis.yml
package.json
files, so that was left aloneIf you’re interested in upgrading this repo to Node.js 10, you can open a PR with these changes. Please note that this issue is just intended as a friendly reminder and the PR as a possible starting point for getting your code running on Node.js 10.
Greenkeeper has checked the engines
key in any package.json
file, the .nvmrc
file, and the .travis.yml
file, if present.
engines
was only updated if it defined a single version, not a range..nvmrc
was updated to Node.js 10.travis.yml
was only changed if there was a root-level node_js
that didn’t already include Node.js 10, such as node
or lts/*
. In this case, the new version was appended to the list. We didn’t touch job or matrix configurations because these tend to be quite specific and complex, and it’s difficult to infer what the intentions were.For many simpler .travis.yml
configurations, this PR should suffice as-is, but depending on what you’re doing it may require additional work or may not be applicable at all. We’re also aware that you may have good reasons to not update to Node.js 10, which is why this was sent as an issue and not a pull request. Feel free to delete it without comment, I’m a humble robot and won’t feel rejected 🤖
There is a collection of frequently asked questions. If those don’t help, you can always ask the humans behind Greenkeeper.
Your Greenkeeper Bot 🌴
Branch | Build failing 🚨 |
---|---|
Dependency | babel-loader |
Current Version | 6.4.0 |
Type | devDependency |
This version is covered by your current version range and after updating it in your project the build failed.
As babel-loader is “only” a devDependency of this project it might not break production or downstream projects, but “only” your build or test tools – preventing new deploys or publishes.
I recommend you give this issue a high priority. I’m sure you can resolve this 💪
There is a collection of frequently asked questions and of course you may always ask my humans.
Your Greenkeeper Bot 🌴
Typings should be changed to allow locals as an array
https://github.com/skolmer/es2015-i18n-tag/blob/master/lib/index.d.ts#L112
Hi!
I'm wondering, is it possible to use es2015-i18n-tag with dynamic key? For instance:
const translations = { KEY_FROM_TRANSLATION: 'translated string' }
i18nConfig({ locales: 'en', translations })
let key = 'KEY_FROM_TRANSLATION'
let translation = i18n`${key}`
will not work, because it will pass key
variable as param of template string. So do any official way to do this exists? Because right now I'm using following workaround:
let translation = i18n([key])
but maybe it worth to consider to have official simple function fallback? Because this issue also occurs with different template engines were tagged strings are not yet supported (Vue for instance) and this limit usage scope of this great project.
The current source is feature complete (and seems to be stable) but needs some testing to be released as 1.0. More testcases for es2015-i18n-tag and tooling are required.
Replace crlf
with lf
line endings for crossplatform translation support
Hi, Awesome project!
Would you consider supporting typescript? Since it provides template strings by default in the language it shouldn't be much work.
I noticed that you have a declaration file index.d.ts in your lib folder, but for typescript to find it you need to either have it in the root of the project, or have a "typings":"./dist/lib/index.d.ts" entry in your package.json. If you add that, typescript will pick up the types.
However even with that fixed, the typings for typescript are slightly wrong since in typescript a template string is of type "TemplateStringsArray" and the current declaration file expects strings.
Hi!
The latest release (1.4.0) introduced a new functionality "added type checks to localizers". And it's definitely a breaking change, because it breaks code like
const total = 6;
i18n`Up to ${total} integrations`
So at least it should be a major version change. But in my opinion the project shouldn't have this functionality at all, because what is wrong with this code? It's pretty straightforward, you can always use .toString()
implicitly, and after all it's a JavaScript, a language where you don't care about types and can spit on OOP 😄
We need better checks to assure that the release artifact is tested and part of the dist
output directory.
Branch | Build failing 🚨 |
---|---|
Dependency | jest |
Current Version | 19.0.0 |
Type | devDependency |
This version is covered by your current version range and after updating it in your project the build failed.
As jest is “only” a devDependency of this project it might not break production or downstream projects, but “only” your build or test tools – preventing new deploys or publishes.
I recommend you give this issue a high priority. I’m sure you can resolve this 💪
There is a collection of frequently asked questions and of course you may always ask my humans.
Your Greenkeeper Bot 🌴
following code raise exception "Cannot read property 'toLocaleString' of undefined "
const mayNullOrUndefined = null;
i18n`${mayNullOrUndefined}`
https://codesandbox.io/s/priceless-tdd-4nw3z
extract with "null" or "undefined" value for placeholder, which is normal template literal behavior.
It may work for detect bug, but unexpected in case the variable may take null/undefined value.
i18n`${mayNullOrUndefined || ""}`
I hate this...
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.