[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"theme-db":3,"$fLg_oD78enFv1IwPylHE8J_gThK3UcWjU3sYGgwVpmME":22,"megamenu":61,"$f4QdU60DcHXcu4aQg2TiLuBFH_gRmGQHMlZW0OC6bEfw":130,"$fKnz2vuX4bZz1LbUTiuFsvSZ3e07l5_5fqNYp4Tzdhi8":144,"header-db":212,"footer-db":225},{"theme":4},{"colors":5,"typography":13,"ui":17,"defaultColorMode":21},{"primary":6,"secondary":7,"background":8,"foreground":9,"muted":10,"headerBg":11,"footerBg":12,"topBarBg":9,"topBarText":11},"#4F46E5","#0D9488","#F9FAFB","#111827","#6B7280","#ffffff","#020617",{"fontFamily":14,"fontUrl":15,"baseFontSize":16},"Inter, system-ui, sans-serif","https:\u002F\u002Ffonts.googleapis.com\u002Fcss2?family=Inter:wght@400;500;600;700&family=Playfair+Display:ital,wght@0,400;0,700;0,800;0,900;1,400;1,700&display=swap","16px",{"borderRadius":18,"contentWidth":19,"shadow":20},"lg","7xl",true,"light",{"title":23,"slug":24,"metaDescription":25,"category":26,"tags":27,"difficulty":34,"psVersions":35,"content":39,"faq":40,"tldr":56,"readingTime":57,"generatedAt":58,"publishDate":58,"relatedArticles":59,"sourceCategory":60},"Modifier l'ordre des catégories dans un menu PrestaShop","modifier-ordre-categories-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.","developpement",[28,29,30,31,32,33],"menu","catégories","SQL","module","tri","position","intermediaire",[36,37,38],"1.6","1.7","8.x","\u003Ch1>Modifier l'ordre des catégories dans un menu PrestaShop\u003C\u002Fh1>\n\u003Ch2>Le problème : un menu trié par ordre alphabétique\u003C\u002Fh2>\n\u003Cp>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.\u003C\u002Fp>\n\u003Cp>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 (\u003Ccode>cl.name ASC\u003C\u002Fcode>) plutôt que sur le champ \u003Ccode>position\u003C\u002Fcode> de la table \u003Ccode>ps_category\u003C\u002Fcode>.\u003C\u002Fp>\n\u003Ch2>Comprendre la source du problème\u003C\u002Fh2>\n\u003Cp>Dans PrestaShop, chaque catégorie possède un champ \u003Ccode>position\u003C\u002Fcode> dans la table \u003Ccode>ps_category\u003C\u002Fcode>. Ce champ est mis à jour automatiquement lorsque vous réorganisez les catégories par glisser-déposer dans le back-office (menu \u003Cstrong>Catalogue > Catégories\u003C\u002Fstrong>).\u003C\u002Fp>\n\u003Cp>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 :\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-sql\">\nSELECT * FROM ps_category c\nLEFT JOIN ps_category_lang cl\n  ON (c.id_category = cl.id_category AND cl.id_lang = 1)\nWHERE c.active = 1\n  AND c.level_depth = 2\nORDER BY c.level_depth, cl.name ASC\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>Le tri \u003Ccode>cl.name ASC\u003C\u002Fcode> impose un classement alphabétique. C'est rarement ce que le marchand souhaite.\u003C\u002Fp>\n\u003Ch2>La solution : trier par position\u003C\u002Fh2>\n\u003Cp>La correction consiste à remplacer le tri alphabétique par un tri sur le champ \u003Ccode>position\u003C\u002Fcode> :\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-sql\">\nSELECT c.*, cl.name, cl.link_rewrite\nFROM ps_category c\nLEFT JOIN ps_category_lang cl\n  ON (c.id_category = cl.id_category AND cl.id_lang = 1)\nWHERE c.active = 1\n  AND c.level_depth = 2\nORDER BY c.position ASC\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch3>Points importants\u003C\u002Fh3>\n\u003Cul>\n\u003Cli>**`c.position ASC`** respecte l'ordre défini dans le back-office PrestaShop.\u003C\u002Fli>\n\u003Cli>Évitez `SELECT *` en production : listez explicitement les colonnes nécessaires pour de meilleures performances.\u003C\u002Fli>\n\u003Cli>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.\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Ch2>Appliquer la modification dans un module\u003C\u002Fh2>\n\u003Cp>La requête incriminée se trouve dans le fichier PHP principal du module de menu concerné. Voici la démarche complète :\u003C\u002Fp>\n\u003Ch3>Étape 1 : Identifier le module\u003C\u002Fh3>\n\u003Cp>Repérez quel module génère votre menu. Les modules courants sont :\u003C\u002Fp>\n\u003Cul>\n\u003Cli>**ps_mainmenu** (PrestaShop 1.7 \u002F 8.x)\u003C\u002Fli>\n\u003Cli>**blocktopmenu** (PrestaShop 1.6)\u003C\u002Fli>\n\u003Cli>Un module tiers de méga-menu\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Ch3>Étape 2 : Localiser la requête\u003C\u002Fh3>\n\u003Cp>Dans le dossier du module (\u003Ccode>\u002Fmodules\u002Fnom_du_module\u002F\u003C\u002Fcode>), recherchez la requête SQL qui récupère les catégories. Cherchez les occurrences de \u003Ccode>category_lang\u003C\u002Fcode> ou \u003Ccode>ORDER BY\u003C\u002Fcode> :\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-bash\">\ngrep -rn \"ORDER BY\" modules\u002Fnom_du_module\u002F\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch3>Étape 3 : Modifier le tri\u003C\u002Fh3>\n\u003Cp>Remplacez la clause \u003Ccode>ORDER BY\u003C\u002Fcode> pour utiliser \u003Ccode>position\u003C\u002Fcode> :\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-php\">\n\u002F\u002F Avant (tri alphabétique)\n$sql = 'SELECT c.*, cl.name, cl.link_rewrite\n    FROM ' . _DB_PREFIX_ . 'category c\n    LEFT JOIN ' . _DB_PREFIX_ . 'category_lang cl\n        ON (c.id_category = cl.id_category\n            AND cl.id_lang = ' . (int)$id_lang . ')\n    WHERE c.active = 1\n        AND c.level_depth = 2\n    ORDER BY c.level_depth, cl.name ASC';\n\n\u002F\u002F Après (tri par position back-office)\n$sql = 'SELECT c.*, cl.name, cl.link_rewrite\n    FROM ' . _DB_PREFIX_ . 'category c\n    LEFT JOIN ' . _DB_PREFIX_ . 'category_lang cl\n        ON (c.id_category = cl.id_category\n            AND cl.id_lang = ' . (int)$id_lang . ')\n    WHERE c.active = 1\n        AND c.level_depth = 2\n    ORDER BY c.position ASC';\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cblockquote>\u003Cp>\u003Cstrong>Sécurité :\u003C\u002Fstrong> notez l'utilisation de \u003Ccode>(int)\u003C\u002Fcode> pour le cast de \u003Ccode>$id_lang\u003C\u002Fcode>. Depuis PrestaShop 1.7, préférez \u003Ccode>(int)\u003C\u002Fcode> à \u003Ccode>intval()\u003C\u002Fcode> pour la cohérence avec les standards du core.\u003C\u002Fp>\u003C\u002Fblockquote>\n\u003Ch3>Étape 4 : Vider le cache\u003C\u002Fh3>\n\u003Cp>Après modification, videz le cache PrestaShop :\u003C\u002Fp>\n\u003Cul>\n\u003Cli>**Back-office** : Paramètres avancés > Performances > Vider le cache\u003C\u002Fli>\n\u003Cli>**En ligne de commande** (PrestaShop 8.x) :\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Cpre>\u003Ccode class=\"language-bash\">\nphp bin\u002Fconsole cache:clear\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch2>Approche recommandée sur PrestaShop 8.x\u003C\u002Fh2>\n\u003Cp>Sur les versions modernes de PrestaShop, la bonne pratique consiste à ne pas modifier directement les fichiers d'un module. Privilégiez plutôt :\u003C\u002Fp>\n\u003Ch3>1. Le système d'override de module\u003C\u002Fh3>\n\u003Cp>Créez un fichier override dans votre thème :\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-\">\n\u002Fthemes\u002Fvotre-theme\u002Fmodules\u002Fps_mainmenu\u002Fps_mainmenu.php\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>Cette approche permet de conserver vos modifications lors des mises à jour du module.\u003C\u002Fp>\n\u003Ch3>2. Utiliser l'API Category native\u003C\u002Fh3>\n\u003Cp>Plutôt que d'écrire du SQL brut, utilisez les méthodes natives de PrestaShop :\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-php\">\nuse PrestaShop\\PrestaShop\\Adapter\\Category\\CategoryProductSearchProvider;\n\n\u002F\u002F Récupérer les sous-catégories triées par position\n$categories = Category::getChildren(\n    (int)Configuration::get('PS_HOME_CATEGORY'),\n    (int)$this-&gt;context-&gt;language-&gt;id,\n    true  \u002F\u002F active uniquement\n);\n\u002F\u002F Le tri par position est appliqué nativement par cette méthode\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>La méthode \u003Ccode>Category::getChildren()\u003C\u002Fcode> trie déjà par position par défaut, ce qui évite tout problème de tri.\u003C\u002Fp>\n\u003Ch2>Gérer les positions dans le back-office\u003C\u002Fh2>\n\u003Cp>Pour réordonner vos catégories :\u003C\u002Fp>\n\u003Col>\n\u003Cli>Allez dans **Catalogue > Catégories**\u003C\u002Fli>\n\u003Cli>Cliquez sur la catégorie parente\u003C\u002Fli>\n\u003Cli>Utilisez le glisser-déposer sur les lignes du tableau, ou modifiez directement les chiffres dans la colonne **Position**\u003C\u002Fli>\n\u003Cli>Les positions sont sauvegardées automatiquement\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Cp>Si les positions semblent incohérentes (doublons, trous dans la numérotation), vous pouvez les réinitialiser via SQL :\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-sql\">\nSET @pos := 0;\nUPDATE ps_category\nSET position = (@pos := @pos + 1)\nWHERE id_parent = 2\n  AND active = 1\nORDER BY position ASC;\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>Remplacez \u003Ccode>id_parent = 2\u003C\u002Fcode> par l'identifiant de votre catégorie parente.\u003C\u002Fp>\n\u003Ch2>Récapitulatif\u003C\u002Fh2>\n\u003Ctr>\u003Cth>Critère\u003C\u002Fth>\u003Cth>Tri alphabétique\u003C\u002Fth>\u003Cth>Tri par position\u003C\u002Fth>\u003C\u002Ftr>\n\u003Ctr>\u003Cth>Clause SQL\u003C\u002Fth>\u003Cth>`ORDER BY cl.name ASC`\u003C\u002Fth>\u003Cth>`ORDER BY c.position ASC`\u003C\u002Fth>\u003C\u002Ftr>\n\u003Ctr>\u003Cth>Contrôle marchand\u003C\u002Fth>\u003Cth>Aucun\u003C\u002Fth>\u003Cth>Total via back-office\u003C\u002Fth>\u003C\u002Ftr>\n\u003Ctr>\u003Cth>Adapté au SEO\u003C\u002Fth>\u003Cth>Non\u003C\u002Fth>\u003Cth>Oui (catégories prioritaires en premier)\u003C\u002Fth>\u003C\u002Ftr>\n\u003Ctr>\u003Cth>Méthode recommandée\u003C\u002Fth>\u003Cth>—\u003C\u002Fth>\u003Cth>`Category::getChildren()`\u003C\u002Fth>\u003C\u002Ftr>",[41,44,47,50,53],{"q":42,"a":43},"Comment changer l'ordre des catégories dans le menu PrestaShop sans modifier de code ?","Rendez-vous dans Catalogue > Catégories, puis utilisez le glisser-déposer pour réorganiser vos catégories. Si votre module de menu respecte le champ `position` (ce qui est le cas du module natif ps_mainmenu sur PrestaShop 1.7 et 8.x), l'ordre sera automatiquement mis à jour. Pensez à vider le cache après modification.",{"q":45,"a":46},"Pourquoi mes catégories s'affichent par ordre alphabétique dans le menu ?","Ce problème vient de la requête SQL du module de menu qui utilise `ORDER BY cl.name ASC` au lieu de `ORDER BY c.position ASC`. Cela arrive souvent avec des modules tiers ou des modules anciens (PrestaShop 1.5\u002F1.6). La solution consiste à modifier la clause ORDER BY dans le fichier PHP du module pour trier par le champ `position`.",{"q":48,"a":49},"La modification de l'ordre du menu est-elle conservée après une mise à jour PrestaShop ?","Si vous avez modifié directement le fichier du module, la mise à jour écrasera vos changements. Pour éviter cela, placez votre override dans le dossier de votre thème (`\u002Fthemes\u002Fvotre-theme\u002Fmodules\u002Fnom_module\u002F`). Ainsi, même après une mise à jour du module, votre personnalisation sera conservée.",{"q":51,"a":52},"Comment réinitialiser les positions des catégories dans la base de données PrestaShop ?","Exécutez une requête SQL de renumérotation : `SET @pos := 0; UPDATE ps_category SET position = (@pos := @pos + 1) WHERE id_parent = VOTRE_ID_PARENT AND active = 1 ORDER BY position ASC;`. Cela supprime les trous et doublons dans la numérotation. Pensez à sauvegarder votre base avant toute modification directe.",{"q":54,"a":55},"Quelle est la différence entre level_depth et position dans la table ps_category ?","Le champ `level_depth` indique le niveau de profondeur de la catégorie dans l'arborescence (0 = racine, 1 = accueil, 2 = premier niveau visible, etc.). Le champ `position` détermine l'ordre d'affichage parmi les catégories de même niveau et même parent. Pour trier un menu, c'est toujours `position` qu'il faut utiliser.","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.",5,"2026-03-21T16:05:23.000Z",[],"PrestaShop pour les développeurs",{"items":62},[63,74,82,90,98,107,114,122],{"id":64,"type":65,"label":66,"href":68,"icon":69,"description":69,"badge":69,"groupTitle":69,"style":69,"gridColumns":69,"cssClass":69,"psCategoryId":69,"showPsChildren":70,"position":71,"children":72,"psChildren":73},41,"link",{"fr":67},"Expertise","\u002Fexpertise",null,false,0,[],[],{"id":75,"type":65,"label":76,"href":78,"icon":69,"description":69,"badge":69,"groupTitle":69,"style":69,"gridColumns":69,"cssClass":69,"psCategoryId":69,"showPsChildren":70,"position":79,"children":80,"psChildren":81},42,{"fr":77},"Blog","\u002Fblog",1,[],[],{"id":83,"type":65,"label":84,"href":86,"icon":69,"description":69,"badge":69,"groupTitle":69,"style":69,"gridColumns":69,"cssClass":69,"psCategoryId":69,"showPsChildren":70,"position":87,"children":88,"psChildren":89},43,{"fr":85},"Modules PrestaShop","\u002Fmodules",2,[],[],{"id":91,"type":65,"label":92,"href":94,"icon":69,"description":69,"badge":69,"groupTitle":69,"style":69,"gridColumns":69,"cssClass":69,"psCategoryId":69,"showPsChildren":70,"position":95,"children":96,"psChildren":97},44,{"fr":93},"Outils IA","\u002Foutils-ia",3,[],[],{"id":99,"type":65,"label":100,"href":102,"icon":69,"description":69,"badge":69,"groupTitle":69,"style":103,"gridColumns":69,"cssClass":69,"psCategoryId":69,"showPsChildren":70,"position":104,"children":105,"psChildren":106},45,{"fr":101},"Offre Starter ✨","\u002Foffre-starter",{"highlight":20},4,[],[],{"id":108,"type":65,"label":109,"href":111,"icon":69,"description":69,"badge":69,"groupTitle":69,"style":69,"gridColumns":69,"cssClass":69,"psCategoryId":69,"showPsChildren":70,"position":57,"children":112,"psChildren":113},46,{"fr":110},"Academy","\u002Facademy",[],[],{"id":115,"type":65,"label":116,"href":118,"icon":69,"description":69,"badge":69,"groupTitle":69,"style":69,"gridColumns":69,"cssClass":69,"psCategoryId":69,"showPsChildren":70,"position":119,"children":120,"psChildren":121},47,{"fr":117},"À propos","\u002Fa-propos",6,[],[],{"id":123,"type":65,"label":124,"href":126,"icon":69,"description":69,"badge":69,"groupTitle":69,"style":69,"gridColumns":69,"cssClass":69,"psCategoryId":69,"showPsChildren":70,"position":127,"children":128,"psChildren":129},48,{"fr":125},"Contact","\u002Fcontact",7,[],[],{"academy":131,"blog":132,"expertise":143},[],[133,137,140],{"title":134,"url":135,"score":79,"type":136},"PrestaShop headless avec Nuxt 3 : pourquoi séparer back et front","\u002Fblog\u002Fprestashop\u002Farchitecture\u002Fprestashop-headless-nuxt-separation-front-back","blog",{"title":138,"url":139,"score":79,"type":136},"PrestaShop headless : Nuxt 3, pas Next.js — le choix souverain","\u002Fblog\u002Fprestashop\u002Farchitecture\u002Fprestashop-headless-nuxt-nextjs-souverainete",{"title":141,"url":142,"score":79,"type":136},"Sylius rachète PrestaShop : ce que ça change pour vous","\u002Fblog\u002Fprestashop\u002Farchitecture\u002Fsylius-rachat-prestashop-headless-souverainete",[],{"columns":145},[146,158,188,204],{"title":147,"links":148},"Plateforme",[149,151,154,155],{"label":150,"href":102,"external":70},"Offre Starter (2 500 €)",{"label":152,"href":153,"external":70},"Devenir Ambassadeur","\u002Fambassadeur",{"label":85,"href":86,"external":70},{"label":156,"href":157,"external":20},"CodeMyShop.com","https:\u002F\u002Fcodemyshop.com",{"title":159,"links":160},"Le Synedre",[161,164,167,170,173,176,179,182,185],{"label":162,"href":163,"external":70},"L'histoire","\u002Fsynedre",{"label":165,"href":166,"external":70},"Constitution","\u002Fsynedre\u002Fconstitution",{"label":168,"href":169,"external":70},"L'équipe","\u002Fequipe",{"label":171,"href":172,"external":70},"Le réacteur en direct","\u002Freacteur",{"label":174,"href":175,"external":70},"Le Drill (entraînement)","\u002Fdrill",{"label":177,"href":178,"external":70},"Protocole de réunion","\u002Fsynedre\u002Freunion",{"label":180,"href":181,"external":70},"Les agents IA","\u002Fagents-ia",{"label":183,"href":184,"external":70},"La Conduite","\u002Fsynedre\u002Fconduite",{"label":186,"href":187,"external":70},"Charte plateforme","\u002Fsynedre\u002Fcharte",{"title":189,"links":190},"Ressources",[191,192,193,196,198,201],{"label":77,"href":78,"external":70},{"label":110,"href":111,"external":70},{"label":194,"href":195,"external":70},"Dictionnaire","\u002Fdictionnaire",{"label":197,"href":68,"external":70},"Expertise PrestaShop",{"label":199,"href":200,"external":70},"Flywheel","\u002Fflywheel",{"label":202,"href":203,"external":70},"Manifeste","\u002Fmanifeste",{"title":117,"links":205},[206,208,211],{"label":207,"href":118,"external":70},"Alexandre Carette",{"label":209,"href":210,"external":70},"Dossier de presse","\u002Fpresse",{"label":125,"href":126,"external":70},{"header":213},{"logo":214,"topBar":219,"contactEmail":222,"features":223,"navBar":69},{"src":215,"alt":216,"text":207,"href":217,"class":218},"\u002Flogo-ac.svg","Alexandre Carette — Architecte E-commerce Souverain","\u002F","h-10 w-10",{"message":69,"showLanguages":70,"align":220,"languages":221},"left",[],"contact@alexandrecarette.fr",{"showSearch":70,"showWishlist":70,"showLogin":20,"showContact":70,"showCart":70,"stickyHeader":20,"headerLayout":224},"inline",{"footer":226},{"theme":227,"description":69,"hours":69,"logo":228,"contact":229,"social":230,"bottomBar":240},"dark",{"src":215,"href":217,"alt":207},{"email":69,"phone":69,"address":69,"cta":69},[231,234,237],{"platform":232,"href":233,"label":232},"linkedin","https:\u002F\u002Fwww.linkedin.com\u002Fin\u002Falexandre-carette\u002F",{"platform":235,"href":236,"label":235},"malt","https:\u002F\u002Fwww.malt.fr\u002Fprofile\u002Falexandrecarette",{"platform":238,"href":239,"label":238},"github","https:\u002F\u002Fgithub.com\u002Fprest4cafe",{"copyright":69}]