Ajouter des attributs de catégorie personnalisés

Ajouter des attributs de catégorie personnalisésIl peut arriver qu'un e-commerce ait besoin de champs spécifiques relatifs aux catégories (plusieurs images, description courte...). Sous Magento il est aisé d'ajouter des attributs de produit depuis l'interface, mais cela est beaucoup moins évident pour les attributs de catégorie.

Le modèle de données EAV (Entity-Attribute-Value) utilisé par Magento offre une grande souplesse dans la gestion des attributs. Il permet d'ajouter de nouvelles entrées sans pour autant modifier la structure même des tables. Ce type de modèle de données complexifie énormément la base (données "éclatées") mais se justifie amplement par la souplesse et la modularité apportée.

L'ajout de caractéristiques produit est grandement simplifié par la gestion des attributs disponible sur le backend. Pour l'ajout d'attributs de catégorie il va falloir procéder autrement...

Une des méthodes consiste à ajouter manuellement une nouvelle entrée dans la table eav_attribute de la base de données. Cette méthode a cependant ses limites, elle peut notamment poser problème lors d'une réinstallation ou d'une réinitialisation complète de la boutique, et va à l'encontre du principe de modularité apporté par Magento (modifier la base de données c'est un peu comme trifouiller les fichiers du core).

Pour ajouter nos attributs de catégorie, nous allons simplement développer une extension qui se chargera d'alimenter la table eav_attribute de 2 nouvelles entrées (picture et short_description).

Architecture du module

  • app/code/local/Magentix/CategoriesAttributes/etc/
  • config.xml
  • app/code/local/Magentix/CategoriesAttributes/sql/categoriesattributes_setup/
  • mysql4-install-0.1.0.php
  • app/etc/modules/
  • Magentix_CategoriesAttributes.xml

Développement du module

L'extension doit donc permettre l'ajout de 2 entrées dans la table eav_attribute. Les attributs seront initialisés lors de l'installation du module. Pour ce faire, nous allons instancier un installeur sql, puis faire appel à la méthode addAttribute() de la classe Mage_Eav_Model_Entity_Setup, évitant ainsi la saisie de requêtes un peu lourdes.

Magento exécutera l'installeur si le code de la ressource du module n'est pas déjà listé dans la table core_resource. L'exécution dépendra également de la version de l'extension (on utilisera un update pour la mise à jour du module).

Table core_resource

Le code de notre ressource sera categoriesattributes_setup et la version du module la 0.1.0. Nous pouvons maintenant configurer l'extension que l'on nommera CategoriesAttributes :

app/code/local/Magentix/CategoriesAttributes/etc/config.xml

<?xml version="1.0"?>
<config>
   <modules>
      <Magentix_CategoriesAttributes>
         <version>0.1.0</version>
      </Magentix_CategoriesAttributes>
   </modules>
   <global>
      <resources>
         <categoriesattributes_setup>
            <setup>
               <module>Magentix_CategoriesAttributes</module>
               <class>Mage_Catalog_Model_Resource_Eav_Mysql4_Setup</class>
            </setup>
            <connection>
               <use>core_setup</use>
            </connection>
         </categoriesattributes_setup>
      </resources>
   </global>
</config>

Reste à déterminer les attributs de catégorie que l'on souhaite ajouter lors de l'exécution de l'installeur. Dans notre exemple nous allons ajouter 2 champs :

  • Le premier pour le chargement d'une deuxième image
  • Le second pour la rédaction d'une description courte

L'entité sera dans les 2 cas de type catalog_category et nous nommerons les champs respectivement picture et short_description.

Un attribut possède de nombreuses options. Il est possible de définir sa portée, sa visibilité, sa valeur par défaut, de l'associer à un modèle... Beaucoup d'options sont cependant réservées aux attributs des produits.

Pour l'ajout des 2 nouveaux attributs nous allons calquer ceux déjà existants : image et description.

La méthode addAttribute() nous simplifie la vie en générant la requête SQL à partir des données passées en paramètre.

app/code/local/Magentix/CategoriesAttributes/sql/categoriesattributes_setup/mysql4-install-0.1.0.php

<?php

$installer = $this;

$installer->startSetup();

$installer->addAttribute('catalog_category', 'picture', array(
                        'type'              => 'varchar',
                        'backend'           => 'catalog/category_attribute_backend_image',
                        'frontend'          => '',
                        'label'             => 'Picture',
                        'input'             => 'image',
                        'class'             => '',
                        'source'            => '',
                        'global'            => 0,
                        'visible'           => 1,
                        'required'          => 0,
                        'user_defined'      => 0,
                        'default'           => '',
                        'searchable'        => 0,
                        'filterable'        => 0,
                        'comparable'        => 0,
                        'visible_on_front'  => 0,
                        'unique'            => 0,
                        'position'          => 1,
                    ));
                                        
$installer->addAttribute('catalog_category', 'short_description', array(
                        'type'              => 'text',
                        'backend'           => '',
                        'frontend'          => '',
                        'label'             => 'Short description',
                        'input'             => 'textarea',
                        'class'             => '',
                        'source'            => '',
                        'global'            => 0,
                        'visible'           => 1,
                        'required'          => 0,
                        'user_defined'      => 0,
                        'default'           => '',
                        'searchable'        => 0,
                        'filterable'        => 0,
                        'comparable'        => 0,
                        'visible_on_front'  => 0,
                        'unique'            => 0,
                        'position'          => 1,
                    ));

$installer->endSetup();

Il ne reste plus qu'à activer notre nouveau module. Lors du rafraîchissement du cache l'installeur sera exécuté.

app/etc/modules/Magentix_CategoriesAttributes.xml

