Mois : février 2020

[Magento 2] La configuration de votre site de manière scriptée via le fichier config.php

L’ensemble des champs de configuration disponibles depuis l’interface admin de Magento 2 peuvent également se piloter depuis le fichier app/etc/config.php. Cette fonctionnalité peut se révéler très utile pour embarquer sous Git des pré-configurations de projet.

Documentation officielle: Magento 2 DevDocs – config.php reference.

ATTENTION CAVEAT!: la pré-configuration de votre/vos sites via ce fichier config.php va désactiver les champs correspondants dans l’interface d’administration. Ceci veut dire que vous ne pourrez plus modifier les paramètres en question via le backoffice. Il faudra impérativement intervenir sur le fichier config.php à cet effet. Magento 2 propose un moyen de pré-configurer vos sites tout en laissant l’admin libre de faire des modifications après coup via le backoffice, mais la config n’est alors pas scriptée. Les changements s’opèrent directement en base de données. Pas pratique!

Pas de panique, il existe une solution pour Pré-configurer vos sites Magento 2 de manière scriptée tout en laissant l’admin libre de faire des modifications après coup via le backoffice.

Obtenir un fichier config.php de référence

Source: Export the configuration.

Un fichier config.php de référence vous permettra d’avoir sous les yeux la majeure partie des paramètres présents en admin. ATTENTION: il est conseillé de faire une copie de sauvegarde de votre fichier config.php initial car il sera écrasé par la commande ci-dessous! Exécuter la commande:

Vous pouvez ensuite renommer le fichier généré en config.default.php et y revenir ultérieurement pour consultation.

Pré-configurer vos sites Magento 2 de manière scriptée tout en laissant l’admin libre de faire des modifications après coup via le backoffice

Testé fonctionnel Magento 2.3.4!

Magento 2 prévoit une commande, agrémentée de quelques paramètres. Doc officielle: Magento 2 DevDocs – Set configuration values:

bin/magento config:set [–scope= »… »] [–scope-code= »… »] [-le | –lock-env] [-lc | –lock-config] path value

Cette commande consigne les directives de configuration en base de données, mais pour des raisons évidentes de portabilité il est tout-à-fait possible de l’exécuter depuis un script bash qui, lui, se révèle plus pratique à l’utilisation (versioning sous Git, déploiement des sites sans dump/restore de la base de donnés, …).

[A lire] Technique à appliquer en connaissance de cause!

Cette méthode n’est pas une méthode miracle et il convient de bien comprendre à quoi elle sert avant de la mettre en oeuvre. Vous allez, au premier déploiement de votre instance Magento 2, pouvoir paramétrer l’apparence graphique de votre site à l’aide d’un script plutôt qu’en faisant tout un tas de manipulations en backoffice. Ce script devra n’être lancé qu’une seule fois, au déploiement de votre/vos site(s). Ensuite, ce(s) dernier(s) vont vivre et le(s) admin(s) vont procéder à des modifications via le backoffice. Si vous relancez votre script après que des modifications aient été effectuées en backoffice sur des champs qui sont paramétrés dans ce premier, vous perdrez tout le bénéfice de ces dernières!

Il est important de bien comprendre que ce type de script permet juste de gagner du temps lors d’un premier déploiement ou en phase de développement lorsque plusieurs développeurs s’échangent du code.

Création d’un fichier init-theme.sh à la racine de votre projet Magento 2:

Cette directive empêche l’ouverture automatique d’une popup d’inscription à la newsletter (fonctionnalité qui vient avec de nombreux thèmes payants) à chaque ouverture de page:

Décryptage: mise en regard de la même directive dans un fichier config.php, la directive ci-dessus prend tout son sens.

Une méthode possible consiste ainsi à générer un fichier config.php de référence après avoir mis en place votre configuration via l’interface d’admin, puis à créer un script bash en regard de ce dernier.

