Ajout de liens au menu des catégories

20

Je sais que c'est une vieille question avec beaucoup de réponses, la plupart suggèrent de modifier le modèle de menu mais cela ne fonctionne pas pour moi. Il n'est pas nécessaire d'expliquer pourquoi, disons que je suis un peu TOC pour faire les choses de la "bonne" manière.
Cette question peut servir de matériel à d'autres personnes dans le besoin. Voici.
A partir de Magento 1.7 le menu du haut est construit en utilisant un événement: page_block_html_topmenu_gethtml_before. Ceci est utilisé par le Mage_Catalogmodule pour ajouter les catégories. Je veux l'utiliser. Pour cela, j'ai créé un observateur dans mon module comme ceci:

<global>
    <events>
        <page_block_html_topmenu_gethtml_before>
            <observers>
                <my_observer>
                    <class>mymodule/observer</class>
                    <method>addItemsToTopmenuItems</method>
                </my_observer>
            </observers>
        </page_block_html_topmenu_gethtml_before>
    </events>
</global>

Dans la Observer.phpclasse que j'ai

public function addItemsToTopmenuItems($observer){
    //get the menu object: //Type Varien_Data_Tree_Node
    $menu = $observer->getMenu();
    //get the tree object in the menu //type Varien_Data_Tree
    $tree = $menu->getTree();
    //get current page handler
    $action = Mage::app()->getFrontController()->getAction()->getFullActionName();
    $brandNodeId = 'category-node-brand';
    //set the node id, label and url
    $data = array(
        'name' => Mage::helper('catalog')->__('Brands'),
        'id' => $brandNodeId,
        'url' => Mage::getUrl('brands'),
        'is_active' => ($action == 'brands')
    );
    //create a node object
    $brandNode = new Varien_Data_Tree_Node($data, 'id', $tree, $menu);
    //add the node to the menu
    $menu->addChild($brandNode);
    return $this;
}

Mon observateur a un autre code qui ajoute toutes les marques comme sous-éléments du Brandsmenu, mais cela n'est pas nécessaire ici.
Cela fonctionne parfaitement et ajoute un menu Brandscomme dernier élément du menu.
Le problème est que je le veux comme premier menu et mon observateur est appelé après l'observateur Mage_Catalogqui ajoute les catégories. Puisqu'il n'y a aucun moyen (pas que je sache) de trier l'ordre des observateurs sur un événement ... J'ai un problème
[EDIT]
Comme @Benmarks l'a suggéré, j'ai fait leMage_Catalogmodule dépend de mon module et maintenant mon élément de menu est le premier de la liste. Mais je dois encore ajouter des menus entre les catégories et à la fin. La création d'un nouveau module résoudrait probablement le problème avec les éléments à la fin du menu, mais j'ai toujours un problème avec ceux entre les catégories,
[/ EDIT]
Donc, fondamentalement, ma question reprend " (Comment) puis-je me déplacer enfant nœuds d'un Varien_Data_Tree_Nodedans un Varien_Data_Treeobjet? "
Veuillez ne pas suggérer d'ajouter la Brandspremière catégorie dans l'arborescence des catégories. Ce n'est pas une option (comme je l'ai dit ... mon TOC à propos de ces choses).

Marius
la source
Y a-t-il une raison pour ne pas créer de catégories vides et n'afficher qu'un bloc CMS? - J'accepte "oui" comme réponse, juste pour être sûr, vous y avez pensé :)
Fabian Blechschmidt
1
@FabianBlechschmidt. "Oui". Il est inutile d'entrer dans les détails, mais il y a des raisons (certaines d'entre elles peuvent être assez stupides). Je ne fais pas les "règles" sur celui-ci. Donc, cela doit être fait comme ça.
Marius
@FabianBlechschmidt: Pour effacer une partie du "brouillard", voici une bonne raison pour que vous ne disiez pas que je suis têtu (même si je le suis). Les liens personnalisés (marques, nouveautés, ventes et autres) ne sont pas au même endroit pour toutes les vues de magasin. Mais toutes les vues de magasin utilisent les mêmes catégories. Je ne veux donc pas créer une arborescence différente pour chaque vue de magasin. En utilisant un observateur, je peux lire certains paramètres de configuration et organiser les éléments comme je le souhaite. Je peux même ajouter les éléments de menu en fonction de l'ID de la vue du magasin.
Marius
Également intéressé, j'ai le même problème, ma solution est de remplacer Varien_Data_Tree_Node_Collection et d'ajouter ici une méthode pour trier les nœuds comme je le souhaite, mais je cherche un moyen plus propre.
Fab

Réponses:

10

