📜 ⬆️ ⬇️

L10n lines in applications (javascript)

image

As part of the study of the new standard, I stumbled upon the Tagged Template Literals , in Russian they often denounce string templates .
Abroad, it is advised to rename the tagged string literals , and in the meantime Template Literals interpolated string literals or simply interpoliterals . I love js party, where khalivar begin even because of the name features :)

What, where, why


Before we go directly to what I wanted to talk about from the title, a few words about the Template Literals .
Surely each of you have already tried them:
var text = `Now is the time for all good men to come to the aid of their country!`; console.log( text ); // Now is the time for all good men // to come to the aid of their // country! 


Their first coolness is that the text of such a literal can be written on several lines and he himself inserts the transition to a new line where necessary.
Of course, the second coolness is the ability to insert expressions into a literal, which greatly simplifies the construction of strings in which you want to insert a value.
Before ES6:
 var name = "Kyle"; var greeting = "Hello " + name + "!"; console.log( greeting ); // "Hello Kyle!" console.log( typeof greeting ); // "string" 

Solving a problem using Template Literals :
 var name = "Kyle"; var greeting = `Hello ${name}!`; console.log( greeting ); // "Hello Kyle!" console.log( typeof greeting ); // "string" 

Of course, it should be noted here that it is not possible to reuse this literal with a different value. Therefore, there is debate about naming. Where it would be more reasonable to call without using the word pattern , but interpolation , so as not to be misleading. This literal is similar to Immediately-Invoked Function Expression (IIFE) , it is immediately baked into a string. Therefore, to transfer it and reuse unfortunately there is no possibility:
 function foo(str) { var name = "foo"; console.log( str ); //name    str  str typeof 'string' } function bar() { var name = "bar"; foo( `Hello from ${name}!` ); } var name = "global"; bar(); 

As I wrote above, you can also insert the result of an expression into a string:
 function upper(s) { return s.toUpperCase(); } var who = "reader"; var text = `A very ${upper( "warm" )} welcome to all of you ${upper( `${who}s` )}!`; console.log( text ); // A very WARM welcome // to all of you READERS! 

')

Tagged Template Literals


And now the most interesting, consider with you the use of Tagged Template Literals :
 function foo(strings, ...values) { console.log( strings ); console.log( values ); } var desc = "awesome"; foo`Everything is ${desc}!`; // [ "Everything is ", "!"] // [ "awesome" ] 

In this case, tag foo , a kind of function call without (...) . Thus, we can process the string additionally.
As arguments, the foo function gets an array of strings that were around the ${desk} expression, and the actual values ​​of the expressions themselves.
With the help of such a sugar syntax, it is very easy to imagine the translation of strings:
 const greeting = lang`Hello ${ name }!` 

As for me it is much easier than - given that there are dynamic data in the line:
 const greeting = `${ lang('Hello') } ${ name }!` 

Or quite a tolerable example that you can often see:
 const greeting = lang('Hello') + name + '!'; 

Since we are getting the parsed string apart into functions, we will have to assemble it ourselves, with this, reduce will help:
 function lang(strings, ...values) { return strings.reduce( function(s,v,idx){ return s + (idx > 0 ? values[idx-1] : "") + v; }, "" ); } 

Add a call to the translation function and make the example a little more readable by getting this snippet:
 const lang = l = (strings, ...values) => strings.reduce((prevString, nextString, index) => prevString + (index > 0 ? values[index - 1] : '') + translate(nextString), ''); //  translate    :) 

Using:
 const name = ''; let greeting = lang`Hello ${ name }, how are you?`; //  greeting = l`Hello ${ name }, how are you?`; // ,  ? 

Another very useful example of converting numbers to US $:
 function dollabillsyall(strings, ...values) { return strings.reduce( function(s,v,idx){ if (idx > 0) { if (typeof values[idx-1] == "number") { // look, also using interpolated // string literals! s += `$${values[idx-1].toFixed( 2 )}`; } else { s += values[idx-1]; } } return s + v; }, "" ); } var amt1 = 11.99, amt2 = amt1 * 1.08, name = "Kyle"; var text = dollabillsyall `Thanks for your purchase, ${name}! Your product cost was ${amt1}, which with tax comes out to ${amt2}.` console.log( text ); // Thanks for your purchase, Kyle! Your // product cost was $11.99, which with tax // comes out to $12.95. 

As a matter of fact, the Tagged Template Literals post processing line has other applications, but this is beyond the scope of the topic, write in the comments if you have something to add :)
Source of inspiration:
github.com/getify/You-Dont-Know-JS/blob/master/es6%20%26%20beyond/ch2.md

UPD: thanks dotme
UPD1: thanks alip

UPD2: thanks frol
In addition, a context is often needed (so that “name” in some cases is translated as “name”, and in others - “name”), where you can add external information (gender {M / F}, number { singular / plural}, and so on and so on).

An interesting note about more advanced translation. In general, in the article I tried to show exactly sugar, and not the methods and approaches of translation, but I forgot to mention something:
 function bar() { return function foo(strings, ...values) { console.log( strings ); console.log( values ); } } const desc = 'OK'; bar()`Everything is ${desc}!`; 

The tag can be an expression that returns a function. Due to this, it is possible to pass any additional arguments:
 lang('ru')`Everything is ${desc}!`; // lang('name', 'number')`${name}'s team is about ${count}`; 

Source: https://habr.com/ru/post/279595/


All Articles