Dans cette course à qui intègrerait plus d’Intelligence Artificielle dans ses offres, Amazon ne souhaite pas se laisser distancer. A défaut d’un partenariat avec OpenAI, comme c’est le cas de Microsoft, ce qui lui donne aujourd’hui une avance considérable sur le marché en particulier sur son rival Google, Amazon lui rend son produit d’aide au développeurs indépendants CodeWhisperer gratuit et cerise sur le gâteau, il fonctionnera y compris pour les personnes n’utilisant pas le cloud AWS.
Amazon a lancé CodeWhisperer en avant-première l’année dernière, que les développeurs peuvent utiliser dans divers environnements de développement intégrés (IDE), comme Visual Studio Code, pour générer des lignes de code sur la base d’une invite textuelle. Alors qu’il n’était à l’origine disponible que pour les clients d’Amazon Web Services, la nouvelle version gratuite devrait le rendre beaucoup plus accessible aux développeurs qui n’utilisent pas AWS.
Cet outil est un concurrent direct de GitHub Copilot, facturé de son coté 10$ par mois. Si le produit de Microsoft, basé sur OpenAI est tout bonnement bluffant, les avis sur celui d’Amazon ne sont pas aussi bons en moyenne, mais à 0€ qui va s’en plaindre ? Le grand perdant, une fois de plus dans cette course à l’IA est sans doute Google qui dispose également de son propre outil « AlphaCode », mais il est encore en phase de test privée…
Pour en revenir au produit d’Amazon, parmi les ponts mis en avant, il est doté de fonctions d’analyse de la sécurité qui permettent d’identifier les vulnérabilités dans le code d’un développeur, tout en proposant des suggestions pour aider à combler les lacunes de sécurité qu’il découvre. CodeWhisperer prend en charge plusieurs langages, dont Python, Java, JavaScript, TypeScript et C#, ainsi que Go, Rust, PHP, Ruby, Kotlin, C, C++, Shell scripting, SQL et Scala.
Une petite vidéo Amazon pour la mise en oeuvre avec Visual Studio Code :
Dans cette course à qui intègrerait plus d’Intelligence Artificielle dans ses offres, Amazon ne souhaite pas se laisser distancer. A défaut d’un partenariat avec OpenAI, comme c’est le cas de Microsoft, ce qui lui donne aujourd’hui une avance considérable sur le marché en particulier sur son rival Google, Amazon lui rend son produit d’aide au développeurs indépendants CodeWhisperer gratuit et cerise sur le gâteau, il fonctionnera y compris pour les personnes n’utilisant pas le cloud AWS.
Amazon a lancé CodeWhisperer en avant-première l’année dernière, que les développeurs peuvent utiliser dans divers environnements de développement intégrés (IDE), comme Visual Studio Code, pour générer des lignes de code sur la base d’une invite textuelle. Alors qu’il n’était à l’origine disponible que pour les clients d’Amazon Web Services, la nouvelle version gratuite devrait le rendre beaucoup plus accessible aux développeurs qui n’utilisent pas AWS.
Cet outil est un concurrent direct de GitHub Copilot, facturé de son coté 10$ par mois. Si le produit de Microsoft, basé sur OpenAI est tout bonnement bluffant, les avis sur celui d’Amazon ne sont pas aussi bons en moyenne, mais à 0€ qui va s’en plaindre ? Le grand perdant, une fois de plus dans cette course à l’IA est sans doute Google qui dispose également de son propre outil « AlphaCode », mais il est encore en phase de test privée…
Pour en revenir au produit d’Amazon, parmi les ponts mis en avant, il est doté de fonctions d’analyse de la sécurité qui permettent d’identifier les vulnérabilités dans le code d’un développeur, tout en proposant des suggestions pour aider à combler les lacunes de sécurité qu’il découvre. CodeWhisperer prend en charge plusieurs langages, dont Python, Java, JavaScript, TypeScript et C#, ainsi que Go, Rust, PHP, Ruby, Kotlin, C, C++, Shell scripting, SQL et Scala.
Une petite vidéo Amazon pour la mise en oeuvre avec Visual Studio Code :
Si vous êtes sous Windows et que vous voulez sortir des sentiers battus en le personnalisant un peu au-delà des paramètres prévus par Microsoft, vous êtes sur le bon site. Sur le site Windhawk, vous trouverez un utilitaire gratuit qui permet d’appliquer des mods à votre Windows.
Un « mod », c’est une modification qui sera faite à Windows pour par exemple avoir un notepad avec un thème sombre, faire un clic avec le bouton du milieu de la souris pour fermer une application ouverte dans la barre des tâches, ou encore contrôler le volume sonore de votre PC en scrollant sur votre barre de menu.
La liste complète des mods proposés par Windhawk se trouve ici et évidemment, le code de chacun d’entre eux est disponible donc vous savez exactement ce que ça fait sur votre système.
Il n’y a pas encore énormément de mods en base, mais c’est un bon début et vous pouvez proposer les vôtres.
En tout cas, pour moi qui aime ce genre de petits hacks, je trouve que c’est une chouette idée à développer.
Si vous voulez vous améliorer en Python, mais que vous manquez de temps et que vous ne voulez pas vous prendre la tête, alors Calmcode.io est la solution pour vous.
Avec plus de 600 vidéos assez courtes et simples à comprendre dans différents cours, vous pourrez facilement apprendre les bases de Python et découvrir de nouveaux outils open source.
Notez que le site propose également une newsletter pour être tenu informé des nouveaux contenus mis en ligne.
L’objectif de Calmcode est de remédier à l’anxiété liée à vos perceptions de vos compétences en développement en proposant des leçons vidéo courtes et simples à capter qui partent de zéro.
Par exemple, vous y trouverez une bonne introduction à l’outil Bandit qui permet de renforcer la sécurité de votre code Python.
Le contenu est axé sur des outils et des réflexions qui peuvent comme ça, rendre votre vie professionnelle plus agréable. Calmcode s’efforce ainsi de suivre des principes importants tels que fournir un contenu clair et concis, mettre l’accent sur la patience et l’itération plutôt que sur des délais à respecter, et surtout « montrer » comment on fait les choses plutôt que simplement les expliquer.
C’est vraiment cool et je suis certain que vous en retirerez des choses. Bref, à fouiller !
L’ERP est-il en perte de vitesse ? Pour le moment, non. Mais se poser la question, c’est déjà donner une indication de réponse. S’il est suffisamment hégémonique pour ne pas être directement menacé par l’émergence des technologies Low Code et No Code, l’ERP est néanmoins obligé de s’adapter pour survivre. Quitte à embrasser son bourreau ? Pas si vite…
Microsoft vient d’annoncer la prévision du kit de développement « Semantic Kernel ». Logiquement ce dernier est dispo en Open Source sur GitHub. Le Semantic Kernel est donc un kit de développement logiciel (SDK) léger qui facilite l’utilisation d’éléments tels que ChatGPT d’OpenAI dans les applications, selon John Maeda, vice-président de Microsoft chargé de la conception et de l’intelligence artificielle, il fonctionne avec les langages de programmation conventionnels, avec une prise en charge actuelle en beta de « C# et Python ». Microsoft envisage d’ajouter la prise en charge de TypeScript et d’autres langages dans un futur proche.
Semantic Kernel, qui a débuté en tant que projet d’incubation interne à Microsoft, il prend actuellement en charge le modèle GPT-4 d’OpenAI et le service Azure OpenAI. Ses capacités peuvent être intégrées dans n’importe quel type d’application et peuvent se connecter à des sources de données et à des services externes. Semantic Kernel se distingue également par le fait qu’il permet aux développeurs d’utiliser des prompts complexes, ce qui peut s’avérer problématique lorsqu’on travaille avec de l’IA
« Ainsi, imaginez que vous puissiez facilement créer des invites complexes, des invites à multiples facettes, des invites qui font toutes sortes de choses comme se connecter à du code natif. Ce genre de choses est offert gratuitement avec Symantec Kernel » – John Maeda.
Ce SDK peut être en réalité considéré comme un ensemble de bonnes pour ajouter une IA riche en sémantique aux applications existantes. Ainsi la source GitHub comprend quelques exemples de codes modèles que les développeurs peuvent essayer. Il existe une capacité de « résumé de chat simple » pour les applications. Un exemple de code « Book creator » permet aux applications de créer des aperçus de livres. Il existe également un modèle de code de connecteur de base qui peut être utilisé pour « s’authentifier et se connecter à une API ».
Nous reviendrons lors du prochain Briefing sur les IA conversationnelles et leurs usages.
Et oui dans tous les cas il multiplie par la taxe !
Bug (erreur) ou fonctionnement normal je ne sais pas.
Mais voici la solution que je vous propose.
Si l’utilisateur est dans un groupe ou on souhaite qu’il ait l’affichage des prix HT
Alors je retourne le prix du produit sans la multiplication
Sinon
Je retourne ce qui était a l’origine.
Salut tout le monde, un petit snippet pour prestashop qui permet de mettre dans un ordre voulu les produits dans un bon de livraison et sur la facture.
Pourquoi faire ça ?
C’est une demande de mon boss, car nous venons de réorganiser les allées des stocks par Fabriquant (marque) puis par référence. Pour que ce soit plus pratique dans la constitution de la commande nous avons ordonné les produits du bon de livraison comme notre organisation physique.
Il suffit de créer un fichier OrderInvoice.php dans le répertoire override/classes/order et d’y ajouter ce petit bout de code.
Dans cette première partie nous allons voir comment mettre en place un menu accessible simple, sans sous-menu : récapitulatif des bases, explications des notions importantes et des moyens pour rendre notre menu à un niveau accessible. C’est parti !
Créer un menu dans WordPress : les bases
Tout d’abord voyons en quelques étapes comment mettre en place un menu sur WordPress.
1) Enregistrer un emplacement de menu
Dans le fichier de configuration du thème (souvent functions.php ou un sous-fichier si vous prônez l’organisation comme chez Alsacréations) enregistrons un menu "Menu principal" avec la fonction register_nav_menu(). Il a pour slug main-menu qui nous sera utile pour afficher le menu :
Dans l’administration WordPress, l’emplacement apparait dans les réglages du menu :
Dans les réglages du menu, l'emplacement “Menu principal“ est sélectionnable.
2) Afficher le menu
Il n’y a plus qu’à appeler le menu là où nous souhaitons l’afficher, dans l’en-tête header.php par exemple.
Pour cela il faut utiliser la fonction wp_nav_menu() et préciser le slug précédemment enregistré :
/**
* Affiche le menu "Menu principal" enregistré au préalable.
*/
wp_nav_menu([
'theme_location' => 'main-menu',
]);
Cette fonction propose des options de configuration très avancées. Vous retrouverez la liste des paramètres disponibles sur la documentation officielle de wp_nav_menu.
3) Administrer le menu
Pour le moment nous souhaitons créer un menu simple. Pour cela créer un nouveau menu dans l'interface d'administration de WordPress, le nommer, et cocher l’emplacement enregistré à l’étape 1.
Si vous avez bien suivi les étapes, vous devriez avoir un menu qui fonctionne à minima. Et voici le code généré par WordPress :
Côté accessibilité, le code généré possède quelques points à améliorer :
le conteneur du menu n’a pas de sémantique. C’est une simple <div>.
La page courante n’est pas restituée aux lecteurs d’écran.
Mais comment corriger cela ? La fonction wp_nav_menu() possède des paramètres qui pourront nous aider, mais cela ne nous permettra pas de tout corriger. Dans ce cas, il faudra modifier le code généré par WordPress.
Comment WordPress gère ce code ? Comment modifier ce code ?
Nous allons utiliser le walker Walker_Nav_Menu qui nous sera utile pour personnaliser le code généré. Mais avant, explications !
Qu’est ce qu’un Walker ?
Un walker est une classe abstraite PHP qui permet de parcourir une arborescence de données (objets ou tableaux) afin de générer du code HTML.
Par rapport à notre menu ➡️ le walker va parcourir le menu, et exécuter à chaque noeud une fonction.
Visualisation des fonctions du walker Walker_Nav_Menu à travers un menu à deux niveaux.
Et l’avantage d’un walker, c’est qu’il est possible de l’étendre afin de customiser ces fonctions. Spoiler : c’est ce que nous allons faire 🤠.
Rendre notre menu sémantiquement parlant
Actuellement, notre menu est perçu simplement comme une liste, avec un conteneur ne donnant aucun contexte.
Nous allons donc ajouter un peu de sémantique pour restituer, à l’utilisateur et aux lecteurs d’écran, que c’est un menu de navigation. Pour cela, faisons appel aux landmarks ARIA.
Rappel : les landmarks permettent de déclarer des régions (header, main, footer, nav, aside, etc.) afin de structurer une page et de restituer le contexte aux lecteurs d’écran.
Ici, nous allons englober notre menu d’une balise <nav> avec un attribut ARIA role="navigation". Si plusieurs menus de navigation existent dans le site, une bonne pratique est de l’identifier via un attribut aria-label ou la combinaison aria-labelledby/id.
Si vous avez regardé en détail le codex de wp_nav_menu(), vous vous demanderez sûrement pourquoi ne pas utiliser les paramètres container et container_aria_label. Comme ils sont de type string, il n’aurait donc pas été possible de passer l’attribut role="navigation".
Nous privilégions donc de ne pas utiliser le conteneur généré par WP :
<nav role="navigation" aria-label="<?php _e('Menu principal', 'text-domain'); ?>">
<?php
wp_nav_menu([
'theme_location' => 'main-menu',
'container' => false // On retire le conteneur généré par WP
]);
?>
</nav>
Préciser la page courante
Visuellement la page courante d’un menu peut-être indiquée par la couleur, la forme (bordure basse), une icône, etc. :
Exemple d’affichage pour indiquer la position courante (site Smashing Magazine)
Mais qu’en-est-il des personnes malvoyantes utilisant un lecteur d’écran ? Il faut une alternative HTML en plus de l’indication visuelle.
L’attribut aria-current rentre en piste ! Il permet d’indiquer aux lecteurs d’écran l’élément actif parmi un ensemble. Dans notre cas, il aura pour valeur :
Quel est l’intérêt me direz-vous ? Simplement pour éviter de faire des erreurs. Nous aurons juste à customiser la/les fonction(s) souhaitée(s).
La seconde étape est de renommer le walker pour le distinguer d’autres potentiels walkers :
class A11y_Walker_Nav_Menu extends Walker {
Ensuite, nous allons appeler ce walker dans la fonction wp_nav_menu() en ajoutant un paramètre walker pour créer une instance de notre classe A11y_Walker_Nav_Menu :
Notre objectif est d’ajouter un attribut aria-current sur un élément du menu lorsqu’il correspond à la page courante.
Comme précisé plus haut, c’est la fonction start_el() qui va permettre de modifier le contenu d’un élément du menu.
Avant tout, regardons plus en détail cette fonction :
/**
* Starts the element output.
*
* @since 3.0.0
* @since 4.4.0 The {@see 'nav_menu_item_args'} filter was added.
* @since 5.9.0 Renamed `$item` to `$data_object` and `$id` to `$current_object_id`
* to match parent class for PHP 8 named parameter support.
*
* @see Walker::start_el()
*
* @param string $output Used to append additional content (passed by reference).
* @param WP_Post $data_object Menu item data object.
* @param int $depth Depth of menu item. Used for padding.
* @param stdClass $args An object of wp_nav_menu() arguments.
* @param int $current_object_id Optional. ID of the current menu item. Default 0.
*/
public function start_el( &$output, $data_object, $depth = 0, $args = null, $current_object_id = 0 ) {
// Restores the more descriptive, specific name for use within this method.
$menu_item = $data_object;
// Suite de la fonction...
Les commentaires nous précisent que :
le paramètre $output est le résultat de la fonction sous forme de contenu HTML.
Le paramètre $data_object est un objet qui nous permet de récupérer toutes les informations de l’élément. À noter que la première ligne de la fonction nous précise d’utiliser $menu_item. Cette variable regroupe plusieurs clés (n’hésitez pas à explorer son contenu en utilisant var_dump($menu_item) ).
Arrêtons-nous sur la clé current. C’est un booléen qui a pour valeur true lorsque l’élément correspond à la page courante. Parfait, c’est ce que nous voulons !
Mais comment ajouter un attribut à l’élément ? Et bien WordPress ne fait pas les choses à moitié : si vous regardez bien la fonction, un paramètre $atts est mis à disposition. Il utilise le filtre nav_menu_link_attributes :
Et voilà, l’attribut est ajouté dans le code lorsque $menu_item possède la clé current. Plutôt simple, hein ?
Ajouter un attribut title si le lien s’ouvre dans un nouvel onglet
L’utilisation d’un attribut title permet d’ajouter un complément d’information. Attention à l’utiliser correctement : il faut reprendre l’intitulé du lien, puis ajouter le texte complémentaire (notes du glossaire RGAA).
Dans notre cas nous allons préciser qu’un lien s’ouvre dans un nouvel onglet lorsque son target vaut _blank:
Exemple :
<a href="#" target="_blank" title="Intitulé du lien (s'ouvre dans un nouvel onglet)">Intitulé du lien</a>
Préciser cette action permet de prévenir les utilisateurs d’un changement brusque et éviter de perturber leur navigation.
Comment le faire sur WordPress ?
Nous allons donc modifier la fonction start_el() pour ajouter un title lorsque le target est _blank. Si vous regardez bien, cette condition existe déjà :
if ( '_blank' === $menu_item->target && empty( $menu_item->xfn ) )
Il n’y a plus qu’à ajouter l’attribut title et lui donner pour valeur le titre de l’élément title suivi de notre texte :
if ( '_blank' === $menu_item->target && empty( $menu_item->xfn ) ) {
// Attribut title : on précise que le lien s'ouvre dans un nouvel onglet
$atts['title'] = $menu_item->title . __( ' (s\'ouvre dans un nouvel onglet)', 'text-domain' );
}
Voilà ce qu’il en est pour la mise en place d’un menu accessible simple. Cette première partie était assez longue car nous trouvions important de revenir sur les bases de la création d’un menu WordPress. La prochaine entrera directement dans le vif du sujet et concernera la gestion des sous-éléments d’un menu.
Dans cette première partie nous allons voir comment mettre en place un menu accessible simple, sans sous-menu : récapitulatif des bases, explications des notions importantes et des moyens pour rendre notre menu à un niveau accessible. C’est parti !
Créer un menu dans WordPress : les bases
Tout d’abord voyons en quelques étapes comment mettre en place un menu sur WordPress.
1) Enregistrer un emplacement de menu
Dans le fichier de configuration du thème (souvent functions.php ou un sous-fichier si vous prônez l’organisation comme chez Alsacréations) enregistrons un menu "Menu principal" avec la fonction register_nav_menu(). Il a pour slug main-menu qui nous sera utile pour afficher le menu :
Dans l’administration WordPress, l’emplacement apparait dans les réglages du menu :
Dans les réglages du menu, l'emplacement “Menu principal“ est sélectionnable.
2) Afficher le menu
Il n’y a plus qu’à appeler le menu là où nous souhaitons l’afficher, dans l’en-tête header.php par exemple.
Pour cela il faut utiliser la fonction wp_nav_menu() et préciser le slug précédemment enregistré :
/**
* Affiche le menu "Menu principal" enregistré au préalable.
*/
wp_nav_menu([
'theme_location' => 'main-menu',
]);
Cette fonction propose des options de configuration très avancées. Vous retrouverez la liste des paramètres disponibles sur la documentation officielle de wp_nav_menu.
3) Administrer le menu
Pour le moment nous souhaitons créer un menu simple. Pour cela créer un nouveau menu dans l'interface d'administration de WordPress, le nommer, et cocher l’emplacement enregistré à l’étape 1.
Si vous avez bien suivi les étapes, vous devriez avoir un menu qui fonctionne à minima. Et voici le code généré par WordPress :
Côté accessibilité, le code généré possède quelques points à améliorer :
le conteneur du menu n’a pas de sémantique. C’est une simple <div>.
La page courante n’est pas restituée aux lecteurs d’écran.
Mais comment corriger cela ? La fonction wp_nav_menu() possède des paramètres qui pourront nous aider, mais cela ne nous permettra pas de tout corriger. Dans ce cas, il faudra modifier le code généré par WordPress.
Comment WordPress gère ce code ? Comment modifier ce code ?
Nous allons utiliser le walker Walker_Nav_Menu qui nous sera utile pour personnaliser le code généré. Mais avant, explications !
Qu’est ce qu’un Walker ?
Un walker est une classe abstraite PHP qui permet de parcourir une arborescence de données (objets ou tableaux) afin de générer du code HTML.
Par rapport à notre menu ➡️ le walker va parcourir le menu, et exécuter à chaque noeud une fonction.
Visualisation des fonctions du walker Walker_Nav_Menu à travers un menu à deux niveaux.
Et l’avantage d’un walker, c’est qu’il est possible de l’étendre afin de customiser ces fonctions. Spoiler : c’est ce que nous allons faire 🤠.
Rendre notre menu sémantiquement parlant
Actuellement, notre menu est perçu simplement comme une liste, avec un conteneur ne donnant aucun contexte.
Nous allons donc ajouter un peu de sémantique pour restituer, à l’utilisateur et aux lecteurs d’écran, que c’est un menu de navigation. Pour cela, faisons appel aux landmarks ARIA.
Rappel : les landmarks permettent de déclarer des régions (header, main, footer, nav, aside, etc.) afin de structurer une page et de restituer le contexte aux lecteurs d’écran.
Ici, nous allons englober notre menu d’une balise <nav> avec un attribut ARIA role="navigation". Si plusieurs menus de navigation existent dans le site, une bonne pratique est de l’identifier via un attribut aria-label ou la combinaison aria-labelledby/id.
Si vous avez regardé en détail le codex de wp_nav_menu(), vous vous demanderez sûrement pourquoi ne pas utiliser les paramètres container et container_aria_label. Comme ils sont de type string, il n’aurait donc pas été possible de passer l’attribut role="navigation".
Nous privilégions donc de ne pas utiliser le conteneur généré par WP :
<nav role="navigation" aria-label="<?php _e('Menu principal', 'text-domain'); ?>">
<?php
wp_nav_menu([
'theme_location' => 'main-menu',
'container' => false // On retire le conteneur généré par WP
]);
?>
</nav>
Préciser la page courante
Visuellement la page courante d’un menu peut-être indiquée par la couleur, la forme (bordure basse), une icône, etc. :
Exemple d’affichage pour indiquer la position courante (site Smashing Magazine)
Mais qu’en-est-il des personnes malvoyantes utilisant un lecteur d’écran ? Il faut une alternative HTML en plus de l’indication visuelle.
L’attribut aria-current rentre en piste ! Il permet d’indiquer aux lecteurs d’écran l’élément actif parmi un ensemble. Dans notre cas, il aura pour valeur :
Quel est l’intérêt me direz-vous ? Simplement pour éviter de faire des erreurs. Nous aurons juste à customiser la/les fonction(s) souhaitée(s).
La seconde étape est de renommer le walker pour le distinguer d’autres potentiels walkers :
class A11y_Walker_Nav_Menu extends Walker {
Ensuite, nous allons appeler ce walker dans la fonction wp_nav_menu() en ajoutant un paramètre walker pour créer une instance de notre classe A11y_Walker_Nav_Menu :
Notre objectif est d’ajouter un attribut aria-current sur un élément du menu lorsqu’il correspond à la page courante.
Comme précisé plus haut, c’est la fonction start_el() qui va permettre de modifier le contenu d’un élément du menu.
Avant tout, regardons plus en détail cette fonction :
/**
* Starts the element output.
*
* @since 3.0.0
* @since 4.4.0 The {@see 'nav_menu_item_args'} filter was added.
* @since 5.9.0 Renamed `$item` to `$data_object` and `$id` to `$current_object_id`
* to match parent class for PHP 8 named parameter support.
*
* @see Walker::start_el()
*
* @param string $output Used to append additional content (passed by reference).
* @param WP_Post $data_object Menu item data object.
* @param int $depth Depth of menu item. Used for padding.
* @param stdClass $args An object of wp_nav_menu() arguments.
* @param int $current_object_id Optional. ID of the current menu item. Default 0.
*/
public function start_el( &$output, $data_object, $depth = 0, $args = null, $current_object_id = 0 ) {
// Restores the more descriptive, specific name for use within this method.
$menu_item = $data_object;
// Suite de la fonction...
Les commentaires nous précisent que :
le paramètre $output est le résultat de la fonction sous forme de contenu HTML.
Le paramètre $data_object est un objet qui nous permet de récupérer toutes les informations de l’élément. À noter que la première ligne de la fonction nous précise d’utiliser $menu_item. Cette variable regroupe plusieurs clés (n’hésitez pas à explorer son contenu en utilisant var_dump($menu_item) ).
Arrêtons-nous sur la clé current. C’est un booléen qui a pour valeur true lorsque l’élément correspond à la page courante. Parfait, c’est ce que nous voulons !
Mais comment ajouter un attribut à l’élément ? Et bien WordPress ne fait pas les choses à moitié : si vous regardez bien la fonction, un paramètre $atts est mis à disposition. Il utilise le filtre nav_menu_link_attributes :
Et voilà, l’attribut est ajouté dans le code lorsque $menu_item possède la clé current. Plutôt simple, hein ?
Ajouter un attribut title si le lien s’ouvre dans un nouvel onglet
L’utilisation d’un attribut title permet d’ajouter un complément d’information. Attention à l’utiliser correctement : il faut reprendre l’intitulé du lien, puis ajouter le texte complémentaire (notes du glossaire RGAA).
Dans notre cas nous allons préciser qu’un lien s’ouvre dans un nouvel onglet lorsque son target vaut _blank:
Exemple :
<a href="#" target="_blank" title="Intitulé du lien (s'ouvre dans un nouvel onglet)">Intitulé du lien</a>
Préciser cette action permet de prévenir les utilisateurs d’un changement brusque et éviter de perturber leur navigation.
Comment le faire sur WordPress ?
Nous allons donc modifier la fonction start_el() pour ajouter un title lorsque le target est _blank. Si vous regardez bien, cette condition existe déjà :
if ( '_blank' === $menu_item->target && empty( $menu_item->xfn ) )
Il n’y a plus qu’à ajouter l’attribut title et lui donner pour valeur le titre de l’élément title suivi de notre texte :
if ( '_blank' === $menu_item->target && empty( $menu_item->xfn ) ) {
// Attribut title : on précise que le lien s'ouvre dans un nouvel onglet
$atts['title'] = $menu_item->title . __( ' (s\'ouvre dans un nouvel onglet)', 'text-domain' );
}
Voilà ce qu’il en est pour la mise en place d’un menu accessible simple. Cette première partie était assez longue car nous trouvions important de revenir sur les bases de la création d’un menu WordPress. La prochaine entrera directement dans le vif du sujet et concernera la gestion des sous-éléments d’un menu.
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 fonctionsprintf 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 filtrelength sur la variable search_result renvoie le nombre d'éléments.
La fonction__() pour les traductions avec le bon textdomain
Le filtreformat 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 !
Le tutoriel d’aujourd’hui m’a été demandé à maintes reprises depuis plus d’une année. Je vous propose aujourd’hui : d’exploiter l’API RESTful du plugin ZWave. Le plugin ZWave met à disposition des web services via un serveur REST. Je vais vous apprendre...
Bonjour aujourd’hui je vais vous présenter une de mes dernières réalisations. Je possède un store banne à caisson Opal Design de la marque Griesser. Le toile est commandée via une télécommande dans un protocole BiLine de Griesser. Je vais vous...
My customer was a school, each year they need to recreate the Teams classroom, to reset the content and canal
The solution was to remove every Teams except the permanent one (workgroup Teams)
Below is the PowerShell Script. I use an xml file to connect easily to the Microsoft 365, avoiding re entering login / password
#By Jeff ANGAMA
#02.09.2020
#************GOAL************#
#This script remove every TEAMS except the one specified in variable $keepThoseTeams
#Write the list of TEAMS without ACCENT !!!
#************PRE REQUISITE - Run those commands to save your creds************#
#$pathToCred = "C:\credTenant.xml"
# $credential = Get-Credential
# $credential | Export-CliXml -Path $pathToCred
#************CONFIG************#
$keepThoseTeams = (
'IT Team',
'Support Informatique',
'Training',
'Administration',
'College',
'Coordinateurs lycee',
'Documents de suivi lycee',
'Budget',
'Demande de creation de classe'
)
#LOGS
$currentFolder = Get-Location
$timeStamp = $(((get-date).ToUniversalTime()).ToString("yyyyMMddThhmmssZ"))
$logFileName = "$currentFolder\logs\logDeleteTeams_" + $timeStamp + ".txt"
Start-Transcript -path $logFileName -append
#Connect
$pathToCred = "C:\credTenant.xml"
$credential = Import-CliXml -Path $pathToCred
Connect-MicrosoftTeams -Credential $credential
#remove accent from text, to avoid issue with contains or eq function containing accents
function get-sanitizedUTF8Input{
Param(
[String]$inputString
)
#replace diacritics
$sb = [Text.Encoding]::ASCII.GetString([Text.Encoding]::GetEncoding("Cyrillic").GetBytes($inputString))
#remove spaces and anything the above function may have missed
return $sb
}
Get-Team | ForEach-Object {
$valueToCheck = get-sanitizedUTF8Input -inputString $_.DisplayName
if($keepThoseTeams -contains $valueToCheck){
Write-Host -ForeGroundColor Green "Do not delete this Team " $_.DisplayName $_.GroupId
}else {
Write-Host "Deleting Team " $_.DisplayName $_.GroupId
#Remove-Team -GroupId $_.GroupId
}
}
Stop-Transcript
Write-Host -ForeGroundColor Green "END OF SCRIPT"