Après un peu de difficulté, voici la solution que j'ai trouvée. Je laisse mon observateur exécuter après celui deMage_Catalog et décidé de recréer entièrement le menu.
L'idée principale est de placer tous les éléments de menu existants dans un tableau temporaire, de les supprimer du menu, puis d'ajouter mes liens entre les éléments existants et, à la fin, d'ajouter à nouveau tous les éléments au menu. Quelque chose comme ça:

public function addItemsToTopmenuItems($observer){
    //get the menu object -Type Varien_Data_Tree_Node
    $menu = $observer->getMenu();
    //get the tree object in the menu -type Varien_Data_Tree
    $tree = $menu->getTree();
    //get current page handler
    $action = Mage::app()->getFrontController()->getAction()->getFullActionName();
    $brandNodeId = 'category-node-brand';
    //set the node id, label and url
    $data = array(
        'name' => Mage::helper('catalog')->__('Brands'),
        'id' => $brandNodeId,
        'url' => Mage::getUrl('brands'),
        'is_active' => ($action == 'brands')
    );
    //create a node object
    $brandNode = new Varien_Data_Tree_Node($data, 'id', $tree, $menu);
    //temporary array with nodes
    $menuItems = array();
    //my first menu item
    $menuItems[] = $brandNode;
    //loop through existing menu items, add them to the array and remove them from the    menu
    foreach ($menu->getChildren() as $child){
        //add the item to the temp array
        $menuItems[] = $child;
        //remove item from the menu
        $menu->removeChild($child);
        //I need to add a new menu item after the category with id 6
        //don't worry the id is not hard coded. it comes from a config setting
        //I just added 6 here to make it easier to read
        if ($child->getId() == 'category-node-6'){
            //create a new node as $brandNode called $newNode
            ...
            //add the node to my temp array
            $menuItems[] = $newNode;
        }
    }
    //add other nodes at the end of my temp array
    ...
    //recreate the menu in the order I need
    foreach ($menuItems as $child){
        $menu->addChild($child);
    }
}

Cela semble résoudre mon problème, mais j'espère une méthode plus élégante pour le faire.

Marius
la source
Marius est-il un autre observateur que page_block_html_topmenu_gethtml_before pour ajouter des liens vers le menu des catégories?
Pradeep Sanku
La raison en est que j'avais utilisé le même observateur mais j'avais une extension pour megamenu qui n'appelle pas page_block_html_topmenu_gethtml_before.please faites le moi savoir
Pradeep Sanku
@PradeepSanku. Je ne connais aucun autre événement. Peut-être que l'extension que vous utilisez remplace complètement le menu principal. Vous devriez demander de l'aide au développeur.
Marius
4

Puisqu'il n'y a aucun moyen (pas que je sache) de trier l'ordre des observateurs sur un événement ... J'ai un problème.

Ah, mais il y en a! Dans votre fichier de déclaration de module, définissez la dépendance de Mage_Catalogvotre module, par exemple:

<modules>
    <Your_Module>
        <active>true</active>
        <codePool>local</codePool>
    </Your_Module>
    <Mage_Catalog>
        <depends>
            <Your_Module/>
        </depends>
    </Mage_Catalog>
</modules>

En outre, vous pouvez (je pense) copier la configuration de l'observateur de catalogue dans la frontendzone d'événements et la désactiver dans la globalzone. Mon hypothèse est que les globalévénements sont traités avantfrontend événements. (Je ne sais pas pourquoi cet événement est configuré globalen premier lieu.)

Et bien sûr, il existe d'autres options que vous pouvez effectuer via les réécritures et PHP.

Benmarks
la source
Merci. Vous avez mon +1 ici. J'ai en fait déplacé mon événement à l'intérieur de la <global>balise, j'ai déclaré Mage_Catalogdépendre de mon module (même si je me sens un peu "sale" en faisant ça) et cela fonctionne, mais je me retrouve avec un autre problème. J'ai besoin d'autres éléments de menu placés entre certaines catégories et à la fin du menu, j'ai donc encore besoin de pouvoir les déplacer dans les environs. Je mettrai à jour la question.
Marius
-1
  1. créer une nouvelle sous-catégorie
  2. changer le lien avec javascript, ex votre nouvelle catégorie est "75"
jQuery(document).ready(function(){
    document.getElementById("menu75").getElementsByTagName("a")[0].href =

" https: // YourNewLinkink "; });

zatanabee
la source
et comment puis-je connaître l'identifiant de l'élément s'il est censé fonctionner avec n'importe quel identifiant? Ce n'est pas une solution viable. Je n'appellerai pas cela même une solution de contournement.
Marius
cela fonctionne sur mon code ... :)
zatanabee
l'id show @ Catalogue> gérer les catégories
zatanabee