Génération de fichier import CSV WooCommerce avec PowerShell

2 Oct 2017

Bonjour,

Pour compléter l’article sur l’import CSV de produits et variations WooCommerce, voici un petit exemple de génération automatique de fichier CSV destiné à être importé, au moyen de Microsoft PowerShell. Le but étant de pouvoir générer un fichier complet représentant la base des produits de votre boutique, et ainsi de pouvoir importer tous vos produits et variations d’un coup, ou de les modifier s’ils sont déjà sur le site.

Pourquoi PowerShell ?

Ayant longtemps évolué sous Unix/Linux, dans le cadre du travail ou non, je suis naturellement devenu accro au SHELL et à grep, find, sed, awk et consorts… Mais ici, plutôt que d’utiliser un shell Unix (en activant par exemple le bash d’Ubuntu sous Windows), j’ai voulu me pencher sur le PowerShell de Windows que je ne connais pas et dont tout le monde dit du bien, afin de voir si je pouvais rapidement trouver les commandes équivalentes… Succès total en quelques minutes de recherche sur le Net ! Un vrai bonheur, aux antipodes du MS-DOS que je n’ai jamais pu encadrer 😉

Attention, vous devrez au préalable autoriser l’exécution de scripts PowerShell dans Windows si ce n’est pas déjà fait.

Le besoin : importer des produits et variations en masse

Je désire importer une base de produits et variations (des photos) dans WooCommerce, avec des prix différents pour chaque variation, les variations correspondant à la taille des photos imprimées (4 tailles), donc différentes selon le format de la photo (paysage, portrait ou carré). Le tout simplement à partir de mes fichiers photos et rien d’autre.

Un produit et ses variations seront donc représentés par l’un de ces trois bouts de fichier CSV, en fonction du format de la photo :

variable,DSCF2145,DSCF2145,1,visible,1,"Format paysage",DSCF2145.jpg,Taille,"30x20, 45x30, 60x40, 75x50",30x20,0,1,,,,
variation,DSCF2145-30x20,DSCF2145-30x20,1,visible,1,,,Taille,30x20,,,,DSCF2145,30,20,40
variation,DSCF2145-45x30,DSCF2145-45x30,1,visible,1,,,Taille,45x30,,,,DSCF2145,45,30,60
variation,DSCF2145-60x40,DSCF2145-60x40,1,visible,1,,,Taille,60x40,,,,DSCF2145,60,40,70
variation,DSCF2145-75x50,DSCF2145-75x50,1,visible,1,,,Taille,75x50,,,,DSCF2145,75,50,80

variable,R0000462,R0000462,1,visible,1,"Format portrait",R0000462.jpg,Taille,"20x30, 30x45, 40x60, 50x75",20x30,0,1,,,,
variation,R0000462-20x30,R0000462-20x30,1,visible,1,,,Taille,20x30,,,,R0000462,20,30,40
variation,R0000462-30x45,R0000462-30x45,1,visible,1,,,Taille,30x45,,,,R0000462,30,45,60
variation,R0000462-40x60,R0000462-40x60,1,visible,1,,,Taille,40x60,,,,R0000462,40,60,70
variation,R0000462-50x75,R0000462-50x75,1,visible,1,,,Taille,50x75,,,,R0000462,50,75,80

variable,R0000937,R0000937,1,visible,1,"Format carré",R0000937.jpg,Taille,"20x20, 30x30, 40x40, 50x50",20x20,0,1,,,,
variation,R0000937-20x20,R0000937-20x20,1,visible,1,,,Taille,20x20,,,,R0000937,20,20,40
variation,R0000937-30x30,R0000937-30x30,1,visible,1,,,Taille,30x30,,,,R0000937,30,30,60
variation,R0000937-40x40,R0000937-40x40,1,visible,1,,,Taille,40x40,,,,R0000937,40,40,70
variation,R0000937-50x50,R0000937-50x50,1,visible,1,,,Taille,50x50,,,,R0000937,50,50,80

Sachant que l’entête du fichier global sera :

Type,SKU,Name,Published,"Visibility in catalog","In stock?",Categories,Images,"Attribute 1 name","Attribute 1 value(s)","Attribute 1 default","Attribute 1 visible","Attribute 1 global",Parent,"Width (cm)","Height (cm)","Regular price"

Je ne m’étendrai par sur ces CSV car aujourd’hui le but est de générer automatiquement ce genre de choses… pas de les comprendre.

Remarque : Les lignes des CSV précédents sont coupées automatiquement au niveau des espaces et tirets car elles sont trop longues, j’espère que ça reste compréhensible. J’ai eu la flemme de régler ce problème après avoir écrit l’article 😉

Analyse du CSV et élaboration de la stratégie

Dans ces bouts de fichier CSV, les éléments spécifiques aux produits/variations sont :

  • le nom du produit, qui est aussi pour moi l’identifiant du produit dans le stock, et le nom du fichier sans extension
  • l’identifiant d’une variation (ID du produit et suffixe)
  • le format de la photo qui correspond ici à une catégorie
  • les valeurs de l’attribut Taille correspondant aux suffixes des ID variations
  • la taille par défaut pour un produit
  • les tailles et le prix pour chaque variation, communes à tous les produits d’un même format

Tout le reste est commun à tous les produits/variations, donc aux trois types de CSV à générer.

A partir de là, il y a pleins de façons de voir les choses, mais pour limiter la complexité du script et ne pas me pencher sur la consultation du format des images par outil tiers, j’ai choisi cette solution :

  • je classe les photos dans des répertoires associés à la catégorie, donc au format de la photo ;
  • j’utilise des fichiers « canevas », sortes de templates qui représentent tout ce qui est commun à mes produits/variations, dans lesquels je vais injecter les informations spécifiques en allant y remplacer des mots-clé.

Préparatifs

Création d’un dossier « Collection » contenant les dossiers « Paysage », « Portrait », « Carre », et copie des photos associées.

Création d’un dossier « Script » au même niveau que Collection, qui contiendra le script et les fichiers « canevas ».

Importation des photos dans la bibliothèque WordPress.

Les fichiers « canevas » CSV

Exemple du fichier associé au format paysage import-paysage.csv :

variable,PRODUIT,PRODUIT,1,visible,1,"Format paysage",PRODUIT.jpg,Taille,"30x20, 45x30, 60x40, 75x50",30x20,0,1,,,,
variation,PRODUIT-30x20,PRODUIT-30x20,1,visible,1,,,Taille,30x20,,,,PRODUIT,30,20,40
variation,PRODUIT-45x30,PRODUIT-45x30,1,visible,1,,,Taille,45x30,,,,PRODUIT,45,30,60
variation,PRODUIT-60x40,PRODUIT-60x40,1,visible,1,,,Taille,60x40,,,,PRODUIT,60,40,70
variation,PRODUIT-75x50,PRODUIT-75x50,1,visible,1,,,Taille,75x50,,,,PRODUIT,75,50,80

J’ai utilisé un unique mot-clé « PRODUIT » ici, puisque toute les informations spécifiques dépendent du nom de mon fichier image.

Les canevas pour les formats portrait et carré sont les mêmes, avec leurs infos spécifiques, le format, les tailles et les prix de chaque variation (import-portrait.csv et import-carre.csv) :

variable,PRODUIT,PRODUIT,1,visible,1,"Format portrait",PRODUIT.jpg,Taille,"20x30, 30x45, 40x60, 50x75",20x30,0,1,,,,
variation,PRODUIT-20x30,PRODUIT-20x30,1,visible,1,,,Taille,20x30,,,,PRODUIT,20,30,40
variation,PRODUIT-30x45,PRODUIT-30x45,1,visible,1,,,Taille,30x45,,,,PRODUIT,30,45,60
variation,PRODUIT-40x60,PRODUIT-40x60,1,visible,1,,,Taille,40x60,,,,PRODUIT,40,60,70
variation,PRODUIT-50x75,PRODUIT-50x75,1,visible,1,,,Taille,50x75,,,,PRODUIT,50,75,80

variable,PRODUIT,PRODUIT,1,visible,1,"Format carré",PRODUIT.jpg,Taille,"20x20, 30x30, 40x40, 50x50",20x20,0,1,,,,
variation,PRODUIT-20x20,PRODUIT-20x20,1,visible,1,,,Taille,20x20,,,,PRODUIT,20,20,40
variation,PRODUIT-30x30,PRODUIT-30x30,1,visible,1,,,Taille,30x30,,,,PRODUIT,30,30,60
variation,PRODUIT-40x40,PRODUIT-40x40,1,visible,1,,,Taille,40x40,,,,PRODUIT,40,40,70
variation,PRODUIT-50x50,PRODUIT-50x50,1,visible,1,,,Taille,50x50,,,,PRODUIT,50,50,80

