Ne vous souciez plus de la target dans vos liens
Pour les personnes en charge de l'édition de contenu, remplir des liens est souvent source de problème car, là où la page des termes et conditions avaient toujours été une page interne au site, la voilà devenu un fichier PDF ou une page plus globale hébergée sur un autre site web ; ce qui demande l'ouverture d'un nouvel onglet pour s'afficher. Et le pire dans tout cela, c'est que c'est juste pour la version du site en Vulcain ! Il va donc falloir laisser ces mêmes personnes gérer eux-mêmes la propriété target ou...
...utiliser un script intelligent qui va ajouter les target="_blank" là ou ils sont nécessaires !
Cela est également très pratique quand on rédige ses pages en Markdown.
Un peu d'histoire
Le fameux attribut target="_blank" que l'on utilise pour ouvrir une fenêtre dans un nouvel onglet à toujours été une petite source de conflit. Très utilisé lors de l'époque du HTML4, il a été boudée un certain temps durant la période xHTML car non valide. La bataille a donc fait rage entre :
- ceux ne faisant que peu de cas des standards,
- ceux affirmant que c'était à l'utilisateur de décider dans quel onglet ouvrir le lien (sans que ce même utilisateur ne sache comment faire), et
- ceux faisant appel au JavaScript pour passer les validations...
Aujourd'hui de l'eau a été mis dans le vin puisque à l'heure du HTML5, la balise target est de nouveau autorisée.
Smart Target Injection
Explication
Voilà les règles établies pour savoir si un lien doit être ouvert dans un nouvel onglet, ou dans l'onglet courant : Si le lien a déjà l'attribut target de défini (à _blank, _self ou autre), on ne touche à rien, mais si cet attribut est absent alors :
- si le lien pointe sur un nom de domaine différent, on ouvre la page dans un nouvel onglet
- si le lien pointe sur notre site web, deux cas :
- si c'est une page web on l'ouvre dans le même onglet,
- si c'est un média/fichier (.pdf, .jpg, .png, .js, .mp4, etc.) on l'ouvre dans un nouvel onglet.
Code jQuery
Voici le petit code jQuery qui va faire cela. Si vous n'aimez pas jQuery, je vous propose une version de ce code en JavaScript natif plus bas et si vous voulez que vos target ne soient pas ajoutées côté client en JavaScript, vous pouvez toujours utiliser NodeAtlas !
/*
* Pour tous les liens de la page courante...
*/
$(document.links).filter(function() {
/*
* ...garder ceux qui n'on pas déjà une `target` dans les attributs...
*/
return !this.target;
}).filter(function() {
/*
* ...et garder les pages qui ne sont pas sur le nom de domaine courant...
*/
return this.hostname !== window.location.hostname ||
/*
* ...ou qui ne sont pas des pages web (.pdf, .jpg, .png, .js, .mp4, etc.).
*/
/\.(?!html?)([a-z]{0,3}|[a-zt]{0,4})$/.test(this.pathname);
/*
* Pour toutes les pages conservées, ajouter l'attribut `target="_blank"`.
*/
}).attr('target', '_blank');
À propos de la RegExp
Vous pouvez comprendre la RegExp utilisée ligne 17 sur cette page explicative.
Il est également bon de noter que dans ce code, seules les extensions .html et .htm s'ouvre dans l'onglet courant. Vous pouvez ajouter des extensions comme cela :
\.(?!html?|aspx?|php3?)([a-z]{0,3}|[a-zt]{0,4})$
ici les pages de type .htm, .html, .php, .php3, .asp et .aspx s'ouvrirons dans le même onglet.
Petit jeu de test
Voici une liste de lien à tester. Sachez que de mon côté, je les ai écris en Markdown ([Accueil relative « ./ »](./)) et que je ne me suis absolument pas soucié de la target (devinez comment ?!).
- Accueil relative « ./ » (page courante)
- Page actuelle relative « ./ne-vous-souciez-plus-de-la-target-dans-vos-liens/ » (page courante)
- Une image du site relative « ./media/images/bw-author.png » (nouvel onglet)
- Le flux RSS du site relatif « ./feeds/articles.xml » (nouvel onglet)
- Un lien relatif sans extension « ./non-exsitante-page » (page courante)
- Un lien relatif avec .htm « ./non-exsitante-page.htm » (page courante)
- Un lien relatif avec .html « ./non-exsitante-page.html » (page courante)
- Accueil absolue « https://blog.lesieur.name/ » (page courante)
- Page actuelle absolue « https://blog.lesieur.name/ne-vous-souciez-plus-de-la-target-dans-vos-liens/ » (page courante)
- Une image du site absolue « https://blog.lesieur.name/media/images/bw-author.png » (nouvel onglet)
- Le flux RSS du site absolue « https://blog.lesieur.name/feeds/articles.xml » (nouvel onglet)
- Page nouvel onglet « https://www.lesieur.name » (nouvel onglet)
- Image nouvel onglet « http://fc08.dev{...}d5k2le2.jpg » (nouvel onglet)
- Image manuellement définie à target="_self" « http://fc08.dev{...}d5k2le2.jpg » (page courante)
- Accueil manuellement définie à target="_blank" « ./ » (nouvel onglet)
Code purement JavaScript
Si vous n'utilisez pas jQuery, voici le code :
var links = document.links;
for (var i = 0, linksLength = links.length; i < linksLength; i++) {
if (!links[i].target) {
if (
links[i].hostname !== window.location.hostname ||
/\.(?!html?)([a-z]{0,3}|[a-zt]{0,4})$/.test(links[i].pathname)
) {
links[i].target = '_blank';
}
}
}