Agregar enlaces al menú de categoría

20

Sé que esta es una vieja pregunta con muchas respuestas, la mayoría de ellas sugiere editar la plantilla del menú, pero eso no funciona para mí. No hay necesidad de explicar por qué, digamos que soy un poco TOC por hacer las cosas de la manera "correcta".
Esta pregunta puede servir como material para otros necesitados. Aquí va.
A partir de Magento 1.7 el menú superior se construye utilizando un evento: page_block_html_topmenu_gethtml_before. El Mage_Catalogmódulo lo usa para agregar las categorías. Quiero usar eso Para esto, he creado un observador en mi módulo como este:

<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>

En la Observer.phpclase que tengo

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;
}

Mi observador tiene otro código que agrega todas las marcas como subelementos del Brandsmenú, pero no hay necesidad de eso aquí.
Esto funciona perfectamente y agrega un menú Brandscomo último elemento en el menú.
El problema es que quiero esto como el primer menú y mi observador se llama después del observador Mage_Catalogque agrega las categorías. Dado que no hay forma (no que yo sepa) de ordenar el orden de los observadores en un evento ... Tengo un problema
[EDITAR]
Como @Benmarks sugirió que hice elMage_Catalogmódulo depende de mi módulo y ahora mi elemento de menú es el primero en la lista. Pero todavía tengo que agregar menús entre las categorías y al final. La creación de un nuevo módulo probablemente resolvería el problema con los elementos al final del menú, pero todavía tengo un problema con los que están entre las categorías,
[/ EDIT]
Entonces, básicamente, mi pregunta se resume en " (¿Cómo) puedo moverme alrededor del niño? nodos de a Varien_Data_Tree_Nodeen un Varien_Data_Treeobjeto? "
No sugiera agregar el Brandscomo la primera categoría en el árbol de categorías. Esta no es una opción (como dije ... mi TOC sobre estas cosas).

Marius
fuente
¿Hay alguna razón para no crear categorías vacías y solo mostrar un bloque CMS? - Acepto "sí" como respuesta, solo para estar seguro, pensaste en esto :)
Fabian Blechschmidt
1
@FabianBlechschmidt. "Sí". No tiene sentido obtener detalles, pero hay razones (algunas de ellas pueden ser bastante estúpidas). No hago las "reglas" en este caso. Entonces se debe hacer así.
Marius
@FabianBlechschmidt: Para despejar algo de la "niebla" aquí hay una buena razón para que no digas que soy terco (incluso si lo soy). Los enlaces personalizados (marcas, novedades, ventas y otros) no están en el mismo lugar para todas las visitas a la tienda. Pero todas las vistas de la tienda usan las mismas categorías. Por lo tanto, no quiero crear un árbol diferente para cada vista de la tienda. Al usar un observador, puedo leer algunos ajustes de configuración y organizar los elementos como quiera. Incluso puedo agregar los elementos del menú dependiendo de la identificación de la vista de la tienda.
Marius
También interesado, tengo el mismo problema, mi solución es anular Varien_Data_Tree_Node_Collection y agregar aquí un método para ordenar los nodos como quiero, pero estoy buscando una forma más limpia.
Fabuloso

Respuestas:

10

Después de luchar un poco, aquí está la solución que encontré. Dejé que mi observador se ejecutara después de la entrada Mage_Catalogy decidí volver a crear el menú por completo.
La idea principal es hacer que todos los elementos del menú existentes los coloquen en una matriz temporal, eliminarlos del menú y luego agregar mis enlaces entre los elementos existentes y al final agregar todos los elementos al menú nuevamente. Algo como esto:

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);
    }
}

Esto parece resolver mi problema, pero espero un método más elegante para hacerlo.

Marius
fuente
Marius, ¿hay algún otro observador que no sea page_block_html_topmenu_gethtml_ antes de agregar enlaces al menú de categorías?
Pradeep Sanku
La razón es que había usado el mismo observador pero tenía una extensión para megamenú que no llama a page_block_html_topmenu_gethtml_before.por favor, hágamelo saber
Pradeep Sanku el
@PradeepSanku. No conozco ningún otro evento. Tal vez la extensión que está utilizando reemplaza completamente el menú principal. Debes pedirle ayuda al desarrollador.
Marius
4

Dado que no hay forma (no que yo sepa) de ordenar el orden de los observadores en un evento ... Tengo un problema.

Ah, pero lo hay! En el archivo de declaración de su módulo, configure la dependencia de Mage_Catalogsu módulo, por ejemplo:

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

Además, podría (creo) copiar la configuración del observador del catálogo en el frontendárea de eventos y desactivarla en el globalárea. Mi suposición es que los globaleventos se procesan antes que los frontendeventos. (No tengo idea de por qué este evento está configurado globalen primer lugar).

Y, por supuesto, hay otras opciones que puede realizar mediante reescrituras y PHP.

puntos de referencia
fuente
Gracias. Tienes mi +1 aquí. De hecho, moví mi evento dentro de la <global>etiqueta, declaró Mage_Catalogque dependía de mi módulo (incluso si me siento un poco "sucio" haciendo eso) y funciona, pero termino con otro problema. Necesito algunos otros elementos del menú ubicados entre algunas categorías y al final del menú, así que todavía necesito poder moverlos alrededor. Actualizaré la pregunta.
Marius
-1
  1. crear nueva subcategoría
  2. cambia el enlace con javascript, tu nueva categoría es "75"
jQuery(document).ready(function(){
    document.getElementById("menu75").getElementsByTagName("a")[0].href =

" https: // YourNewLinkink "; });

zatanabee
fuente
¿Y cómo sé la identificación del elemento si se supone que funciona con alguna identificación? Esta no es una solución viable. No lo llamaré ni siquiera una solución.
Marius
funciona en mi código ... :)
zatanabee
the id show @ Catalog> gestionar categorías
zatanabee