Magento 2’deki navigasyon bağlantılarına kategori dışı bağlantı ekleme


29

Burada neyi yanlış yaptığımdan emin değilim. Kategori bağlantılarını tutan bloğa navigation.sections adı verilir. Aşağıdaki argümanları konteynere yönlendirerek, altında yeni bir link oluşturabileceğimi düşündüm. Herhangi bir yardım takdir edilmektedir.

<referenceContainer name="navigation.sections">
            <block class="Magento\Framework\View\Element\Html\Links" name="mylink">
                    <arguments>
                        <argument name="label" xsi:type="string">Mylink</argument>
                        <argument name="path" xsi:type="string">mypath</argument>
                        <argument name="css_class" xsi:type="string">mycss</argument>
                    </arguments>
            </block>
</referenceContainer>

Aynı merak ediyorum .. Bunun için bir çözüm buldunuz mu?

Listelenen her iki çözüm de benim için çalıştı.
themanwhoknowstheman,

Hangi Magento versiyonu üzerinde çalışıyorsunuz?
Razvan Zamfir

Yanıtlar:


34

[EDIT]
Görünüşe göre M2'nin son sürümlerinde bu artık işe yaramıyor.
Bunu işaret ettiği için teşekkürler Max.
Daha sonraki sürümlerde Magento\Theme\Block\Html\Topmenu, bir gözlemci yerine bir eklenti eklemeniz gerekir .
Bunu ekleetc/frontend/di.xml

<type name="Magento\Theme\Block\Html\Topmenu">
    <plugin name="[module]-topmenu" type="[Namespace]\[Module]\Plugin\Block\Topmenu" />
</type>

ve eklenti sınıf dosyasını oluşturun [Namespace]/[Module]/Plugin/Block/Topmenu.php

<?php 

namespace [Namespace]\[Module]\Plugin\Block;

use Magento\Framework\Data\Tree\NodeFactory;

class Topmenu
{
    /**
     * @var NodeFactory
     */
    protected $nodeFactory;

    public function __construct(
        NodeFactory $nodeFactory
    ) {
        $this->nodeFactory = $nodeFactory;
    }

    public function beforeGetHtml(
        \Magento\Theme\Block\Html\Topmenu $subject,
        $outermostClass = '',
        $childrenWrapClass = '',
        $limit = 0
    ) {
        $node = $this->nodeFactory->create(
            [
                'data' => $this->getNodeAsArray(),
                'idField' => 'id',
                'tree' => $subject->getMenu()->getTree()
            ]
        );
        $subject->getMenu()->addChild($node);
    }

    protected function getNodeAsArray()
    {
        return [
            'name' => __('Label goes here'),
            'id' => 'some-unique-id-here',
            'url' => 'http://www.example.com/',
            'has_active' => false,
            'is_active' => false // (expression to determine if menu item is selected or not)
        ];
    }
}

[/ EDIT]
Orijinal cevap:
Etkinliği kullanarak üst menüye öğeler ekleyebilirsiniz page_block_html_topmenu_gethtml_before.

Bu nedenle, bu dosyaların bulunduğu bir modül oluşturmanız gerekir (tüm dosyaların içinde olması gerekir app/code/[Namespace]/[Module]):

etc/module.xml - modül bildirim dosyası

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
    <module name="[Namespace]_[Module]" setup_version="2.0.0">
        <sequence>
            <module name="Magento_Theme"/>
        </sequence>
    </module>
</config>

registration.php - kayıt dosyası

<?php
\Magento\Framework\Component\ComponentRegistrar::register(
    \Magento\Framework\Component\ComponentRegistrar::MODULE,
    '[Namespace]_[Module]',
    __DIR__
);

etc/frontend/events.xml - etkinlik bildirim dosyası

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
    <event name="page_block_html_topmenu_gethtml_before">
        <observer name="[namespace]_[module]_observer" instance="[Namespace]\[Module]\Observer\Topmenu" />
    </event>
</config>

Observer/Topmenu.php - gerçek gözlemci

<?php
namespace [Namespace]\[Module]\Observer;
use Magento\Framework\Event\Observer as EventObserver;
use Magento\Framework\Data\Tree\Node;
use Magento\Framework\Event\ObserverInterface;
class Topmenu implements ObserverInterface
{
    public function __construct(
        ...//add dependencies here if needed
    )
    {
    ...
    }
    /**
     * @param EventObserver $observer
     * @return $this
     */
    public function execute(EventObserver $observer)
    {
        /** @var \Magento\Framework\Data\Tree\Node $menu */
        $menu = $observer->getMenu();
        $tree = $menu->getTree();
        $data = [
            'name'      => __('Menu item label here'),
            'id'        => 'some-unique-id-here',
            'url'       => 'url goes here',
            'is_active' => (expression to determine if menu item is selected or not)
        ];
        $node = new Node($data, 'id', $tree, $menu);
        $menu->addChild($node);
        return $this;
    }
}

Şimdi php bin/magento setup:upgrademodülü kurmak için cli komutunu çalıştırın ve gitmeniz iyi olur.


Topmenu.php kodun bir parçası mı eksik?
themanwhoknowstheman 7:16

1
@Solide. Bağlantıların sırası, gözlemcilerin uygulanma sırasına bağlıdır. Ana sayfanızın gözlemcisi katalogdan önce yürütülürse, önce ana sayfanın bağlantısı eklenmelidir. Değilse, bağlantıların sırasını değiştirmek için bu yaklaşıma bir göz atabilirsiniz : magento.stackexchange.com/q/7329/146 . yaklaşım Magento1 içindir, ancak bunu M2 koduna çevirebilirsiniz.
Marius

1
@ Marius: ne olmalı 'is_active'. Lütfen bir örnek ekleyin. Bu sayfada aktif link istiyorum.
zed Blackbeard

1
Bir olayda bir gözlemci kullanılıyor. Bir eklenti, herhangi bir genel yöntem üzerinde çalışabilir. Eklenti yaklaşımını kullanmanızı tavsiye ederim, çünkü bir tanesi üst menüye kategorileri eklemek için çekirdekte kullanılıyor.
Marius

1
Üzgünüm, aptal gibi hissediyorum, ancak birden fazla menüyü nasıl ekleyebilirsiniz? Bir $menu->addChild($node)kereden fazla kullanırsam , sonuncusu diğerlerini geçersiz kılar. Sadece bir menü gösterir (sonuncusu).
pinicio

17

Neden herkes hep modül yazmak istiyor. Bunu ben yaptım layout.xmlve bir çekicilik gibi çalıştı:

    <referenceBlock name="catalog.topnav">
        <block class="Magento\Framework\View\Element\Html\Link" name="contact-link">
            <arguments>
                <argument name="label" xsi:type="string" translate="true">Contact us</argument>
                <argument name="path" xsi:type="string" translate="true">contact</argument>
            </arguments>
        </block>
    </referenceBlock>

bu bağlantı yeni sekmede nasıl açılır?
jafar pinjar 28:18

İyi soru. Kodda bir şey buldum. Belki şunu deneyin: <argument name = "öznitelikler" xsi: type = "array"> <item name = "target" xsi: type = "string"> _ blank </item> </argument> Test edilmedi, ancak özellikler seçeneği kullanılabilir.
Johnny Longneck

Bir modül oluşturmak onu çok daha dinamik hale getirir. Çalıştığım birçok müşteri, bu durumda kendileri gibi şeyler yapmak istiyor, sayfalar yaratıyor ve bunları belirli bir sırada topmenüe ekliyor.
Roy Jeurissen

6

Bir modül yaratmanın dışındaki bir başka çözüm ise topmenu.phtml dosyasının üzerine yazmaktır. Bağlantılarınızı navigasyon sınıflarını miras almayı düşünüyorsanız, @Marius tarafından sağlanan çözümün bunu yapmanın en iyi yolu olduğunu not edeceğim. Bu Magento'nun mobil menüsünde sadece uygun css olmadan gösteriyor. Css_class argümanını uygun şekilde biçimlendirmek için kullanabilirsiniz.

YourTheme / Magento_Theme / templates / html / topmenu.phtml

<?php $columnsLimit = $block->getColumnsLimit() ?: 0; ?>
<?php $_menu = $block->getHtml('level-top', 'submenu', $columnsLimit) ?>

<nav class="navigation" role="navigation">
    <ul data-mage-init='{"menu":{"responsive":true, "expanded":true, "position":{"my":"left top","at":"left bottom"}}}'>
        <?php /* @escapeNotVerified */ echo $_menu; ?>
        <?php echo $block->getChildHtml() ?>
    </ul>
</nav>

YourTheme / Magento_Theme / düzeni / default.xml

<referenceContainer name="catalog.topnav">
               <block class="Magento\Framework\View\Element\Html\Link\Current" name="your.link">
                    <arguments>
                        <argument name="label" xsi:type="string">Link-name</argument>
                        <argument name="path" xsi:type="string">Link-url</argument>
                    </arguments>
              </block>
</referenceContainer>

Css sınıfı bağımsız değişkeninin bir örneğini nereden bulabilirim?
camdixon 27:16


şablon dosyasını xml dosyasına nasıl
bağlarsınız

6

Bu cevap Marius ♦ tarafından verilmiştir. Ben sadece kategori sekmesi menüsünde alt kategori eklemek için değiştirdim Marius answer 'ın cevabını başvurabilirsiniz. Ana kategoriye alt kategori eklemek için alt Topmenu.php dosyasını değiştirdim.

<?php 

namespace Ktpl\Navigationlink\Plugin\Block;

use Magento\Framework\UrlInterface;
use Magento\Framework\Data\Tree\NodeFactory;
use Magento\Store\Model\StoreManagerInterface;

class Topmenu
{
    /**
     * @var NodeFactory
     */
    protected $nodeFactory;
    protected $urlBuilder;
    protected $_storeManager;

    public function __construct(
        UrlInterface $urlBuilder,
        NodeFactory $nodeFactory,
        StoreManagerInterface $storeManager
    ) {
        $this->urlBuilder = $urlBuilder;
        $this->nodeFactory = $nodeFactory;
        $this->_storeManager = $storeManager;
    }

    public function beforeGetHtml(
        \Magento\Theme\Block\Html\Topmenu $subject,
        $outermostClass = '',
        $childrenWrapClass = '',
        $limit = 0
    ) {
        // condition for store
        if($this->getStoreCode() == 'store_id'):
        $productNode = $this->nodeFactory->create(
            [
                'data' => $this->getNodeAsArray('Products','products'),
                'idField' => 'id',
                'tree' => $subject->getMenu()->getTree()
            ]
        );
        $stockistsNode = $this->nodeFactory->create(
            [
                'data' => $this->getNodeAsArray('Stockists','stockists'),
                'idField' => 'id',
                'tree' => $subject->getMenu()->getTree()
            ]
        );
        $ourstoryNode = $this->nodeFactory->create(
            [
                'data' => $this->getNodeAsArray('Our Story','ourstory'),
                'idField' => 'id',
                'tree' => $subject->getMenu()->getTree()
            ]
        );
        $contactsNode = $this->nodeFactory->create(
            [
                'data' => $this->getNodeAsArray('Customer Care','contacts'),
                'idField' => 'id',
                'tree' => $subject->getMenu()->getTree()
            ]
        );
        /******* contacts's child *******/
        $warrantyRegistrationNode = $this->nodeFactory->create(
            [
                'data' => $this->getNodeAsArray('Warranty Registration','warranty-registration'),
                'idField' => 'id',
                'tree' => $subject->getMenu()->getTree()
            ]
        );
        $faqNode = $this->nodeFactory->create(
            [
                'data' => $this->getNodeAsArray('Frequently Asked Questions','faq'),
                'idField' => 'id',
                'tree' => $subject->getMenu()->getTree()
            ]
        );
        $ourProductGuaranteeNode = $this->nodeFactory->create(
            [
                'data' => $this->getNodeAsArray('Our Product Guarantee','our-product-guarantee'),
                'idField' => 'id',
                'tree' => $subject->getMenu()->getTree()
            ]
        );
        $warrantiesNode = $this->nodeFactory->create(
            [
                'data' => $this->getNodeAsArray('Warranties, Repairs & Spare Parts','warranties-repairs-spare-parts'),
                'idField' => 'id',
                'tree' => $subject->getMenu()->getTree()
            ]
        );
        $termsNode = $this->nodeFactory->create(
            [
                'data' => $this->getNodeAsArray('Terms & Conditions','terms-and-conditions'),
                'idField' => 'id',
                'tree' => $subject->getMenu()->getTree()
            ]
        );
        $privacyPolicyNode = $this->nodeFactory->create(
            [
                'data' => $this->getNodeAsArray('Our Privacy Policy','privacy-policy'),
                'idField' => 'id',
                'tree' => $subject->getMenu()->getTree()
            ]
        );
        $bookNode = $this->nodeFactory->create(
            [
                'data' => $this->getNodeAsArray('Book A Viewing','book-a-viewing'),
                'idField' => 'id',
                'tree' => $subject->getMenu()->getTree()
            ]
        );

        $contactsNode->addChild($warrantyRegistrationNode);
        $contactsNode->addChild($faqNode);
        $contactsNode->addChild($ourProductGuaranteeNode);
        $contactsNode->addChild($warrantiesNode);
        $contactsNode->addChild($termsNode);
        $contactsNode->addChild($privacyPolicyNode);
        $contactsNode->addChild($bookNode);
        /******* end contacts's child *******/

        $subject->getMenu()->addChild($productNode);
        $subject->getMenu()->addChild($stockistsNode);
        $subject->getMenu()->addChild($ourstoryNode);
        $subject->getMenu()->addChild($contactsNode);
        endif;
    }

    protected function getNodeAsArray($name,$id)
    {
        return [
            'name' => __($name),
            'id' => $id,
            'url' => $this->urlBuilder->getUrl($id),
            'has_active' => false,
            'is_active' => false // (expression to determine if menu item is selected or not)
        ];
    }

    public function getStoreCode()
    {
        return $this->_storeManager->getStore()->getCode();
    }
}

Üst kategori ve alt kategori için düğüm oluşturmanız gerekiyor ve bundan sonra addChild yöntemini kullanarak alt kategoriyi üst kategoriye atayabilirsiniz.

$contactsNode->addChild($warrantyRegistrationNode);

Teşekkürler! Alt menü eklemek o kadar kolay değildi!
Juliano Vargas

Efendim, eklediğim bağlantıda özel div'imi göstermek istersem Topmenu. Mesela, Link'in üzerine geldiğimde, benim özel divimi
Asad Khan,

1

Yukarıdaki cevapları Marius kullanarak alt menü öğelerini ekledim. Ayrıca, html oluşturulmadan önce ağacı düzenlemenin bir yolunu ve ardından oluşturulduktan sonra doğrudan html'nin nasıl düzenleneceğini gösteririm. Magento 2.1'de çalışır. Topmenu.php dosyasını şununla güncelle:

<?php
namespace Seatup\Navigation\Observer;
use Magento\Framework\Event\Observer as EventObserver;
use Magento\Framework\Data\Tree\Node;
use Magento\Framework\Event\ObserverInterface;
class Topmenu implements ObserverInterface
{
    protected $_cmsBlock;

