Quantcast
Channel: Alsacreations.com - Apprendre
Viewing all 405 articles
Browse latest View live

Tutoriel : Traduire vos extensions WordPress

$
0
0

Pour ce dernier article de 2021 (et pour ne pas vous prendre trop de temps pendant les préparatifs des fêtes de fin d'année 😉), voici un complément au sujet précédent, qui portera cette fois sur l'internationalisation des extensions dans l'écosystème de WordPress.

⚠ Si vous ne l'avez pas déjà fait, nous vous invitons vraiment à lire l'article Préparer un thème WordPress pour l'internationalisation. Les outils et concepts sont les mêmes pour les thèmes et les extensions et nous ne les réexpliquerons pas ici.

Les extensions indispensables

On commence directement avec un petit cas particulier.

Utilisez-vous les mu-plugins (Must-Use plugins) ?

Ces extensions un peu spéciales sont toujours activées et ne peuvent pas être désactivées autrement qu'en supprimant leurs fichiers sources (vous pouvez les retrouver dans la section "Indispensables" de l'administration des extensions). Pratique pour éviter les erreurs humaines, comme une suppression maladroite par exemple... 🤫

Sans rentrer dans les détails, il est tout à fait possible d'y inclure des textes et il faut donc penser à les rendre traduisibles. Pour se faire, utilisez la fonction load_muplugin_textdomain de la manière suivante :

/**
 * Chargement des fichiers de traductions dans le dossier /lang
 */
function load_translations() {
  load_muplugin_textdomain( 'textdomain', 'lang' );
}
add_action( 'muplugins_loaded', 'load_translations' );

Ici, on part du principe qu'un dossier /lang a été rajouté au dossier mu-plugins de WordPress.

On utilise le hook muplugins_loaded pour que les traductions soient chargées le plus tard possible, de la même manière que l'on utilise after_setup_theme pour charger les fichiers de traductions d'un thème.

Si vous voulez en apprendre davantage sur les mu-plugins, consultez l'article Connaissez-vous les MU Plugins de WordPress ? qui explique les bases et donne des exemples concrets de cas d'utilisation.

Et pour les extensions plus classiques ?

Avant de nous lancer dans le coeur du sujet, commençons par quelques rappels de conventions et conseils de base.

1/ Toutes les chaines de caractères doivent être accompagnées d'un domaine de traductions.

Seul le coeur de WordPress utilise des traductions du type __( 'Settings' ) et même s'il peut être tentant de réutiliser ces chaines si votre extension les partage, il n'est pas impossible qu'une une mise à jour les change, rendant ainsi votre chaîne intraduisble.

2/ Les textes à traduire doivent avoir un sens et un contexte.

Évitez de faire de la concaténation de mots et préférez des phrases entières.

3/ N'utilisez pas de variables directement dans des appels à __().

Si besoin d'insérer du HTML ou des données, entourez vos fonctions de printf ou sprintf pour pouvoir utiliser des placeholders selon ce genre de modèle

sprintf(
  __( 'Bonjour %s', 'textdomain' ),
  $username
);

4/ N'oubliez pas de renseigner les commentaires d'entêtes de votre extension !

/*
 * Plugin Name: Mon extension à moi !
 * Author: (La loi) C'est moi !
 * Text Domain: text-domain
 * Domain Path: /lang
 */

Les 2 informations qui nous intéressent ici sont Text Domain et Domain Path (notez bien les majuscules, elles sont importantes).
Elles permettent respectivement d'indiquer à WordPress votre domaine de traduction ainsi que l'emplacement de vos fichiers de traductions et ce, même si votre extension est désactivée !

Ce ne sont évidemment pas les seuls points de vigilance, mais s'attarder davantage ici ne ferait que paraphraser la documentation officielle, qui est déjà bien assez complète.

Maintenant que ces quelques détails ont été abordés, nous pouvons enfin passer au chargement de vos précieuses traductions ! 😉 L'avantage est que la procédure reste exactement la même. Seule la fonction utilisée change.

/**
 * Chargement des fichiers de traductions dans le dossier /lang
 */
function load_translations() {
  load_plugin_textdomain( 'textdomain', false, dirname( plugin_basename( __FILE__ ) ) . '/lang' );
}
add_action( 'init', 'load_translations' );

On évitera d'utiliser le hook plugins_loaded, qui arrive trop tôt dans le cycle de vie de WordPress et pourrait créer des conflits avec les traitements appliqués par d'autres scripts.

Note : Depuis WordPress 4.6, load_muplugin_textdomain et load_plugin_textdomain tenteront d'abord de charger les fichiers de traductions depuis le dossier /languages de WordPress, donc si vous le voulez, vous pouvez les y mettre directement.

Utiliser des traductions dans des fichiers JavaScript

Vous savez dorénavant comment utiliser vos fichiers .po et .mo dans vos extensions. Il ne nous reste donc qu'un dernier sujet à couvrir : comment utiliser vos traductions dans vos fichiers JS.

Fort heureusement, WordPress met à disposition une fonction à cet effet répondant au doux nom de wp_localize_script et dont les 3 paramètres (tous requis) sont les suivants :

  1. $handle, qui correspond au nom donné au script auquel vous souhaitez transmettre des chaines de caractères (le "nom" du script fait référence au premier paramètre des fonctions wp_register_script ou wp_enqueue_script).
  2. $object_name. Tout simplement le nom de la variable JS qui sera injectée par WordPress.
  3. $l10n, un tableau clé/valeur des traductions que vous voulez rendre disponibles dans votre fichier JS.

Voici un exemple de code pour un script nommé script-kiwi auquel on voudrait passer plusieurs traductions.

/**
 * Chargement des scripts de l'extension
 */
function plugin_scripts() {
  wp_enqueue_script( 'script-kiwi', ... );
  wp_localize_script( 'script-kiwi', 'mon_super_objet',
    array( 
      'chaine_1' => __( 'Ma super traduction', 'textdomain' ),
      'chaine_2' => __( 'Mon autre super traduction', 'textdomain' ),
      'chaine_3' => __( 'Une traduction encore mieux que les autres', 'textdomain' ),
    )
  );
}
add_action( 'wp_enqueue_scripts', 'plugin_scripts' );

Et voilà ! 🎉

Dorénavant, WordPress mettra à disposition une variable globale mon_super_objet que l'on peut utiliser comme un objet JavaScript standard pour en extraire les propriétés. Ainsi, mon_super_objet.chaine_1 affichera la chaine "Ma super traduction" dans la langue souhaitée.

Cette fonction ne peut être utilisée que si votre script a déjà été ajouté via wp_register_script ou wp_enqueue_script.

Un dernier pour la route

Le dernier point de vigilance auquel prêter attention est la mise à jour de vos propres extensions.

Il est assez fréquent de faire évoluer ses extensions pour y inclure de nouvelles fonctionnalités, refactoriser du code qui commence à se faire vieux ou plus simplement rajouter des commentaires pour expliquer à quoi sert la fonction doEverything() de votre extension maison.

Tous ces exemples ont en commun que l'emplacement physique de vos chaines de traductions (les lignes dans votre fichier) peut ne plus être le même en passant de la version X à la version Y et si vous ne régénérez pas vos fichiers .pot, .po et .mo, vous courrez droit à la catastrophe !

Un exemple bien senti venant directement du fichier .po de Polylang.

#: modules/wizard/view-wizard-step-last.php:26
#: modules/wizard/view-wizard-step-last.php:44
msgid "Read documentation"
msgstr "Lire la documentation"

Les nombres en fin de ligne correspondent à la ligne du fichier dans lequel on retrouve la chaine en question. A partir de là, il est facile de comprendre que si une chaine bouge, elle ne sera plus reconnue, ce qui serait dommage après tous ces efforts.

Pour cela, une règle simple : si une chaine change de ligne, il faut le refléter dans vos fichiers de traductions.

Conclusion

Comme promis, rien de bien méchant si vous avez survécu à la lecture du premier article.

Maintenant, vous n'avez plus aucune excuse pour ne pas internationaliser tout ce qui bouge dans vos développements WordPress !

Bonnes fêtes de fin d'année à toutes et tous ! 🎅🎄

Retrouvez l'intégralité de ce tutoriel en ligne sur Alsacreations.com


Article : Le modèle de conception ARIA Disclosure

$
0
0

Bonjour à toutes et à tous ! 🙂

Chez Alsacréations (.com et .fr 😉), l'année 2022 sera résolument placée sous le signe de l'accessibilité et cela commence par le premier épisode de notre nouvelle série dédiée aux modèles de conception (Design Patterns chez la Reine Elisabeth) ARIA.

Pour démarrer en douceur avec quelque chose d'abordable et de facile à mettre en place, nous allons découvrir dans un premier temps le modèle de conception Disclosure.

Définition

Impossible de commencer cette série sans préciser ce que sont ces fameux modèles de conception !

En clair, il s'agit de l'ensemble des règles et principes qui régissent la création de composants accessibles dont le but est de garantir leur utilisabilité par le plus grand nombre.

Cela couvre un large panel de fonctionnalités allant de la fenêtre modale à une arborescence de dossiers, en passant par nos vieilles <table> ou encore un simple bouton (qui, on le verra, n'est pas toujours aussi simple que l'on peut le penser).

Le concept du jour: Disclosure

Comme indiqué plus haut, le modèle que nous allons évoquer aujourd'hui se nomme Disclosure.

Sous ce nom un peu obscur au premier abord se cache quelque chose de plutôt commun puisqu'il s'agit d'un bouton permettant d'afficher ou de cacher un contenu défini.

Rien de bien sorcier n'est-ce pas ?

Pourtant, les utilisateurs de technologies d'assistance peuvent passer à côté d'informations importantes ou même de fonctionnalités entières, selon ce que vous décidez de cacher derrière ces boutons.

Comment ça s'utilise ?

Rassurez-vous, c'est de loin le modèle de conception le plus abordable et qui demandera le moins d'adaptations du code existant.

Pour cela, nous utiliserons seulement 2 attributs ARIA:

Le rôle du premier est d'indiquer, via une valeur booléenne (true ou false) l'état dans lequel se trouve l'élément qui est contrôlé par le bouton. Le second permet de relier ce dernier à l'élément qu'il contrôle via un attribut id HTML.

Si aria-controls est indiqué comme optionnel dans la documentation, il est tout de même fortement recommandé.

Voici un exemple de mise en place:

<button type="button" aria-controls="expandable" aria-expanded="false">
  Montrer le contenu
</button>

<div id="expandable">
  Contenu caché !
</div>

Et voilà, c'est tout pour la partie HTML ! Un id sur le contenu que vous souhaitez contrôler et 2 attributs sur votre bouton et le modèle est prêt !

Bon, ce n'est pas tout à fait vrai.
Il reste quelques lignes de Javascript à ajouter pour rendre le tout dynamique (gestion du clic, bascule true/false de l'attribut aria-expanded et changement du texte du bouton pour refléter l'état du contenu.).

Voici une démo plus complète qui vous permettra de voir le tout en action.

Mais à quoi ça peut servir dans la vraie vie ?

On peut légitimement se demander quels peuvent être les cas d'utilisation de Disclosure. En vérité, vous l'avez très certainement déjà rencontré sans y attacher beaucoup d'importance.

Pourtant, qui n'a jamais vu une FAQ déroulante ou un menu qui fait apparaitre ses enfants au clic (et pas qu'au survol hein, on parle d'accessibilité ici 😉) ?

À ces exemples, même si plus souvent gérés uniquement avec du Javascript et sans le petit zeste d'accessibilité qui ferait la différence, on peut rajouter l'ajout d'une description détaillée pour des images, tableaux ou autres contenus touffus qui pourraient être synthétisés dans un texte court ou que sais-je encore ?

Conclusion

À sujet plus simple, article plus court.

Les prochains articles de la série rentreront plus directement dans le sujet et devraient tous être présentés selon la même structure pour faciliter la lecture.

Si vous découvrez le concept de modèle de conception ARIA, nous espérons que vous avez appris quelque chose d'utile et que vous vous en servirez dans vos projets futurs.

Cependant, n'oubliez pas que si vous n'êtes pas sûrs de vous ou de ce que vous faites No ARIA is better than Bad ARIA !

Publié par Alsacreations.com

Article : Le menu burger sur mobile est-il toujours d'actualité en 2022 ?

$
0
0

Tout comme la loupe pour une barre de recherche ou un rouage pour les paramètres, le burger est aujourd'hui un symbole reconnu pour représenter la navigation d'un site web.

Un menu burger se présente généralement sous la forme de trois barres horizontales parallèles, derrière lesquelles se cache la totalité des items et sous-items du menu. Il permet, notamment sur mobile, de gagner de la place.

Mais d'où vient le menu burger ?

L'apparition d'un bouton burger est due à Norm Cox qu'il imagina en 1981 pour le Xerox Star, l'un des premiers ordinateurs personnalisés conçus pour le travail de bureau. Tombée dans l'oubli, cette icône reviendra sur mobile au sein de l'application Voice Memos sur iOS 3.0 en 2009, puis sera popularisée par Facebook en 2010.

Dès lors, le burger sera critiqué par les uns, acclamé par les autres, et fera l'objet de nombreux articles tout en continuant sa conquête du monde de l'internet (ahem).

Le menu burger, une fausse bonne idée ?

L'utilisation d'une icône « burger » est depuis longtemps dans le collimateur des experts UX. Et pour cause : si certaines icônes comme les play / pause ont été intégrées dans le langage commun, c'est grâce à des années d'utilisation dans notre quotidien, sur le web mais pas seulement : on les retrouve également sur les lecteurs Cds, DVDs, les radios, les manettes de télévision... Bref, dans notre vie de tous les jours. L'apprentissage de ces icônes s'est donc fait naturellement et il est désormais possible de les utiliser sans le moindre label.

