Le piège des routeurs sur Magento
Magento a un système de routes assez complexe...
Entre les routes frontend
, les routes admin
, le catalogue et son URL rewriting
et les pages CMS... On a vite fait de s'y perdre !
Cet article est là pour vous montrer que Magento reste une application très permissive. Attention !
Je me suis longtemps trompé sur la manière de créer mes routes... surtout celles destinées à mes contrôleurs d'admin.
Le front
Pour ajouter une routes simple pour le front il y a un bout de XML à connaître. Rien de bien compliqué :
Quelques explications :
name_of_my_route
c'est le nom de la route... vraiment. Par exemple si je veux générer une URL via notre nouvelle route je fais :
<use>standard</use>
c'est pour dire que c'est une route en front.<module>My_Module</module>
c'est le nom de votre module. Si vous mettezSuper_Foo
alors le contrôleurindex
aura pour nom :Super_Foo_IndexController
.<frontName>foo</frontName>
c'est le "final" de la route : http://example.com/foo/bar/baz.
L'admin
En admin c'est exactement pareil... ou presque.
En réalité les routes de l'admin sont « parsées » avant celles du front. Ce qui fait que si votre route admin permet d'accéder à un contrôleur frontal... bah ça fonctionnera.
Exemple « bad practices »
L'architecture :
app/code/local/Jbh/Blog
└── controllers
├── Adminhtml
│ └── ManageController.php
└── IndexController.php
controllers/IndexController.php
:
controllers/Adminhtml/MagnageController.php
:
Maintenant regardez bien ce fichier de config :
Vous remarquerez que nous n'avons rien dans la balise frontend
, que notre routeur est bien dans <admin/>
et a bien une balise <use>
qui vaut admin
également.
On est donc en droit de penser que notre contrôleur front : Jbh_Blog_IndexController
qui étend Mage_Core_Controller_
Front_Action
ne peut pas être accessible via cette route dédiée à l'admin.
Que neni !
http://example.com/blog/index/index => « front »
http://example.com/blog/adminhtml_manage/index => « admin »
WTF ?!
[ Faites le test ;) ]
Bonnes pratiques
La manière de créer un routeur en front ne change pas car dans ce sens tout est bon. Impossible d'accéder à un contrôleur admin depuis un routeur frontal.
Par contre voici comment éviter que nos routeurs d'admin ne soient utilisés pour afficher des contrôleurs front :
Ce que ça donne :
Tu peux nous expliquer ce que ça change ?
Le plus important c'est la balise <module>
qui vaut maintenant Jbh_Blog_Adminhtml
.
Ceci a pour effet d'automatiquement préfixer les contrôleurs demandés par cette route de Jbh_Blog_Adminhtml_
.
La route admin a également un nom différent pour pouvoir la différencer de la route front :)
Exemple
Mage::getUrl('jbh_blog_adminhtml/manage/index'); // => http://example.com/blog_adminhtml/manage/index // => controller: Jbh_Blog_Adminhtml_ManageController
Conclusion
Nous avons donc forcément besoin d'une route front pour accéder à notre Jbh_Blog_IndexControler
. Inévitable.
Problème résolu.
- Suffixez vos routeurs d'admin par quelque chose (
_adminhtml
tout simplement, ou_admin
à la limite ;)). - Pensez à la balise
<module/>
pour forcer l'utilisation d'un sous répertoire dans lescontrollers
.
En espérant que vous y verrez plus clair dans vos routes et que vous ne ferez pas (plus ?) cette erreur !