Je crée également un « faux canevas » import-entete.csv pour l’entête du fichier (voir ci-dessus), qui sera simplement inséré au début (pas de mot-clé à remplacer).

Construction du fichier d’import CSV

Voici donc le fameux script, appelé genereCSV.ps1 :

gc $PSScriptRoot\import-entete.csv
foreach ($dir in "Paysage", "Portrait", "Carre") {
 foreach ($file in gci $dir/*.jpg) {
   gc $PSScriptRoot\import-$dir.csv | % {$_ -replace "PRODUIT", $file.basename }
 }
}

Complètement fou, non, qu’un si petit programme puisse gérer toute une boutique WooCommerce ? Même après tant d’années, je suis toujours comme un enfant devant la puissance et la simplicité des langages « script », et PowerShell ne déroge pas à la règle.

Et donc, pour exécuter ce script, je me place dans le dossier Collection, et je le lance grâce à la ligne de commande :

../genereCSV.ps1 > fichier-import.csv

Et j’obtiens pratiquement instantanément dans le fichier fichier-import.csv mes centaines de produits/variations. Il n’y a plus qu’à l’importer 🙂

Explications

La première ligne affiche l’entête stocké dans le fichier canevas de l’entête.

La seconde parcourt mes trois répertoires (les formats de photo).

La troisième parcourt les photos de chaque dossier format.

La dernière récupère les fichiers canevas pour chaque format, et y remplace pour chaque photo le mot-clé PRODUIT par le nom du fichier photo privé de son extension.

Remarque : L’utilisation de la variable $PSScriptRoot pour localiser les fichiers « canevas » permet de lancer le script d’où l’on veut, et donc de gérer des bases de test ou plusieurs bases produits, en créant différents dossiers de type « Collection ».

Conclusion

J’espère que cet exemple pourra vous inspirer pour automatiser l’import de vos produits dans WooCommerce.

Pour moi, le plus important dans tout ça, et c’est ce qui fait qu’après tout est fluide, c’est le travail en amont pour identifier :

  • tout ce qui est commun ou spécifique aux produits et variations,
  • des catégories qui vont permettre de factoriser certains éléments spécifiques pour simplifier leur traitement.

Evidemment, c’est plus facile à dire qu’à faire, et dans la pratique on commence souvent grossièrement, puis on affine au fur et à mesure… Mais avec l’habitude, on arrive à bien débroussailler en amont et on gagne beaucoup de temps !

On pourrait bien sûr aussi améliorer ce procédé (ce qui va fatalement arriver, je me connais), par exemple :

  • ajouter le dossier script dans la variable $PATH
  • passer les dossiers en arguments du script pour être plus souple et ne générer que les catégories souhaitées ou au contraire des nouvelles (en ayant auparavant créé les fichiers import-XXX.csv associés)
  • utiliser un outil pour détecter le format des photos et utiliser des mots-clé CATEGORIE, TAILLE1, TAILLE2, etc, afin de se passer de la structure des dossiers « format » et de n’avoir qu’un seul fichier « canevas » pour tout le monde
  • ajouter des tags aux fichiers photos pour les importer dans les étiquettes WooCommerce
  • transférer les fichier photos sur le serveur pour éviter de tout importer au préalable dans la bibliothèque WordPress
  • etc…

Mais je vous conseille d’y aller par étapes, de créer un script minimal qui effectue une action, puis une autre. De l’améliorer par la suite par petits bouts. De le rendre ensuite le plus générique possible pour pouvoir le réutiliser ou l’adapter à d’autres cas.

Et surtout, particulièrement dans un cadre de développement/production professionnel, toujours essayer de jauger le ratio entre le temps nécessaire à améliorer ou optimiser certains aspects du script et le temps que ça nous fait gagner au final !

Et ne pensez pas au temps que vous allez passer à essayer de raconter tout ça dans un article… c’est que de l’amour !

Bref, vous vouliez du clic-clic avec WordPress, et vous vous retrouvez mordus de script, félicitations 🙂