Lecteur CD avec boutons play / pause
(exemple d'icônes play, pause, stop... sur un objet du quotidien)

Le menu burger, lui, est plus particulier : son usage est quasi exclusivement réservé au web et de nombreuses études prouvent que, même si la majorité des utilisatrices et utilisateurs en connaît le sens, il reste encore flou pour une partie d'entre eux.

Alors, est-ce une bonne idée d'utiliser un menu burger en 2022 ?

Les avantages et inconvénients du menu burger

Jetons d'abord un coup d'oeil aux bons et mauvais côtés d'un tel menu :

Avantages

  • Permet de gagner de la place pour le reste du contenu
  • Symbole reconnu par une majorité de personnes
  • Moins d'éléments visuels = moins de charge cognitive

Inconvénients

  • Cache l'information
  • Toujours pas reconnu par certaines personnes
  • Nécessite un clic supplémentaire pour accéder à la navigation

S'il permet effectivement de pallier au problème de place sur mobile, le menu burger cache également une partie de l'information nécessaire à la bonne utilisation d'un site.

Les bonnes questions à se poser

Prenons le problème à l'envers : pourquoi n'utilisions-nous pas de menu burger lorsque la navigation se faisait exclusivement sur desktop ?

  • Pour avoir un accès direct à l'information
  • Pour présenter au visiteur les différents chemins de navigation afin qu'ils ne manque rien d'important
  • Pour que l'on puisse comprendre la structure du site et où on se trouve à l'intérieur de celle-ci

Un menu sert à la fois à la navigation et à la compréhension d'un site web. Le masquer, c'est donc ajouter une difficulté supplémentaire à la bonne prise en main de votre site.

Pour vous aider à prendre la bonne décision concernant votre projet, nous vous conseillons alors de vous poser ces quelques questions :

  • Le visiteur sera-t-il capable de trouver l'information qu'il cherche dans le contenu de vos pages, et notamment de votre page d'accueil ?
  • Existe-t-il d'autres chemins d'accès disséminés dans votre site (maillage interne, fil d’ariane, plan du site…) ?
  • Avez-vous mis en place des boutons CTAs (Call To Action) suffisamment attractifs pour les orienter dans leur visite ?
  • Vos pages présentent-elles un cheminement logique, compréhensif et facile à suivre ?
Wireframe avec CTA Wireframe avec fil d'ariane
(exemple de wireframes avec CTA et fil d'ariane)

Si oui, alors l'utilisation d'un menu burger est toute indiquée !

Afin de mettre toutes les chances de votre côté, assurez-vous également que votre menu burger ressemble bien à un bouton, et pour permettre à toutes les personnes de comprendre ce qui se cache derrière, n'hésitez pas à ajouter un label juste à côté.

Menu burger simple Menu burger bouton Menu burger bouton et label
(exemple de menus burger : simple, avec une apparence bouton, et avec un label)

Les alternatives au menu burger

À l'inverse, si votre navigation interne repose uniquement sur votre menu (ce qui n’est pas très conseillé), il serait plus sage de ne pas cacher son contenu.

Voici quelques idées alternatives au menu burger pour mobile :

  • Tabs (onglets)
  • Icônes (assurez-vous qu'elles soient compréhensives par tous.te.s)
  • « More » / « Plus »
  • Scroll horizontal
  • Dropdown
  • Mise en place d'un menu principal + d'un menu burger pour la navigation secondaire
Menu tabs Menu icônes Menu more Menu scroll horizontal Menu dropdown
(quelques alternatives au menu burger classique)

Bon, mais alors, burger ou pas burger ?

En conclusion, il n'y a pas de solution universelle. Tout dépend de votre projet, des contraintes, du contenu des pages internes et de leur structure... A vous d'analyser votre site web et de choisir la meilleure solution. Comme dans tout projet, c'est l'articulation entre votre cible et vos objectifs qui vous dictera la bonne marche à suivre.

Soyez à l'écoute des besoins de vos utilisatrices et utilisateurs et ils vous le rendront bien !

Publié par Alsacreations.com

Article : Le headless à l'aise avec l'API Rest de WordPress

$
0
0

On connait tous WordPress, on ne va plus le présenter ici et passer directement à ce qui nous intéresse l'API REST de WordPress !

Wordpress Logo

...Quoi sérieux ? Tu connais pas ?

Mais si tu sais le CMS le plus populaire du monde, sur lequel 43 % du web repose !

Non, toujours pas !?

Bon alors, un petit récap' vite fait s'impose et après on y va !

Petit récap' !

WordPress c'est un Système de Gestion de Contenu (SGC en bon français) ou Content Management System (CMS en anglais) qui permet de créer et gérer facilement l'ensemble d'un site.

Ses fonctionnalités permettent de créer et gérer différents types de site web :

  • Blog (c'est son cœur de métier à la base)
  • Site institutionnel
  • Portfolio
  • Site vitrine
  • Boutique en ligne (WooCommerce)

C'est écrit en PHP et repose sur une base de données MySQL, la plupart des installations WordPress utilisent des thèmes basés sur des modèles de page pour afficher le contenu.

Voilà pour les bases !

L'API REST

l'API REST a fait son apparition dans la version 4.5 en 2016, cependant elle existait déjà sous la forme d’une extension avant cela. Mais aujourd'hui elle est native et disponible avec l'url suivante : https://monWordPress.fr/wp-json/wp/v2

Exemple de requête globale sur l'api WordPress

Cela nous retourne un tableau avec les options de l'api et les requêtes pouvant être exécutées comme sur des :

  • Posts
  • Taxonomies
  • Catégories
  • Médias

Si on voulait avoir la liste des posts par exemple, il suffirait de faire une requête plus précise commehttps://monWordPress.fr/wp-json/wp/v2/posts

Exemple de requête sur les posts de l'api WordPress

Cela retourne un tableau avec tous nos posts et toutes les informations liées a chaque post comme :

  • L'id
  • Le titre
  • Le contenu
  • La catégorie

Vous l'aurez compris il est possible de faire les mêmes requêtes que sur un WordPress du moment que les champs y sont enregistrées.
Voici le lien vers la documentation pour plus d'informations à son sujet.


⚠️ Cependant attention !

L'API ne fonctionne pas si les Réglages > Permaliens sont réglés sur Simple, vous devez activer une autre option parmi les choix proposés.

Page du back-office de wordpress sur le réglage de permaliens


Par défaut l'API ne contient que ce qui y est prévu de base à savoir les options disponibles à l'installation comme :

  • les articles
  • les catégories associées
  • les médias
  • les commentaires
  • les widgets
  • Le menu (lui fait exception !)

Par exemple si on voulait ajouter un nouveau custom post type, au register_post_type() il faut impérativement passer l'option show_in_rest => true sinon il ne serait pas accessible depuis l'API. Il en va de même pour tout ajout supplémentaire à ce que WordPress inclut de base.

Mais nous verrons tout cela dans un tuto pour approfondir les choses !

Ok, le Headless ça à l'air cool, mais c'est quoi !?

Dans le cas de l'utilisation classique de WordPress, qui est conçu pour manager le contenu avec son back-office et afficher ce contenu via des modèles de page qui mélangent du PHP et du HTML. (Sauf si t'utilises Timber 😉)
WordPress génère les pages côté serveur donc en SSR (Server-Side Rendering)

Schématisation du fonctionnement de WordPress


Dans le cas de l'utilisation avec l'API REST, si on considère le back-office comme le corps et l'affichage en front comme la tête, ça revient à couper la tête de WordPress !

On se libère de la technologie PHP pour construire les interfaces, pour ne garder que le back-office et c'est un framework front qui génère les pages côté client donc en CSR (Client-Side Rendering).

Ce qui nous offre un contrôle complet sur la façon dont le contenu est présenté et nous permet d'utiliser notre framework frontend préféré ! Comme VueJS par exemple ! 😏

Schématisation du fonctionnemet de l'api de WordPress

Les avantages ✔️

  • Flexibilité : Le frontend étant dissocié de WordPress on peut développer à l’aide d’outils frontend modernes.

  • Performances : La mise en cache permet de ne pas devoir constamment faire des requêtes aux serveurs.

  • Sécurité supplémentaire : Vous pouvez héberger votre WordPress et votre front-end sur des serveurs différents. Et vous avez moins à vous soucier de toutes les mises à jour de sécurité et des autres problèmes de maintenance liés à son utilisation.

Les inconvénients ❌

  • Fonctionnalités manquantes : L'API ne prend pas en charge toutes les fonctionnalités. Par exemple un des intérêts de ce CMS est l’éditeur Gutenberg, l’aperçu en direct ne fonctionnera pas si vous utilisez un frontend séparé. (L'API renvoi le contenu en RAW HTML).

  • Plugins : Lorsqu'il repose uniquement sur des extensions et des fonctionnalités spécifiques, vous devez vous en tenir à WordPress, sauf si les extensions proposent des options basées sur l’API (Comme ACF par exemple depuis la V.5.11)

  • Contraintes : Malgré le côté headless pour alimenter l'API il faudra toujours développer les customs post type et taxonomies en PHP dans le thème et il faut faire toute une installation pour l'utiliser.

Conclusion

L'API REST de WordPress n’est pas parfaite au départ et arrive avec quelques contraintes.
Mais avec un peu de code, on arrive assez facilement à l'enrichir et elle s'avère bien utile pour certains projets !

Cependant aujourd'hui il existe d'autres headless CMS sur le marché comme le français Strapi par exemple.
Lui aussi est open source, gratuit et écrit en JS. Toutefois l’approche est différente il faut tout construire de toutes pièces et nécessite d'avoir d'autres compétences.

Voilà déjà deux cas avec une approche et des langages différents, mais il en existe d'autres comme Directus ou encore Contentful par exemple.

Toutefois il faut garder à l'esprit que WordPress n'a pas été développé pour être un headless CMS, mais que l'option est disponible et elle fonctionne bien.

Et vous ? Vous avez déjà utilisé l'API de WordPress ? Ou un autre CMS headless ?

Publié par Alsacreations.com

Tutoriel : Découverte de TypeScript

$
0
0

Si vous êtes ici, c'est que vous avez sûrement déjà entendu parler de TypeScript. Au premier abord, on peut ne pas vraiment savoir à quoi ça sert, voire même ne pas savoir ce que c'est du tout.

Dans ce tuto, nous allons partir à sa découverte et explorer ce qu'il a à proposer.

Mais c'est quoi TypeScript ?

En prenant la définition depuis la documentation officielle, TypeScript (que nous nommerons "TS" par la suite) est un langage de programmation construit par-dessus Javascript et offrant de nouvelles fonctionnalités.

Il a été créé par Anders Hejlsberg pour Microsoft (rangez vos fourches, le projet est open source) en 2012, dans l'objectif de combler les manques de Javascript (JS) comme par exemple les classes qui, à l'époque n'existaient pas encore.

Anders Hejlsberg
Anders Hejlsberg

Ce type de technologie est souvent appelé "Superset", un exemple très connu est SASS pour le CSS.

Concrètement, nous allons pouvoir écrire du code TypeScript qui sera ensuite compilé en Javascript natif.

Et donc finalement, ça sert à quoi ?

L'une des principales fonctionnalités de TypeScript se trouve dans son nom, "Type".

En effet, grâce à lui, il devient possible de typer son code, c'est à dire de indiquer des types explicites à ses variables, fonctions, etc. qui devront être respectés.

wtf

Si cela n'est pas tout de suite clair, voici un exemple.

En JS, nous pouvons écrire une fonction prenant un nombre en paramètre et qui retourne son double:

function get_double(my_number) {
  return my_number * 2
}

/* Aucune erreur, ça fait 4 */
const result = get_double(2)
/* Aucune erreur même si l'on ne passe pas un nombre, on obtient également 4 */
const second_result = get_double('2')
/* Aucune erreur, cependant on obtient NaN */
const third_result = get_double('foo')
/* Aucune erreur, cependant on obtient NaN */
const third_result = get_double()

Dans cet exemple, il n'y a rien d'explicite pour dire que my_number doit être un nombre.

  • Si l'on passe bien un nombre, aucun souci, c'est ce qui est voulu.

  • Si l'on passe une string contenant un nombre, JS va le comprendre et utiliser notre paramètre comme un nombre.

  • Si l'on passe une string classique, apparemment aucun souci mais "foo" * 2 n'est pas une opération valide et get_double ne retournera pas un nombre mais NaN.

  • Si l'on ne passe rien, apparemment aucun souci mais undefined * 2 n'est pas une opération valide et get_double ne retournera pas un nombre mais NaN.

Vous avez sûrement compris que ce comportement n'est pas idéal pour développer et il serait préférable de ne pas envoyer notre code en production tout de suite...

Avec TS, il nous est possible de définir le type de my_number pour être sûr de ne pouvoir passer que des nombres.

function get_double(my_number: number) {
  return my_number * 2
}

const my_result = get_double(2)

// Argument of type 'string' is not assignable to parameter of type 'number'
const my_second_result = get_double('2')
// Argument of type 'string' is not assignable to parameter of type 'number'
const my_third_result = get_double('foo')

Notre code TypeScript n'est pas vraiment différent de notre code JS (pour l'instant en tout cas...). On peut voir qu'il a suffi de remplacer get_double(my_number) par get_double(my_number: number).

Il nous sera ensuite impossible de compiler si nous passons autre chose qu'un nombre à get_double.

🎊 Vous savez maintenant quelle est l'utilité principale de TypeScript, mais vous allez voir que ce n'est pas tout !

Autocomplétion

Une des plus grandes forces de TS est en réalité de pouvoir laisser notre éditeur mieux comprendre notre code. En effet, en typant explicitement notre code, notre éditeur est capable de nous proposer des choses qui ne seraient normalement pas possibles.

Reprenons l'exemple de get_double.

JS

function get_double(my_number) {
  my_number.split() // Mon éditeur ne comprend pas que `split` n'existe pas sur un nombre
  return my_number * 2
}

TS

function get_double(my_number: number) {
  my_number.split() // Property 'split' does not exist on type 'number', c'est la catastrophe.
  return my_number * 2
}

Cette aide supplémentaire va nous faire gagner un temps précieux et surtout nous éviter des erreurs bêtes mais courantes.

L'autocomplétion possible avec TS va bien au-delà de cet exemple, mais c'est en dehors du périmètre de cette découverte 😉.

C'est bien beau, mais comment on compile du TypeScript ?

La méthode la plus simple et rapide pour tester est d'installer le module npm typescript et d'utiliser la commande tsc.

npm install -g typescript
tsc ./mon-fichier.ts

Cette dernière nous sortira un fichier mon-fichier.js sans aucune source TS encore présente.

Avec les outils comme Webpack, Rollup ou encore un que vous connaissez sûrement Gulp, il est plus facile de compiler son code.

La compilation se fera en tâche de fond et vous n'aurez pas à vous en occuper une fois configurée.

Certains frameworks front-end comme Vue.js (notre favori chez Alsacréations) proposent même d'installer TypeScript à l'aide d'une simple commande.

vue add typescript

Si vous utilisez un autre framework, Vite.js propose des modèles prêts à l'emploi pour React, Svelte, Vue, et même du JS natif !

Il y a encore d'autres méthodes pour utiliser TypeScript mais cela est en dehors du périmètre de ce tutoriel.

Pour suivre le reste de cet article, vous pouvez tout simplement utiliser le Playground officiel.

Les bases de TS

Maintenant que nous savons à quoi sert TypeScript et comment l'installer sur notre projet, comment écrire du code TS ?

Typer des variables simples

const my_string = 'Hello World!' // Valide en JS et TS
const my_typed_string: string = 'Hello World!' // Valide en TS

Ici nous avons deux solutions, nous pouvons donner le type explicitement ou laisser notre éditeur le comprendre tout seul.

En effet, my_string étant défini en brut, notre éditeur est capable d'inférer son type tout seul. Avec my_typed_string nous ne faisons que le dire explicitement.

Pour typer une variable explicitement, il suffit d'ajouter : {type} après le nom de la variable. (Remplacez "{type}" par le type voulu).

Les types les plus courants sont: string, number, boolean et void.

Le type void est un type particulier, en effet il permet de dire rien. Cela est particulièrement utile dans les fonctions qui ne retournent rien, en réalité le retour sera undefined.

Définition de tableaux

Pour travailler avec des tableaux, deux possibilités s'offrent à nous.

  • Ajouter [] après le type (: {type}[]), [] étant la syntaxe commune d'un tableau.
  • Utiliser un Generic que nous verrons un peu plus tard.
const my_string_array: string[] = ['Hello', 'World!']
const my_string_array: Array<string> = ['Hello', 'World!']

/* Argument of type 'number' is not assignable to parameter of type 'string' */
my_string_array.push(1337)

Définition d'objets

Si vous connaissez déjà la syntaxe des objets JS, bonne nouvelle, vous connaissez également celle de TS :p

const my_object: { message: string, words: number } = { message: 'Hello World!', words: 2 }

my_object.message = 1337 // Type 'number' is not assignable to type 'string'

Les fonctions

Les fonctions peuvent elles aussi être typées au niveau de leurs paramètres ainsi que de leur valeur de retour.

const dogs: Dog[] = [/* ... */]

/**
 * Ici, on dit que `name` est une string,
 * et que la fonction retourne un `Dog` ou `undefined`
 */
function get_dog(name: string): Dog | undefined {
  return dogs.find(dog => dog.name === name)
}

/**
 * Fonction qui ne retourne rien avec le type `void`
 */
function pet_dog(): void {
  /* happy dog */
}

/**
 * Fonction fléchée
 */
const get_dog = (name: string): Dog | undefined => dogs.find(dog => dog.name === name)

const my_dog = get_dog('Idefix') // Dog | undefined

Création et réutilisation de types

L'autre grande force de TS réside dans la possibilité de créer ses propres types et de les réutiliser comme bon nous semble.

Dans la suite de l'article, nous utiliserons Dog comme exemple. Malheureusement nos Dog seront un peu moins mignons que celui-ci...

type Dog = {
  name: string,
  age: number,
  cute: boolean
}

const cute_dog: Dog = { name: 'Idefix', age: 2, cute: true }
/**
 * Property 'name' is missing in type '{ age: number; cute: false; }' but required in type 'Dog'
 *
 * PS: C'est juste pour l'exemple, tous les chiens sont mignons 😉
 */
const ugly_dog: Dog = { age: 2, cute: false }

Un type peut également être défini (et c'est souvent fait de cette façon) avec une Interface

interface Dog {
  name: string
  age: number
  cute: boolean
}

const cute_dog: Dog = { name: 'Idefix', age: 2, cute: true }

/* Property 'name' is missing in type '{ age: number; cute: false; }' but required in type 'Dog' */
const ugly_dog: Dog = { age: 2, cute: false }

Les interfaces sont souvent utilisées pour décrire une class en JS

/*
 * Class 'Doggo' incorrectly implements interface 'Dog'.
 * Property 'cute' is missing in type 'Doggo' but required in type 'Dog'
 */
class Doggo implements Dog {
  name = 'Idefix'
  age = 2
}

Définition de fonctions dans une interface

interface Dog {
  give_food: () => void
  give_bath: (use_shampoo: boolean) => void
  get_name: () => string
}

Types dynamiques avec les Generics

Enfin, il est possible de créer des types dépendants d'autres en leur passant ce qu'on pourrait appeler des paramètres par abus de language. C'est cela que l'on appelle cela des Generics.

/**
 * Notre Generic ici est T, il permet d'y passer un paramètre comme dans une fonction JS
 */
interface Dog<T> {
  name: string
  age: T
  cute: boolean
}

/* OK 🐶 */
const cute_dog: Dog<number> = { name: 'Idefix', age: 2, cute: true }
/* Type 'string' is not assignable to type 'number' */
const second_cute_dog: Dog<number> = { name: 'Idefix', age: '2', cute: true }
/* OK 🐕‍🦺 */
const third_cute_dog: Dog<string> = { name: 'Idefix', age: '2', cute: true }
/**
 * On peut également passer plusieurs Generics,
 * De plus, les interfaces ne sont pas les seules à pouvoir les utiliser
 */
type Dog<N, A, C> = {
  name: N,
  age: A,
  cute: C
}

/**
 * Les fonctions peuvent aussi le faire
 */
function get_dog<N, A, C>(name: N): Dog<N, A, C>

const my_dog = get_dog<string, number, boolean>('Idefix') // Dog<string, number, boolean>
const my_dog = get_dog<string, string, boolean>('Idefix') // Dog<string, string, boolean>

Les Generics dans les fonctions sont très puissants, ils permettent une autocomplétion plus avancée:

type Dog<N> = {
  name: N,
  age: number,
  cute: boolean
}

function get_dog<N>(name: N): Dog<N> {
  return { /* */ }
}

/**
 * Je ne suis pas obligé de passer mon Generic explicitement,
 * mon éditeur comprend tout seul que j'ai passé
 * une string pour `name`, et comprend que N est maintenant une string.
 */
const my_dog = get_dog('Idefix') // Dog<string>

Types utilitaires et operators

Par défaut, TS possède des types utilitaires pour nous aider à en construire de nouveaux, comme par exemple ReturnType.

Nous avons également accès à des mots clés comme keyof et typeof pour nous aider à inférer de nouveaux types.

Par exemple typeof permet d'obtenir le type d'une variable JS.

const message = 'Hello World!'

type MessageType = typeof message // string

Deuxième exemple, ReturnType<T> permet d'obtenir le type de retour d'une fonction.

function get_dog(name: string): Dog {
  return { /* */ }
}

type GetDogType = typeof get_dog // (name: string) => Dog

/**
 * Ici ReturnType utilise un Generic, on lui passe `GetDogType`
 */
type GetDogReturnType = ReturnType<GetDogType> // Dog

J'ai quand même l'impression que c'est plus compliqué qu'autre chose...

En effet, à première vue TS n'est pas si simple à prendre en main. En débutant, vous obtiendrez peut-être de nombreuses erreurs alors que votre code fonctionnait en JavaScript.

Cependant avec un peu de patience et un temps d'adaptation pour bien comprendre ces erreurs, votre code en sortira plus stable et moins sujet aux bugs invisibles remontés par Javascript lors d'une mise en production... (c'est du vécu 😄)

Il n'est pas nécessaire d'utiliser TS à 100% dès le départ, il est tout à fait possible de migrer doucement une base de code JS vers TS notamment avec allowJs ou même de n'utiliser les types qu'avec JSDoc.

Mot de la fin

Nous avons vu ensemble ce qu'est TypeScript et pourquoi c'est l'une des technologies front-end les plus populaires.

Et vous, l'avez-vous essayé ? Qu'en pensez-vous ?

👋

Retrouvez l'intégralité de ce tutoriel en ligne sur Alsacreations.com

Article : Le plugin figma du mois : Neumorphism

$
0
0

On commence cette nouvelle série d'article (un mois, un plugin Figma) avec un premier plugin vous permettant d'implémenter des effets Neumorphism en quelques secondes !

Exemples de Neumorphism avec le plugin Figma

Mais d'abord, une rapide petite définition...

Qu'est-ce que le Neumorphism ?

Le Neumorphism (ou néomorphisme) est un style graphique à mi-chemin entre le Skeuomorphisme et le flat design. Il est caractérisé par l'utilisation d'ombres et d'effets d'élévation pour simuler un rendu réaliste avec différents niveaux d'incrémentation. Google material en est un bon exemple.

Le plugin Neumorphism pour Figma

Ce petit plugin gratuit est disponible dans la banque communautaire de Figma. Il vous permettra d'appliquer rapidement des effets d'ombre et d'élévation typiques au Neumorphism, avec la possibilité d'ajuster le niveau d'élévation, l'intensité de l'ombre, le style de votre élément (plat, concave, convexe, enfoncé), la direction de la source lumineuse et l'adoucissement des bords – ainsi que la couleur de l'ombre, bien sur.

Les possibilités du plugin Figma Neumorphism

Mais alors, comment ça marche ?

C'est très simple : sélectionnez un composant (ici, un bouton) sur lequel vous souhaitez ajouter un style Neumorphism, faites un clic droit et dans « plugin », choisissez « neumorphism ». Vous accéderez directement à la fenêtre de customisation et n'aurez plus qu'à configurer vos effets comme vous le souhaitez !

Attention, le plugin ne prend pas en charge les layers multiples ni les groupes. Dans notre exemple, nous avons utilisé une frame en mode auto layout.

Les options disponibles sont peu nombreuses mais largement suffisantes pour simuler tous types d'effets différents.

Petite subtilité : la couleur de votre ombre sera calculée selon la couleur de fond de votre élément. Ainsi, un bouton blanc sur fond coloré n'aura pas un très beau rendu, puisque la couleur de base utilisée pour l'ombre sera aussi le blanc...

Pour contrer cela, n'oubliez pas de changer la couleur de fond de votre élément avant d'appliquer le plugin Neumorphism, puis, une fois fait, réappliquez la couleur désirée.

La couleur est la seule option qu'il n'est pas possible de customiser directement dans le panneau du plugin. Si vous avez déjà appliqué un effet Neumorphism sur un élément et que vous souhaitez modifier la couleur de l'ombre après coup, vous pouvez également passer par la sidebar de Figma et jouer avec les couleurs d'ombrage. Il vous faudra préparer une couleur plus claire et une plus foncée que le fond sur lequel se trouvera votre élément.

Et pour l'intégration ?

Bien entendu, il conviendra de confirmer avec votre équipe front-end (ou vous même si vous savez tout faire) que ce qui est designé est reproductible en CSS et, si ce n’est pas le cas, de trouver une solution qui convienne à toutes et tous.

La fonction Inspect de Figma permet de récupérer le code CSS généré par le plugin Neumorphism. Vous pouvez visualiser quelques exemples sur ce CodePen et comparer le résultat en code VS le rendu Figma ci-dessous.

Exemple d'exports CSS du plugin Figma Neumorphism

Et voilà !

Ce n'est pas plus compliqué que ça, alors à vos pinceaux numériques !

Publié par Alsacreations.com

Actualité : Les podcasts web du moment

$
0
0

Les podcasts (audio) peuvent vous accompagner partout, durant vos périodes de transport, de pauses, d'activités manuelles, pour découvrir et apprendre sans être devant un écran.

👂 Vous pouvez les écouter facilement dans un navigateur ou sur votre smartphone Android / iOS qui téléchargera automatiquement les nouveaux épisodes dans votre playlist : Podcast Addict, BeyondPod, PodBean, Pocket Casts, Google Podcasts, Apple Podcasts et bien d'autres.

En voici une sélection : flux ou épisodes qui vous inspireront sûrement, parmi lesquels se cachent des personnes membres du forum, oratrices et orateurs de la Kiwiparty ; à vous de les retrouver.

Carré, Petit, Utile

Carré, Petit, Utile, animée par DaScritch, est une émission diffusée tous les jeudi sur Radio FMR qui aborde des sujets variés autour du monde du numérique. Derniers épisodes en date : l'histoire d'Internet Explorer et Microsoft Edge avec David Catuhe en guest. On note également une belle série sur les Légendes confidentielles du minitel en 3 parties et De VideoLAN à VLC. Avec bientôt 200 épisodes au compteur, de nombreuses heures d'écoute.

CPU Carré Petit Utile

Le code a changé

Le code a changé (France Inter), pensé et produit par Xavier de La Porte qui s'interroge : en quoi toutes ces technos changent quelque chose à nos vies ? Là aussi les sujets abordés et les invités sont aussi variés que captivants, notons par exemple L'homme qui avait la formule mathématique des bonnes histoires, Dans un avion, confie-t-on sa vie à des logiciels ?, Coincé dans Zoom, Ils cherchent “les trucs bizarres qu’il y a dans vos téléphones” : rencontre avec des traqueurs de trackers, Pourquoi s'est-on mis à tout noter ?.

Le code a changé

La Confrérie

La Confrérie est un podcast maison et rudement bon auquel participent David Catuhe (encore lui?), David Rousset, Etienne Margraff, autrement connus sous leur identité secrète Deltakosh, Davrous, Meulta, et Akumasai. Il se structure souvent en 2-3 sujets majeurs scrutés sous l'oeil de ces joyeux geeks crakosaures, assortis de recommandations et de retours d'expérience, qui vont de l'univers des jeux vidéo jusqu'à l'alpinisme et les Intra-terrestres, en passant par la fusion nucléaire ou le paradoxe de Fermi.

La Confrérie

Le meilleur des mondes

Le meilleur des mondes (France Culture) par François Saltiel propose de mettre le futur en débat et de questionner les nouvelles technologies qui reconfigurent notre société. De la fiction à la réalité, de l’utopie à la dystopie et de la promesse d’un monde meilleur au "Meilleur des mondes" d’Huxley ; la frontière est ténue. Notons dernièrement Splendeurs et décadences de la Silicon Valley ou Dans les arcanes de Tik Tok et encore Wikipédia : le plus beau cadeau de l'internet ?.

Le meilleur des mondes

Entendez-vous l'éco

Entendez-vous l'éco ? (France Culture), par Tiphaine de Rocquigny est une émission généraliste autour de l'économie, qui aborde de temps à autre des sujets relatifs au numérique et qui récemment a proposé des thématiques L'éco face à la menace cyber et des épisodes tels que Les arnacoeurs du web, Jeux-vidéo : le choc des géants, Les start-up sont-elles seules à innover ? mais aussi Quand les GAFA captent l'attention des enfants

Entendez-vous l'éco

L'octet vert

L'octet vert est un podcast de Tristan Nitot (que l'on ne présente plus) qui parle de climat, de numérique, et ce que ça implique dans nos vies et nos métiers avec chaque fois un invité différent. Rafraîchissant.

L'Octet Vert

Design MasterClass

Design MasterClass ainsi que son nom l'indique est un podcast orienté Design, dont un épisode récent est à remarquer : Design Accessible : une priorité ?

Design MasterClass

Superfail

Superfail (France Culture) animé par Guillaume Erner : Parce qu’il n’y a pas que la réussite dans la vie, "Superfail" ne s’intéresse qu’à l’erreur, l’échec, la catastrophe. "Superfail" parce que ça n’est pas si facile de réussir à échouer. En une dizaine de minutes, retour sur ces expériences qui n'ont pas marché, et dernièrement Google Glass, les lunettes que l’on a presque pas vues.

Superfail Google Glass

Et vous, quels podcasts écoutez-vous ?

Publié par Alsacreations.com

Tutoriel : Création d'une API REST avec Express et TypeScript

$
0
0

Nous avons récemment vu les bases de TypeScript, mais qu'en est-il d'un cas concret ?

Aujourd'hui nous allons construire une simple API REST à l'aide d'Express et TypeScript.

Avant de continuer ce tuto, je vous recommande vivement d'être à l'aise avec :

  • Les codes HTTP et les méthodes HTTP
  • JavaScript
  • TypeScript (si ce n'est pas le cas, je connais un super article, lien plus haut 😉)
  • Node.js et NPM (des bases suffisent)
  • Express (recommandé mais pas obligatoire)

Un peu de contexte

Premièrement, c'est quoi une API REST ?

Concrètement, une API (Application Programming Interface) consiste à fournir une interface (du code, des adresses HTTP, etc.) utilisable dans un autre contexte.

Un exemple simple sûrement parlant à un grand nombre : JQuery. Avec JQuery nous n'avons accès qu'à ce qui nous est offert. Nous utilisons l'API de JQuery.

<body>
  <h1 id="title"></h1>
</body>

<script>
  $('#title')
    .text('Mon titre')
</script>

Une API REST (REpresentational State Transfer) nous permet de récupérer des données (souvent JSON) depuis une adresse HTTP.

Par exemple comme nous l'avons vu dans Wordpress, il nous suffirait de faire un appel HTTP sur l'adresse https://wordpress.example.com/wp-json/wp/v2/posts pour récupérer tous les posts du site au format JSON.

Express

Express est un framework pour Node.js, qui nous propose une API nous facilitant le travail pour créer des serveurs WEB.

Nous nous en servirons pour développer une API REST dans ce tuto mais Express peut tout à fait être utilisé pour un simple serveur HTTP renvoyant des pages HTML.

Installation du projet

Avant toute chose, il nous faut installer tout ce dont nous avons besoin pour développer.

Premièrement, nous créerons un dossier pour notre projet, pour ce tuto je l'appellerai api-express.

Dans ce dossier, nous allons créer deux sous-dossiers :

  • src qui contiendra notre code source
  • types qui contiendra nos types TypeScript

Deuxièmement, nous allons instancier un projet Node.js, avec la commande suivante (libre à vous de changer les informations de package.json).

npm init -y

Passons maintenant à l'installation des dépendances.

Les dépendances de développement

npm install -D @types/express @types/node @types/cors nodemon ts-node tsconfig-paths tsup typescript
  • @types/xxx, ces modules nous permettent simplement d'avoir accès aux types TS de nos dépendances. Sans ça, TS nous criera probablement dessus 😉
  • nodemon, nous permet de relancer le serveur à chaque changement dans les fichiers sources.
  • ts-node, compile nos fichiers TS en développement et nous permet d'exécuter nos fichiers à la volée. EX: ts-node mon_fichier.ts === node mon_fichier.js
  • tsconfig-paths, nous permet de donner des chemins relatifs personnalisables à ts-node. EX: ~/mon_fichier.ts === /src/mon_fichier.ts. Cela est notamment pratique dans de gros projets.
  • tsup, nous permettra de compiler nos fichiers TS en un seul fichier JS prêt pour la production.
  • typescript, besoin d'explications ? 😄

Les dépendances de développement et de production

Ici c'est plus léger, nous n'aurons besoin que d'express et cors.

cors permet d'autoriser uniquement certains domaines (ou tous) à envoyer des requêtes à notre API.

npm install express cors

Nous allons ensuite définir des "scripts" dans notre package.json pour lancer des commandes rapidement.

"scripts": {
  "dev": "nodemon --watch src -e js,ts,json --exec \"ts-node src/index.ts\"",
  "build": "tsup src/index.ts --format cjs --clean",
  "start": "node dist/index.js"
}
  • dev, lance nodemon en lui disant d'observer le dossier src pour les changements. On lui demande de vérifier les fichiers JS, TS et JSON, enfin, à chaque changement il relance le serveur avec ts-node.
  • build, compile le projet avec tsup et génère notre fichier de destination.
  • start, une fois le projet compilé, nous permettra de lancer le serveur en production.

Enfin, il ne nous manque plus que notre fichier tsconfig.json à la racine du projet qui configure la façon dont TypeScript fonctionne.

{
  "compilerOptions": {
    "baseUrl": ".",
    "target": "es2017",
    "module": "CommonJS",
    "lib": ["esnext"],
    "moduleResolution": "node",
    "esModuleInterop": true,
    "strict": true,
    "strictNullChecks": true,
    "resolveJsonModule": true,
    "skipDefaultLibCheck": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "outDir": "./dist",
    "strictPropertyInitialization": false,
    "paths": {
      "~/*": ["./src/*"],
      "~~/*": ["./*"]
    }
  },
  "ts-node": {
    "require": ["tsconfig-paths/register"]
  }
}

Les options importantes pour ce projet sont :

  • baseUrl, explicite à TS que l'entrée du projet est le dossier courant.
  • target, vers quelle version de JavaScript nous allons compiler.
  • module, quels types de modules JavaScript nous allons utiliser. CommonJS (require('un-module')) est la version encore la plus utilisée avec Node.js.
  • esModuleInterop, nous pourrons utiliser la syntaxe import x from 'y' avec les modules CommonJS. Merci TypeScript 👍 !
  • paths, on définit les chemins personnalisés du projet.
  • ts-node, on demande à ts-node d'utiliser nos chemins personnalisés.

Passons au code

Vu le type de projet, placer des snippets de code tout au long du tuto n'est pas vraiment viable.

Je vous propose donc d'utiliser un projet CodeSandbox et de vous expliquer quel fichier fait quoi (en plus des commentaires dans le code).

Vous pouvez ignorer la page de prévisualisation navigateur, elle ne nous servira pas

Explications

Le dossier types

C'est dans ce dossier que nous définirons nos types TypeScript, ici pour les animaux et les erreurs personnalisées.

Le dossier src

index.ts est notre fichier d'entrée, c'est dans ce fichier que nous instancierons le serveur ainsi que les routes (chemins) HTTP.

config.ts est un simple fichier exportant un objet contenant notre configuration, ici le port sur lequel le serveur tourne.

data.ts est un simple fichier exportant un tableau d'animaux, il nous servira de fausse base de données.

Le dossier src/utils

C'est ici que nous définirons les différentes "utilités" dont nous aurons besoin un peu partout.

exceptions.ts contient des classes JavaScript nous permettant de créer des erreurs HTTP plus simplement. Ici nous n'aurons besoin que des erreurs 404 et 400.

Exemple

throw new NotFoundException('Mince une erreur') // Notre route nous retournera une 404 avec ce message d'erreur dans le JSON

Le dossier src/resources

Ce dossier contiendra toute la logique pour chaque resource. Ici, notre seule ressource est pets, dans un vrai projet nous aurions par exemple users, articles, products.

Chaque sous-dossier contient :

  • Un controller, qui défini les routes ainsi que le contenu à renvoyer pour chaque route. Ce fichier est généralement petit, et ne sert qu'à appeler le service ou traiter les paramètres de la requête.
  • Un service, c'est lui qui s'occupe de toute la logique. Par exemple, c'est lui qui traite la base de données, les requêtes etc.

Le dossier src/middlewares

Dans ce dossier nous créerons des middlewares Express, des hooks en quelques sortes. Ils nous permettent d'ajouter de la logique a des moments précis lors de chaque requête.

exceptions.handler.ts, c'est lui qui va gérer toutes les erreurs (les nôtres avec les 404 et 400, mais aussi celles d'Express).

unknownRoutes.handler.ts, c'est lui qui va gérer toutes les routes demandées qui n'existent pas. Par exemple, si la route /dogs n'existe pas, il nous renverra une 404 avec un message d'erreur.

C'est bien beau, mais comment peut-on tester ?

Pour tester chaque route, je conseille Postman ou Insomnia qui permettent d'envoyer des requêtes HTTP facilement.

Conclusion

Nous avons non seulement vu comment préparer un projet Node.js avec TypeScript mais également comment en faire une API REST avec Express.

Le processus n'est, en soi, pas compliqué. Cependant, vous avez peut-être remarqué le nombre de dépendance et les étapes préalables avant de pouvoir commencer.

En effet, Express n'est pas opinionated, c'est à dire qu'il ne force en rien une structure de code, ni de façons de faire. C'est donc à vous de vous débrouiller et de commencer à zéro.

Si cette approche ne vous convient pas, des frameworks basés sur Express existent, comme le plus connu Nest.js qui utilise TypeScript par défaut !

Sur ce, je vous dis à bientôt dans un autre tuto 👋

Retrouvez l'intégralité de ce tutoriel en ligne sur Alsacreations.com


Tutoriel : Utilisation d'une API REST avec Vue.js et TypeScript

$
0
0

Comment développer une simple application Vue.js (3) avec TypeScript qui utilise une API : c'est ce que nous voyons à la suite de l'épisode précédent dans lequel nous avions créé notre API REST avec Express et TypeScript. Cependant nous n'avions pas encore d'interface utilisateur pour nous servir de notre nouvelle API.

Avant de continuer ce tuto, je vous recommande vivement d'être à l'aise avec :

  • JavaScript
  • TypeScript
  • Les méthodes HTTP
  • Vue.js (si vous avez des connaissances dans un autre framework, cela peut suffire)
  • Node.js et NPM (des bases suffisent)

Installation de notre projet

En suivant la documentation, nous créerons l'application avec Vite.js qui remplace maintenant Webpack dans la nouvelle version de Vue.

  1. Dans votre terminal, entrez la commande :
npm create vite@latest
  1. Entrez le nom de votre projet, ici je le nomme express-vue3
  2. Choisissez vue
  3. Choisissez vue-ts
  4. Pour finir, nous installerons axios pour lancer nos appels API.
npm i axios

Types

Dans le tuto précèdent, nous avons défini des types TS pour nos animaux, nous allons les copier et les placer dans un dossier types à la racine du projet.

Customisation du projet

Une fois le projet créé, libre à vous de supprimer les fichiers dont vous n'avez pas besoin. Dans la suite du tuto, je développerai directement dans App.vue. À vous d'adapter selon votre cas d'usage.

Passons au code

Comme dans la première partie, je vous propose un projet CodeSandbox ainsi que des explication sur "quel fichier fait quoi" (en plus des commentaires dans le code).

Pour que la prévisualisation fonctionne, l'API REST doit tourner sur votre machine

Explications

Le dossier src

C'est ici que nous écrirons notre code source.

  • main.ts est le fichier d'entrée de notre application. C'est lui qui va monter tout ce qui est nécessaire dans le DOM; c'est également ici que nous importons nos styles.

  • env.d.ts, ce fichier de déclaration TS sert principalement à dire à notre éditeur que les fichiers .vue sont des composants Vue.js.

  • App.vue, c'est dans ce fichier que nous développerons toute notre logique.

    Nous commençons par définir notre partie <script>, c'est ici que nous enverrons les requêtes et que nous sauvegarderons les informations de l'API.

    Vous remarquerez que les ref prennent un Generic TS pour expliciter le type de la ref; c'est une partie vraiment importante quand on travaille avec TypeScript.

    Nous récupérerons tous les animaux ainsi qu'un animal unique dans le hook onMounted.

    Ensuite, nous définissons des fonctions qui seront appelées par nos boutons pour mettre à jour, supprimer, et créer un animal.

    Dans la partie <template>, rien de compliqué. Nous affichons simplement les informations de l'API, ainsi que des boutons / formulaires pour interagir avec notre API. Si vous êtes à l'aise avec Vue.js, vous devriez vous y retrouver.

    Enfin la partie <style> est complètement optionnelle et ne sert qu'à rendre notre application visuellement potable 😄

Le dossier src/modules

C'est ici que nous définirons les différents fichiers, "modules", dont nous aurons besoin un peu partout.

  • api.ts, ce fichier nous sert à préparer les requêtes avant de les envoyer. C'est une convention chez Alsacréations, cela nous permet de garder notre code DRY (Don't Repeat Yourself) et de debugger les requêtes plus facilement.

Le dossier src/styles

C'est ici que nous placerions les styles globaux de l'application, dans cet exemple je n'utilise que Tailwind (qui n'est pas du tout important pour la suite du tuto).

