Comment utiliser les template strings / literals en JavaScript ?
May 13, 2019 -9 min de lecture
Photo by Tim Arterbury on Unsplash
ES6 a introduit en JavaScript une petite chose bien utile qui s’appelle les template literals ou template strings. Traduisez en français littéraux de gabarits selon MDN🤮. J’aurais personnellement traduit par « modèles textuels », mais c’est un choix purement personnel. Dans cet article, j’utiliserai la terminologie anglaise, car je trouve que la version française sonne horriblement mal et peut même engendrer des crises de vomissements aigus chez certaines personnes. Sincèrement, aucune envie de vomir sur mon clavier.
Que sont les template strings ?
Les template strings permettent d’insérer du code JavaScript dans n’importe quelle chaine de caractères. Ce code peut aller d’un simple nom de variable à afficher dans un texte à du code plus complexe avec des boucles et des conditions pour faire varier l’affichage selon divers paramètres.
Je vais vous donner une série d’exemples pour vous aider à comprendre, mais retenez ceci : les template strings remplacent la concaténation classique de JavaScript.
La concaténation en JavaScript (méthode poussiéreuse)
A noter que je vais délibérément utiliser var
pour déclarer mes variables pour insuffler un côté dépassé à cette méthode. C’est de la manipulation. Mais c’est mon côté commercial qui ressort par moments.
var person = {
name: 'Mathias',
country: 'france',
age: 28
}
var sentence = 'Je m\'appelle ' + person.name + 'et je vis en ' + person.country.toUpperCase() + 'depuis toujours. Soit plus ou moins ' + person.age 'ans.'
Pour une phrase toute bête, vous pouvez constater qu’il y a déjà beaucoup de '
qui viennent polluer le rythme l’écriture de cette variable . Ce n’est vraiment pas top. Heureusement, depuis ES6 (la spécification utilisée par JavaScript depuis 2015), il existe une autre méthode beaucoup plus simple et qui permet de faire des choses vraiment intéressantes en prime sans avoir à marteler la touche d’apostrophe comme un taré.
Oubliez cette concaténation poussiéreuse et dites bonjour aux template strings. Bienvenu en 2019.
Comment utiliser les template strings
Pour utiliser cette méthode, rien de plus simple, il vous faut faire deux choses.
- Utiliser des accents graves en lieu et place de vos apostrophes (simples ou doubles) pour encadrer votre chaine de caractères.
- Intégrer votre code JavaScript à l’intérieur d’un bloc de ce type :
${}
. Vous trouvez ça moche ? Vous allez vite changez d’avis, croyez-moi …
Transformons le code précédent dans une version actualisée de JavaScript.
const person = {
name: "Mathias",
country: "france",
age: 28,
}
const sentence = `Je m'appelle ${
person.name
} et je vis en ${person.country.toUpperCase()} depuis toujours. Soit plus ou moins ${
person.age
} ans.`
C’est tout de suite beaucoup plus lisible n’est-ce-pas ? Qui plus est, vous ne risquez pas d’oublier une apostrophe ou un signe plus dans votre chaine de caractères.
Pourquoi utiliser les template strings ?
Si vous n’êtes pas déjà convaincu, je vais vous montrer un certain nombre de raisons pour utiliser cette technique dès que vous en avez la possibilité.
Utiliser les template strings pour passer des blocs de HTML
Passer des blocs entiers de HTML n’aura jamais été aussi simple. Les template strings sont nativement compatibles avec les blocs multilignes. Vous pourrez alors passer votre code HTML comme si vous étiez dans votre page HTML, avec l’indentation qui va avec. Regardez plutôt :
const html = `
<div class="person">
<h2>
${person.name}
<span class="country">${person.country}</span>
</h2>
<p class="age">Le bougre n'a que : ${person.age} ans.</p>
</div>
`
Vous voyez comme c’est fluide ? Cela vous permet de passer du code structuré comme vous le souhaitez, sans vous soucier d’autre chose que de votre code.
Utiliser les template strings imbriqués pour faire des boucles en JavaScript
En JavaScript, vous devez parfois générer de manière dynamique un grand nombre d’éléments HTML. Dans ce cas on utilise des boucles pour éviter de répéter le même code encore et encore. Ce qui est merveilleux, c’est qu’on peut aussi le directement dans les template strings !
const users = [
{ name: 'Bob', points: 67 },
{ name: 'Bobby', points: 889 },
{ name: 'Bobo', points: 123 }
{ name: 'Bobet', points: 45 },
{ name: 'Bibet', points: 345 },
{ name: 'Bolet', points: 23 }
];
const html = `
<ul class="users">
${users.map(user => `
<li>${user.name} a ${user.points} points</li>`).join('')}
</ul>
`;
document.body.innerHTML = html;
🧐 La chose la plus importante à comprendre ici c’est qu’il est possible d’imbriquer plusieurs template strings les uns dans les autres en utilisant des accents graves. C’est ce qui nous permet d’effectuer des traitements plus complexes que d’afficher une simple phrase. Dans le cas présent on peut créer une boucle en se servant de la méthode .map()
afin d’afficher la liste de tous les utilisateurs sans devoir taper chaque ligne une à une.
Plutôt pratique non ?
Utiliser des conditions dans des template strings
Comme il est possible d’intégrer du code JavaScript dans les template strings, il est tout à fait possible d’y intégrer des conditions simples en utilisant l’opérateur ternaire. Si vous ne savez pas ce qu’est un opérateur ternaire (ternary operator) il s’agit d’une méthode pour écrire une condition en une seule ligne au lieu d’écrire un if - else
classique. Très utile pour des conditions simples comme celle que nous allons voir.
const user = {
name: "Franck",
isModerator: true,
}
const html = `
<div class="user">
<p>
${user.name} - ${user.isModerator ? `(Modérateur)` : ""}
</p>
</div>
`
document.body.innerHTML = markup
Ainsi, dans le cas présent, les template string nous permettent de vérifier directement si un utilisateur est un modérateur pour afficher leur rôle entre parenthèses à côté de leur nom. Si l’utilisateur n’est pas modérateur, nous n’afficherons rien. Cool !
Comment utiliser les tagged template literals
Parlons maintenant d’un concept un peu plus compliqué : les tagged template strings. Ce concept vous permet d’utiliser une fonction avec un template literal. Je dis bien avec et pas dans. Vous pouvez tout à fait insérer n’importe quel code JavaScript dans vos template strings comme nous l’avons vu plus haut.
L’idée est ici que la fonction va fonctionner main dans la main avec le template string (car oui une fonction fonctionne, mais ne marche pas. Je pense que nous sommes tous d’accord avec ce principe fondamental 😅).
Cela va se passer en plusieurs étapes.
- La première étape est que votre template string va passer toutes ses valeurs à la fonction.
- La fonction va s’occuper d’assembler les morceaux et faire un peu ce que vous voulez avec le template string que vous aviez au départ.
- Le traitement fini, la fonction va retourner la valeur obtenue lors du traitement. Valeur qui prendra la place du template.
Voici un exemple concret qui permet de mettre en valeur les données saisies par l’utilisateur avec une balise <strong>
à l’aide d’un tagged template literal.
function userInput(strings, ...values) {
let taggedTemplateString = ""
strings.forEach((string, i) => {
taggedTemplateString += `${string} <strong>${values[i] || ""}</strong>`
})
return taggedTemplateString
}
const person = {
name: "Mathias",
country: "france",
age: 28,
}
const sentence = userInput`Si j'ai bien compris, votre nom est : ${
person.name
}, vous vivez en ${person.country.toUpperCase()} et vous avez ${
person.age
} ans ?`
document.body.innerHTML = sentence
Si vous débutez en JavaScript, ne prenez pas peur, ce code qui a l’air un peu compliqué pour faire une chose très simple n’est en fait pas si terrible quand on le prend morceau par morceau.
function userInput(strings, ...values)
strings
correspond à un array contenant toutes les parties continues du template qui sont fixes comme « si j’ai bien compris, votre nom est : ». Dès que la fonction rencontre une valeur ${}
, cela crée un nouvelle entrée dans l’array et ainsi de suite, jusqu’à arriver à la fin de la chaine de caractères.
Dans le cas présent il se compose comme ça :
- Si j’ai bien compris, votre nom est :
- , vous vivez en
- et vous avez
- ans ?
Chaque entrée comprend les espaces de la chaine d’origine de sorte que vous n’ayez pas en vous en soucier pour formater votre texte.
values
comprend toutes les valeurs dynamiques sous forme d’array également. Ce sont toutes les valeurs contenues dans ${}
. Voici ce qu’il contient dans notre cas :
person.name
person.country.toUpperCase()
person.age
...
C’est ce qu’on appelle l’opérateur « rest ». Cela permet d’indiquer à la fonction de prendre tout le reste des valeurs de la fonction sans devoir les spécifier une à une sous la forme de value1, value2, value3, value4
. Ainsi peu importe le nombre de valeurs à passer, elles seront toutes dans votre fonction. Ça c’est vraiment pratique pas vrai ? Taper 100 fois la même chose, très peu pour moi ! 😉
On utilise ensuite une boucle forEach
pour parcourir chaque entrée et effectuer le traitement que nous souhaitions, à savoir rajouter une balise <strong>
.
Petite précision cependant sur cette partie du code : ${values[i] || ''}
. C’est une expression qui permet de gérer une condition toute bête sans devoir l’écrire sous la forme if - else
. Ce la signifie que si values[i]
existe, on l’affiche. || ''
ou, si elle n’existe pas, nous insérons une chaine de caractère vide.
Pourquoi prendre cette précaution ? Vous n’avez peut-être pas fait attention, mais l’arrêt strings
comporte 4 entrées alors que values
n’en comprend que 3. Si nous n’avions pas intégré cette petite condition, nous aurions vu apparaître un joli undefined
dans l’affichage final pour values[3]
. Ce qui aurait été nul (dans le sens pourri). Et nous, on aime pas les trucs nuls pas vrai ? 😆
Les tagged template strings c’est vraiment utile ?
Certains diront que ça fait beaucoup de code alors que nous aurions tout simplement pu mettre des balises <strong></strong>
autour de chaque variable dans notre template. C’est complètement vrai. Mais l’intérêt de procéder de la sorte est que nous respectons le principe DRY. Don’t Reapt Yourself. Ne pas se répéter est la clé de voute du développement. Vous pouvez écrire des milliers de lignes en plus, mais au moins vous ne vous répétez pas. C’est le principal 😅.
Blague à part, cela permet non seulement d’avoir un code plus propre et réutilisable à volonté dans l’intégralité de votre application, mais ça le rend aussi plus simple à maintenir. Ainsi dans notre cas si vous vous rendez compte que vous souhaiteriez mettre des <span>
pour faire une mise en forme spécifique en CSS, vous pouvez le faire dans la fonction userInput
et tout code qui utilise cette fonction sera impacté. Pas besoin de mettre à jour manuellement la centaine de balises que vous aviez insérées manuellement dans chaque chaine de caractère.
Utiliser les Tagged Template literals pour traduire vos variables
Dernier exemple pour la route de l’utilisation des Tagged Template strings. Vous pouvez vous en servir pour traduire vos template strings dans différentes langues avec la librairie : es2015-i18n-tag.
const name = 'Steffen';
const amount = 1250.33;
const date = new Date(2019, 05, 10, 19, 0, 0);
const blaBla = i18n`Hello ${name}, you have ${amount} :c(EUR) in your bank account. Nous sommes le : ${date}`);
Selon la configuration que vous aurez faite de la fonction i18n
, vous verrez apparaître dans le résultat final la version traduite de votre variable. Dingue non ? Voilà qui peut être bien pratique si vous aviez pour projet d’internationaliser votre application/site internet. Le tout est de configurer la chose convenablement en suivant la documentation de la librairie que vous trouverez en suivant le lien plus haut.
En conclusion
Pour conclure, j’espère que vous avez été subjugués par la puissance de ces template strings. J’espère que cette pratique intégrera rapidement vos codes si ce n’est pas déjà le cas et que vous avez pu découvrir l’intérêt des tagged template literals qui paraissent souvent mystérieux et restent souvent dans un coin de notre tête sans que nous fassions l’effort de les utiliser.
Trêve de bavardages, je retourne geeker le code moi 😉