<?xml version="1.0"?>
<config>
    <modules>
        <Magentix_CategoriesAttributes>
            <active>true</active>
            <codePool>local</codePool>
        </Magentix_CategoriesAttributes>
    </modules>
</config> 

Si l'on observe maintenant la table eav_attribute, on y trouve les 2 nouvelles entrées :

Table eav_attribute

Les champs peuvent alors être renseignés lors de l'édition d'une catégorie :

Édition d'une catégorie

On peut enfin les exploiter dans nos templates, comme par exemple dans le template catalog/category/view.phtml :

catalog/category/view.phtml

$_helper    = $this->helper('catalog/output');
$_category  = $this->getCurrentCategory();

/* Afficher l'image */

$_picHtml = '';
if($_category->getPicture()) {
        $_picUrl = Mage::getBaseUrl('media').'catalog/category/'.$_category->getPicture();
        $_picHtml = '<img src="'.$_picUrl.'" alt="'.$this->htmlEscape($_category->getName()).'" />';
        $_picHtml = $_helper->categoryAttribute($_category, $_picHtml, 'picture');
}
        
echo $_picHtml;

/* Afficher la description courte */
        
if($_category->getShortDescription()) {
        echo $_category->getShortDescription();
}

Commentez cet article Ajouter des attributs de catégorie personnalisés

Damien @ 03-02-2010 16:57:44
Bonjour
Merci pour l'article qui semble très utile.
J'ai testé votre script : il m'ajoute bien une entrée dans la table core_ressources.
Par contre, il ne semble jamais passer dans le setup, puisque l'attribut n'est pas ajouté dans eav_attributes
Je travaille avec Magento 1.3.2.4. Et voici mon code :

Fichier etc/config.xml :
<?xml version="1.0"?>
<config>
   <modules>
      <Test_ExtraAttributes>
         <version>0.1.2</version>
      </Test_ExtraAttributes>
   </modules>
   <global>
      <resources>
         <extra_attributes_setup>
            <setup>
               <module>Test_ExtraAttributes</module>
               <class>Mage_Catalog_Model_Resource_Eav_Mysql4_Setup</class>
            </setup>
            <connection>
               <use>core_setup</use>
            </connection>
         </extra_attributes_setup>
      </resources>
   </global>
</config>

Fichier sql/extra_attributes_setup/mysql4-install-0.1.2.php
<?php
$installer = $this;
$installer->startSetup();
$installer->addAttribute('catalog_category', 'picture', array(
                        'type'              => 'varchar',
                        'backend'           => 'catalog/category_attribute_backend_image',
                        'frontend'          => '',
                        'label'             => 'Illustration',
                        'input'             => 'image',
                        'class'             => '',
                        'source'            => '',
                        'global'            => 0,
                        'visible'           => 1,
                        'required'          => 0,
                        'user_defined'      => 0,
                        'default'           => '',
                        'searchable'        => 0,
                        'filterable'        => 0,
                        'comparable'        => 0,
                        'visible_on_front'  => 0,
                        'unique'            => 0,
                        'position'          => 1,
                    ));
                           
$installer->endSetup();

J'imaginais un problème de nommage de fichiers, mais j'ai beau retourné le problème, je ne vois pas mon erreur : pourriez vous m'aider svp ?
Y'a-t-il un moyen d'avoir les logs de passage dans ce fichier ?
Magentix @ 03-02-2010 19:54:10
Le problème peut tout simplement venir de là :
sql/extra_attributes_setup/mysql4-install-0.1.2.php >> sql/extraattributes_setup/mysql4-install-0.1.2.php
Damien @ 04-02-2010 08:21:57
Oui c'était ça.
Après j'avais pas tilté tout de suite sur le nommage des fichiers et la subtilité avec les fichiers upgrade.
Ainsi, à la première exécution, il faut le bon numéro de version sur le fichier install (le même numéro de version que dans le fichier xml)
Pour les mises à jour, il faudra des fichier de type mysql4-upgrade-0.1.2-0.1.3.php. Ainsi, cela multiplie le nombre de fichier car il faudra tout bonnement faire autant de fichier que d'associations de numéro de version possible.
C'est assez fastidieux pour le débuggage car tant qu'il y a un bug, il faut renommer tous les fichiers et mettre à jour le fichier xml pour que ce soit exécuté.
Magentix @ 04-02-2010 11:07:32
En fait pour une nouvelle installation d'un module, Magento exécutera mysql4-install-0.1.0.php puis mysql4-upgrade-0.1.0-0.1.1.php, ou directement mysql4-upgrade-0.1.0-0.1.1.php si la version 0.1.0 était déjà installée.

Par contre il faut que je me penche sur la cas de figure suivant :

J'ai la version 0.1.1 d'installée. Dans mes fichiers j'ai mysql4-upgrade-0.1.0-0.1.2.php.
Je ne sais pas si le fichier sera exécuté, ou s'il faut obligatoirement un fichier de transition entre chaque version : mysql4-upgrade-0.1.1-0.1.2.php.

Si une version intermédiaire ne modifie rien dans la base c'est un peu bête de multiplier les fichiers comme tu le suggères.

Pour résumé la question est dois-je créer les fichiers suivants :
mysql4-install-0.1.0.php [base modifiée]
mysql4-upgrade-0.1.0-0.1.1.php [aucune modification]
mysql4-upgrade-0.1.1-0.1.2.php [base modifiée]

Ou peut-on se passer de la version de transition puisqu'aucune modification dans la base :
mysql4-install-0.1.0.php [base modifiée]
mysql4-upgrade-0.1.0-0.1.2.php [base modifiée]

Je vais regarder çà de plus près...

Ajouter un commentaire

[b]Gras[/b] [i]italic[i] [url=http://www.domaine.com]Lien[/url] [code]Code[/code]

* champs obligatoires, l'e-mail ne sera pas publié