Le fichier config.php auto-généré peut contenir beaucoup d’informations. Pour trouver rapidement celle qui vous intéresse, vous pouvez passer votre backoffice en anglais et regarder le libellé du champ qui vous intéresse. Dans notre exemple, il s’agit de « Show Newsletter Popup » qui se traduit par show_newsletter_popup dans le fichier config.php.

Il est à noter que certains champs sont accompagnés d’une coche/checkbox sur laquelle vous ne pourrez pas avoir la main via votre script.

Jouer votre script:

Tout d’abord, passer le script en exécutable:

…puis le jouer:

REMARQUE TRES IMPORTANTE: avant de voir les effets du script en front, il faudra impérativement vous connecter à l’interface d’admin et vous rendre dans Stores > Configuration [Settings] et activer à la main le bouton « Save Config ».

Les scopes pour une boutique simple (un seul ‘Store View’):

Magento 2 User Guide – Scope.

Modifie la valeur pour ‘Default Website’ et surcharge la valeur de ‘Default Config’:

Modifie la valeur pour ‘Default Store View’ et surcharge les valeurs de ‘Main Website’ et de ‘Default Config’:

[Magento 2] Configurer l’envoi de mail par SMTP lorsque vous travaillez avec Docker

Doc officielle: Configuring Email Communications

Fichiers à modifier ou à vérifier:

docker-compose.yml

.env

app/etc/env.php

app/etc/config.php

Hosts (VM Ubuntu server tournant sous Windows pour ma part) C:\Windows\System32\drivers\etc\hosts

Commandes à exécuter:

  • Arrêter/Relancer le conteneur Docker mail
  • Puis, $ n98-magerun2 setup:upgrade

En backoffice, sous Boutiques > Configuration [Paramètres] > menu colonne de gauche Avancé > Système > volet Paramètres d’envoi des emails, vous devriez avoir ceci:

  • Serveur: mail.projet.local
  • Port (25): 8025

[Magento 2] Corriger le bug de traduction du message d’ajout au panier

Testé fonctionnel Magento 2.3.3. Source: Magento 2 translation issue: notification Added to shopping cart.

You’re CSV columns are enclosed in double quotes, but you don’t appear to be escaping the double quotes of the href attribute. Have you tried:

Ce n’est pas le fichier vendor/magento/module-checkout/view/frontend/templates/messages/addCartSuccessMessage.phtml qu’il faut surcharger, mais dans votre fichier CSV:

[Magento 2] Afficher une liste produits par sous-catégories sur la page principale d’une catégorie

Par défaut, Magento 2 utilise un template PHTML unique pour afficher les listes produits d’une catégorie et de ses sous-catégories. Il s’agit du fichier vendor/magento/module-catalog/view/frontend/templates/product/list.phtml.

L’un des problèmes posé par ce mode de fonctionnement réside dans le fait qu’on se retrouve avec une page catégorie principale/main qui affiche, dans une liste unique, tous les produits contenus dans cette catégorie ainsi que ses sous-catégories et ceux sans aucun distingo. Ce qui nous donne, de manière très schématisée:

Le code décrit dans ce billet va permettre d’obtenir ceci:

Création d’un Helper: app/code/Pdv/Catalog/Helper/Data.php

Note: j’avais déjà créé ce Helper pour récupérer les Simple Products associés à un Configurable Product. Consulter le billet en question pour de plus amples infos si vous ne souhaitez pas exploiter tout le code ci-dessous. Ce Helper étend vendor/magento/module-catalog/Helper/Data.php.

Rajouts par rapport au Helper existant:

Sous la ligne namespace Pdv\Catalog\Helper;:

Sous la ligne protected $typeConfigurableResourceModel; // 1. Du nom du model dont je veux injecter la propriété de la classe:

Dans le constructeur, sous la ligne \Magento\ConfigurableProduct\Model\ResourceModel\Product\Type\Configurable $typeConfigurableResourceModel // 2. Demande à Magento une instance de mon configurable ressource model (EN RAJOUTANT UNE VIRGULE en fin de la ligne existante):

Sous la ligne $this->typeConfigurableResourceModel = $typeConfigurableResourceModel; // 3. ...et mappe le paramètre du constructeur avec la propriété de la classe:

Le commentaire:

…est enrichi comme suit:

Et la fonction getCurrentCategory() qui suit…

…est remaniée en:

app/design/frontend/Sodifrance/pdv/Magento_Catalog/templates/product/list_abonnements_category.phtml

Ce template PHTML se contente de boucler, autant de fois qu’il y a de sous-catégories, sur le template Magento_Catalog::product/list_abonnements_subcategory.phtml qui est une version custom du template vendor/magento/module-catalog/view/frontend/templates/product/list.phtml.

L’équivalent de ce fichier list_abonnements_subcategory.phtml DOIT exister dans votre projet. Si vous n’avez pas besoin d’en créer un spécifique, vous pouvez boucler sur le template par défaut fourni par Magento 2. Dans le code ci-dessus: ->setTemplate("Magento_Catalog::product/list.phtml"). Edit: il faut en créer un spécifique pour exploiter notre Helper.

app/design/frontend/Sodifrance/pdv/Magento_Catalog/templates/product/list_abonnements_subcategory.phtml

Ce template PHTML doit partir de vendor/magento/module-catalog/view/frontend/templates/product/list.phtml. Il est impératif de rajouter les lignes suivantes en haut de fichier, sous la ligne $hoverChange = $themeSettingConfig->getStoreConfig('themesettings/catalog/hover_change');:

app/design/frontend/Sodifrance/pdv/Magento_Theme/page_layout/abonnements_category.xml

Reportez-vous à ce billet pour voir comment afficher un layout différent selon une catégorie spécifique. Cette étape est indispensable pour faire pointer notre catégorie vers notre template PHTML spécifique app/design/frontend/Sodifrance/pdv/Magento_Catalog/templates/product/list_abonnements_category.phtml. Un exemple de code pour ce fichier ci-dessous:

Vous voudrez aussi créer le layout XML app/design/frontend/Sodifrance/pdv/Magento_Theme/page_layout/abonnements_subcategory.xml

…pour fairez pointer les sous-catégories vers le template PHTML .

Externaliser le code JS

Afin que le code JS initialement présent au bas du fichier list.phtml ne soit pas exécuté autant de fois qu’il existe de sous-catégories, il a été externalisé dans un fichier app/design/frontend/Sodifrance/pdv/Magento_Catalog/templates/product/list_abonnements_js.phtml et déclaré de la sorte dans nos layouts XML spécifiques:

app/design/frontend/Sodifrance/pdv/Magento_Catalog/templates/product/list_abonnements_js.phtml

Le code de ce fichier, sorti de list.phtml:

[Magento 2] Récupérer le compte des produits possédant un attribut donné

Attention: pas testé.

Source: Magento 2 product count by attribute.

[javaScript] Exploiter les Mutation Observers pour surveiller la disponibilité d’éléments dans le DOM

Attention: l’article et le code ci-dessous ne sont valables qu’au document ready. Ceci signifie qu’au chargement de la page seulement, on va vérifier la disponibilité d’un ou plusieurs éléments dans le DOM. Les sources ne concernent pas l’observation de modifications dans le DOM une fois que la page est chargée et/ou qu’un utilisateur effectue des actions. Pour cette deuxième fonctionnalité, se référer à la documentation de Mutation Observer sur developer.mozilla.org et un exemple d’utilisation ici: [Magento 2] Utiliser les Mutation Observers de javascript pour détecter les changement dans le DOM suite à une action utilisateur.

Source: Using Mutation Observers to Watch for Element Availability. Code source sous GIT. Version PDF pour la postérité.

[Magento 2] Créer des Swatches (ou échantillons) pour afficher toutes les options et prix d’un produit configurable dans la liste des catégories et des produits

Testé fonctionnel Magento 2.3!

Ressources en ligne m’ayant permises d’arriver à mes fins:

Créer un produit configurable