Le dossier public

Tout ce qui est placé dans ce dossier ne sera pas compilé et sera juste copié dans le dossier de destination. Concrètement, le serveur WEB qui fera tourner notre front-end ne fera que servir les fichiers originaux.

EX: https://mon-front-end.com/favicon.ico === public/favicon.ico

Conclusion

🥳 Félicitations, vous êtes arrivé au bout de ce tuto.

Finalement, utiliser Vue.js avec TypeScript n'a rien de compliqué si vous êtes déjà familier avec le framework.

Nous n'avons fait qu'annoter nos ref et les paramètres de nos fonctions... et le tour est joué !

En plus de ça, vous savez maintenant comment utiliser une API REST depuis votre application et ce, en quelques minutes !

Sur ce, je vous dis à la prochaine 👋

Retrouvez l'intégralité de ce tutoriel en ligne sur Alsacreations.com

Actualité : Évolution des quiz pour tester vos connaissances web

$
0
0

Après une longue réflexion menée sur les Quiz et tests de connaissances web qui permettent de vous exercer et évaluer votre savoir, nous avons décidé de revoir leur fonctionnement.

Quiz Alsacreations

Ces quiz ayant eu beaucoup de succès avec plus de 1 818 048 tests validés à ce jour, nous nous sommes aperçus au fil du temps que les choix proposés ne correspondaient plus à la réalité du développement web d'aujourd'hui.

