Afficher les produits dans le menu de navigation principale
- Par Magentix le 30/05/2010
- Difficulté : 3/4
Les menus déroulants sur les sites e-commerce se complexifient de plus en plus. Outre la traditionnelle hiérarchisation et classification des catégories, il n'est pas rare d'y voir apparaître offres promotionnelles et produits. Ces menus s'élargissent et prennent parfois la totalité de l'espace disponible (Cdiscount, Tati...).
Utiliser le menu de navigation principale pour communiquer autour d'une offre promotionnelle ou d'un produit phare (nouveauté, promotion, bestseller...) est un excellent moyen d'attirer et de guider l'internaute vers un produit incontournable qu'il ne doit pas manquer. C'est une technique à la mode, très bien exploitée sur le site de Tati ouvert récemment (Tati.fr) :
Tati offre ici un menu de navigation géant sur lequel il est facile de s'orienter, et auquel vient s'ajouter pour chacune des catégories un produit sélectionné pour son prix plutôt attractif. C'est également un excellent moyen d'égayer le menu et d'appuyer l'intitulé de la catégorie par un visuel des produits qu'elle contient.
Le développement d'un petit module pour Magento peut nous permettre d'associer et d'afficher facilement un produit dans les catégories du menu de navigation principale. L'idée est d'ajouter sur la fiche produit de l'administration une nouvelle option nommée "Activer dans le menu". Le produit apparaîtra alors dans la catégorie correspondante.
Architecture du module
- app/code/local/Magentix/NavigationProduct/Block/
- Navigation.php
- app/code/local/Magentix/NavigationProduct/etc/
- config.xml
- app/code/local/Magentix/NavigationProduct/sql/navigationproduct_setup/
- mysql4-install-0.1.0.php
- app/etc/modules/
- Magentix_NavigationProduct.xml
Développement du module
Dans un premier temps nous allons surcharger le bloc utilisé pour l'affichage du menu principale. Il s'agit du bloc Mage_Catalog_Block_Navigation. L'objectif est d'y ajouter une méthode permettant de récupérer un produit spécifique en fonction de la catégorie à laquelle il est associé.
Le bloc Mage_Catalog_Block_Navigation présente une fonction récursive nommée drawItem chargée d'établir la hiérarchisation du menu. Nous allons la modifier afin de permettre l'ajout d'un produit en bas de la liste des sous-catégories.
app/code/local/Magentix/NavigationProduct/Block/Navigation.php
<?php
class Magentix_NavigationProduct_Block_Navigation extends Mage_Catalog_Block_Navigation {
public function drawItem($category, $level=0, $last=false) {
$html = '';
if (!$category->getIsActive()) {
return $html;
}
/* ... (Voir app/code/core/Mage/Catalog/Block/Navigation.php) */
if ($hasChildren){
$j = 0;
$htmlChildren = '';
foreach ($children as $child) {
if ($child->getIsActive()) {
$htmlChildren.= $this->drawItem($child, $level+1, ++$j >= $cnt);
}
}
if (!empty($htmlChildren)) {
$html.= '<ul class="level' . $level . '">'."\n"
.$htmlChildren
/***** Ajout *****/
.$this->getProduct($category,$level)
/* ************* */
.'</ul>';
}
}
$html.= '</li>'."\n";
return $html;
}
}
Une fois la méthode drawItem modifiée, il ne reste plus qu'à écrire la méthode getProduct. Celle ci accepte en paramètre la catégorie actuelle et le niveau (level) du menu. Dans notre exemple seule la catégorie de niveau 0 pourra afficher un produit.
app/code/local/Magentix/NavigationProduct/Block/Navigation.php
<?php
class Magentix_NavigationProduct_Block_Navigation extends Mage_Catalog_Block_Navigation {
public function drawItem($category, $level=0, $last=false) {
/* ... */
}
public function getProduct($category,$level) {
$product = '';
if($level == 0) {
$category = Mage::getModel('catalog/category')->load($category->getId());
$_productCollection = Mage::getResourceModel('catalog/product_collection')
->addAttributeToSelect('name')
->addAttributeToSelect('small_image')
->addAttributeToFilter('product_navigation',1)
->addCategoryFilter($category)
->setPageSize(1);
foreach($_productCollection as $p) {
$product = '<li class="nav-product">
<a href="'.$p->getProductUrl().'"><img src="'.Mage::helper('catalog/image')->init($p, 'small_image')->resize(150).'" alt="'.$p->getName().'" class="nav-product-img" /></a>
<a href="'.$p->getProductUrl().'"><span>'.$p->getName().'</span></a>
</li>';
}
}
return $product;
}
}
Nous récupérons une collection de produits filtrés sur la catégorie et sur un nouvel attribut appelé product_navigation. Le nombre de produit est limité à 1 grâce à la méthode setPageSize. Nous parcourons ensuite la collection comportant un unique produit, puis établissons son affichage. Dans cet exemple nous ne souhaitons afficher que le nom du produit et son visuel, il est bien sûre possible de sélectionner d'autres attributs au sein de la collection (addAttributeToSelect).
Il nous faut ensuite définir le nouvel attribut product_navigation. Celui ci sera ajouté lors de la première initialisation du module dans Magento :
app/code/local/Magentix/NavigationProduct/sql/navigationproduct_setup/mysql4-install-0.1.0.php
<?php
$installer = $this;
$installer->startSetup();
$installer->addAttribute('catalog_product', 'product_navigation', array(
'type' => 'int',
'backend' => '',
'frontend' => '',
'label' => 'Activer dans le menu',
'input' => 'boolean',
'global' => 1,
'visible' => 1,
'required' => 0,
'user_defined' => 1,
'default' => 0,
'searchable' => 0,
'filterable' => 0,
'comparable' => 0,
'visible_on_front' => 0,
'unique' => 0,
));
$installer->endSetup();
Nous pouvons enfin éditer le fichier de configuration afin de spécifier la surcharge du bloc et le setup à exécuter :
app/code/local/Magentix/NavigationProduct/etc/config.xml
<?xml version="1.0"?>
<config>
<modules>
<Magentix_NavigationProduct>
<version>0.1.0</version>
</Magentix_NavigationProduct>
</modules>
<global>
<blocks>
<catalog>
<rewrite>
<navigation>Magentix_NavigationProduct_Block_Navigation</navigation>
</rewrite>
</catalog>
</blocks>
<resources>
<navigationproduct_setup>
<setup>
<module>Magentix_NavigationProduct</module>
<class>Mage_Catalog_Model_Resource_Eav_Mysql4_Setup</class>
</setup>
<connection>
<use>core_setup</use>
</connection>
</navigationproduct_setup>
</resources>
</global>
</config>
Puis on active le module :
app/etc/modules/Magentix_NavigationProduct.xml
<?xml version="1.0"?>
<config>
<modules>
<Magentix_NavigationProduct>
<active>true</active>
<codePool>local</codePool>
<depends>
<Mage_Catalog />
</depends>
<version>0.1.0</version>
</Magentix_NavigationProduct>
</modules>
</config>
Une fois le module déclaré à Magento, il est nécessaire d'associer le nouvel attribut product_navigation aux groupes d'attributs produit.
Il suffit ensuite d'activer le produit depuis sa fiche :
Note : le menu est mis en cache par Magento, pour que les modifications soient prises en compte il est nécessaire d'actualiser le cache.
On peut finalement intégrer visuellement le produit depuis le fichier CSS du template. Le code HTML généré ici est le suivant :
Code HTML généré
<li class="nav-product">
<a href="/produit-1.html"><img src="..." alt="Plateau aromatique" class="nav-product-img"></a>
<a href="/produit-1.html"><span>Plateau aromatique</span></a>
</li>
Moi je dit top :)
J'ai essayé l'extension "explode menu" qui modifie aussi cette méthode mais l'ajout d'un produit est mieux.
Le top c'est comme le site de la redoute.
serait il possible de l'avoir en 1 seule
Bien Cordialement Laurent
encore une question comment mettre plus d'images dans le menu ?
Cordialement
http://www.commentmaigrir.biz/
un petit coup de pouce pour le fichier =>Navigation.php<= serait génial et en tous cas merci de m'avoir répondu aussi vite vraiment super réactif le top !
D'avance merci
Cordialement laurent
if (!empty($htmlChildren)) {
$html.= '<ul class="level' . $level . '">'."\n"
.$htmlChildren
.'</ul>';
}
Et modifier de cette façon :
if (!empty($htmlChildren)) {
$image = '';
if ($_imageUrl = $category->getImageUrl()) {
$image = '<li><img src="'.$_imageUrl.'" alt="" /></li>';
}
$html.= '<ul class="level' . $level . '">'."\n"
.$htmlChildren
.$image
.'</ul>';
}
Je n'ai pas essayé mais çà devrait passer ;)
Ps: on parle toujours du fichier en local ?
perso, je suis en train de reproduire ce menu, que je trouve super beau
http://www.blancheporte.fr/
J'ai bien l'option disponible dans les parametres des produits "afficher dans le menu" mais lorsque je mets ou rien ne change :(
Content d'avoir découvert cette partie de votre site :)
Pour JoE et dojo, si vous n'avez pas de sous-catégories, le produit ne se génère pas.
Il faut modifier un peu le code de Magentix pour "handle" le fait qu'il n'y aie pas de sous-catégories (il faut activer les fonctions de rollover et de génération des produits uniquement lorsqu'il y a des sous-produits)
Bonne journée
Je suis un novice, merci pour le tuto et vive le partage, j'ai un souci.
L'attribut product_navigation n’appairait pas sur la fiche général du produit du coup je ne peux pas sélectionner de produit pour tester.
Tout c'est apparemment bien passer car j'ai bien associé le nouvel attribut product_navigation aux groupes d'attributs produit.
Merci pour votre aide.
Merci pour ce module. Toutefois j'ai une petite question...
Comment cela ce passe t il quand le produit fait parti de plusieurs categories???
Bonne journée