A la création des configurations, vous allez créer un attribut dont le type d’entrée catalogue pour le propriétaire de la boutique sera Texte échantillon (Text Swatches). Ceci permettra d’afficher les différentes options de votre produit configurable comme Magento 2 le fait pour les couleurs par exemple.

  • Boutiques > Produit [Attributs]
  • Propriétés > Propriétés de l’attribut:
  • Type d’entrée catalogue pour le propriétaire de la boutique: Texte échantillon
  • Propriétés > Gérer les échantillons (valeurs de votre attribut) > ajouter des échantillons. Attention: la valeur saisie dans le champ « Admin » sera celle affichée en front (?!)

  • Propriétés du front office > Propriétés du front office
  • Utiliser dans la navigation par filtres: Filtrable (avec résultats)
  • Visible sur les pages du catalogue de la boutique: Oui
  • Utiliser dans les listes de produits: Oui
  • Utiliser pour le tri des listes produits: Oui
  • Remarque importante: la visibilité pour chacune de vos configuration doit être sur Non visible individuellement.

    Modifier le fichier vendor/magento/module-swatches/view/frontend/web/js/swatch-renderer.js

    Archive contenant le fichier final modifié: swatch-renderer.

    NDLA: pardon pour ce contenu moitié anglais/moitié français repris en partie de ce post sur StackOverflow. Et attention car je n’ai pas repris ligne pour ligne les directives données dans ce dit post. J’ai amélioré le code notamment sur certains aspects que je décris au moment venu.

    Dans Magento 2, la gestion des différentes options/swatches/échantillons des produits configurables se fait via javaScript, dans ce fichier plus précisément: vendor/magento/module-swatches/view/frontend/web/js/swatch-renderer.js. Il faudra donc commencer par le surcharger dans app/design/frontend/Vendor/default/Magento_Swatches/web/js/swatch-renderer.js.

    Dans ce fichier, les valeurs de chaque échantillon sont générées via la fonction _RenderSwatchOptions.

    Modification #1: _RenderSwatchOptions do not get data of $widget veriable. So, I have make below change.

    Avant:

    Après modification:

    Change #2: search with _RenderSwatchOptions and change argument from where this function call from swatch-renderer.js file

    Avant:

    Après modification:

    Change #3: Now I can get the value of $widget object in to _RenderSwatchOptions function but not abel to get price value of options.

    So, to add option id wise price please add below code below the line change which applied in #2.

    Avant:

    Après modification… De nombreux axes d’amélioration du code trouvé sur StackOverflow ici:

    • Le prix retourné était un nombre entier (pour un prix de 12,50 € renseigné en backoffice, c’est la valeur 12 s’affichait) à cause de l’utilisation de la méthode parseInt() (qui renvoie seulement un entier) que j’ai remplacé par la méthode parseFloat() (qui renvoie également les décimales). J’ai également utilisé la méthode toFixed(2) avec une valeur de « 2 » pour afficher deux chiffres après la virgule.
    • Le prix retourné via la méthode parseFloat() séparait les décimales avec un caractère . au lieu d’une virgule. J’ai donc mis en place un remplacement automatique via la méthode replace (replace(/\./g,',').

    Change #4: Add price div into _RenderSwatchOptions function.

    My attribute is swatch options with type = text. So, I made below changes.

    Avant:

    Après modification… Un tout petit axe d’amélioration du code trouvé sur StackOverflow ici:

    • J’ai rajouté la devise , mais de façon totalement fixe (pas récupérée dynamiquement). C’est encore un axe d’amélioration.

    [Magento 2] Produit configurable – afficher une fourchette de prix plutôt qu’un prix d’appel dans la liste des catégories/produits

    Pas testé, mais trouvé par hasard et mis de côté pour le jour où j’ai besoin!

    Source: Display Configurable Product Price Ranges in Magento 2 et version PDF pour la postérité.

    Dans la liste produits (ou catégories) par défaut, Magento 2 affiche le prix d’un produit configurable de cette manière: A parti de <prix_le_plus_bas>. L’auteur du blog ci-dessus propose d’afficher une fourchette de prix plutôt qu’un prix d’appel: <prix_le_plus_bas><prix_le_plus_haut>.