カテゴリメニューへのリンクの追加


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カテゴリーを追加した後にオブザーバーが呼び出されることです。イベントのオブザーバーの順序を並べ替える方法はないので(私にはわかりません)...問題があります
[編集]
@Benmarksが示唆したように、Mage_Catalogモジュールは私のモジュールに依存し、メニュー項目がリストの最初になりました。ただし、カテゴリ間および最後にメニューを追加する必要があります。新しいモジュールを作成すると、おそらくメニューの最後にあるアイテムの問題は解決しますが、カテゴリ間のものにはまだ問題があります。
[/編集]
したがって、基本的に私の質問は「(方法)ノードVarien_Data_Tree_NodeVarien_Data_Treeオブジェクト?」カテゴリツリーの最初のカテゴリとしてを
追加することを提案しないでくださいBrands。これはオプションではありません(私が言ったように...これらのことについての私のOCD)。


空のカテゴリを作成せず、CMSブロックのみを表示する理由はありますか?-私は答えとして「はい」を受け入れます、確かに、あなたはこれについて考えました:)
ファビアンBlechschmidt

1
@FabianBlechschmidt。「はい」。詳細を取得する意味はありませんが、理由があります(その一部はかなり愚かかもしれません)。私はこれに「ルール」を作りません。そのため、このようにする必要があります。
マリウス

@FabianBlechschmidt:ここにある「霧」のいくつかをクリアするのは正当な理由ですので、あなたが私が頑固だとは言わないでしょう(たとえ私がそうであっても)。カスタムリンク(ブランド、新規、販売など)は、すべてのストアビューで同じ場所にはありません。ただし、すべてのストアビューは同じカテゴリを使用します。したがって、ストアビューごとに異なるツリーを作成する必要はありません。オブザーバーを使用することで、いくつかの構成設定を読み取り、必要に応じてアイテムを配置できます。ストアビューIDに応じてメニュー項目を追加することもできます。
マリウス

また、私は同じ問題を抱えています。私の解決策は、Varien_Data_Tree_Node_Collectionをオーバーライドし、ここにノードを並べ替えるメソッドを追加することですが、よりクリーンな方法を探しています。
ファブ

回答:


10

ここで少し苦労した後、私が見つけた解決策があります。私はオブザーバーを1つ後に実行させ、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);
    }
}

これは私の問題を解決するために継ぎ目がありますが、よりエレガントな方法を望んでいます。


Mariusは、カテゴリメニューにリンクを追加するpage_block_html_topmenu_gethtml_before以外のオブザーバーですか?
Pradeep Sanku

その理由は、私は同じオブザーバを使用していたが、私はpage_block_html_topmenu_gethtml_before.pleaseを呼び出していませんmegamenuの拡張子を持っていたされたが、私が知っている
プラディープ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で動作することになっている場合、どのようにして要素のIDを知るのですか?これは実行可能な解決策ではありません。私はそれを回避策とも呼びません。
マリウス

それは私のコードで動作します... :)
zatanabee

カタログ@ IDショー>カテゴリ管理
zatanabee
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.