Modifier l'ordre des catégories dans un menu PrestaShop
Comment changer l'ordre d'affichage des catégories dans le menu PrestaShop : tri par position au lieu de l'ordre alphabétique. Guide SQL et module.
En bref : Pour corriger l'ordre des catégories dans un menu PrestaShop, remplacez `ORDER BY cl.name ASC` par `ORDER BY c.position ASC` dans la requête SQL du module de menu, ou utilisez la méthode native `Category::getChildren()` qui trie par position par défaut.
Modifier l'ordre des catégories dans un menu PrestaShop
Le problème : un menu trié par ordre alphabétique
De nombreux marchands PrestaShop constatent que les catégories de leur menu horizontal ne respectent pas l'ordre défini dans le back-office. Au lieu de suivre les positions configurées manuellement, les catégories s'affichent par ordre alphabétique.
Ce comportement provient généralement d'un module de menu (qu'il soit natif ou tiers) dont la requête SQL trie les résultats sur le nom de la catégorie (cl.name ASC) plutôt que sur le champ position de la table ps_category.
Comprendre la source du problème
Dans PrestaShop, chaque catégorie possède un champ position dans la table ps_category. Ce champ est mis à jour automatiquement lorsque vous réorganisez les catégories par glisser-déposer dans le back-office (menu Catalogue > Catégories).
Le problème survient quand un module de menu construit sa propre requête SQL sans exploiter ce champ. Voici un exemple typique de requête fautive :
SELECT * FROM ps_category c
LEFT JOIN ps_category_lang cl
ON (c.id_category = cl.id_category AND cl.id_lang = 1)
WHERE c.active = 1
AND c.level_depth = 2
ORDER BY c.level_depth, cl.name ASC
Le tri cl.name ASC impose un classement alphabétique. C'est rarement ce que le marchand souhaite.
La solution : trier par position
La correction consiste à remplacer le tri alphabétique par un tri sur le champ position :
SELECT c.*, cl.name, cl.link_rewrite
FROM ps_category c
LEFT JOIN ps_category_lang cl
ON (c.id_category = cl.id_category AND cl.id_lang = 1)
WHERE c.active = 1
AND c.level_depth = 2
ORDER BY c.position ASC
Points importants
- **`c.position ASC`** respecte l'ordre défini dans le back-office PrestaShop.
- Évitez `SELECT *` en production : listez explicitement les colonnes nécessaires pour de meilleures performances.
- Le `level_depth = 2` cible les catégories de premier niveau (les enfants directs de la catégorie racine). Adaptez cette valeur si votre arborescence diffère.
Appliquer la modification dans un module
La requête incriminée se trouve dans le fichier PHP principal du module de menu concerné. Voici la démarche complète :
Étape 1 : Identifier le module
Repérez quel module génère votre menu. Les modules courants sont :
- **ps_mainmenu** (PrestaShop 1.7 / 8.x)
- **blocktopmenu** (PrestaShop 1.6)
- Un module tiers de méga-menu
Étape 2 : Localiser la requête
Dans le dossier du module (/modules/nom_du_module/), recherchez la requête SQL qui récupère les catégories. Cherchez les occurrences de category_lang ou ORDER BY :
grep -rn "ORDER BY" modules/nom_du_module/
Étape 3 : Modifier le tri
Remplacez la clause ORDER BY pour utiliser position :
// Avant (tri alphabétique)
$sql = 'SELECT c.*, cl.name, cl.link_rewrite
FROM ' . _DB_PREFIX_ . 'category c
LEFT JOIN ' . _DB_PREFIX_ . 'category_lang cl
ON (c.id_category = cl.id_category
AND cl.id_lang = ' . (int)$id_lang . ')
WHERE c.active = 1
AND c.level_depth = 2
ORDER BY c.level_depth, cl.name ASC';
// Après (tri par position back-office)
$sql = 'SELECT c.*, cl.name, cl.link_rewrite
FROM ' . _DB_PREFIX_ . 'category c
LEFT JOIN ' . _DB_PREFIX_ . 'category_lang cl
ON (c.id_category = cl.id_category
AND cl.id_lang = ' . (int)$id_lang . ')
WHERE c.active = 1
AND c.level_depth = 2
ORDER BY c.position ASC';
Sécurité : notez l'utilisation de
(int)pour le cast de$id_lang. Depuis PrestaShop 1.7, préférez(int)àintval()pour la cohérence avec les standards du core.
Étape 4 : Vider le cache
Après modification, videz le cache PrestaShop :
- **Back-office** : Paramètres avancés > Performances > Vider le cache
- **En ligne de commande** (PrestaShop 8.x) :
php bin/console cache:clear
Approche recommandée sur PrestaShop 8.x
Sur les versions modernes de PrestaShop, la bonne pratique consiste à ne pas modifier directement les fichiers d'un module. Privilégiez plutôt :
1. Le système d'override de module
Créez un fichier override dans votre thème :
/themes/votre-theme/modules/ps_mainmenu/ps_mainmenu.php
Cette approche permet de conserver vos modifications lors des mises à jour du module.
2. Utiliser l'API Category native
Plutôt que d'écrire du SQL brut, utilisez les méthodes natives de PrestaShop :
use PrestaShop\PrestaShop\Adapter\Category\CategoryProductSearchProvider;
// Récupérer les sous-catégories triées par position
$categories = Category::getChildren(
(int)Configuration::get('PS_HOME_CATEGORY'),
(int)$this->context->language->id,
true // active uniquement
);
// Le tri par position est appliqué nativement par cette méthode
La méthode Category::getChildren() trie déjà par position par défaut, ce qui évite tout problème de tri.
Gérer les positions dans le back-office
Pour réordonner vos catégories :
- Allez dans **Catalogue > Catégories**
- Cliquez sur la catégorie parente
- Utilisez le glisser-déposer sur les lignes du tableau, ou modifiez directement les chiffres dans la colonne **Position**
- Les positions sont sauvegardées automatiquement
Si les positions semblent incohérentes (doublons, trous dans la numérotation), vous pouvez les réinitialiser via SQL :
SET @pos := 0;
UPDATE ps_category
SET position = (@pos := @pos + 1)
WHERE id_parent = 2
AND active = 1
ORDER BY position ASC;
Remplacez id_parent = 2 par l'identifiant de votre catégorie parente.
Récapitulatif
Questions fréquentes
Tout ce que vous devez savoir sur ce sujet.
Un projet PrestaShop ?
Discutons-en directement.
193 projets livrés
Lire sur le blog

Alexandre Carette
Expert PrestaShop & Architecture E-commerce
Développeur PrestaShop depuis 2014, 193 projets livrés. Je conçois des architectures headless Nuxt + PrestaShop et des outils d'automatisation IA pour les e-commerçants.