Page 2 of 72

[Magento 2] Etendre un Block pour en hériter et lui ajouter de nouvelles fonctionnalités

Note: dans un but d’anonymisation, le véritable libellé du vendor a été remplacé par MyVendor.

Ressource en ligne: Créer un bloc sous magento 2.

Les fichiers obligatoires pour la création d’un nouveau module dans Magento 2 (ou Adobe Commerce)

app/code/MyVendor/KlarnaOnsitemessaging/registration.php

app/code/MyVendor/KlarnaOnsitemessaging/etc/module.xml

app/code/MyVendor/KlarnaOnsitemessaging/etc/di.xml

Etendre un Block dans Magento 2

Le Block (fichier) initial

vendor/klarna/module-onsitemessaging/Block/Product.php

Le Block étendu

app/code/MyVendor/KlarnaOnsitemessaging/Block/Product.php

Raison de l’extension: dans la fiche produit, nous avons besoin de cacher la bannière Klarna pour les produits > 10 000 euros ainsi que les produits not salable ou qui ont un stock = 0.

Nous allons pour ce faire créer une fonction publique getProduct() qui va nous permettre de récupérer tout un tas d’informations sur le produit affiché et notamment celles que nous allons exploiter dans la fonction publique conditionalShowOnProduct() qui teste que toutes les conditions sont remplies pour afficher la bannière.

app/code/MyVendor/KlarnaOnsitemessaging/etc/config.xml

Dans la class Product que nous venons d’étendre (cf. extension de /Block/Product.php), nous utilisons une config const CHECKOUT_PRICES_ABOVE = 'checkout/prices_above'; que nous définissons dans ce fichier (plutôt qu’en dur).

app/design/frontend/MyTheme/default/Klarna_Onsitemessaging/templates/html/placement/product.phtml

On interroge la fonction conditionalShowOnProduct() présente dans notre Block étendu pour afficher ou non la bannière Klarna.

[Magento 2] matchMedia mediaCheck boucler dans un tableau de media-queries avec la méthode jQuery each()

Ressource: How to loop through array in jQuery?. très bien expliqué avec des exemples spécifiques pour du javasqcript vanilla (ES5, ES6, …) et l’utilisation avec this.

Dans mon exemple, je cherche simplement à ré-initialiser un carousel Slick Slider dès qu’un nouveau breakpoint est rencontré. Il est important de comprendre que c’est le même code qui est exécuté à chaque fois.

Si vous souhaitez utiliser des paramètres différents en fonction de vos vues (Mobile, Tablet, Desktop) avec Slick Slider, il faut utiliser l’option responsive.

…revient à déclarer ceci:

[Magento 2] Récupérer la config JSON d’un produit configurable en front

Depuis la fiche produit d’un produit configurable, afficher la source (crtl + u) et effectuer une recherche sur Magento_Swatches/js/swatch-renderer": {.

ATTENTION: c’est la première occurence qui sera retournée qui est la bonne, à moins que vous ne cherchiez un product ID spécifique. A ce moment là, votre recherche peut se faire sur le modèle "[data-role=swatch-option-XXXX]"XXXX correspond au product ID.

Le JSON récupéré peut ensuite être affiché joliment.

[Magento 2] Récupérer la placeholder image de votre store dans un block PHP

Objectif:

Dans la fonction suivante, je souhaite rajouter en else la possibilité d’afficher la placeholder image rendue disponible par Magento 2 si l’utilisateur admin backoffice n’a pas uploadé d’image spécifique.

Solution:

Tout d’abord, juste après la déclaration class myClassName extends…, déclarer le Helper Image et sa variable $imageHelper:

NOTE: dans mon cas (un peu particulier), une protected function _construct(): void existe déjà dans le block. Il ne faut pas chercher à la modifier!

Au lieu de ça, dans notre code et juste en-dessous ce premier contructeur, on crée une nouvelle extension de public function __construct sur le modèle de la fonction _construct tout droit issue de vendor/magento/framework/View/Element/Template.php et on y ajoute le image helper:

NOTE: \Template\Context $context devient \Magento\Framework\View\Element\Template\Context $context pour l’occasion.

Puis compléter la fonction de départ avec un else qui retourne l’image placeholder:

Cette manip’ donnera le même résultat que si on mettait en place le code suivant la le fichier template PHTML chargé d’afficher les images ou, à défaut, le placeholder. On est cependant plus efficace en renvoyant directement l’image adéquate via le block PHP. Donc, le code ci-dessous est présent juste à titre informatif mais éviter de l’utiliser dans la mesure du possible (on voit qu’on utilise, comme argument de la condition, la même méthode empty() que dans le block PHP):

[Magento 2] i18n, bonnes pratiques

Insérer un ou plusieurs liens dans une même chaîne de caractères:

(Exemple pour dans un fichier PHTML)

Insérer un mail:

(Exemple pour dans un fichier PHTML)

[jQuery] Eviter la duplication d’éléments du DOM lorsqu’on utilise .each() en exploitant correctement l’objet $(this)

Dans mon exemple, j’ai trois containers <div class="payment-method" /> qui sont présents dans le DOM. Chacun de ces containers possède son propre bouton. Je cherche à ajouter un seul nouveau bouton dans chaque container qui n’est pas tout-à-fait un clone de celui qui existe déjà, mais qui en reprend le code HTML enfant.

Problème: avec le code ci-dessous, les trois boutons que j’ajoute sont créés une fois dans chaque container. En d’autres termes, je me retrouve avec quatre boutons (au lieu de deux) dans chaque container.

Solution: le souci provient d’une mauvaise utilisation de $(this) en combinaison de .each(). Ci-dessous le code qui me donne le résultat attendu:

[Magento 2] Google Tag Manager Google Analytics

Admin, backoffice

Trouver et activer l’extension Google Tag Manager

Dans STORES > Configuration > SALES > Google API > Google Analytics. Mettre enable à « Yes ».

Ne pas oublier de mettre le Container Id dans le champ prévu à cet effet.

[Magento 2] Exploiter l’Escaper dans les fichiers PHTML et HTML utilisant Knockout JS (extension Page Builder) pour maintenir certaines balises dans du contenu HTML

Escaper dans les templates PHTML

Magento 2 supprime de manière radicale toutes les balises HTML que vous pourriez renseigner dans des champs du BO. Dans notre exemple, le champ à renseigner affiche un titre en front et si on renseigne ceci: 50<sup>th</sup> Anniversary, l’élément <sup> est automatiquement supprimé.

Pour éviter ceci, on peut déclarer(1) et exploiter l’Escaper dans les fichiers PHTML en listant dans un tableau(2) l’ensemble des balises HTML à conserver:

Valable également en cas d’utilisation d’une clé de traduction (fichiers CSV):

Extension Page Builder de Magento 2 (payante)

Documentation officielle du Page Builder Adobe Commerce (ex Magento 2).

Knockout JS dans les fichiers HTML

C’est en fait dans un fichier title-tag-escaper.js qu’on liste les tags HTML à ne pas échapper:

Configuration d’un module dans un fichier XML

Dans app/code/MyVendor/PageBuilder/view/adminhtml/pagebuilder/content_type/module_XX, afin que la liste des balises autorisées soit prise en compte il faut ajouter un attribut converter pour l’élément (le champ du formulaire d’édition en BO) ciblé:

[Javascript] Exécuter un événement qui se déclenche plusieurs fois de suite seulement après un certain délais en temps (un timeout)

Nouvelle méthode (tips: utilisez celle-ci)

Source: Debouncing and Throttling in JavaScript

Version PDF: Debouncing and Throttling in JavaScript


Ancienne méthode

…et en fait j’ai jamais réussi à la faire fonctionner.

Source: How to respond to a Javascript event only if it is fired once and then not fired again during some time period?, Debouncing Javascript Methods

Problème:

In my application I listen to the Google Maps API ‘bounds_changed’ event to send an ajax request to update some div on the web page depending on the new boundaries of the map:

The event ‘idle’ is fired with a high frequency when the user drag the map around. So much that there are too many ajax requests sent to the server.

Basically I would like to make the function to be executed only after the user has stopped to move the map during some time period (for example 500ms).

Solution

A l’addListener pour l’événement idle de l’API Google Maps, on déclare une fonction qui contiendra juste notre appel à la fonction debounce:

[Javascript] Utiliser l’API de Géolocalisation avec des promesses ou Async Await

Source: un billet clair, concis et efficace: How to use Geolocation API with Promises

Avec une promesse:

Avec async, await: