Dodawanie linków do menu kategorii

20

Wiem, że to stare pytanie z dużą ilością odpowiedzi, większość z nich sugeruje edycję szablonu menu, ale to nie działa dla mnie. Nie trzeba wyjaśniać, dlaczego, powiedzmy, że jestem trochę obsesyjny na punkcie robienia rzeczy „we właściwy sposób”.
To pytanie może służyć jako materiał dla potrzebujących. Tutaj idzie.
Począwszy od Magento 1.7 top menu jest zbudowany przy użyciu zdarzenie: page_block_html_topmenu_gethtml_before. Jest to używane przez Mage_Catalogmoduł do dodawania kategorii. Chcę tego użyć. W tym celu stworzyłem obserwatora w moim module w następujący sposób:

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

W Observer.phpklasie mam

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

Mój obserwator ma jakiś inny kod, który dodaje wszystkie marki jako podelementy Brandsmenu, ale tutaj nie ma takiej potrzeby.
Działa to doskonale i dodaje menu Brandsjako ostatnią pozycję w menu.
Problemem jest to, że chcę to jako pierwsze menu, a mój obserwator jest wywoływany po tym, jak obserwator Mage_Catalogdodaje kategorie. Ponieważ nie ma możliwości (nie wiem o tym) sortowania kolejności obserwatorów na zdarzeniu ... Mam problem
[EDYCJA]
Jak sugerował @Benmarks, zrobiłemMage_Catalogmoduł zależy od mojego modułu, a teraz mój element menu jest pierwszy na liście. Ale nadal muszę dodać menu między kategoriami i na końcu. Utworzenie nowego modułu prawdopodobnie rozwiązałoby problem z elementami na końcu menu, ale nadal mam problem z tymi między kategoriami,
[/ EDYCJA]
Tak więc w zasadzie moje pytanie powraca do „ (Jak) mogę poruszać się po dziecku węzły Varien_Data_Tree_Nodew Varien_Data_Treeobiekcie? ”
Nie sugeruj dodawania Brandspierwszej kategorii w drzewie kategorii. To nie jest opcja (jak powiedziałem ... mój OCD na te rzeczy).

Marius
źródło
Czy istnieje powód, aby nie tworzyć pustych kategorii i wyświetlać tylko blok CMS? - Akceptuję odpowiedź „tak”, dla pewności, pomyślałeś o tym :)
Fabian Blechschmidt
1
@FabianBlechschmidt. „Tak”. Nie ma sensu wchodzić w szczegóły, ale są powody (niektóre z nich mogą być dość głupie). Nie ustanawiam „reguł” w tym przypadku. Tak więc należy to zrobić.
Marius
@FabianBlechschmidt: Usunięcie „mgły” tutaj jest dobrym powodem, abyś nie powiedział, że jestem uparty (nawet jeśli jestem). Niestandardowe linki (marki, nowe, sprzedażowe i inne) nie znajdują się w tym samym miejscu dla wszystkich wyświetleń sklepu. Ale wszystkie widoki sklepu korzystają z tych samych kategorii. Nie chcę więc tworzyć innego drzewa dla każdego widoku sklepu. Korzystając z obserwatora, mogę odczytać niektóre ustawienia konfiguracji i rozmieścić elementy tak, jak chcę. Mogę nawet dodać elementy menu w zależności od identyfikatora widoku sklepu.
Marius
Również zainteresowany, mam ten sam problem, moim rozwiązaniem jest zastąpienie Varien_Data_Tree_Node_Collection i dodanie tutaj metody sortowania węzłów, jak chcę, ale szukam czystszego sposobu.
Fab

Odpowiedzi:

10

Po trudnych chwilach znalazłem rozwiązanie. Pozwoliłem mojemu obserwatorowi wykonać polecenie po tym, co się Mage_Catalogpojawiło i postanowiłem całkowicie utworzyć menu.
Główną ideą jest umieszczenie wszystkich istniejących elementów menu w tymczasowej tablicy, usunięcie ich z menu, a następnie dodanie moich łączy między istniejącymi elementami, a na koniec dodanie wszystkich elementów do menu ponownie. Coś takiego:

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

To rozwiązuje mój problem, ale mam nadzieję na bardziej elegancką metodę.

Marius
źródło
Marius jest innym obserwatorem oprócz page_block_html_topmenu_gethtml_przed dodaniem linków do menu kategorii?
Pradeep Sanku
Powodem jest to, że użyłem tego samego obserwatora, ale miałem rozszerzenie dla megamenu, które nie wywołuje page_block_html_topmenu_gethtml_before. Proszę dać mi znać
Pradeep Sanku
@PradeepSanku. Nie znam żadnego innego wydarzenia. Być może używane rozszerzenie zastępuje całkowicie menu główne. Poproś programistę o wsparcie.
Marius
4

Ponieważ nie ma sposobu (nie o tym wiem) sortowania porządku obserwatorów na zdarzeniu ... mam problem.

Ach, ale jest! W pliku deklaracji modułu ustaw zależność Mage_Catalogmodułu, np .:

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

Można również (myślę) skopiować konfigurację obserwatora katalogu do obszaru frontendzdarzenia i dezaktywować go w tym globalobszarze. Zakładam, że globalzdarzenia są przetwarzane przed frontendzdarzeniami. (Nie mam pojęcia, dlaczego to wydarzenie jest skonfigurowane globalw pierwszej kolejności).

Oczywiście są też inne opcje, które można wykonać poprzez przepisywanie i PHP.

zalety
źródło
Dzięki. Masz tutaj moją +1. Właściwie przeniosłem swoje wydarzenie do <global>tagu, zadeklarowałem, że jestem Mage_Catalogzależny od mojego modułu (nawet jeśli czuję się trochę „brudny”, robiąc to)) i działa, ale mam inny problem. Potrzebuję innych elementów menu umieszczonych między niektórymi kategoriami i na końcu menu, więc nadal muszę móc je przenosić. Zaktualizuję pytanie.
Marius
-1
  1. utwórz nową podkategorię
  2. zmień link za pomocą javascript, np. nowa kategoria to „75”
jQuery(document).ready(function(){
    document.getElementById("menu75").getElementsByTagName("a")[0].href =

https: // YourNewLinkink ”; });

zatanabee
źródło
i skąd mam znać identyfikator elementu, jeśli ma on działać z dowolnym identyfikatorem? To nie jest realne rozwiązanie. Nie będę tego nazywać nawet obejściem.
Marius
działa na moim kodzie ... :)
zatanabee
id show @ Katalog> zarządzaj kategoriami
zatanabee