Додавання посилань на меню категорій


20

Я знаю, що це старе питання з великою кількістю відповідей, більшість із них пропонують редагувати шаблон меню, але це не працює для мене. Не потрібно пояснювати, чому, скажімо, я трохи OCD щодо того, щоб робити справи "правильним" способом.
Це питання може слугувати матеріалом для інших, хто потребує. Ось іде.
Починаючи з Magento 1.7 Верхнє меню будується з допомогою події: page_block_html_topmenu_gethtml_before. Це використовується Mage_Catalogмодулем для додавання категорій. Я хочу цим скористатися. Для цього я створив спостерігача у своєму модулі так:

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

У Observer.phpкласі я

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

У мого спостерігача є ще якийсь код, який додає всі бренди як підпункти Brandsменю, але в цьому немає необхідності.
Це прекрасно працює і додає меню Brandsяк останній пункт у меню.
Проблема полягає в тому, що я хочу, щоб це було як перше меню, і мій спостерігач викликається після спостерігача, Mage_Catalogякий додає категорії. Оскільки немає можливості (не те, що я знаю) сортувати порядок спостерігачів за подією ... У мене є проблема
[EDIT]
Оскільки @Benmark запропонував, я зробивMage_CatalogМодуль залежить від мого модуля, і тепер мій пункт є першим у списку. Але мені все ж доводиться додавати меню між категоріями і в кінці. Створення нового модуля, ймовірно, вирішить проблему з пунктами в кінці меню, але у мене все ще виникає проблема з тими, що перебувають між категоріями,
[/ EDIT]
Тому в основному моє питання поновлюється на " (Як) я можу пересуватися навколо дитини вузли a Varien_Data_Tree_Nodeв Varien_Data_Treeоб’єкті? "
Будь ласка, не пропонуйте додавати Brandsяк першу категорію в дерево категорій. Це не варіант (як я вже сказав ... мій OCD про ці речі).


Чи є причина не створювати порожні категорії та показувати лише блок CMS? - Я приймаю "так" як відповідь, просто щоб бути впевненим, ви думали про це :)
Fabian Blechschmidt

1
@FabianBlechschmidt. "Так". Немає сенсу деталізувати деталі, але є причини (деякі з них можуть бути досить дурними). Я не приймаю "правил" на цьому. Так це робиться так.
Маріус

@FabianBlechschmidt: Очистити деякі "тумани" тут є вагомою причиною, тому ви не скажете, що я впертий (навіть якщо я є). Спеціальні посилання (бренди, нові, продажі та інші) не в одному місці для всіх представлень магазинів. Але всі представлення магазинів використовують однакові категорії. Тому я не хочу створювати інше дерево для кожного представлення магазину. Використовуючи спостерігач, я можу прочитати деякі налаштування конфігурації та впорядкувати елементи так, як мені хочеться. Я навіть можу додати пункти меню залежно від ідентифікатора перегляду магазину.
Маріус

Також цікаво, у мене така ж проблема, моє рішення полягає в тому, щоб замінити Varien_Data_Tree_Node_Collection і додати сюди метод для сортування вузлів так, як я хочу, але я шукаю більш чистий спосіб.
Fab

Відповіді:


10

Після трохи зусиль тут я знайшов рішення. Я дозволив моєму спостерігачеві виконати роботу після входу Mage_Catalogі вирішив повністю створити меню повністю.
Основна ідея полягає в тому, щоб усі існуючі пункти меню помістити їх у тимчасовий масив, видалити їх з меню, потім додати мої посилання між існуючими елементами і, врешті-решт, знову додати всі елементи до меню. Щось на зразок цього:

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

Це дозволяє вирішити мою проблему, але я сподіваюся на більш елегантний метод зробити це.


Маріус - це будь-який інший спостерігач, окрім page_block_html_topmenu_gethtml_для того, щоб додати посилання на меню категорій?
Pradeep Sanku

Причина в тому, що я використовував того ж спостерігача, але у мене було розширення для мегамену, яке не викликає page_block_html_topmenu_gethtml_before.please, дайте мені знати
Pradeep Sanku

@PradeepSanku. Я не знаю жодної іншої події. Можливо, розширення, яке ви використовуєте, повністю замінює головне меню. Вам слід попросити розробника про підтримку.
Маріус

4

Оскільки немає можливості (не те, що я знаю) сортувати порядок спостерігачів за подією ... У мене є проблема.

Ах, але є! У файлі декларації модуля встановіть залежність від Mage_Catalogвашого модуля, наприклад:

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

Крім того, ви можете (я думаю) скопіювати конфігурацію спостерігача за каталогом у frontendобласть події та дезактивувати її в globalзоні. Моє припущення, що globalподії обробляються до frontendподій. (Я навіть не знаю, чому саме ця подія налаштована globalв першу чергу.)

І звичайно, є й інші варіанти, на які можна скористатися за допомогою переписувань та PHP.


Спасибі. У вас тут мій +1. Я фактично перемістив свою подію всередині <global>тегу, я оголосив, Mage_Catalogщо залежить від мого модуля (навіть якщо я відчуваю це трохи "брудно", але це працює, але я закінчую інше питання. Мені потрібні деякі інші пункти меню, розміщені між деякими категоріями та в кінці меню, тому мені ще потрібно мати можливість переміщати їх по всьому. Я оновлю питання.
Маріус

-1
  1. створити нову підкатегорію
  2. змінити посилання на javascript, коли ваша нова категорія "75"
jQuery(document).ready(function(){
    document.getElementById("menu75").getElementsByTagName("a")[0].href =

" https: // YourNewLinkink "; });


і як мені знати ідентифікатор елемента, якщо він повинен працювати з будь-яким id? Це не є прийнятним рішенням. Не буду називати це навіть вирішенням проблеми.
Маріус

працює на мій код ... :)
zatanabee

id show @ Каталог> керуйте категоріями
zatanabee
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.