Tagwidget

[Magento 2] Astuces pour adapter rapidement du code javascript aux standards jQuery UI Widget

L’intérêt de ce billet est de donner quelques astuces pour adapter rapidement du code javascript aux standards jQuery UI Widget pour une meilleure exploitation dans Magento 2.

Télécharger les sources: Magento2-jQuery-widget-example.

Dans cette archive au format ZIP, deux fichiers:

  • la version « old » du code du module, fonctionnelle mais pas formatée à la sauce jQuery UI Widget Factory
  • la version standardisée jQuery UI Widget Factory du code, pour une meilleure exploitation dans Magento 2

Note: très bonne ressource, en marge de la doc officielle, pour créer un widget jQuery UI pour Magento 2.

Découpage du squelette de base d’un widget jQuery UI pour Magento 2

Note: notre fichier d’exemple est placé dans un thème Magento 2 suivant le chemin: app/design/frontend/MyVendor/mytheme/web/js/attribute-carousel.js

On commence par un bon vieux define qui nous servira à définir notre widget en tant que de module via RequireJS. Il pourra ensuite s’articuler avec d’autres modules définis en tant que tels, toujours via RequireJS:

Déclaration ici des variables globales pour ce widget (facultatif, votre widget n’en a peut-être pas besoin):

Déclaration du widget sous la forme $.widget('mage.<nomDuWidget>', {:

Déclaration des options du widget sous forme d’objet options, si il exploite des arguments (facultatif).
Le libellé options ne doit pas être modifié!
(voir aussi les commentaires directement dans le bout de code ;))

La fonction privée _create" (présence obligatoire), qui sera automatiquement exécutée à chaque initialisation de ce widget depuis un PHTML, un fichier JS, …
Le libellé _create ne doit pas être modifié!

Variabiliser le sélecteur, présent dans le DOM, sur lequel est initialisé le widget. Remarquer ici le chemin this.options.attributeSelectorId pour exploiter la valeur de l’option simple attributeSelectorId déclarée plus haut dans notre objet options.

Et variabiliser this (ici sous l’alias that) est important dès lors qu’on cherche à exécuter une fonction de ce widget (on le verra plus bas):

On précède chaque exécution d’une fonction de ce widget par notre « that » alias de « this »:

Commentaires directement dans le bout de code 😉

Manière de déclarer une fonction (<nomDeLaFontion>: function(<argument>, <argument>) { return <quelque chose> }):

Ici, on déclare le chemin this.options.slick pour exploiter la valeur d’une option du sous-objet « slick » déclaré plus haut dans notre objet « options ».
Note: il y a probablement plus simple pour passer une série d’arguments que de repointer un à un tous les objets. Je manquais de temps sur le projet en question.

Manière de déclarer une fonction (: function(, ) { sans « return » cette fois-ci (ça fonctionne mais ce n’est pas la meilleure pratique!) }):

On n’oublie pas de retourner le widget avant de refermer définitivement l’accolade et la parenthèse qui embrassent (c’est bô <3!) le widget:

Version finale (également disponible dans le ZIP):

Déclaration de notre widget jQuery UI via RequireJS

Fichier app/design/frontend/MyVendor/mytheme/requirejs-config.js:

Utilisation du widget dans un template PHTML de Magento 2

[Magento 2] Les bases et patterns de l’utilisation de javascript (AMD, requireJS, widget jQuery, plugin, module, x-magento-init, etc…)

Intégrer et exploiter dans Magento 2 un plugin jQuery tiers dont le code source est structuré selon le pattern AMD

Pour illustrer cette partie, nous allons intégrer dans Magento 2 le plugin jQuery Slick Carousel, dont le code source est structuré selon le pattern AMD.

Remarque: l’intégration du plugin jQuery tiers va se faire dans un thème. Si vous comptez utiliser le plugin en question sur un projet multi-sites/multi-thèmes ou sur plusieurs projets, une meilleure stratégie consisterait à intégrer ce premier dans un nouveau module MyVendor_Slick qu’on placerait dans app/code/MyVendor/Slick.
Cette démarche n’est pas décrite ici, mais mériterait d’être envisagée en fonction de vos besoins.

Récupération du plugin sous Git et copie dans l’arborescence du thème

Récupérer la source minifiée du plugin Slick sous Git (tag v1.8.1 dans mon exemple, mais vous pouvez vérifier si il existe un tag plus récent) et copier-coller le fichier dans votre thème, au chemin suivant: app/design/frontend/MyVendor/mytheme/web/js/vendor/slick/slick.min.js.

Déclaration du plugin en tant que module via RequireJS

Dans le fichier app/design/frontend/MyVendor/mytheme/requirejs-config.js:

Création d’un fichier d’initialisation d’une instance du plugin

Dans votre thème, créer le fichier app/design/frontend/MyVendor/mytheme/web/js/init-slick.js qui va servir à appeller et à initialiser une instance du plugin javascript Slick et vous donnera accès à toutes les options de l’API originale:

Petite subtilité: ajouter une configuration spécifique par défaut à toutes les instances de votre plugin

Dans l’exemple ci-dessous, le fichier app/design/frontend/MyVendor/mytheme/web/js/init-slick.js est agrémenté d’un objet defaults qui surcharge (via les settings proposés de base par le plugin Slick Carousel prevArrow et nextArrow) l’aspect graphique des chevrons « slide précédent/slide suivant ».

L’intérêt d’ajouter une configuration spécifique par défaut à toutes les instances de votre plugin réside, pour l’exemple du Carousel, dans le fait qui si la charte graphique de votre projet prévoit les mêmes chevrons spés pour tous les sliders du site, vous allez pouvoir tous les initialiser sans avoir besoin de re-préciser à chaque fois que vous voulez surcharger les pictos fournis de base par ceux de votre charte.

Vous pouvez, bien entendu, les re-surcharger et utiliser d’autres options du plugin à la demande pour chaque nouveau Carousel que vous allez mettre en place.

Appeler et initialiser une instance du plugin sur un élément du DOM

Cette page de la documentation officielle vous expliquera comment appeler et initialiser une instance du plugin sur un élément du DOM dans Magento 2.

Elle aborde notamment la manière de procéder depuis un fichier template PHTML, depuis un fichier JS et comment exécuter data-amge-init et x-magento-init dans un cas où le DOM se met à jour dynamiquement.

Dans ce billet, je vais me contenter d’illustrer un exemple de notation déclarative avec x-magento-init depuis un fichier PHTML.

Exemple de notation déclarative avec x-magento-init depuis un fichier PHTML

Ici, j’initialise simplement mon module Slick sur l’élément du DOM qui porte l’ID home-slider. Le carousel va s’afficher soit avec les options de base fournies par le plugin Slick, soit avec les options de base fournies par le plugin Slick ET des pictos chevrons surchargés par ma configuration par défaut si j’en ai défini une.

Même exemple avec ajout d’options

Ici, je choisis de paramétrer mon carousel afin qu’il affiche 4 slides à la fois et qu’on scrolle d’une slide à chaque fois qu’on active les boutons prev/next ou tout autre mode de navigation fourni par le plugin. Les options slidesToShow et slidesToScroll sont fournies par le plugin Slick et exploitables immédiatement grâce à la magie d’AMD, de RequireJs et de Magento.

Ressources en ligne:

[Magento 2] Etendre un composant JS natif

Testé fonctionnel Magento 2.4. Source: Extending Magento 2 default JS components. Version PDF – inchoo.net-Extending Magento 2 default JS components.

Etendre le composant UI Tabs pour ajouter un effet de bordure animée sous les onglets:

app/design/frontend/MyVendor/mytheme/web/js/tabs-custom.js

app/design/frontend/MyVendor/mytheme/requirejs-config.js

app/design/frontend/MyVendor/mytheme/Magento_Theme/templates/html/sections.phtml

app/design/frontend/MyVendor/mytheme/web/css/source/tabs.less

app/design/frontend/MyVendor/mytheme/Magento_Sales/layout/sales_order_info_links.xml et app/design/frontend/MyVendor/mytheme/Magento_Sales/layout/sales_order_guest_info_links.xml

[Magento 2] DropdownDialog widget

Attention: le code sample du widget DropdownDialog fourni dans la documentation officielle de Magento 2 (v2.3) génère des bugs à l’utilisation.

Résolution du problème: le <div class="block block-minicart"> doit être inséré immédiatement sous le <button>:

Par ailleurs, le paramètre closeOnEscape semble déprécié ou n’est pas détaillé dans la documentation.

[Magento 2] Utiliser le source model Yesno pour faire apparaître de manière dynamique et sous condition un champ caché dans un widget custom

Nous avons ici deux champs mais l’affichage du second, masqué au chargement du formulaire, est conditionné à l’activation du premier qui est un booléen (true/false -> si « true », alors le second champ est affiché).

Cas où l’affichage du champ caché dépend de l’activation de plusieurs autres champs

Pas encore testé, mais vu sur le net et notifié comme fonctionnel (bug fixé dans la 2.3.x).

[Magento 2] Afficher des widgets sur n’importe quelle page du site (CMS custom, category, product, …)

Avant-propos: j’ai testé plusieurs pistes pour parvenir à mes fins. Si la méthode #2 décrite plus bas fonctionne avec de grosses limitations (je vous déconseille de la mettre en place), j’ai choisi de la consigner car elle m’a appris des choses sur Magento 2. Mais gardez à l’esprit que la seule méthode valide est la méthode #1.

Méthode #1

Pré-requis (2 profils d’utilisateurs Magento 2): vous devez avoir accès au code source de votre projet pour pouvoir déclarer chaque nouvelle création d’une page CMS custom (ces pages ne se référencent pas automatiquement dans Magento 2) ou vous avez défini, au moment de monter votre projet, le nombre et la nature des pages CMS custom dont vous aurez besoin et votre prestataire mettra en place le nécessaire pour vous.

Mes sources pour la première partie de ce billet:

Etendre un fichier page_types.xml dans un module spécifique

Convention: dans ce tuto, nous allons considérer que les Vendor/Module sont Sodifrance/Pdv.

Repérer le fichier vendor/magento/module-cms/etc/frontend/page_types.xml et l’étendre dans app/code/Sodifrance/Pdv/etc/frontend/page_types.xml. Ce fichier sert à lister les pages CMS qui seront disponibles depuis l’interface d’administration de Magento 2 pour y glisser des widgets (prononcer « widjets »). Par défaut, les pages CMS custom ne s’ajoutent pas automatiquement à cette liste. Nous n’allons pas introduire d’automatisme, mais un ajout manuel.

Vous pouvez supprimer tous les types existants dans le fichier de départ car l’ensemble des déclarations de types seront mergées par Magento 2 au moment venu de la compilation. Votre fichier d’extension va donc ressembler à ceci:

Trouver le handle d’une page CMS custom

Pour aller plus loin, il faut au préalable avoir créé au moins une page CMS custom.

Le handle est identifiant unique assigné de manière automatique par Magento 2 à chaque nouvelle création de page CMS (les pages « système » comme la page des catégories ou la page des produits en ont aussi un) sous le format cms_page_view_id_[clé_d'URL].

Logiquement, si on connaît le format et la clé d’URL (visible dans la colonne « Clé d’URL » du tableau qui liste les pages CMS dans l’interface d’admin (Contenu > [Eléments] Pages)), on n’a pas besoin de faire la manip’ qui suit mais je la décris quand-même à toutes fins utiles.

Pour trouver celui d’une page CMS custom, nous pouvons éditer provisoirement un fichier PHP du core de Magento 2. Rendez-vous dans le fichier vendor/magento/framework/View/Model/Layout/Merge.php et localisez la fonction addHandle(). De là, placez un echo $name; dans le foreach et un echo $handleName; dans le else. Voir ci-dessous:

Ainsi, par exemple, si vous avez créé une page CMS en backoffice avec comme clé d’URL page-de-test, le handle de cette page est: cms_page_view_id_page-de-test.

Ajouter le handle de votre page CMS custom dans le fichier étendu page_types.xml

Tout est dit dans le titre:

Il ne vous reste plus qu’à lancer un $ n98-magerun2 cache:clean et à vous rendre en admin. Depuis l’interface de création de widgets, ajoutez ou éditez un widget > [Encart de gauche WIDGET] > Propriétés du front office > Section Mise à jour d’agencements > champ « Display on », choisir « Pages génériques > Page spécifiée » > champ « Page », choisir « CMS page-de-test » > champ « Container », choisir une zone qui existe dans votre page CMS (en général « Main Content Top » est présente) > Enregistrez la configuration de votre widget et rendez-vous en front sur votre page CMS custom. Le widget s’affiche! Si il ne s’affiche pas, re-videz vos caches!


Méthode #2

ATTENTION: cette méthode ne fonctionne pas à 100%. Il reste déconseillé de l’utiliser avant d’avoir pris connaissances de ses limites (énoncées ci-dessous).

  • Les balises HTML saisies ou générées depuis un champ code/WYSIWYG du widget que l’on insère dans un bloc statique sont automatiquement échappées par Magento 2. Ceci signifie que lorsque vous allez saisir <h3>titre</h3>, votre saisie sera réinterprétée en &lt;h3&gt;titre&lt;/h3&gt; et affichée comme telle sur les pages de votre site.
    Cette « transformation » s’effectue à l’enregistrement du widget, lorsque celui-ci est créé via la création d’un bloc statique. Si vous êtes courageux, vous pouvez repasser sur le code échappé et ré-enregistrer votre bloc statique. Avec une repasse à la main, ça fonctionne. Faut juste en avoir envie…
  • Si vous voulez utiliser des classes sur vos éléments HTML (<h3 class="heading-three">titre</h3>), votre widget ne s’affichera pas. J’ai tenté en remplaçant les caractères "" par des '' mais sans plus de succès. Peut-être une piste de solution « programmatique » ici (html tags in widgets breaks edit mode), mais selon moi ça devient vraiment overkill de rentrer dans des trucs comme ça…

Créer un bloc statique

  1. Contenu > Blocs > Bouton « Ajouter un nouveau bloc ».
  2. On renseigne les champs obligatoires, puis dans le champ WYSIWYG on clique sur le bouton « Insérer un widget » (pour notre exemple, mettre « [test] static block » dans le champ « Titre du bloc » et « test_static_block » dans le champ « Identifiant »).
  3. De là, on choisit le type de widget qu’on souhaite insérer et on renseigne les paramètres de ce dernier selon nos besoins, puis on clique sur le bouton « Insérer un widget ».
  4. Puis, on clique sur le bouton « Enregistrer » pour enregistrer le bloc.
  5. Dans la liste des blocs, on note l’identifiant du bloc qu’on vient de créer (Bloc « [test] static block » dont l’ID est « test_static_block » dans notre exemple).

Voir ici pour résoudre le problème de conversion, par l’éditeur WYSIWYG, des tags en entités HTML (par exemple: <h3> est transformé en <h3>). Y’a pas de solution: passez votre chemin si les limitations observées ne vous permettent pas d’obtenir satisfaction en regard de vos besoins en matière d’exploitation CMS.

Insérer le bloc statique créé précédemment dans une page CMS custom

  1. Contenu > Blocs > Bouton « Ajouter une nouvelle page » ou Choisir > Modifier une page existante.
  2. Ouvrir le volet « Contenu » > si besoin on clique sur le bouton « Afficher/masquer l’éditeur » pour masquer les boutons d’édition du champ WYSIWYG (pour avoir accès à la vue « code »).
  3. Dans la vue code, placer ceci: {{block class="Magento\Cms\Block\Block" block_id="test_static_block"}} (où test_static_block est notre identifiant de bloc statique d’exemple).
  4. De là, on clique sur le bouton « Enregistrer » pour enregistrer le bloc.

A ce stade, notre bloc statique contenant un widget est visible en front sur notre page CMS custom de test (Choisir > Voir dans la liste des pages, au niveau de la page dans laquelle nous venons d’insérer le bloc statique).

Insérer le bloc statique créé précédemment dans une page référencée par Magento 2 (catégorie de produits, …)

Dans notre exemple, nous allons choisir d’afficher notre bloc statique dans une catégorie de produits.

  1. Contenu > Widgets > Bouton « Ajouter un widget ».
  2. Section « Paramètres » > Champ « Type » > choisir « Bloc CMS statique ».
  3. Remplir les autres champs obligatoires de cette section (mettre « [test] widget » dans « Titre du widget » pour suivre notre exemple) et cliquer sur « Continuer ».
  4. Section « Mise à jour d’agencements » > Champ « Display on » > choisir « Catégorie ancrée ».
  5. Champ « Catégories » > cocher le bouton radio « Spécifique à Catégories ».
  6. Champ « Container » > choisir « Main Content Top » (cette zone reste disponible dans à peu près tous les layouts proposés par défaut dans Magento 2, mais si vous utilisez un thème ou que vous travaillez sur un projet qui contient beaucoup de code custom, il vous faudra peut-être sélectionner une autre zone pour voir apparaître votre bloc statique en front).
  7. En-dessous, cliquer sur l’icône « Ouvrir le sélecteur » > cochez les catégories et sous-catégories dans lesquelles votre bloc statique doit apparaître.
  1. Dans l’encart de gauche (« Widget ») > cliquez sur « Options du widget ».
  2. Section « Options du widget » > champ « Bloc » > cliquez sur le bouton « Sélectionnez un bloc… ».
  3. Si vous avez suivi notre tuto à la lettre, le bloc que vous devez sélectionner est: « [test] static block ».
  4. De là, on clique sur le bouton « Enregistrer » pour enregistrer le widget.

A ce stade, notre bloc statique contenant un widget est visible en front sur les pages de catégories/sous-catégories que nous venons de cocher dans la configuration de notre widget.

Résoudre le problème de conversion, par l’éditeur WYSIWYG, des tags en entités HTML

Exemple de problème rencontré: <h3> est transformé en &lt;h3&gt;). Une balise <p> est également ajoutée autour de la déclaration du widget…

Autre exemple:

Une fois que le markup est repassé à la main, le problème de conversion ne se pose plus, mais il reste l’ajout de l’élément <p> autour du widget!

[Magento 2] Ajouter un sélecteur d’image ou un champ WYSIWYG dans un widget custom

Pour ajouter un sélecteur d’image ou un champ WYSIWYG dans un widget custom dans Magento 2, nous allons utiliser l’extension suivante: Useful widget types for Magento 2 like image selector and wysiwyg text editor (un article de l’auteur ici: Using an Image Selector Parameter for Magento Widgets).

Code source zippé – magento2-widget-parameters-master.

Convention: on part du principe qu’on crée un widget pour le vendor Sodifrance et le module Pdv.

Installation de l’extension magento2-widget-parameters via Composer

Documentation officielle de Magento 2 sur comment installer une extension via composer.

Lancer la commande $ composer require dmatthew/magento2-widget-parameters:1.0.1 à la racine de votre projet Magento 2.
Des warnings vont probablement s’afficher. Ne pas en tenir compte.

app/code/Sodifrance/Pdv/etc/widget.xml

Nous allons déclarer un widget contenant 3 paramètres:

  • un titre
  • une image issue de la « médiathèque » de Magento 2
  • un champ WYSIWYG (qui permet d’utiliser du code HTML pour la mise en page, ou d’inclure un bloc statique)

app/code/Sodifrance/Pdv/Block/Widget/Tab.php

Il a fallu créer une fonction pour permettre de récupérer l’URL de l’image uploadée.

app/code/Sodifrance/Pdv/view/frontend/templates/widget/tab.phtml

Le template PHTML.

Flusher les caches:

Si problèmes…

Voir aussi: [Magento 2] Créer un widget custom et l’utiliser pour afficher un bloc statique dans une catégorie unique du catalogue.

[Magento 2] Créer un widget custom et l’utiliser pour afficher un bloc statique dans une catégorie unique du catalogue

Créer un widget custom dans Magento 2 peut être utile, notamment car cette solution permet de placer un bloc statique de manière beaucoup plus sélective (on peut cibler une catégorie unique du catalogue par exemple) et depuis l’interface d’admin.

Dans ce billet:

Créer un widget custom dans Magento 2

Je me suis inspiré de la doc officielle et d’un autre tuto pour arriver à mes fins, la doc officielle étant incomplète et les exemples de code erronés!

On part du principe qu’on crée un widget pour le vendor Sodifrance et le module Pdv.

Initialiser le widget

app/code/Sodifrance/Pdv/registration.php

app/code/Sodifrance/Pdv/etc/widget.xml

Créer un template pour le widget

app/code/Sodifrance/Pdv/view/frontend/templates/widget/test.phtml

Créer un block pour le widget

app/code/Sodifrance/Pdv/Block/Widget/Test.php

Ajouter une dépendance au module Magento_Widget dans le fichier module.xml

app/code/Sodifrance/Pdv/etc/module.xml

Commandes à exécuter

Appliquer la dépendance de module déclarée dans le fichier module.xml:

Flusher les caches:

Accès BO à votre widget custom

  • Contenu > Widgets > Ajouter un widget
  • Choisir le type de widget dans la liste déroulante: « Test Widget »

Pour afficher un widget dans une seule catégorie du catalogue:

  • Contenu > Widgets > Ajouter un widget
  • Choisir le type de widget et le thème de design
  • Remplir les champs obligatoires de la section « Propriétés du front office »
  • Dans la section « Mises à jour d’agencements » > Ajouter une mise à jour d’agencements
  • Display on: catégorie ancrée
  • Catégories: Spécifique à Categories
  • Cliquer sur l’icône « Ouvrir le sélecteur »
  • Déplier l’arbre de catégories/sous-catégories et cocher la ou les catégories dans laquelle le widget doit s’afficher; il ne s’affichera pas dans les autres

Ajouter un bloc statique dans un widget custom Magento 2

[Magento 2] Inclure un bloc statique depuis un champ WYSIWYG (nouvelle fenêtre).

Une liste de ressources en ligne intéressantes sur le sujet

Dépôts Git de démonstration, proof of concepts, etc …

  • Magento 2: Widgets – This module is to demonstrate the different fields available for Magento 2 widgets. The idea is to use this as a base or reference for creating your own widgets. There is an example widget provided which has all the possible field types available.

Tutoriels

  • inchoo.net – Magento 2 custom widget. Now we will see how we can create a custom one, or even better, how to extend the core one. For this example I picked default catalog product listing widget that I will extend with sorting fields for better customization of this widget.

[Magento 2] Exploiter le widget javascript jQuery natif Accordion dans le fichier PHTML des filtres produit (page category)

Note: ce widget Accordion fait partie d’une collection étendue de widgets fournis de base par Magento 2 (à ne pas confondre avec la bibliothèque UI Magento 2, fournie de base également, et qu’il convient de connaître aussi.

Pour ce tuto, nous allons afficher les différentes familles de tri produits (catégorie, taille, activity, color, erin recommends, genre, material, nouveau, prix, etc…) sous forme d’accordéons. De base, ils s’affichent tous ouverts, y-compris en vue Mobile ce qui force l’utilisateur à scroller bas dans la page avant de voir apparaître le premier produit. Le fonctionnalités voulues pour ce accordéon:

  • tous les accordéons (différentes familles de tri) sont ouverts au chargement de la page
  • plusieurs accordéons peuvent rester ouverts simultanément

(Note pour plus tard: il peut être intéressant, dans le cadre de la découverte des media-queries côté JS, d’initialiser ce widget avec des options différentes en fonction de l’affichage mobile/desktop).

A noter: il existe plusieurs méthodes pour initialiser du code javascript dans une vue dans Magento 2. Nous allons nous concentrer sur deux d’entre-elles qui ne sont ni meilleures, ni moins bonnes que les autres.

Imperative notation

En initialisant notre widget directement dans un fichier *.phtml, entre balises <script type="text/javascript">.

Commencer par éditer le fichier *.phtml app\design\frontend\<Vendor_name>\<theme_name>\Magento_LayeredNavigation\templates\layer\view.phtml qui constitue la base de la vue des différents filtres. Notez bien l’ajout, par rapport à la vue que nous surchargeons, des attributs data-role="collapsible", data-role="trigger" et data-role="content" respectivement placés sur les éléments dt, a et dd, ainsi que de la classe filter-options-collapsible-trigger placée sur le nouvellement ajouté élément a.

Le widget s’initialise ensuite comme suit avec requireJS (code placé dans le même fichier view.phtml, immédiatement après la ligne <?php if ($block->canShowBlock()): ?>):

Declarative notation

Le widget va s’initialiser sans avoir recours à un require déclaré dans une balise <script />, par de biais d’un attribut data-mage-init placé directement sur l’élément à partir duquel nous venons précédemment d’initialiser notre widget à la manière de jQuery.

Dans les deux cas on n’oublie pas de lancer un cache:clean en console!

[CSS] Une largeur fluide pour le widget Comments de Facebook

Source : How to make Facebook comments widget a fluid width?.

© 2021 devfrontend.info

Theme by Anders NorénUp ↑