Lukas Blouin¶
Présentation¶
Je suis actuellement en licence pro ADSILLH à l'université de bordeaux.
Vous pouvez me joindre à cette adresse mail : lukas.b@laposte.net.
Je suis en stage du 03 avril jusqu'au 31 juillet 2023 en tant que développeur web fullstack et Administrateur Système.
Stage¶
Rapport de stage : rapport.pdf¶
Lundi 03 Avril 2023¶
Découverte du site internet et installation du projet en local. Le but est de changer la carte google maps par une map openstreetmap Issue#1
J'ai clone le projet et je me suis rendu compte qu'il n'y avait pas d'instruction sur comment lancé le projet en local.
#Installation de composer
sudo apt install composer
composer install #problème de dépendance
Note : l'utilisation de docker pourrait faciliter l'installation du projet (docker-compose), à voir si c'est nécessaire
# Installer php 8.0.2 sur
sudo apt install apt-transport-https lsb-release ca-certificates wget -y
sudo wget -O /etc/apt/trusted.gpg.d/php.gpg https://packages.sury.org/php/apt.gpg
sudo sh -c 'echo "deb https://packages.sury.org/php/ $(lsb_release -sc) main" > /etc/apt/sources.list.d/php.list'
sudo apt update
# Expand the curly braces with all extensions necessary.
sudo apt install php8.2 php8.2-cli php8.2-{mbstring,xml,pgsql,curl}
## Remove old packages (doesn't work with zsh)
sudo apt purge php7.4*
J'essaye de démarrer le serveur avec
php8.2 artisan serve
mais j'obtiens une erreur 500. J'ai essayé de voir comment ahmad s'y était pris mais sa page personnel est vide. J'ai fait une recherche sur le wiki avec les mot clé : Laravel, composer, php mais j'ai quasiment rien...Il y a un fichier nommé 'zzz_commands' avec on dirait les commandes qu'il a utilisé pour initier le projet.
après quelque recherche, j'ai trouvé les logs dans "storage/logs/laravel.log" et il semble qu'il manque une clé "production.ERROR: No application encryption key has been specified.".
Pour générer la clé : php artisan key:generate
il manque le fichier .env donc je me sers de env.example. et génére la clé
Could not find driver error : sudo apt install php-mysql
Installation d'une bdd mysql en local : https://www.digitalocean.com/community/tutorials/how-to-install-the-latest-mysql-on-debian-10
Charger la Database du projet : php artisan migrate
Le site fonctionne enfin en local !
Problème :
- Les boutons de connexion et d'inscriptions perdent leurs style sur la page de login (et je suppose aussi sur la page d'inscription)
- Il semble qu'il y a eu des copiés collés d'importation de scripts non nécessaire sur plusieurs page.
- Tailwind est présent dans le projet mais ne semble pas être utilisé. C'est soit on utilise bootstrap, soit tailwind mais pas les deux, en général.
TODO :
- Faire un nettoyage du code
- Changer les fonts de google par des font libre (ex: IBM Plex Mono)
Mardi 04 Avril 2023¶
Installation sur mon pc portable du projet, correction des étapes pour lancer le projet.
Inscription non fonctionnel en local ->
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'statut_actuel' in 'field list'
insert into `users` (`nom`, `prenom`, `telephone`, `email`, `statut_actuel`, `password`, `updated_at`, `created_at`) values (Blouin, Lukas, 0700000000, lukas.b@laposte.net, etudiant-ub, $2y$10$Ei0U4i02SXuRenidCe0a5D.TwFWS, 2023-04-04 12:06:51, 2023-04-04 12:06:51)
j'essaye de d'ajouter le champs manquant dans le fichier php qui créer la tables. J'obtiens la même erreur
Donc je décide de commenter la ligne dans l'ajout de l’utilisateur qui pose problème, cela fonctionne mais lorsque je veux accéder au profil, une fois connecté, je me fait déconnecter.
Je commence à me dire que le code qui est sur le repo est pas tout à fait à jour comparé à celui du serveur. Et effet pierre me le confirme et on se rend compte de plusieurs problème qui ont mené à l'écriture du deuxième tickets. On a pas réussi à créer un autre compte admin depuis l'interface de gestion du site.
Je suis donc partie pour copier les fichiers du serveur, les push sur le repo et cherry pick mes changement.
je regarde la conf de apache dans /etc/apache2/ mais je trouve pas le chemin vers le site, je regarde dans /var/www mais pas dedans et là je regarde dans apache2/site-available. Je trouve le fichier de conf et vois que le projet est dans /opt/laravel/laravel.
D'ailleurs faudra faire le ménage (duplicata Portail-web).
Je copie les fichier sur mon pc et décompresse tout les fichier compresser en gz avec find -type f -name "*.gz" -exec gunzip {} \;
Je copie également la database du serveur en local et l'importe en local sur mon pc.
Je sécurise la base de donnée sur le serveur car elle n'était pas sécurisé (mot de passe root facilement devinable), et je lance le script pour sécuriser les BDD mysql : mysql_secure_installation .
Mercredi 05 Avril 2023¶
Changement front Accueil et Contact
Traduction et correction du textes dans contact et accueil
Essaie de refaire la bannière de l'accueil avec bootstrap car actuellement c'est pas très jolie avec le responsive. J'ai essayé de la refaire avec à la main. A la fin, le résultat quasiment similaire sans l'image avec 60% de blanc mais pas responsive, je dois trouver une template.
Mise en place de l'environnement de travail (terminal, zsh, neovim...)
Jeudi 06 Avril 2023¶
je me suis rendu compte que ubuntu n'installe pas les dernière version des paquets(je m'en suis rendu compte sur deux paquets :neovim et composer), composer était en 1.10.2 alors que la dernière version est en 2.5.5. J'ai mis à jour manuellement depuis les sources et la plupart des warning ont disparu.
Mise à jour de ubuntu dans wsl 20.04 -> 22.04 (d'où les sources pas à jour)
Suppresion de tailwind css https://www.reddit.com/r/laravel/comments/j6sc7d/comment/g80jg15/?utm_source=share&utm_medium=web2x&context=3
Remise en ordre du footer du site :
Nettoyage du code html/css : header présent dans d'autres pages alors que le header est globaliser dans sites.blade.php donc non sens et conflit
Ajout de titres dynamique + ajout de la favicon : Laravel sur toutes les pages -> <nom de la page> - Fablab Coh@bit
Il est prévu de changer les descriptions de la même manière pour chaque page pour le référencement (SEO)
Je ne l'ai pas précisé mais comme j'utilise git on peut voir jour après jour les changement que j'ai apportés.
J'ai fait une fausse manip avec git et j'ai perdu ce que j'avais fait sur le footer.
C'est frustrant, car il ne restait plus qu'à le push mais en voulant faire les screenshot pour le redmine j'ai mal gérer.
Tant pis je reprendrais demain, maintenant c'est frais dans ma tête donc ça devrais être rapide.
Note à moi même ne plus utiliser git stash pop mais git stash apply (attention au merge) ou git checkout stash -- . (https://stackoverflow.com/questions/16606203/force-git-stash-to-overwrite-added-files#16625128)
Vendredi 07 Avril 2023¶
- Réunion avec Pierre pour déterminé ce qu'il faut change sur le site : Réunion_Site_Web
- Footer du site à été refait
- Intégration de font-awesome pour remplacer icofont car icone mastodon pas disponible mais problème pour afficher une icone
- Impression 3D avec Arthur Lebouvier pour remplacer le bouton d'éjection manquant d'un Joycon d'une Nintendo Switch :
- Création du modèle 3D avec FreeCad
- Impression avec une imprimante 3D
- Et démontage du joycon pour ajouter le bouton
Fichier du modèle : Bouton Joycon.FCStd
Mardi 11 Avril 2023¶
Migration de icofont vers font-awesome effectué, le problème de vendredi était que les nom des fichier css était mal orthographier dans le fichier html
débogguage avec bastien boineau du site laravel qui est hébergé sur le serveur (erreur 403 forbidden)
Ajout des réseaux sociaux dans le footer et je me suis rendu compte que matrix n'avait pas d’icône et seulement donc j'ai récupérer le svg depuis matrix.org et je l'ai adapter en icône.
Je ne suis pas satisfait du résultat, je trouve que les barre sont trop fine mais bon à la base je suis pas graphiste !
matrix-logo.svg
matrix-icon-black.svg
matrix-icon-white.svg
Le problème d'accés au site laravel (403) héberger sur le serveur était lié à une commande que j'ai mal gérer et qui a compressé chaque fichier en .gz.
Mercredi 12 Avril 2023¶
Le footer à été améliorer pour être responsiveBootstrap a été mis à jour pour avoir accès à la propriété gap et aussi car il n'utilise plus jquery.
Autres modifications faites :
- Virer Compagny Support et Compagny Licence
- Remplacer tous droit réservé par une licence Creative Common (CC BY-ND ) Fablab Cohabit (sauf certain contenu)
- lien RS : mastodont, twiiter, linkedin, facebook, linkedin, matrix
- ajouter dans nos service : Accompagnement (1er)
Jeudi 13 Avril 2023¶
Modification de l'accueil :- description réservation d'une machine
- ajout carrousel
- ajout partenaires
- Ajout d'un formulaire pour faire remonter les problème (création automatique de ticket sur redmine)
Vendredi 14 Avril 2023¶
Développement de la page de présentation du Fablab :- Historique du Fablab
- Fablab / Technoshop
- Equipe du Fablab
Mercredi 19 Avril 2023¶
Bouton de connexion et d'inscription déplacer dans la navbar
Ajout dans page Présentation d'un bouton qui fait apparaitre/disparaitre les membres du fablab
Réparation des menu déroulants suite à la migration de bootstrap
Modification navbar
Modification Page de login, inscription
Recherche sur comment fonctionne les dropdown avec bootstrap
Test de mettre la vidéo de démo dans le carousel (résultat peu concluant)
Difficulté à ajouter une route dans laravel pour la FAQ :
Pour ajouter une route qui sera render avec un modèle il faut créer un fichier php dans "app/Http/Livewire/Frontend/nom_de_la_route.php"
<?php
namespace App\Http\Livewire\Frontend;
use Livewire\Component;
class Nom_de_la_route extends Component
{
public function render()
{
return view('livewire.frontend.Nom_de_la_route')->layout('layouts.frontend.site');
}
}
puis dans routes/web.php ajouter la ligne suivante :
Route::get('/nom_de_la_route', App\Http\Livewire\Frontend\Nom_de_la_route::class)->name('frontend.Nom_de_la_route');
Lundi 24 Avril 2023¶
Modification page de contact :
- suppression formulaire contact
- ajout d'informations pour venir
- changement de la disposition
Réunion Service informatique
Maintenant priorité sur le portfolio et le carnet d'expérience depuis le site
Mardi 25 Avril 2023¶
Déverouillage bootloader de la tablette nexus 9 :- pour démarrer en mode fastboot :
- volume + et power (la tablette doit être éteinte)
- ou activer les "options pour développeur" et cocher "Débogguage usb" puis depuis un pc lancer la commande
adb reboot fastboot
fastboot oem unlock
Boot sur le recovery custom TWRP :
fastboot boot twrp-3.7.0_9-0-flounder.img
télécharger le recovery : https://dl.twrp.me/flounder/ Flash lineage os sur la tablette => https://forum.xda-developers.com/t/unofficial-8-1-0-lineageos-15-1-for-nexus-9-wifi-06-17-18.3670395/
Changement de la splashscreen image au démarrage => https://forum.xda-developers.com/t/guide-tool-nexus-9-splash-screen-tool-v1-6.2931575/
Changement de la bootanimation au démarrage :
- Galère pour faire du montage vidéo sur shotcut en mode portrait donc fait en mode paysage
- Piste vidéo <=> calque
- pour modifier la taille et la position application du filtre "Taille, position & rotation"
- Pour faire une rotation de 90° sur une vidéo avec ffmpeg : ffmpeg -i .\fablab_splashscreen.mp4 -vf "transpose=1" out.mp4
- Extraire toute les frame en png : ffmpeg -i out.mp4 -s 1000x1000 test/frame_%03d.png
- desc.txt => https://blog.justinbull.ca/making-a-custom-android-boot-animation/
- Utilisation d'un script déjà existant pour remplacer la bootanimation avec twrp
- flash dans twrp : adb sideload "flashable_bootanimation_fablab.zip"
- Application de base => mauvais focus + peu d'option
- Installation de fdroid/aurora store + libre camera
- En photo résolution max et en vidéo le plus fluide est "medium"
- splashscreen : splashscreen.png
- bootanimation (mp4) : out.mp4
- bootanimation (zip) : bootanimation.zip
- bootanimation flashable (twrp) : flashable_bootanimation_fablab.zip
- projet Shotcut : fablab_splashscreen.zip
Mercredi 26 Avril 2023¶
- Configuration de tinymce avec tous les plugin open source (copie de la config de la doc => https://www.tiny.cloud/docs/tinymce/6/full-featured-open-source-demo/)
- Test de tinymce :
- découverte des fonctionnalités
- test de sécurité (notamment xss ou iframe) => besoin de d'établir une blacklist
- Test des 2 tablettes nexus 7, 1 ipad air et 2 nexus 5 :
- Il a été nécessaire de charger manuellement avec un cable usb dénuder les batterie des nexus 7 pour qu'elles est suffisamment d'énergie pour que le système s'amorcent et prennent en charge le chargement de la batterie
- 1 des nexus 5 a besoin d'une nouvelle batterie
- Sinon tous le reste fonctionne
Jeudi 27 Avril 2023¶
- Configuration des 2 tablette nexus 7 :
- mise à jour de l'os de Android 4.4.4 (kikat) vers Android 7.1.2 (Nougat) (https://forum.xda-developers.com/t/rom-nzh54d-2023-04-05-asus-nexus-7-2012-wifi-3g-f2fs-ext4-android-7-x-aosp.3467514/)
- Changemement du splashscreen impossible sur ce modèle
- changement de la bootanimation (flashable_bootanimation_nexus7_fablab.zip)
- installation des applications (fdroid,aurora store,fx explorer,brave,libre camera)
- Configuration du nexus 5 :
- mise à jour de l'os de Android 6.0.1 (Marshmallow) vers Android 12.1 (https://forum.xda-developers.com/t/rom-unofficial-lineageos-19-1-for-nexus-5-hammerhead-discontinued.4521253/#post-88221415 ==> lineage-19.1-20221126-UNOFFICIAL-hammerhead-signed.zip)
- libre camera a un bug d'affichage en mode paysage donc installation de secure camera (https://github.com/GrapheneOS/Camera) pour remplacer open camera qui est très peu d'option de configuration
- changement du splashscreen par celle du fablab (splashscreen_nexus5.zip) (https://forum.xda-developers.com/t/tool-v1-3-2-change-bootlogo-and-other-images-with-imgdata-tool.2763698/)
- attention les partitions ont été modifié car la partition système n'était pas assez grande pour android 12.1 (voir sur la page de la rom)
- Ipad air :
- Un compte a été créer mais on ne connais pas le mot de passe, sans ce mot de passe on ne peut pas installer d'application et réinitialiser la tablette
- A cause de trop de tentative infructueuse le compte a été bloqué et le mot de passe doit être changée obligatoirement
- En attente des informations de sécurité pour accéder au compte
Vendredi 28 Avril 2023¶
Modification page de profile :- Suppression Photo de profile, Réalisation et Formation dans profile
- Modification de la configuration de tinymce (ajout de tout les plugins gratuit)
- Ajout de nouveaux onglets
https://git.cohabit.fr/ahmad.alajaj/Portail-site-web/commit/9b366684ee31ffba0f1f86c15335f5c1629a84e6
Mardi 02 Mai 2023¶
Galère pour rendre persistant tinymce avec livewire
Essaie d'utiliser le binding de livewire => mais à cause du wire:ignore, il faut manuellement envoyé l'évenement
Je ne voulais pas passer par le JS car je pensais que le contenu de la textarea pouvait être récupérer directement via PHP mais il s'avère qu'une fois charger la textarea est désactiver.
Essaie d'utiliser wire:submit_prevent => pour une raison inconnu, il ne fonctionnais pas
Je me suis rendu compte également que le système de log de laravel était merdique.
Problème pour récupérer le contenu car conf js, template html et vue (3 différent fichier), finalement je ne suis pas passer par la template html de tinymce.
La solution a été d'utiliser l'évenement js onsubmit et de récupérer le contenu et de le set dans la classe php, puis d'émettre sur un listener créer pour l'occasion qui va sauvegarder le contenu dans un fichier. Le bouton de sauvegarder agissant comme un bouton de validation de formulaire (submit), à chaque appuie ou CTRL+S le contenu est sauvegarder sur le serveur.
Résolution tinymce saute après validation d'un formulaire => livewire actulise le DOM, ce qui casse tinymce (ajout de wire:ignore)
Mercredi 03 mai 2023¶
- Refait mon CV
- Déploiement site sur serveur :
Pour mettre à jour le site, il faut allez dans /opt/laravel/laravel et faire un git pull (en cas de conflit git stash)
Vendredi 05 mai 2023¶
- Fix route pointant au mauvais endroit et supression de duplication de fichier
- Refactorisation du code des routes (web.php)
- Ajout fonctionnalité upload photo dans tinymce
- Suppression dépendance javascript non utilisé
Mardi 09 mai 2023¶
- Refactorisation du modèle et de la template du profile en plusieurs fichiers
- Modification de la route portfolios/edit en profile
- Changement du layout site en public
- Déplacement des réservations utilisateur dans le profile
Mercredi 10 mai 2023¶
Changement de la structure du projet, suppression de fichier non utilisé, changement mineur dans le style
Correction d'oublies dans profile
Jeudi 11 mai 2023¶
Réunion matin avec pierre et jb pour faire le point sur le site : Machine,Formation,Ajout reproduction, modification navbar
Aidé quentin sur le projet robotgowest pour config la raspberry pi 4 en ssh
Debuggage mise à jour redmine
Vendredi 12 mai 2023¶
- Copie des modifications apporter au css dans le scss (erreur de ma part)
- Mise à jour des dépendances
- écriture des règle mix pour compiler, assembler, minifier le code js et css, ainsi que copier les ressources nécessaires
- Déplacement de la plupart des ressources de public à ressources
- Test d'une nouvelle implémentation pour bind le titre et la descriptions des vues
- Ajout de vérification lors de l'édition d'une machine dans le panel admin
Lundi 15 mai 2023¶
Configuration d'une raspberry pi 3 pour que lorsqu'on appuie sur une touche du pavé numérique, une vidéo se lance.Problème rencontré :
- La vidéo se lançait plusieurs fois car le buffer du terminal n'était pas vider avant de relire donc en cas de spam.
perl -e 'use POSIX; tcflush(0, TCIFLUSH);' - cvlc ajoutais les vidéo a une playlist, mpv décoder mal la vidéo, omxplayer ininstallable sur la dernière version de raspbian => installation de la précédente release pour installer omxplayer.
- désactiver le curseur pour avoir un écran noir (tput civis pour cacher) (tput cnorm pour le rendre visible)
Mardi 16 mai 2023¶
Configuration de l'oculust quest 2 pour jouer à super hot, je me rend compte que le casque n'était pas charger => du coup plus à l'heure => donc pas de wifi
pas de menu dans les paramètre pour change l'heure, seul solution passer par adb mais pas de dev mode activer donc je suis bloquer et je peux avoir d'internet :'(
du coup hard factory reset et reconfiguration, activation du mode déboggue pour installer des apk et lancer des commandes adb.
Pour lancer des commande adb, il faut connecter le casque à un pc et avoir installer les platforms-tools (choco install adb/sudo apt install platform-tools).
adb devices pour afficher les appareils connecter.
Le casque peut être configurer un peu plus via l'application occulus sur mobile, une fois appairer
Attention le wifi cohabit est un peu instable avec le casque, privilégier quand possible d'un autre réseaux wifi.
Si problème d'heure ou "connexion limité" pour le wifi, lancer la commande adb :
adb shell date -s "yyyymmdd.[[[hh]mm]ss]" ou adb shell am start -a android.intent.action.VIEW -d com.oculus.tv -e uri com.android.settings/.DevelopmentSettings com.oculus.vrshell/.MainActivity
Ne pas utiliser slide quest pour installer des applications
Mercredi 17 mai 2023¶
Problème d'upload d'image :- Ne semble pas venir du type
- Après investigation c'est la taille qui est limiter à 2mb
Pour régler ce problème, je regarde les rules dans mon composant et pas de limite apparante.
Je teste de changer la limite global dans le fichier d'environnement mais pas ça
Je fini par décourvrir que les serveur php limite à 2M les upload en post de fichier.
Il faut changer dans le php.ini (cheminavec phpinfo()), la variable "upload_max_filesize"
- Modification des machines dans le backend
- Modification page contact pour rendre cliquable toute la div
- Modification de l'édition et de l'affichage des machines
Test pour améliorer le redmine (theme, plugin (collapse))
Lundi 22 Mai 2023¶
usermod -aG sudo
mise à jour site sur serveur
création de comptes pour les nouveaux stagiaire
changement style page de réservation
Mardi 23 Mai 2023¶
use laravel
show tables;
show create table users;
Mardi 06 Juin¶
Développement calendrier de réservation, ajout couleur différente pour chaque utilisateur, ajout limite de réservations,
suppression de table non utiliser plus modification table machine et réservation
Panne du serveur -> go to aquilenet
boot in emergency, impossible de monter les partition pourtant les ssd sont intacte
message d'erreur indiquant d emettre à jour le bios, mise à jour du bios (optiplex 9020) mais ne résout pas le problème (en même temps je m'en doutais)
même problème en mettant les ssd (raid 0) dans une autre machine
on fait une backup chiffrer sur un autre support
on prend le premier ssd et alexander prend le deuxième au cas où
Mercredi 07 Juin¶
On remonte un serveur en local sur un de spc du fablab à partir du ssd du serveur.
On restore postgresql installation puis copie depuis le ssd de /var/lib/postgres (ne marche qu'vaec la même architecture et version de postgres)
On restore redmine avec beaucoup de galère (la doc de redmine n'est pas à jour et truffer d'erreur) solution: https://stackoverflow.com/a/54440419
Pendant ce temps...¶
Le serveur à été refait depuis 0. Dans un 1er temps, on a restaurer redmine et gitea en local puis on remis la machine à aquilenet
Migration postgresql était une erreur, problème de permissions/droits, du coup les fichiers de migrations sont très chiant à exécuter
Création des news sur l'accueil
Utilisation d'une bibliothèque livewire pour afficher les modèles dans le panel admin et pouvoir chercher et trier plus facilement
Pour plus de détails la liste des commits est disponible sur forgejo
Lundi 26 Juin¶
Déploiement laravel sur serveur :
cd /opt/laravel/laravel
git pull
git stash (si besoin)
php artisan migrate
composer update
npm install
npx mix
#nettoyer le cache
php artisan clear-compiled &&
php artisan cache:clear &&
php artisan route:clear &&
php artisan view:clear &&
php artisan config:clear &&
composer dumpautoload -o
Mardi 27 Juin¶
Résolution de l'erreur 422 lors de l'upload d'un fichier => php.ini comme expliquer Lukas_Blouin
Écriture d'un composent pour l'upload d'image mais impossible de le tester car live wire ne parvient pas à le trouver quand je l'appelle !
Tips and Trick Livewire : https://laravel-news.com/laravel-livewire-tips-and-tricks
Mercredi 28 Juin¶
Pas là !
Jeudi 29 Juin¶
Bibliothèque table : https://github.com/rappasoft/laravel-livewire-tables
démo bootstrap 4 : https://tables.laravel-boilerplate.com/bootstrap-4
code démo bootstrap 4 : https://github.com/rappasoft/laravel-livewire-tables-demo/blob/master/app/Http/Livewire/UsersTable.php
Ajout de la fonctionnaliser de suppression d'un utilisateur => supprime que dans la bdd, faudrait supprimer aussi les fichier dans storage
Essaie d'ajout de lien pour faire des action sur l'utilisateur => pas vraiment essayer car ajout de bouton dans edit bien plus facile
Essaie d'action en masse (Bulk Action), dropdown ne fonctionne pas car js bootstrap 5 =/= css bootstrap 4, il faudrait refaire le css du back pour switch vers bootstrap 5 (Gain de performance (moins de css et js), plus jolie, plus facile à maintenir)
On a l'autorisation d'utiliser le dalek pour la page 404 => https://twitter.com/LukasBlouin/status/1654134289754124289?s=20
Pour peaufiner ajout de Bulk Action, action en lien sur une colonne à la fin et ajout des champ profile, description dans user
Passer les autres pages avec les tables rappasoft
Tableau des choses urgente à faire
Problème pour afficher les projets :
J'ai vérifier que chaque balise été fermé et qu'elles avait toute leur paires.
Ce problème apparaît seuleument quand j'ajoute le bouton, ce qui n'est pas logique
Il me génére beaucoup trop de <a> avec la class feature-item-hover :
Cela semble venir de la class en elle même, pour une raison que j'ignore, elle rend parfois très mal