    public function __construct(
        \Magento\Cms\Block\Block $cmsBlock
    )
    {
        $this->_cmsBlock = $cmsBlock;
    }
    /**
     * @param EventObserver $observer
     * @return $this
     */
    public function execute(EventObserver $observer)
    {
        /** @var \Magento\Framework\Data\Tree\Node $menu */
        $eventName = $observer->getEvent()->getName();
        if($eventName == 'page_block_html_topmenu_gethtml_before'){
            // With the event name you can edit the tree here
            $menu = $observer->getMenu();
            $tree = $menu->getTree();
            $children = $menu->getChildren();

            foreach ($children as $child) {
                if($child->getChildren()->count() > 0){ //Only add menu items if it already has a dropdown (this could be removed)
                    $childTree = $child->getTree();
                    $data1 = [
                        'name'      => __('Menu item label here'),
                        'id'        => 'some-unique-id-here',
                        'url'       => 'url goes here',
                        'is_active' => FALSE
                    ];
                    $node1 = new Node($data1, 'id', $childTree, $child);
                    $childTree->addNode($node1, $child);
                }
            }
            return $this;
        } else if($eventName == 'page_block_html_topmenu_gethtml_after'){
            // With the event name you can edit the HTML output here
            $transport = $observer['transportObject'];

            //get the HTML
            $old_html = $transport->getHtml();

            //render the block. I am using a CMS block
            $new_output = $this->_cmsBlock->getLayout()->createBlock('Magento\Cms\Block\Block')->setBlockId('cms_block_identifier')->toHtml();
            //the transport now contains html for the group/class block
            //which doesn't matter, because we already extracted the HTML into a 
            //string primitive variable
            $new_html = str_replace('to find', $new_output , $old_html);    
            $transport->setHtml($new_html);
        }
    }
}

1

<header>
CMS sayfasına bağlantı ekleme, Galeri’deki en üstteki gezinmeye bağlantı eklemek istiyorum

Burada default.xml dosyasını düzenleyin / yerleştirin:

app/design/frontend/Vendor/theme/Magento_Theme/layout/default.xml

Aşağıdaki kodu ekleyin:

<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <body>
        <referenceContainer name="catalog.topnav">
           <block class="Magento\Framework\View\Element\Html\Link\Current" name="gallery.link">
                <arguments>
                    <argument name="label" xsi:type="string">Gallery</argument>
                    <argument name="path" xsi:type="string">gallery</argument>
                </arguments>
          </block> 
       </referenceContainer>
    </body>
</page>

Bu, aşağıdaki ayarlarla CMS sayfasına (Galeri) bir bağlantı ekler:

Title = Gallery
Url Key = gallery
Link = https://example.com/gallery/

Yeni bağlantının doğru hizalandığından emin olmak için aşağıdaki stili ekleyin:

.navigation .nav.item {
margin: 0 10px 0 0;
display: inline-block;
position: relative;
}

Kodun sonuçları (Ürünler, örneğin bir kategori olarak ayarlanmıştır)



0

is_activeİfade eklemek isteyenler için , özellikle yukarıda sorulan @zed Karasakal.

Kişiyi bağlamak için kullandım ve birine bağlandığım gibi özel modülle de çalışacak.

'is_active' => ($ $ -> request-> getFrontName () == 'contact'? true: false)

// (menü öğesinin seçilip seçilmediğini belirleyen ifade)

Umarım herkese yardım eder.


0

Bu da iyi bir seçenek:

Uygulamanın / tasarım / kullanıcı arayüzü / işportacı / yourtheme / Magento_Theme / düzeni / default.xml

<referenceBlock name="header.links">
    <block class="Magento\Framework\View\Element\Html\Link" name="yourlinkname" before='wish-list-link'>
        <arguments>
            <argument name="label" xsi:type="string" translate="true">yourlink</argument>
            <argument name="path" xsi:type="string" translate="true">yourlink</argument>
        </arguments>
    </block>
</referenceBlock>

-1

Sadece bir gezinme menüsü bağlantısı için, elde edilecek çok fazla adım yok, bunu yapmak için kısa bir rehber buldum, bu topmenu.phtmldosyayı Magento_Thememodülden geçersiz kılan bir temaya işaret ediyor : https://linkstraffic.net/adding-custom- menu-item-inside-magento2 / Başarıyla test ettim, bu yüzden sizinle paylaşıyorum.


Magento SE'ye hoş geldiniz. Bağlantıları bir cevapta gönderirseniz, lütfen bağlantının bir anda kesilmesi durumunda cevabın hala değerli olduğundan emin olun: Örneğin, bağlantılı makaleyi özetleyin veya ilgili parçaları alıntılayın. Bu önemlidir çünkü StackExchange şu anda bir kişiye yardım edecek bir destek forumu değil bir bilgi veritabanı olmayı hedeflemektedir. Gelecekteki ziyaretçiler hala sorulardan ve cevaplardan faydalanmalıdır.
Siarhey Uchukhlebau
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.