linguistic
v0.1.0
Published
A very tiny library to translate your application based on its DOM with ease.
Downloads
3
Maintainers
Readme
linguistic.js
A tiny, modular, dependency-free library to translate your web application on demand using the DOM as reference.
Getting started
Installing
npm install linguistic
Or you can use a script from the build/
folder.
Note: linguistic.js is compatible with CommonJS, AMD or window invokation.
Usage
linguistic is designed based on modularity thinking. It is unobtrusive and let you decide what convention you want to follow.
That being said, its flow is basically divided in four fragments, which are:
- A dictionary. It is responsible to read a physical element and pull a text into it;
- A dictionaries collection. It is responsible to route which dictionary will be used for which language;
- A handler. It is responsible to handle the dictionaries;
- A translator. It is responsible to, with the correct dictionaries, translate your application on demand.
Maybe you're scared, huh? But don't be — it's easier than you think. See the following example:
var linguistic = require ('linguistic');
var pt = {
'h1': 'Olá, mundo!',
'h3': 'Como você está?'
};
var en = {
'h1': 'Hello, world!',
'h3': 'How do you do?'
};
var dictionaries = {
'pt-BR': pt,
'en-US': en
};
linguistic.handle(dictionaries).translate();
Looking deeper:
pt
is adictionary
for portuguese language (JavaScript object);en
is adictionary
for english language (JavaScript object);dictionaries
is adictionary
of languages (JavaScript object);
This will work based on a HTML like this:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Linguisticjs Markup Demonstration</title>
</head>
<body>
<h1>Bonjour le monde !</h1>
<h3>Comment ça va ?</h3>
</body>
</html>
How does linguistic.js decide when to use pt-BR
or en-US
?
Under the hood, it uses navigator.language
as its first criteria. In other words, it is primarily based on client's browser language. If you want to apply your own logic to handle the language that linguistic.js must to consider, feel free to do it through .interpret()
method, such as:
linguistic
.interpret('pt-BR')
.handle(dictionaries)
.translate();
Of course, the example above is flat and probably you won't apply it — but you can, for instance, make something sharper depending of your need, like extracting the locale from URL. Learn more further.
Injecting complexity to your translations
Having this markup as example:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Linguisticjs Markup Demonstration</title>
</head>
<body>
<h1>Bonjour le <span class="target"></span> !</h1>
<h3>Comment ça va ?</h3>
</body>
</html>
We can do:
var linguistic = require ('linguistic');
var names = [];
function getRandom (matrix) {
return matrix[Math.floor(Math.random() * matrix.length)];
};
var en = {
'h1 span.target': function () {
names = ['world', 'ninja'];
return 'Hello, ' + getRandom(names) + '!';
},
'h3': 'How do you do?'
};
var pt = {
'h1 span.target': function () {
names = ['mundo', 'ninja'];
return 'Olá, ' + getRandom(names) + '!';
},
'h3': 'Como você está?'
};
var dictionaries = {
'en-US': en,
'pt-BR': pt
};
linguistic.handle(dictionaries).translate();
You see? It's possible to use any element you want to get its string translated, also you are not limited to use only strings in the values of your dictionaries — functions are here to make all the logic you need and/or want.
Dealing with pluralisation
There are two ways to work with pluralisations. The easy way:
var en = {
'.followers': [
5,
'No followers',
'One follower',
'%s followers'
]
};
Yes, simple as that: an array with four spaces!
- The very first value should be the number to assert quantity;
- The second value should to be wether the value is 0;
- The third value should to be wether the value is 1;
- The fourth value should to be wether the value is 2 or plus.
Or, if you want to implement your own logic:
var en = {
'.followers': function () {
var value = 5;
if (value === 0) {
return 'Nobody likes you. No followers.';
};
if (value === 1) {
return 'One follower';
};
if (value > 1) {
return value + ' followers';
};
if (value === 5) {
return '5ive followers';
};
}
};
Interface
.translate() : returns void
Applies a dictionary against the language the client is requesting.
linguistic.translate();
Wether the element doesn't exist in your markup, linguistic will leave it untouchable. In other words, with its default value.
Note: translate
method depends of a handled dictionary. See the next topic.
.handle(Object) : returns void
It handles a compatible dictionary based on the client's language — which can be pre-defined through .interpret()
or assuming the default criteria, that is navigator.language
property.
linguistic.handle(dictionaries);
.clientLanguage : is a string
Get the language linguistic is assuming to use.
linguistic.clientLanguage;
.handleLanguage() : returns void
Handle the language client is using.
linguistic.handleLanguage();
.setUsefulDictionary(Object) : returns void
It creates a usefulDictionary
that is the one to be currently used based on your client's need.
linguistic.setUsefulDictionary(dictionary);
.usefulDictionary : is an object
It is the property storing the dictionary in use. Basically, this is the chosen one to be applied into your client's interface based on his language.
linguistic.usefulDictionary;
.getTranslation(String) : returns string
It retrieves a specific translation based on a specified parameter.
linguistic.getTranslation('h1');
.parsePluralisation([Array]) : returns string
It will check for the very first value of its parameter (which is supposed to be an array) using isSingular()
or isPlural()
methods to determine wether string it should to return: [1] for emptiness; [2] for singular; [3] for plural.
var matrix = [
5,
'No followers',
'1 follower',
'%s followers'
];
linguistic.parsePluralisation(matrix); // returns '5 followers'
Note: %s
is the same thing (value) of the first ([0]
) position of your matrix. Only available to use in the fourth ([3]
) position.
.isSingular(Number) : returns boolean
Check wether a number is or isn't singular. 1
is singular and 0
returns false
.
linguistic.isSingular(1); // returns true
.isPlural(Number) : returns boolean
Check wether a number is or isn't plural. > 1
is plural and everything else returns false
.
linguistic.isPlural(3); // returns true
The concept behind
Making a decoupled application is a goal that lots of developers has nowadays. Linguistic.js has born with an optimistic purpose: make the way you translate your application more modular and decoupled — keeping in the front-end what belongs to it.
As you can see, it is minimalistic and very easy to inject into your architecture, no matter if you are using Backbone, Ember, Angular or Vanilla JavaScript — you can go seamlessly.
What's the point using DOM as reference?
Translating what your client sees isn't responsibility of the back end. Hence, everything people sees in a web application belongs to elements: <h1>
s, <p>
s, <div>
s, etc. So, why can't we use the DOM in our favor?
You can distribute your translations via an API, consume them via JavaScript and finally inject them into dictionaries to be rendered painlessly — all the hardwork belongs to linguistic and nobody else. Please, keep your focus on creating your HTML and translations — all other efforts are linguistic's!
Contributing guidelines
If you want to improve linguistic in any way, please read our CONTRIBUTING.md document.
Tests
To make the tests, we are using Facebook's Jest. To proceed, please clone:
git clone [email protected]:chiefGui/linguistic.js.git && cd linguistic.js
Then
npm install && npm test
And you're good to go! :-)
License
MIT © 2015