Si les questions sont toujours pertinentes dans de nombreux cas pour les langages front-end, les nombreuses conditions liées à l'environnement ne permettent plus d'être aussi catégoriques qu'avant : avec ou sans Babel, responsive ou non, Edge Chromium ou EdgeHTML, avec ou sans Docker, V8 en version 100.0.4896.60 ou antérieure, headless ou production, les combinaisons sont si variées qu'il n'y a plus de réponse unique.

C'est pourquoi dorénavant, toutes les réponses proposées dans les quiz ont été modifiées par des termes plus appropriés et adaptés aux situations réelles du métier. À vous de tester et de nous faire part de vos retours !

On ne sait pas

Le calcul des scores reste cependant le même, par souci de rétro-compatibilité.

Bonne chance aux candidats en entretien d'embauche à qui on fait parfois passer ces quiz : vous allez faire forte impression, on est avec vous !

Publié par Alsacreations.com

Actualité : Que retenir de l'enquête WebAIM 2022

$
0
0

L'initiative WebAIM (Web Accessibility In Mind), pilotée par l'Université d'Etat de l'Utah, a publié les résultats de son enquête 2022 portant sur un million de pages d'accueil : The WebAIM Million.

Rappelons que WebAIM développe WAVE une suite d'outils pour évaluer l'accessibilité, également disponible en extension Firefox ou Chrome, à essayer si vous ne l'avez pas encore fait.

WebAIM 2022

Un bon nombre de conclusions et statistiques en sont tirées, voici une sélection des faits les plus marquants parmi les thématiques abordées pour pouvoir tous nous situer dans le respect des bonnes pratiques.

Les pages ont été bien entendu analysées automatiquement par un algorithme et non par un audit humain, ce qui comporte des limites. Rien ne vaut un audit exhaustif réalisé par un·e expert·e en accessibilité qui saura à la fois exploiter des outils de tests et détecter les bonnes/mauvaises pratiques uniquement perceptibles par un cerveau organique.

De manière générale :

  • La complexité a augmenté (en nombre d'éléments par page).
  • Il y a toujours un taux d'erreur assez élevé.

WebAIM 2022 erreurs

Les 4 erreurs les plus courantes :

  • Le texte faiblement contrasté
  • L'alternative texte manquante
  • Les liens vides
  • Les labels manquants sur les formulaires (en amélioration)

D'autres statistiques intéressantes :

  • Près de 10% des pages n'utilisent aucun titre (éléments <h1>, <h2>, etc).
  • Environ 75% des pages semblent utiliser, au moins partiellement, les régions (landmarks ARIA).
  • L'usage d'ARIA a fortement augmenté ; les erreurs en découlant aussi, signifiant probablement (corrélation n'est pas causalité) que plus on tente de le mettre en place, plus il semble également "mal" intégré. Sa complexité de mise en oeuvre est-elle trop élevée ?
  • 20% des pages comportent des liens formulés tels que "cliquez ici".
  • 15% des pages comportent des liens d'évitement.

WebAIM 2022 catégories de sites

Parmi les catégories de sites, on notera que ceux qui ont le moins d'erreurs sont ceux qui se doivent de respecter des contraintes légales d'accessibilité (sites gouvernementaux, éducation) ou qui y mettent les moyens (technologie, réseaux sociaux). Les moins bien servis sont les sites de loisirs ou d'achat en ligne (qui devraient paradoxalement disposer d'un budget à cet effet).

Du côté des CMS (ou gestionnaires de contenu), Squarespace et Wix sont notés avec le moins d'erreurs, suivis de la famille Drupal, Typo3, Joomla, WordPress. On peut certainement penser que les plateformes tout-en-un qui ne nécessitent pas d'intervenir absolument sur le code source sont moins sujettes aux failles de conception. On peut aussi y deviner une influence du modèle économique pour les CMS conventionnels et des thèmes à personnaliser ou télécharger pour chacun d'entre eux. Il est difficile d'en tirer une conclusion tant la qualité des thèmes et extensions est variable : vous pouvez très bien disposer d'un site conçu "maison", simple et très accessible, tout comme un célèbre thème gratuit ou acheté qui n'aura pas été pensé avec un objectif de qualité.

Les chiffres sont détaillés pour les bibliothèques et frameworks JavaScript, sans toutefois dégager de score très significatif : là aussi c'est l'usage que l'on en fait qui est primordial, combiné à l'ancienneté. Un framework récent aura très probablement quelques bonnes pratiques de base déjà prises en compte, et écueils évités, et aura servi à concevoir des pages avec une meilleure prise en compte de l'accessibilité... par rapport à un site sorti il y a une dizaine d'années avec un "vieux" code.

Enfin, les régies publicitaires semblent générer plus de difficultés : les pages utilisant Google AdSense ou encore Criteo comportent statistiquement plus d'erreurs. C'est un point de vigilance.

Bonne lecture !

Publié par Alsacreations.com

Actualité : Interview des gens du web : Pierre Sauvé

$
0
0

Pour cette nouvelle interview des gens du web, nous souhaitions aborder un sujet qui change un peu et qui pourtant concerne tous les projets web (ou presque ?) : le référencement.

Derrière cet acronyme de Search Engine Optimization (Optimisation du Référencement Naturel) se cache tout un monde obscur. Pour faire la lumière sur ce sujet et nous sauver de toute la confusion qui règne dans le domaine, nous avons fait appel à Pierre Sauvé.

(Alsacréations) Peux-tu te présenter en quelques mots ?

Je m’appelle Pierre, 29 printemps et je suis depuis 3 ans consultant SEO Senior chez Digimood, une agence SEO / SEA / SMA présente sur Marseille, Montpellier (où je suis), Paris et dans les Alpes. J’ai une formation un peu hybride de développeur puis en marketing qui m’a amenée à découvrir le SEO en agence généraliste avant d’en faire une passion et un métier dans une agence spécialisée.

Pierre Sauvé, dans son milieu naturel
Pierre Sauvé, dans son milieu naturel

(Alsacréations) Tu es actuellement Consultant en SEO : qu’est-ce qui te passionne dans ton métier ?

Plusieurs choses mais pour tenter de raccourcir, je dirais les deux points suivants.

D’abord l’aspect “défis” du SEO qui est très motivant. On est face à un algorithme qui bouge beaucoup et face à des concurrents qui rivalisent d’ingéniosité pour passer devant nous, ça impose un certain rythme mais aussi une rigueur que j’aime bien.

Deuxième chose c’est le côté pluridisciplinaire, en faisant du SEO on touche à plein de choses : l’aspect technique bien sûr mais aussi l’aspect humain, l’UX, le rédactionnel, etc. Souvent un.e consultant.e va avoir des spécialités et dans une agence on est du coup ultra complémentaire les uns les autres.

Les prestations en SEO sont multiples et variées

(Alsacréations) Par quoi as-tu été amené à te spécialiser dans ce domaine ?

Presque par hasard, j’étais en agence web avant et je touchais un peu à tout : SEO, SEA, Facebook Ads, Community Management, etc. C’est intéressant pendant un temps mais j’avais envie d’être vraiment spécialisé dans un domaine et de laisser tomber les autres.

J’ai eu l’opportunité de rencontrer quelqu’un de chez Digimood, on a discuté et j’ai dit GO pour faire du SEO. Et voilà ça s’est fait comme ça !

Finalement c’est assez naturel, j’ai un background plus technique donc le SEO reste le levier qui fait le plus appel à mes compétences.

Digimood, agence SEO, SEA et Social Ads
Digimood, agence SEO, SEA et Social Ads

(Alsacréations) Y-a-t-il des fausses croyances en SEO sur lesquelles tu aimerais sensibiliser notre lectorat ?

Il y en a tellement, c’est d’ailleurs l’un des gros soucis de notre domaine, ce côté “science inexacte” qui permet à pas mal de fake news de circuler. Mais d’expérience voici celles contre lesquelles je bataille le plus :

  • “l’attribut nofollow empêchera Google d’explorer la page cible du lien” : C’est faux, cet attribut sert à donner une indication à Google sur le fait que vous ne souhaitez pas donner à la page cible de poids. Cela n’empêchera pas Google d’explorer cette URL. Les guidelines officielles sont pourtant très claires sur ce point.
  • “il faut au moins X mots pour avoir un contenu qui se positionne” : le SEO est tout sauf une science exacte, on peut sortir des milliers d’exemples de page avec 150 mots qui se positionnent très bien sur des mots-clés pertinents et inversement des milliers de pages de 2000 mots qui sont inefficaces. L'important c’est le contexte !
  • “en faisant du Google Ads j’améliore mon SEO” : là-dessus aucun commentaire particulier mis à part dire que c’est un mythe et bien heureusement !
  • “mettre un lien vers un site d’autorité externe apportera un meilleur signal SEO à ma page” : c’est mon préféré je pense ! On voit souvent des webmasters qui mettent un lien vers Wikipédia ou vers des sites gouvernementaux prétextant que cela aide au ranking. C’est faux, ça n’a jamais été démontré par des tests solides et ça n’a jamais été confirmé par Google. Il y a une utilité connue cependant : permettre de sourcer des informations (dans la santé notamment) ou permettre à ses lecteurs.trices d’aller plus loin dans leur lecture après votre site.

Il y en à plein d’autres, comme la balise meta keywords, mais ils sont beaucoup plus souvent cités je pense.

(Alsacréations) Selon toi, comment réussir à suivre les actualités et évolutions dans le domaine du SEO ? (Est-ce que ça change si souvent que ça ?)

C’est paradoxal, ça bouge tout le temps et pourtant on dit très souvent “comme au bon vieux temps”. En fait l’algorithme Google c’est comme un vieux bâtiment auquel on ajoute des nouveautés chaque année. Les fondations ne changent pas beaucoup, mais au bout de 10 nouveautés, le bâtiment change beaucoup aux yeux des gens.

Je pense qu’il n’y a pas de recette miracle pour suivre les actualités SEO, il faut échanger avec des professionnels du domaine et tester sans cesse les pistes. On a en France une communauté SEO qui est quand même assez active notamment sur Twitter, c’est un bon début. Personnellement je me promène pas mal sur les articles des communautés américaine et allemande, aussi sur reddit ou sur des blogs spécialisés.

Google communique quand même pas mal sur les évolutions de l’algorithme (parfois très tardivement), donc il est important de rester à l’écoute, tout en sachant qu’ils ne disent pas tout non plus…

(Alsacréations) Quels outils préconises-tu pour faire l’audit d’un site et monter une stratégie SEO efficace, basée sur de vraies données ?

Pour auditer un site, un bon référenceur n’aura pas besoin d’autres outils qu’un navigateur et Google. À mon avis, il faut toujours éviter de trop se reposer sur des outils au risque d’en devenir esclave. Sinon, l'outil qui reste le plus fiable, après nos méninges, est la Search Console car c’est le principal outil sur lequel de la vraie data issue de Google ressort.

Bien sûr il existe une tonne d’outils externes qu’on utilise pour nous faciliter les choses notamment dans le cadre des analyses concurrentielles et des stratégies de mots-clés. Le grand classique est Semrush car il a l’avantage d’avoir une base de données solide mais personnellement, j’utilise plus souvent l’excellent SEOBserver qui, en plus d’être français, est un condensé de data vraiment pensé pour les référenceurs.

(Alsacréations) Quelles sont tes extensions de navigateur préférées ?

On en a trop mais les indispensables sont, je pense, les suivants :

  • Web Developer : plugin multifonction qui permet notamment de facilement désactiver JS/CSS d’une page, de lister les liens, d’afficher le plan des , etc.

  • SEO pro extension : qui est aussi multifonction et qui est surtout pratique pour voir rapidement la <title> et l’URL canonique d’une URL.

  • Robots Exclusion Checker : comme son nom l’indique, elle permet de visuellement voir rapidement le statut d’indexabilité de l’URL courante.

  • Redirect Path : pour tout simplement suivre le(s) redirection(s) d’une URL afin de limiter les longues chaînes de 301.

  • SERP Counter : pour avoir la position des URLs directement depuis les pages de résultats de Google.

  • Hreflang tag Checker : comme son nom l’indique aussi, pour vérifier l’implémentation aller/retour de la balise hreflang pour des sites multilingue.

  • ModHeader : un peu plus rare mais très pratique, il permet de modifier facilement l’entête HTTP pour notamment tester votre page avec un UserAgent différent.

  • Ryte structured data helper : qui permet de voir directement depuis la page courante la structure des données structurées.

(Alsacréations) Si tu devais former un•e débutant•e en SEO, sur quels thèmes insisterais-tu particulièrement ?

Sans aucun doute l’importance de la notion d’intention de recherche. Pour moi ça a été le point qui m’a permis de vraiment passer une étape en SEO.

Il faut comprendre que Google a toujours comme objectif de remonter la page qu’il va juger la plus pertinente selon le contexte de l’utilisateur.trice (et cela avec des tonnes de facteurs bien sûr).

Si vous comprenez ce que votre cible attend lorsqu’elle tape une requête sur Google et que vous prenez le soin nécessaire pour répondre correctement à cette requête avec une URL adéquate, vous aurez fait une grosse part du travail !

L'objectif est d'aider l'internaute à trouver le contenu le plus qualitatif pour répondre à sa recherche.

(Alsacréations) Dans une autre vie, quel métier aurais-tu aimé exercer ?

J’ai voulu être pilote pendant très longtemps mais je suis myope comme une taupe… Du coup je dirais sans doute avocat ou journaliste pour défendre et informer les gens face à toutes les injustices qu’on peut croiser dans le monde d’aujourd’hui.

(Alsacréations) Question Bonus : peux-tu nous raconter une anecdote amusante à ton sujet ? (pro ou non)

J’en ai une qui n’est pas “amusante” mais qui m’a beaucoup fait grandir sur le pro comme le perso. Il y a peu, j’avais été contacté par quelqu’un que je connaissais d’une expérience pro passée pour travailler sur un projet “de rêve” : grosses ambitions, gros budget, cadre technique ultra poussé, deadlines correctes, etc…

Tout était parfait sauf une chose : la thématique qui était à l’opposé de mes valeurs personnelles sous tous les angles.

De mon côté j’étais persuadé de ne pas vouloir travailler dessus, mais je n’ai jamais osé en parler à mes supérieurs et ça m’a rongé pendant un moment jusqu’au jour où j’ai un peu sauté le pas pour ouvrir le sujet avec mon responsable.

Finalement, la majorité de mes collègues, y compris décideurs, était du même avis et on n’a pas donné suite. C’est un point qui m’a appris l’importance du dialogue et le fait de toujours essayer de travailler en accord avec ses valeurs personnelles.

Vraiment, on ne voit pas de meilleure conclusion, merci Pierre pour tout ce retour d'expérience et tes enseignements !

Publié par Alsacreations.com

Astuce : Passer de node-sass à dart sass

$
0
0

Si vous utilisez régulièrement Sass dans vos projets en tant que pré-processeur CSS, pour tous les avantages qu'il apporte, vous devez certainement utiliser l'une des deux implémentations : Dart-Sass ou Node-Sass, ce dernier étant en réalité une interface pour LibSass.

Sass

Ces outils sont utilisables en ligne de commande ou intégrés aux environnements de développement dans le processus de compilation, par exemple dans weboack, pour Vue, Nuxt, React, etc.

Or, le module node-sass (libSass) est désormais obsolète bien qu'il semble plus performant selon Quick comparison between sass and node-sass par Peter Bengtsson et Node-Sass or Dart-Sass : The CSS Preprocessor Dilemma par Ali Bahraminezhad.

Il y a plusieurs façons de migrer. Même si la documentation vous indique qu'il suffit de remplacer node-sass par sass dans package.json car dart-sass se veut compatible... cela peut être bien plus subtil. Voici quelques explications complémentaires, simplifiées, car évidemment cela dépend de chaque projet et de la version de Node utilisée (12+).

⚠️ Faites une sauvegarde avant toute modification en profondeur. Si votre projet est versionné sur git, c'est encore mieux.

Identifier la situation

Consultez le fichier package.json à la racine du projet.

S'il comporte "node-sass": "^5.0.0" ou autre numéro de version, dans les dependencies (dépendances) c'est que vous utilisez bien, pour le moment, node-sass.

Désinstaller/installer

Vous pouvez supprimer manuellement la ligne concernée et le dossier correspondant dans node_modules, cependant le plus propre sera de passer par les commandes npm :

npm uninstall --save sass
npm install --save sass

À partir de là, vous pouvez déjà tenter de relancer la compilation, et avec un peu de chance vous n'aurez pas besoin de faire autre chose, par exemple npm run dev ou npm run serve selon votre framework.

Si des avertissements et erreurs apparaissent, cela signifie que vous utilisez probablement des syntaxes Sass qui doivent être adaptées au nouveau module.

Adapter la syntaxe

Nous prendrons ici un seul exemple car il sera le plus fréquent : la division en CSS. D'autres évolutions peuvent être faites par la suite, optionnelles ou nécessaires si bloquantes.

Dans les fichiers, le caractère / est utilisé à la fois comme séparateur (dans Grid, rgb, hsl) et comme opérateur de division. C'est une difficulté pour Sass qui doit en comprendre le sens selon le contexte. L'usage de math.div() pour poser une division devient alors nécessaire.

Exemple :

/* node-sass */
line-height: (19 / 14);
height: (1rem / 16);

/* dart-sass */
line-height: math.div(19, 14);
height: math.div(1rem, 16);

Il existe un script de migration automatique sass-migrator qui peut faire le travail pour vous, mais il ne fonctionnera que sur les fichiers *.scss, pas les fichiers .vue qui associent différentes syntaxes (et il ne semble pas prévu de faire évoluer l'outil pour les supporter).

Vous devez l'installer pour y avoir accès en ligne de commande et spécifier le fichier à analyser comme point d'entrée, par exemple :

npm install -g sass-migrator
sass-migrator division --migrate-deps assets/css/main.scss

L'option --migrate-deps indique que l'outil passe aussi sur tous les fichiers importés à l'aide de règles @use, @import... La transformation menée ici est la division, il existe aussi module et namespace, reportez-vous à la documentation de Migrator.

⚠️ La règle @import est aussi destinée à devenir obsolète.

Sass:math

Il est possible que selon votre organisation de fichiers, la fonction math.div nécessite l'ajout de l'instruction @use "sass:math"; en début de fichier puisqu'elle dépend du module math. Or, le compilateur pourra vous renvoyer des erreurs si vos fichiers sont assemblés depuis de multiples dossiers ou composants car il ne souhaite cette instruction qu'en début de fichier. La solution est alors d'indiquer à webpack d'injecter cette ligne en préfixe via son loader dédié à Scss, dans la section build (fichier webpack.config.js, vue.config.js, nuxt.config.js, etc) :

  build: {
    /* Autres instructions existantes... */
    loaders: {
      scss: {
        additionalData: '@use "sass:math";'
      }
    }

Et voilà le travail !

Publié par Alsacreations.com

Actualité : Interview des gens du web : Chloé Temesvari

$
0
0

Pour cette nouvelle Interview des Gens du Web, j'ai eu le plaisir de prendre le flambeau et pour l'occasion, j'ai décidé d'échanger avec Chloé Temesvari, UX Designer et ergonome au sein de l'agence Impact Positif.

Chloé Temesvari
Chloé Temesvari, c'est bien elle !

Nous partageons le même (joli) prénom et une passion commune pour les post-it, voilà qui était une bonne base de départ :)

(Alsacréations) Hello Chloé, peux-tu te présenter en quelques mots ?

Bonjour ! Je m’appelle Chloé Temesvari, j’ai 35 ans et je travaille à Strasbourg en tant qu’UX designer, avec une spécialisation en ergonomie des interfaces.

J’ai travaillé pendant 8 ans en freelance et il y a deux ans, j’ai rejoint à mi-temps Impact Positif, société spécialisée dans l’expérience utilisateur.

A mi-temps car j’enseigne beaucoup en parallèle, et ce depuis la sortie de mes études il y a 10 ans. J’ai la chance depuis deux ans d’enseigner à mi-temps à l’IUT de Haguenau en DUT/BUT et Licence pro.

Et pour être sûre de ne pas m’ennuyer, j’interviens également dans différentes écoles privées, dans des formations Bac +5 !

Minitel
Quand on demande à Chloé son objet fétiche - véridique

(Alsacréations) Par quoi as-tu été amenée à te spécialiser dans l’ergonomie et l’UX Design ? Qu’est-ce qui t’a attiré dans le domaine ?

L’humain ! C’est peut-être un peu niais mais très vrai !

Quand je me suis engagée dans un master de création de sites web, ça en a fait sourire plus d’un car je n’étais vraiment pas à l’aise avec un ordinateur ou un smartphone ! J’avais de ce fait une empathie assez naturelle pour les personnes comme moi, un peu en galère avec l’informatique ;-)

Pendant ma formation, j’ai assisté à un court module sur l’ergonomie qui a piqué ma curiosité et j’ai réalisé que je pouvais par ce biais améliorer la navigation des internautes et les mettre en confiance.

La spécialisation professionnelle est venue plus tard. L’ergonomie n’était pas beaucoup pratiquée à l’époque, que ce soit par des free ou des agences. J’ai donc commencé comme beaucoup d’autres en faisant des sites “de A à Z” et je me suis rapidement rendue compte qu’à force de vouloir “tout” faire, le “tout” n’était pas de qualité. J’ai donc pris la décision de me spécialiser dans les thématiques avec lesquelles j’avais le plus d’affinités : l’ergonomie, la gestion de projet et la formation !

Quant à l’étiquette d’”UX designer”, j’ai mis du temps à me l’approprier car je ne me sentais pas légitime. C’est en pratiquant des prestations de recherche utilisateurs, de tests, etc. que je me suis autorisée à sauter le pas !

(Alsacréations) Actuellement, tu es Ergonome et UX designer mais également Formatrice à l'Université de Strasbourg : quelle évolution (poste, compétences) aimerais-tu poursuivre ?

C’est une excellente question !

J’aime profondément ce que je fais, à la fois dans ma pratique métier auprès des mes clients mais aussi dans l’enseignement auprès de mes étudiants. J’apprécie la complémentarité de ces deux approches qui restent centrées sur mon métier mais me permettent de l’aborder différemment. Je ne me vois pas faire un choix entre les deux pour le moment mais peut-être que j’y viendrai un jour 😉

Le dilemme de Chloé
Le dilemme de Chloé

En fait, je crois que mon ambition ne se traduit pas vraiment en termes de poste. J’ai surtout envie de continuer de faire évoluer mes interventions pour susciter de l’intérêt chez mes étudiants et m’assurer qu’ils repartent avec un bagage suffisant en sortant de mes cours.

J’ai également envie d’avoir plus de temps au quotidien pour faire de la veille. J’adorerais en particulier monter en compétences sur des notions de sociologie, de psychologie cognitive, d’accessibilité ou encore de statistiques et data analyse poussée.

(Alsacréations) Quels sont tes outils de travail au quotidien ? Comment les as-tu choisi parmi tous les autres ?

Au quotidien, les outils que j’utilise le plus sont…roulements de tambours…du papier, un crayon et des post-its !

Quand je travaille sur la conception d’une interface, que ce soit sur de l’architecture d’information ou des wireframes, j’ai besoin de réfléchir sur papier (ou tablette) avant de rentrer dans un logiciel, que ce soit en esquissant un écran ou en recouvrant les murs de mon bureau de posts-it pour tenter d’organiser mes idées !

le bureau post-it de Chloé
Le bureau de Chloé dans notre imaginaire

Il en va de même pendant les ateliers avec les clients, même si la pandémie et le recours au distanciel m’ont amenée à utiliser de plus en plus Miro. Une très jolie découverte que j’utilise également de plus en plus en cours ! J’aime beaucoup cette plateforme; c’est un formidable outil collaboratif qui ne cesse d’évoluer.

Figma est l’autre outil sur lequel je suis passée il n’y a pas si longtemps pour faire du maquettage; j’y ai encore beaucoup de choses à apprendre mais j’apprécie la fluidité de l’outil et la possibilité de maquetter et de prototyper au même endroit !

(Alsacréations) Quels sont ton navigateur et tes extensions préférées pour gagner du temps dans tes missions quotidiennes ?

Mon navigateur préféré est Chrome. Je n’utilise pas beaucoup d’extensions dans mon travail au quotidien si ce n’est WCAG Contrast Checker pour vérifier la qualité des contrastes des interfaces que j’évalue dans le cadre d’audit d’ergonomie, ou encore colorblindly qui permet de simuler la vue d’une page web sous différents types de daltonismes.

colorblindly
Colorblindly

(Alsacréations) Lorsque tu dois former un•e débutant•e en ergonomie et Webdesign, sur quels thèmes / règles d’or insiste-tu particulièrement ?

L’un des premiers points sur lesquels j’insiste, c’est la définition du mot design 😉. On en a définitivement pas tous la même et il est important qu’on s’aligne sur le vocabulaire avant d’aller plus loin. Pour moi, Design équivaut à conception. Une fois que ça c’est dit, on peut passer au reste ! Comme la définition de l’UX par exemple 😂 et le fait que même entre professionnels, nous ne sommes pas toujours d’accord sur son périmètre !

En ergonomie, j’aborde évidemment les incontournables heuristiques de Bastien et Scapin, de façon à identifier un ensemble de bonnes pratiques. Mais j’aime surtout aborder ce sur quoi reposent ces bonnes pratiques; effleurer le fonctionnement de notre cerveau, le mécanisme de notre perception, avec entre autres la théorie de la Gestalt, de notre attention, de notre mémoire.

J’ai le sentiment que cela offre une compréhension plus large de ces fameuses bonnes pratiques et évite ainsi de tomber dans la checklist bête et méchante.

Je rappelle aussi que ça n’est pas parce que c’est “tendance” que c’est forcément ergonomique. Tout comme concevoir une interface nécessite de se poser un peu la question de sa raison d’être avant de se perdre dans un logiciel de maquettage.

ergonomie ou design
Ergonomie ou design, faut-il choisir ?

Mais le fil conducteur, que ce soit en ergonomie/webdesign/UX, c’est l’utilisateur, et la nécessité de le prendre en considération. J’ai beaucoup lu qu’il était primordial de “se mettre à la place des utilisateurs” pour lesquels on conçoit. Cela me paraît délicat. Je ne peux pas me mettre dans les chaussures d’une personne qui a une expérience de navigation réduite, qui exerce un tout autre métier, qui a d’autres centres d’intérêt, ou encore un autre contexte d’usage.
Je peux tenter de me projeter mais ce ne seront que des hypothèses.
Je peux avoir de l’empathie, ça oui, c’est important ! Mais pour comprendre, je dois aller à la rencontre. C’est comme ça que j’en saurai plus sur mes utilisateurs finaux, leurs attentes, leurs besoins, et c’est comme ça que je serai à même de concevoir une interface qui leur correspond.

(Alsacréations) Question difficile : vois-tu émerger des nouveaux comportements des utilisateurs ces dernières années ?

Cette question est immense ! 😱

De quels utilisateurs parle-t-on ? De quels types de comportements ? Il est difficile de généraliser !

Ce que j’observe néanmoins ces derniers mois, c’est la nécessité d’aller vers plus d’équité numérique. La pandémie que nous vivons a mis en lumière de grandes disparités quant à l’accès au numérique : qu’il s’agisse d’accès purement matériel mais aussi d’éducation, et ce quel que soit l’âge.

Beaucoup sont partis du principe que parce que les outils numériques existaient, notre vie, ou tout du moins certains aspects de cette dernière, pourraient se transposer sans trop de difficultés à distance.
Je prends pour cela l’exemple des cours à distance. De nombreuses structures de formation, qu’elles soient publiques ou privées, étaient rassurées d’avoir une plateforme pour l’enseignement à distance, sans pour autant en avoir fait souvent l’usage. L’objectif était donc de reproduire au maximum l’environnement d’une salle de classe mais par écrans interposés : on conserve les mêmes horaires, le même format de cours et surtout on allume bien sa caméra.

C’est pourtant un contresens terrible ! Il ne s’agit pas d’outil mais de contexte d’usage. On n’enseigne pas à distance de la même manière qu’en présentiel, on n’a pas la même attention seul devant un ordinateur qu’au milieu d’une salle de classe, on n’a pas le même rapport à l’image quand le regard porté sur soi est avant tout une webcam.

Cela n’a fait que renforcer ma conviction que c’est en se concentrant sur leS utilisateurs et leurS contextes d’usage, en s’adaptant à eux, qu’on sera en capacité de forger les outils les plus efficaces.

(Alsacréations) Quel est le plus gros défi que tu considères avoir accompli ces derniers temps ?

En dehors de ne plus travailler (la majeure partie du temps) les soirs et week-end, je dirais de monter en compétences sur de la facilitation d’ateliers.

J’ai eu l’occasion ces derniers temps de faciliter quelques ateliers, en présentiel et à distance, et certains d’entre eux seule, ce qui n’a pas été sans inquiétudes !

La facilitation paraît proche de l’enseignement mais elle ne l’est pourtant pas tout à fait : la posture diffère. Le facilitateur n’est pas là pour “amener les réponses” mais pour “faciliter” la recherche de ces dernières par les participants eux-mêmes.

J’ai beaucoup aimé ces expériences qui m’ont permis de prendre confiance ! J’ai hâte d’en vivre d’autres et d’en apprendre plus !

(Alsacréations) Question Bonus : pourquoi un œuf à la coque en avatar sur Twitter ?

Parce que ! 😉
A l’époque, l’avatar par défaut sur twitter était un œuf. Comme je voulais personnaliser le mien sans pour autant y mettre ma bouille…et comme j’étais assez peu inspirée et en plein petit dej’, j’ai mis un œuf à la coque !

Le fameux oeuf, comme ça vous suivez

Publié par Alsacreations.com

Article : Le clavier, un moyen de navigation à ne pas négliger

$
0
0

Pourquoi est-ce utile ?

Pour certaines personnes, la navigation au clavier est un moyen essentiel pour naviguer et interagir avec les éléments d’un site. Par exemple, certains handicaps moteurs sont incompatibles avec la souris, et nécessitent d'utiliser des claviers adaptés. Pour les personnes malvoyantes ayant une cécité sévère ou totale, l’accès au contenu se fait via un lecteur d’écran qui est pilotable exclusivement par un clavier. Ou bien encore, pour n'importe qui utilisant les raccourcis claviers pour son propre confort.

En bref, la navigation au clavier est un aspect important de l’accessibilité web. Elle permet de rendre son site utilisable pour tous et de manière équitable.

Photo par Jay Zhang pour Unsplash

Comment l’utiliser

Si vous ne savez pas comment faire, c’est très simple. Il suffit de cliquer sur la page puis utiliser la touche tabulation Tab de votre clavier pour naviguer entre les éléments interactifs. Pour revenir en arrière, il faut combiner la touche Tab + Maj. La tabulation va alors se faire par rapport à l'endroit cliqué.

ℹ️ Si sur Mac cela ne fonctionne pas, il faut se rendre dans les "Préférences Système" > "Clavier" > “Raccourcis" et cocher *"Utiliser la navigation clavier pour déplacer la cible sur les différentes commandes"* (documentation Apple).

Faisons le test sur la page actuelle. Nous remarquons que :

  1. La tabulation se fait sur les liens, le champ de recherche, le bouton de soumission du formulaire, etc.
  2. La tabulation se fait selon l’ordre des éléments de la page.
  3. Que l’on visualise notre progression dans la page grâce à un contour vert.
  4. Que 3 liens cachés (Aller au menu / contenu / à la recherche ) apparaissent au début du site.

La visibilité du focus d’un élément interactif

La tabulation se fait sur tous les éléments interactifs : boutons, liens, champs de formulaire, sélecteur, etc. Lorsque l’on tabule sur l’élément, on constate la plupart du temps la mise en valeur par un contour (sur la page actuelle : vert kiwi 🥝) qui correspond à la propriété outline de l’élément. Et la tabulation correspond à déclencher, en CSS, la pseudo-classe :focus de l’élément (à noter que le :focus est également déclenché au clic, et au touch).

Il faut savoir que les navigateurs web ont un outline par défaut :

outline par défaut des navigateurs web : Chrome, Safari et Firefox
À l’heure actuelle l’outline par défaut des navigateurs web (ici de gauche à droite : Chrome, Safari et Firefox) est représenté par une bordure bleue légèrement arrondie.

Faisons un petit test : nous allons déclencher le focus en tabulant jusqu’au bouton ci-après et constater ce que l’on voit :

Vous y êtes parvenu ? Sûrement, mais vous ne l’avez pas vu car l’outline a été retiré. Déroutant hein ? Imaginez-vous ce que ça serait si l’outline était retiré sur tout un site... On n'aurait plus aucune indication sur la position du focus.

Cette indication est primordiale lors de la navigation au clavier, c'est ce qui va permettre à l'utilisateur de se repérer.

En résumé, il ne faut jamais retirer l’outline (le fameux *:focus { outline: none; }) ou bien utiliser une alternative comme la pseudo-classe CSS focus-visible, compatible sur la majorité des navigateurs modernes, qui permet de ne faire apparaitre le focus qu’à la navigation clavier. Dans ce dernier cas et dans celui où l’apparence de l’outline est modifiée il faut s’assurer qu’il soit assez contrasté par rapport à son milieu environnant.

Il existe d’ailleurs un critère RGAA à ce sujet :

📘 Critère 3.3. Dans chaque page web, les couleurs utilisées dans les composants d’interface ou les éléments graphiques porteurs d’informations sont-elles suffisamment contrastées (hors cas particuliers) ?
  • Le rapport de contraste est de 3:1, au moins ;
  • Un mécanisme permet un rapport de contraste de 3:1, au moins.

Pourquoi est-ce important ?

Pour toutes personnes ayant une déficience visuelle ou ayant une basse vision, ce rapport de contraste permet de distinguer et de faciliter la lisibilité des contenus.

Faisons un autre test. Déclenchons le focus du "bouton 1" et du "bouton 2". Qu’observons-nous ?

Pour le bouton 1 : peut-être rien, ou sinon très légèrement. C’est normal car le lien a un outline beaucoup trop clair par rapport à son fond environnant blanc. Son rapport de contraste est de 1,4:1 (testé sur Contrast finder) ce qui est très inférieur au 3:1 demandé par le RGAA.

En tabulant sur le bouton 2, le rapport de contraste est respecté, on peut distinguer l’état focus du bouton.

Si l'outline natif des navigateurs n'est pas annulé ou modifié par votre feuille de styles, le RGAA précise que le critère 3.3 ci-dessus n’est pas concerné :

Les cas suivants sont non applicables pour ce critère : […] Composant d’interface pour lequel l’apparence est gérée par les styles natifs du navigateur sans aucune modification par l’auteur (par exemple, le style au focus natif dans Chrome ou Firefox) ;

L’ordre du DOM

Concernant l’ordre des éléments : la tabulation suit successivement les éléments interactifs de la page. En fait elle reprend l’ordre naturel du DOM. Lors de l’intégration de sa page HTML, il faut donc s’assurer que les éléments soient positionnés de manière cohérente et logique.

Par exemple, pour un élément details lorsqu’il est ouvert, la tabulation doit être faite sur le premier élément interactif de la zone affichée.

Pourquoi est-ce important ?

Tout simplement pour ne pas perturber le lecteur et assurer une logique dans l’interactivité des éléments. Pour les personnes n’utilisant qu’un clavier, si la tabulation n’est pas cohérente, son utilisation sera complexifiée voire inutilisable. Voici un exemple :

La vidéo montre un formulaire avec plusieurs champs où l'ordre de tabulation est incohérent.

Il existe un critère RGAA à ce sujet :

📘 Critère 12.8. Dans chaque page web, l’ordre de tabulation est-il cohérent ?

À noter qu'il est possible de modifier l'ordre de tabulation grâce à l'attribut tabindex : soit en rendant un élément interactif (tabindex="0") soit en modifiant l'ordre naturel (non conseillé). Je vous redirige vers cet article pour en savoir plus sur son utilisation.

S’assurer que tous les éléments interactifs soient atteignables au clavier

Si un élément n’est pas correctement développé, il peut être totalement inutilisable au clavier.

Pour cela quelques principes sont à prendre en compte :

  • Utiliser correctement les button ou a href="#". Un bouton sert à déclencher une action sans changer de page (par exemple l'ouverture d'un menu, bloc caché ou d'une modale); un lien sert à naviguer vers une nouvelle page (interne ou externe).
  • Développer des composants atteignables au clavier et ne pas avoir de piège au clavier : le nouveau site du W3C sur les motifs de conception permet de retrouver un ensemble de composants utiles. Chaque composant est accompagné d'exemples concrets et d'une partie "Keyboard Interaction" (Interaction clavier) listant toutes les interactions à mettre en place. Les codes sources JS sont téléchargeables et donnent des exemples de code fonctionnel.

Mettre à disposition des liens d'accès rapides

Nous l’avons vu dans notre premier test : 3 liens cachés sont apparus à la tabulation lors de notre arrivée sur le site. Mais pourquoi ? Car ces liens permettent de se rendre directement au contenu souhaité. C’est un accès rapide à différentes zones d’un site (contenu principal, menu, recherche, pied de page, etc.) qui permet de faciliter la navigation au clavier ! Bien sûr, la page doit être correctement structurée en zones claires et sémantiques (Régions landmarks) dans un premier temps.

Il faut savoir que le RGAA préconise d’en avoir un à minima correspondant à l’accès rapide du contenu principal :

📘 Critère 12.7. Dans chaque page web, un lien d’évitement ou d’accès rapide à la zone de contenu principal est-il présent (hors cas particuliers) ?

Ce lien d'accès rapide doit être le premier élément interactif du site, et peut-être masqué de manière accessible (donc visible pour les lecteurs d’écran (en utilisant la classe sr-only de Tailwind par exemple)) et visible pour tous au focus.

Ces quelques points représentent les actions importantes à mettre en place pour assurer la navigation au clavier sur son site web. Bien sûr, il existe d’autres critères à mettre en place (hiérarchie des titres, structuration de la page, etc.) mais nous ne pouvons tout voir dans un seul article. Si vous êtes curieux·euses d’en savoir plus n’hésitez pas à le dire. Bonne lecture !

Publié par Alsacreations.com


Article : Le Reset CSS, une histoire d'héritage et de réinitialisation

$
0
0

Un Reset CSS c'est quoi ? Pour quoi ?

Les navigateurs web sont tenus d'appliquer des styles par défaut (User Agent Stylesheet) à chaque page HTML, sinon le document afficherait une page blanche (source : specifications CSS).

Chaque navigateur applique ses propres styles par défaut pouvant se révéler différents les uns des autres, sinon ce serait trop facile pour nous autres développeuses et développeurs !

Deux méthodes permettent de contourner ces différences d'affichages entre les navigateurs : le Reset CSS et le Normalize CSS.

Différence de rendu entre les navigateurs web (source)

Reset ou Normalize ?

Un "Reset CSS" (réinitialisation) est une technique qui consiste à repasser toutes les valeurs des propriétés CSS à leur état initial afin repartir de zéro et d'une base vierge avant d'appliquer nos propres styles.

Un "Normalize CSS" (harmonisation) consiste à appliquer des styles de base cohérents identiques sur chaque navigateur. Cette méthode corrige également les différences d'interprétation des spécifications et d'affichage sur l'ensemble des navigateurs et produit une base de travail suffisante (typographie, interlignages, marges, etc.)

Cela dépend bien évidemment de vos besoins, mais dans la plupart des projets il est suffisant d'appliquer une couche de Normalisation, car un Reset vous forcera à redéfinir toutes les propriétés une à une pour votre projet.

L'article (en anglais) Normalize CSS or CSS Reset?! de Elad Shechter résume bien cette dualité d'outils.

L'article (en anglais aussi) A tale of CSS Resets and Everything You Need to Know About Them. Revisited. de Margo Roi est extrêmement riche en informations sur l'évolution des techniques de Reset / Normalize, leur intérêt dans le détail et propose une liste très complète de l'ensemble des solutions existantes actuellement (Eric Meyer, Yahoo!, Normalize, Sanitize, Reboot, Remedy, etc.)

Comprendre et provoquer l'héritage des propriétés

Une propriété héritable est une propriété qui récupère automatiquement la valeur de son parent. C'est le cas par exemple des propriétés typographiques ou des listes (ex. font-size, color, list-style, etc.).

Une propriété non héritable adoptera par défaut la valeur initial telle que définie dans les Spécifications. Par exemple une bordure, une largeur de boîte ou une couleur de fond n'est pas transmise par héritage aux descendants. La majorité des propriétés CSS ne sont pas héritables.

Voici une liste des propriétés CSS héritables courantes :

  • color
  • cursor
  • direction
  • font-family
  • font-size
  • font-style
  • font-variant
  • font-weight
  • font
  • letter-spacing
  • line-height
  • list-style-image
  • list-style-position
  • list-style-type
  • list-style
  • text-align
  • text-indent
  • text-transform
  • visibility
  • white-space
  • word-spacing
Propriété héritée ou non ? (source)

Il est possible de forcer l'héritage d'une propriété en lui appliquant la valeur inherit. Elle prendra alors la valeur de la propriété du parent (c'est à dire son ancêtre direct).

Il est également possible de contrôler l'héritage de toutes les propriétés grâce à la propriété raccourcie all afin d'appliquer la valeur indiquée sur toutes les propriétés (source : MDN : Héritage).

Cibler toutes les propriétés via all

La propriété all est un super-raccourci de toutes les propriétés appliquables à un élément, ce qui lui permet d'hériter ou de réinitialiser toutes les valeurs à la fois.

Les valeurs possibles sont inherit, initial, unset et revert.

Exemple :

.parent {
  display: grid;
  margin: 2rem;
  color: hotpink;
}
.enfant {
  all: inherit; 
}

Dans cet exemple, all cible toutes les propriétés de .enfant et inherit les rend héritables, donc cela est équivalent au code suivant (pour les propriétés concernées) :

.enfant {
  display: grid;
  margin: 2rem;
  color: hotpink;
}

Appliquer les valeurs par défaut via initial

La valeur initial appliquée à une propriété lui confère sa valeur par défaut telle que prévue par les Spécifications CSS.

Exemple :

.parent {
  display: grid;
  margin: 2rem;
  color: hotpink;
}
.enfant {
  all: initial; 
}

Cet exemple est équivalent au code suivant (pour les propriétés concernées) :

.enfant {
  display: inline;
  margin: 0;
  color: canvastext;
}

Ce résultat peut surprendre dans la mesure où l'on s'attend généralement à la valeur block pour la propriété display (surtout si l'enfant est un élément tel que <div> ou <p>) ou black pour la propriété color, or il n'en est rien.

Il faut comprendre que toutes les propriétés CSS ont une valeur initiale définie dans les Spécifications (exemple display vaut inline). Puis elle est parfois écrasée par le navigateur au cas par cas selon les éléments (exemple div {display: block})

Quelques exemples de valeurs initial surprenantes :

  • display: initial; vaut inline
  • max-width: initial; vaut none
  • width: initial; vaut auto
  • position: initial; vaut static
  • cursor: initial; vaut auto
  • appearance: initial; vaut none
  • color: initial; vaut canvastext (valeur récente, adaptée aux modes utilisateur Dark et Light).

Réinitialiser ou hériter via unset

La valeur unset appliquée à une propriété lui confère la valeur du parent si la propriété peut être héritée ou la valeur initiale dans le cas contraire.

Exemple :

.parent {
  display: grid;
  margin: 2rem;
  color: hotpink;
}
.enfant {
  all: unset; 
}

Cet exemple est équivalent au code suivant (pour les propriétés concernées) :

.enfant {
  display: inline;
  margin: 0;
  color: hotpink;
}

Dans cet exemple, display et margin ne sont pas héritables donc leur valeur est calculée à initial, mais la couleur, héritable, est transmise.

Quelques exemples de valeurs unset :

  • max-width: unset; : non héritable donc unset vaut initial qui vaut none
  • width: unset; : non héritable donc unset vaut initial qui vaut auto
  • position: unset; : non héritable donc unset vaut initial qui vaut static
  • font-size: unset; : héritable donc récupère la valeur du parent
  • color: unset; : héritable donc récupère la valeur du parent (ici hotpink)
Tweet de Benjamin de Cock illustrant l'intérêt de la valeur `unset` appliquée sur un bouton

Récupérer la valeur du navigateur via revert

La valeur revert récupère la valeur appliquée par l'Agent Utilisateur.
S'il n'y en a pas, revert devient unset (qui lui-même vaut inherit ou initial selon le cas 🤯)

Exemple :

.parent {
  display: grid;
  margin: 2rem;
  color: hotpink;
}
.enfant {
  all: revert; 
}

Cet exemple est équivalent au code suivant (pour les propriétés concernées) :

.enfant {
  display: block;
  margin: 0;
  color: hotpink;
}

Dans cet exemple, display vaudra block puisque c'est la valeur attribuée par le navigateur sur l'élément <div>. Le navigateur n'applique pas de valeurs spécifiques au propriétés margin et color donc elles deviendront respectivement initial et inherit.

Quelques exemples de valeurs revert selon l'élément appliqué :

  • div {display: revert} vaut block
  • p {display: revert} vaut block
  • span {display: revert} vaut inline
  • td {display: revert} vaut table-cell
  • input {display: revert} vaut inline-block

Ces valeurs conférées par les navigateurs (User Agent Stylesheet) présentent parfois quelques différences selon les moteurs de rendu.

L'inspecteur d'élément de votre navigateur (clic droit > Inspecter) permet lui aussi d'afficher les valeurs CSS qu'il applique.

Vers le Reset / Normalize parfait ?

L'ensemble des propriétés et valeurs décrites au sein de cet article (all, inherit, initial, unset et revert) offre une très large panoplie de possibilités de réinitialisation en CSS lorsque cela vous est nécessaire.

Un Reset CSS proche de la perfection ressemblerait à ces deux simples lignes :

* {
  all: unset;
  display: revert;
}

Ces deux lignes résument à elles seules les consignes suivantes :

  • Toutes les propriétés appliquables à tous les éléments doivent être remises à zéro, sauf pour les propriétés héritables qui sont conservées, cela évite de devoir tout re-styler notamment pour les propriétés typographiques.
  • Concernant la propriété display, nous souhaitons que la navigateur continue d'appliquer ses valeurs préférées (donc block, inline, etc. selon l'élément).

Si la perfection existait, nous serions en présence du Reset ultime. Mais dans la vraie vie il y a aussi des images, des vidéos, des iframes, des tableaux, des SVG, etc.

Voilà pourquoi je ne saurais que vous conseiller de vous intéresser au projet "The New CSS Reset" maintenu sur Github par l'excellent Ahmad Shadeed et qui apporte les quelques affinages nécessaires.

The New CSS Reset

Et vous, quelle est votre position par rapport à ces problématiques d'héritages, de cascades et de reset CSS ?

Avez-vous des solutions à tout faire que vous nous recommanderiez ?

Publié par Alsacreations.com

Tutoriel : Traductions multilingues avec Timber

$
0
0

On l'a vu dans l'article "Pourquoi écrire du Twig dans WordPress ?", Timber est une excellente dépendance pour WordPress faite pour les développeurs.

J'aimerais faire le lien avec l'article "Préparer un thème WordPress pour l'internationalisation", car la syntaxe n'est pas forcément évidente si vous êtes habitués à l'écriture standard de WordPress.

Les bases

Dans l'ensemble, rien de bien plus compliqué qu’avec PHP hormis la syntaxe. On utilise toujours la même fonction WordPress qui est aussi disponible dans Timber.

Voilà un exemple simple avec PHP :

<?php echo __( "Voir toutes les actualités", "textdomain" ); ?>

Et voilà son équivalent avec Timber :

{{ __( "Voir toutes les actualités", "textdomain" ) }}

Jusqu’ici tout va bien, si vous avez l’habitude d’écrire en Twig c’est la même chose.

Abordons maintenant un cas plus spécifique.

Gérer les singuliers et les pluriels

Dans cette partie, on utilisera l'exemple de la barre de recherche, qui est un composant que l'on retrouve fréquemment sur beaucoup de sites et qui est naturellement accompagnée d'une page de résultats, sur laquelle on retrouve une phrase récapitulant le nombre de résultats trouvés et la requête faite par l'utilisateur.

Le formulaire de recherche d'alsacreations.com

Cette dernière est souvent sous la forme : "X résultat(s) trouvé(s) pour le mot Y."

Ce qui induit qu'en fonction du nombre de résultats trouvés, cette phrase peut être au pluriel. Comme toujours, il y a plusieurs méthodes pour réaliser cela et je divulgâche, mais certaines de ces méthodes sont meilleures que d'autres sur plusieurs points.

Première méthode

En tant que développeur, on peut être tenté de gérer l'affichage avec une condition.

Par exemple :

  • Si le résultat de ma recherche est supérieur à 1, j'affiche le pluriel, sinon j'affiche le singulier.
  • J’utilise la fonction sprintf avec les spécificateurs adéquats respectivement pour le nombre de résultats et le terme de recherche.

En PHP, cela donnerait :

<?php if( $search_result > 1 ) : ?>

  <?php
    sprintf(
      __( "%d résultats trouvés pour le mot \"%s\".", "textdomain" ),
        $search_result,
        get_search_query()
    );
  ?>

<?php else : ?>

  <?php
    sprintf(
      __( "%d résultat trouvé pour le mot \"%s\".", "textdomain" ),
        $search_result,
        get_search_query()
      );
  ?>

<?php endif; ?>

Et avec Timber :

{% if search_result|length > 1 %}

  {{
    __( "%d résultats trouvés pour le mot \"%s\".", "textdomain")|format(
      search_result|length,
      fn('get_search_query')
    )
  }}

{% else %}
  {{
    __( "%d résultat trouvé pour le mot \"%s\".", "textdomain" )|format(
      search_result|length,
      fn('get_search_query')
    )
  }}

{% endif %}

C’est la même chose, excepté que l’on remplace un appel de fonction par un filtre.

On y retrouve :

  • Le filtre length sur la variable search_result renvoie le nombre d'éléments.
  • La fonction __() pour les traductions avec le bon textdomain
  • Le filtre format qui est l’équivalent de la fonction sprintf en PHP
  • fn() ou function() qui permet d’utiliser une fonction WordPress ou PHP

Avec cette méthode, si search_result est supérieur à 1, on obtiendra :

2 résultats trouvés pour le mot Burger.

Sinon :

1 résultat trouvé pour le mot Burger.

Parfait, le résultat est comme attendu. Ça fonctionne !

Dans notre outil de traduction (Poedit), on retrouve bien les chaînes de caractères à traduire. Cependant, il y a une chaîne pour gérer le singulier et une pour gérer le pluriel.

Les chaines de traduction dans Poedit

Pourquoi ça ne va pas ?!

  • On se retrouve avec deux traductions à produire, alors que c’est potentiellement la même phrase.
  • S'il y a des cas similaires à traiter sur le site, on aura un fichier de traduction long comme le bras, qui contient pleins de doublons de phrases.
  • Si le fichier doit être fourni à une tierce personne pour la traduction, cela manquera de contexte pour traduire correctement.

Il existe des fonctions faites pour ce genre de cas !

La bonne méthode

Pour avoir des traductions singulier/pluriel propres et optimisées, on utilise la fonction WordPress _n(), qui est un tout-en-un.

Il suffit de lui passer la valeur qui sert de référence et elle s'occupera de choisir d'afficher le singulier ou le pluriel.

Toujours dans l'exemple de page de résultats de recherche, voici comment l'utiliser avec PHP :

<?php
  sprintf(
    _n(
      "%d résultat trouvé pour le mot \"%s\".",
      "%d résultats trouvés pour le mot \"%s\".",
      $search_result,
      "textdomain"
    ),
    $search_result,
    get_search_query()
  );
?>

Et son équivalence avec Timber :

{{
  __(
    _n(
      "%d résultat trouvé pour le mot \"%s\".",
      "%d résultats trouvés pour le mot \"%s\".",
      search_result|length,
      "textdomain"
    )|format(
      search_result|length,
      fn('get_search_query')
    )
  )
}}

Mais c’est plus imbriqué, plus dur à lire/écrire et la finalité est la même ! Alors ça change quoi ? 🤔

Le résultat dans l'outil de traduction est complètement différent !

Un exemple de gestion correcte des pluriels dans Poedit

Pourquoi c’est mieux ? Pourquoi privilégier cette méthode ?

  • Le singulier et le pluriel se retrouvent dans le même champ pour la traduction
  • On apporte plus de contexte et de compréhension
  • On obtient un fichier de traduction optimisé et propre

Et voilà ! Vous avez une bonne pratique supplémentaire à intégrer dès le début du développement de votre thème WordPress avec Timber !

À bientôt pour un prochain article. 🙂

Retrouvez l'intégralité de ce tutoriel en ligne sur Alsacreations.com

Article : Maîtriser la spécificité CSS grâce à Cascade Layers

$
0
0

Les styles CSS doivent leur nom à la Cascade, qui est un bien joli et complexe algorithme tenant compte de nombreux paramètres tels que l'origine des styles, la spécificité des sélecteurs ainsi que leur ordre d'apparence.

La Cascade, c'est l'essence même de CSS. C'est ce qui fait son utilité, sa beauté… et c'est aussi le pire cauchemar des intégratrices et intégrateurs.

La Cascade, c'est ce qui fait que nos paragraphes arboreront une chatoyante couleur hotpink avec les déclarations suivantes :

<p class="kiwi">Coucou !</p>
p {color: tomato;}
p {color: hotpink;}

Mais quel est le problème au juste ?

Dans un monde idéal, l'intégration HTML / CSS est prise en compte en amont du projet, en se donnant les ressources adéquates et les compétences nécessaires. Ce n'est bien évidemment pas un domaine que l'on traite à la légère, après le budget alloué à la communication, au SEO, aux développements "lourds" etc. en se disant que "après tout ce n'est que du CSS, même pas un vrai langage".

Mais ça c'est dans un monde idéal.

Dans un vrai projet, on récupère du code produit par des anciens stagiaires disparus ou par des frameworks de version obsolète, on a totalement oublié de s'appuyer sur une convention de nommage, on intègre avec un onglet de Stackoverflow toujours ouvert dans un coin, et on peste contre le monde entier à tenter d'écraser des styles avec !important (voire des !veryimportant ah non ça c'était une blague).

Qui n'a jamais utilisé !important me jette la première <br> !

Le vrai projet, c'est celui où l'on passe toujours trop de temps à comprendre pourquoi nos paragraphes sont chocolate et pas hotpink dans ce cas là :

p {color: tomato;}
.kiwi {color: pink;}
div p:first-child {color: chocolate;}
p.kiwi {color: hotpink;}

Où les Cascade Layers entrent en jeu

Les spécifications CSS ont introduit une règle-at @layer permettant de redéfinir l'ordre et la priorité dans la cascade CSS à l'aide de "layers" (couches).

Le principe général est simple : l'ordre de déclaration des layers (Layers Order) est prioritaire sur la spécificité des sélecteurs.

Ainsi, dans l'exemple qui suit, les paragraphes prendront la couleur hotpink car leur couche est déclarée en dernier.

@layer reset {
  p {color: olive;}
  .kiwi {color: pink;}
  div p:first-child {color: chocolate;}
}
@layer base {
  p {color: hotpink;}
}

Un tiramisu pour représenter les couches

Déclarer des layers

Il existe plusieurs moyens de créer des couches de styles : la règle @layer avec styles associés, la même sans styles, ou l'import de fichiers de styles externes.

Règle @layer avec styles associés

On déclare la couche via @layer en lui donnant un nom (optionnel) et on y applique des règles CSS.

@layer reset {
  /* ici les règles CSS de la couche reset */
}
@layer base {
  /* ici les règles CSS de la couche base */
}

Règle @layer sans styles

On déclare la couche via @layer vide.

@layer reset;
@layer base;

Pour info, cet exemple est équivalent à cette syntaxe :

@layer reset, base;

Cette formulation, sans styles associés, n'a d'autre but que de déclarer un ordre précis dans les couches.

Import de styles externes

La notion de layer peut être associée à la règle @import :

@import url("reset.css") layer(reset);

En plus de l'import via @import, le W3C travaille sur une version importée avec l'élément <link>.

Concrètement cela représente un moyen très simple de pouvoir :

  • Importer les styles d'un framework tel que Boostrap (au hasard) au sein de layers, donc avec une spécificité moindre
  • Pouvoir redéfinir ses propres styles sans se soucier du poids des sélecteurs Boostrap ni même des !important… et si j'évoque ce framework en particulier, ce n'est pas tout à fait anodin (oui, il y a bien 1307 !important dans ce seul fichier CSS)
@import url("bootstrap.css") layer(framework);

Cake sucré de marque Layers of Joy

En pratique

Le postulat de base est que chaque layer est prioritaire sur le layer déclaré avant lui. L'ordre est donc primordial.

Dans l'exemple qui suit, tous les paragraphes seront de couleur hotpink même s'ils disposent de la classe .kiwi car le layer base est déclaré après reset :

@layer reset {
  p.kiwi {color: tomato;}
}
@layer base {
  p {color: hotpink;}
}

Étendre des styles aux layers existants

Il est possible d'ajouter des styles à une couche existante, simplement en reprenant le nom du layer déjà créé :

@layer reset {
  p.kiwi {color: tomato;}
}
@layer base {
  p {color: hotpink;}
  h1 {color: olive;}
}
@layer reset {
  h1 {color: chocolate;}
}

Dans cet exemple, les styles sur h1 sont ajoutés à ceux déjà présents dans la couche reset.

Notez qu'étendre des layers ne modifie pas l'ordre originel (et donc l'application) des layers. En clair, ici la couleur des titres h1 sera olive car le layer base est déclaré après reset.

Une bonne pratique consiste à définir dans un premier temps l'ordre de toutes les couches en une règle raccourcie (ex. @layer reset, base;), puis d'étendre les styles de chacun des layers, ainsi il n'est pas possible de se tromper dans l'ordre d'application des couches.

Dans l'exemple suivant, je souhaite prioriser les styles de la couche base, je vais donc commencer par indiquer l'ordre à respecter.

Ici, malgré ma maladresse (j'ai étendu les styles base puis ceux de reset), ce sont bien les styles de base qui sont prioritaires et s'appliquent. Les paragraphes seront hotpink :

@layer reset, base;

@layer base {
  p {color: hotpink;}
}

@layer reset {
  p {color: olive;}
  .kiwi {color: tomato;}
}

Cake sucré de marque Multi Layers

Particularité des styles sans layer

Cela peut paraître curieux, mais les styles sans layer sont appliqués en priorité.

Ainsi, dans l'exemple qui suit les paragraphes seront de couleur hotpink :

p {color: hotpink;}

@layer reset {
  p {color: olive;}
  p.kiwi {color: tomato;}
}

Imbrication de layers

On peut imbriquer les Cascade Layers de cette manière :

@layer framework {
  @layer reset {

  }
}

Il est ensuite possible d'étendre les styles de ce layer en y faisant référence ainsi :

@layer framework.reset {
  /* j'étends les styles dans le layer reset dans framework */
  p { color: hotpink; }
}

Compatibilité et mot de la fin

Bonne nouvelle : CSS Cascade Layers est une spécification dont le support est relativement large. À l'heure où cet article est rédigé, seules les anciennes versions de Safari et Samsung Internet sont à la traîne (si on ne tient pas compte d'Internet Explorer bien sûr). Cela signifie que cette fonctionnalité peut très vite être utilisable en production.

Support de CSS Cascade Layer sur les navigateurs web à partir de caniuse.com

Et vous, qu'en pensez-vous ? Êtes-vous aussi impatient que moi de pouvoir bénéficier de cette spécification afin d'assainir radicalement tous les anciens projets web que l'on maintient tant bien que mal ?

Publié par Alsacreations.com

Tutoriel : L'API Fetch en JavaScript, qu'est ce que c'est ?

$
0
0

Si vous êtes développeur front-end, vous avez sûrement déjà rencontré le besoin de récupérer des informations depuis le navigateur.

Aujourd'hui, nous allons voir comment utiliser l'API fetch disponible dans la quasi totalité des navigateurs.

Le besoin

Dans certaines situations, il peut être avantageux de récupérer des informations directement depuis le navigateur plutôt qu'avant le rendu de la page sur le serveur (par exemple avec PHP).

Dans le cas d'un formulaire de recherche, il n'est pas forcément nécessaire de recharger complètement la page pour la régénérer sur le serveur, nous pourrions ici faire une requête Ajax en arrière plan qui serait plus rapide.

Pour ce faire, nous aurons besoin d'une API REST. Pour faire simple, une API REST est une collection d'URI sur lesquelles nous pouvons faire des requêtes HTTP (GET, POST, PATCH,...) et récupérer des informations, préférablement en JSON.

EX: GET "https://jsonplaceholder.typicode.com/todos/1"

Résultat:

{
  "userId": 1,
  "id": 1,
  "title": "delectus aut autem",
  "completed": false
}

Utilisation

Pour répondre à notre besoin, la méthode la plus simple (et la plus moderne) est d'utiliser fetch.

Sans plus attendre, passons au code. ▶️

Pour lancer une requête, c'est aussi simple que d'appeler la fonction avec notre URI, ainsi que la méthode HTTP correspondante.

fetch('https://jsonplaceholder.typicode.com/todos', { method: 'GET' })

Cependant ceci ne suffit pas pour récupérer le résultat de la requête, puisque fetch retourne une promesse.

Nous utilisons ici .then() pour récupérer le résultat de cette promesse.

fetch('https://jsonplaceholder.typicode.com/todos', { method: 'GET' })
  .then(function (response) {
    // `response` contiendra ces propriétés (en partie)

    /*
      readonly headers: Headers; -> https://developer.mozilla.org/fr/docs/Web/HTTP/Headers
      readonly ok: boolean; -> `true` si la requête s'est bien déroulée, `false` sinon
      readonly status: number; -> https://developer.mozilla.org/fr/docs/Web/HTTP/Status

      blob(): Promise<Blob>; -> Conversion du résultat en Blob
      formData(): Promise<FormData>; -> Conversion du résultat en formData
      json(): Promise<any>; -> Conversion du résultat en JSON
      text(): Promise<string>; -> Conversion du résultat en texte
    */
  })

Dans le cadre de notre besoin, ce qui nous intéresse, c'est de recevoir le résultat en JSON, nous utiliserons donc response.json() qui retourne également une promesse.

fetch('https://jsonplaceholder.typicode.com/todos', { method: 'GET' })
  .then(function (response) {
    return response.json()
  })
  .then(function (json) {
    // `json` est le vrai résultat de notre requête !
  })

Dans la plupart des cas (et selon vos conventions de code), les requêtes fetch s'écrivent:

fetch('https://jsonplaceholder.typicode.com/todos', { method: 'GET' })
  .then((response) => response.json())
  .then((json) => { /* ... */ })

fetch permet également de passer plusieurs options à notre requête HTTP, par exemple des headers.

Certaines requêtes comme les POST ou PUT peuvent récupérer un body, également pris en charge par fetch !

const options = {
  method: 'POST',

  headers: {
    // Nous n'accepterons que le JSON en résultat.
    'Accept': 'application/json',
    // Dans le cas d'une requête contenant un body,
    // par exemple une POST ou PUT, on définit le format du body.
    'Content-Type': 'application/json',
    // Cas d'usage courant pour gérer l'authentification avec une API REST.
    'Authorization': 'Bearer ${token}'
  },

  body: JSON.stringify({
    title: 'Un post',
    content: 'Contenu de mon post'
  })
}

fetch('https://example.com/posts', options)
  .then((response) => response.json())
  .then((createdPost) => { /* ... */ })

Conclusion

fetch est une façon très simple (beaucoup moins verbeuse que XMLHttpRequest) de faire des requêtes HTTP et permet d'améliorer la performance d'un site dans certains cas.

Nous sommes toujours curieux chez Alsacréations, n'hésitez pas à nous faire des retours d'expérience en relation avec fetch 😉.

Retrouvez l'intégralité de ce tutoriel en ligne sur Alsacreations.com

Tutoriel : Votre première application Svelte

$
0
0

Sans avoir à télécharger ou à installer quoi que ce soit, vous allez apprendre tout ce que vous devez savoir sur Svelte.

Svelte est un framework orienté composants et réactivité (comme React ou Vue), mais avec des différences majeures dans son architecture : pas de Virtual DOM, une transformation des instructions dès la compilation en JavaScript qui va directement modifier le DOM. Ainsi il n'y a pas d'injection du framework lui-même dans le code produit, l'idée est de favoriser les performances au maximum.

Svelte

Vous allez utiliser l'application REPL sur le web.

Un REPL lit le code que vous saisissez, l'évalue, le met à jour et l'affiche. Il existe des REPL pour de nombreux langages de programmation et de frameworks web. Le REPL est une passerelle parfaite pour développer des petites applications. Pour des projets plus complexes, un éditeur de texte ou IDE sera plus adapté.

Ce cours explique comment télécharger des applications REPL pour un petit développement. En le suivant jusqu'à la fin, vous serez prêt à commencer à développer vos propres applications Svelte.

Le Repl de Svelte

Svelte.dev fournit un REPL permettant de définir des composants Svelte et de voir leur rendu. L'utilisation de ce REPL est le moyen le plus facile d'expérimenter Svelte.

Pour commencer, allez sur le site Web principal de Svelte.dev, puis cliquez dans le navigation sur le lien REPL. Vous devriez constater que l'on vous présente une petite application qui se nomme "Hello World".

L'utilisation du REPL de Svelte

Le seul fichier fourni dans le REPL est App.svelte. Ce fichier peut en importer d'autres. Ils sont définis dans des onglets supplémentaires au sein du REPL.

Pour ajouter d'autres fichiers .svelte ou .js, cliquez sur le bouton plus (+) à droite des onglets, puis donnez un nom à votre nouveau fichier. Par défaut, les fichiers nouvellement créés ont une extension *.svelte. Pour signifier que vous utiliserez un fichier *.js, renommez complètement l'onglet.

En général, lorsque vous constatez l'erreur "Failed to construct 'URL' : Invalid base URL", cela signifie que le nom de l'onglet (donc le nom du fichier) ne comporte pas d'extension. De ce fait, il vous sera impossible d'importer ce dernier.

Pour supprimer un fichier, cliquez d'abord sur l'onglet correspondant si ce n'est pas le fichier actif, puis cliquez sur la croix "X" qui apparaît à droite de son nom.

Le REPL contient trois onglets à droite :

  • Result : affiche la sortie rendue de App.svelte. Lorsque cet onglet est sélectionné, le coin inférieur droit du REPL affiche le résultat de l'application.
  • JS output : affiche le code compilé en Javascript
  • CSS output : affiche le CSS minifié et généré par l'application.

La barre supérieure du REPL contient des liens vers de nombreuses ressources Svelte (des tutoriels, la documentation de l'API, des exemples, le blog Svelte, la FAQ Svelte, la page d'accueil de Sapper, etc.).

barre de navigation du repl de svelte

Vous pouvez afficher ou masquer la navigation en cliquant sur le bouton "Plein écran" (qui devient une croix si vous êtes déjà en plein écran).

Svelte : bouton plein écran

Votre première application Svelte

Créons une application simple pour découvrir certaines fonctionnalités de Svelte.

Ajoutez le code HTML avant l'élément h1 :

<label for="name">Name</label>
<input id="name" value={name}>
L'élément HTML input est ce que l'on appelle un mono-élément ou élément auto fermant. Lorsque des mono-éléments vides sont utilisés dans des composants Svelte ils n'ont pas besoin d'être terminés par `/>`. Cependant, si Prettier est utilisé pour formater le code, il modifiera les mono éléments pour qu'ils soient terminés de cette façon. C'est pourquoi certains exemples de code dans ce tutoriel montrent des mono éléments terminés.

Maintenant nous devons saisir un nom, mais cela ne change pas le message d'accueil. Lorsque l'utilisateur saisit le nom, nous devons ajouter un événement afin que la valeur de la variable name soit mise à jour. Pour ce faire, modifiez l'élément input comme ceci :

<input id="name" on:input={event => name = event.target.value} value={name} />

Modifiez le texte dans le champ : cela fonctionne ! Mais ce n'est pas toujours la bonne solution... Nous pouvons faire mieux en utilisant la directive Svelte bind. Plus tard, nous parlerons des nombreuses utilisations de la directive bind. L'une d'entre elles consiste à lier la valeur d'un élément (input) d'un formulaire à une variable.

Voilà ce que ça donne :

<input id="name" bind:value={name} />

Nous pouvons même raccourcir le code si le nom de l'attribut est le même nom que la variable à écouter :

<input id="name" bind:value />

C'est bien beau tout ça, mais ça manque de fantaisie, n'est ce pas ? Après le code HTML, ajoutez ceci :

<style>
    h1 {
        color: #FF5349;
    }
</style>

Désormais, le titre doit être en rouge-orangé. Il serait intéressant que l'utilisateur puisse changer la couleur de ce titre. Nous allons ajouter un champ input de type color. L'avantage de cet élément html, c'est qu'il permet de sélectionner une couleur facilement avec un sélecteur de couleur (color picker, pour les amateurs de la langue de Shakespeare).

Svelte : sélecteur de couleurs

Voici le code complet qui permet de changer la couleur du titre et d'afficher un rappel de la couleur choisie dans un petit carré à côté du sélecteur.

<script>
    let color = '#FF5349';
    let name = 'tout le monde';
</script>

<label for="name">Votre nom</label>
<input id="name" bind:value={name}>

<label for="color">Couleur </label>
<input id="color" type="color" bind:value={color}>

<div style="background-color: {color}" class="swatch" />
<h1 style="color: {color}">Salut {name}!</h1>

<style>
    .swatch {
        display: inline-block;
        height: 20px;
        width: 20px;
    }
</style>

Réactivité

Ajoutons une fonctionnalité dans la partie <script> afin de permettre à l'utilisateur de mettre le texte en majuscules :

let upper = false;
$: greeting = `Salut ${name}!`;
$: casedGreeting = upper ? greeting.toUpperCase() : greeting;

(Cela ne suffit pas, attendez la suite...) Mais... Que signifie $: ??

Il s'agit d'une instruction réactive. Les instructions réactives sont ré-exécutées chaque fois que la valeur d'une variable à laquelle elles font référence change. Les déclarations réactives qui attribuent une valeur à une variable sont également appelées déclarations réactives.

Dans le code précédent, nous calculons une nouvelle valeur pour greeting chaque fois que la valeur de name change. Puis nous calculons une nouvelle valeur pour casedGreeting à chaque fois que la valeur de upper ou greeting change.

Pratique n'est ce pas ? ajoutons un champ de type checkbox (case à cocher) afin de modifier facilement la valeur de upper :

<label><input type="checkbox" bind:checked={upper}> Uppercase </label>

N'oublions pas de changer le titre pour utiliser la bonne variable réactive casedGreeting :

<h1 style="color: {color}">{casedGreeting}</h1>

Nous avons fini avec cette mini-application. Vous pouvez la télécharger en cliquant sur le bouton download" !

Svelte : bouton télécharger son application

Lorsque vous cliquez sur celui-ci, vous devriez récupérer une archive zip. Si vous décompressez dans un dossier et que vous voulez tester "en local", vous devez avoir installé NodeJS et npm sur votre ordinateur.

Pour tester/développer en local

De la même façon que pour certains autres frameworks tels que Vue, Nuxt ou React :

  • Ouvrez un terminal.
  • Rendez-vous dans le dossier dézippé (avec les commandes cd).
  • Saisissez npm install pour installer les dépendances.
  • Saisissez npm run dev pour lancer le serveur de développement.
  • Le terminal va vous indiquer l'url sur laquelle vous rendre pour voir votre application dans votre navigateur.

Vous pourrez alors modifier les fichiers locaux dans le dossier src/ notamment App.svelte et constater immédiatement les changements dans le navigateur.

  • Le fichier main.js est le point d'entrée de notre application.
  • Le dossier public/ contient les fichiers statiques disponibles depuis la racine HTTP, par exemple favicon, images, css.

Svelte Terminal

💡 Petite astuce : Lorsque vous ne savez pas quelle commande utiliser pour lancer une application NodeJS, ayez le réflexe de jeter un oeil au fichier package.json. S'il est correctement rédigé, il devrait contenir une partie script, qui est une liste des commandes disponibles. Vous devrez préfixer votre commande par npm run, par exemple npm run build, puis npm run start pour lancer la compilation et l'exécution.

Nous venons de faire un bref tour d'horizon de Svelte, mais il y a encore tellement de choses à voir ! A bientôt pour un nouveau chapitre consacré à Svelte !

Retrouvez l'intégralité de ce tutoriel en ligne sur Alsacreations.com

Viewing all 405 articles
Browse latest View live