Magento 2 में नेविगेशन लिंक के लिए एक गैर-श्रेणी लिंक जोड़ना


29

मुझे यकीन नहीं है कि मैं यहां क्या गलत कर रहा हूं। जिस श्रेणी में श्रेणी लिंक होती है उसे नेविगेशन के रूप में संदर्भित किया जाता है। मैंने सोचा कि कंटेनर की ओर निम्नलिखित दलीलों को निर्देशित करके मैं इसके तहत एक नया लिंक बना सकूंगा। किसी भी मदद की सराहना की है।

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

मैं वही सोच रहा हूँ .. क्या आपने इसके लिए कोई हल ढूंढा है?

सूचीबद्ध दोनों समाधान मेरे लिए काम कर चुके हैं।
themanwhoknowstheman

आप किस Magento के संस्करण पर काम कर रहे हैं?
रज़वान ज़म्फिर

जवाबों:


34

[संपादित करें]
जाहिर है, एम 2 के नवीनतम संस्करणों में यह काम नहीं करता है।
इसे इंगित करने के लिए अधिकतम करने के लिए धन्यवाद।
बाद के संस्करण के लिए आपको Magento\Theme\Block\Html\Topmenuएक पर्यवेक्षक के बजाय एक प्लगइन जोड़ने की आवश्यकता है ।
इसमें जोड़ेंetc/frontend/di.xml

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

और प्लगइन वर्ग फ़ाइल बनाएँ [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]
मूल उत्तर:
आप इवेंट का उपयोग करके शीर्ष मेनू में तत्व जोड़ सकते हैं page_block_html_topmenu_gethtml_before

तो आपको इन फाइलों के साथ एक मॉड्यूल बनाने की जरूरत है (सभी फाइलें अंदर होनी चाहिए app/code/[Namespace]/[Module]):

etc/module.xml - मॉड्यूल घोषणा फ़ाइल

<?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 - पंजीकरण फ़ाइल

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

etc/frontend/events.xml - घटनाओं घोषणा फ़ाइल

<?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 - वास्तविक पर्यवेक्षक

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

अब php bin/magento setup:upgradeमॉड्यूल को स्थापित करने के लिए क्ली में चलाएं और आप जाने के लिए अच्छे हैं।


क्या Topmenu.php कोड का हिस्सा नहीं है?
थीमनोक्वनस्टीमैन

1
@Solide। लिंक का क्रम पर्यवेक्षकों द्वारा निष्पादित किए जाने वाले आदेश पर निर्भर करता है। यदि आपके मुखपृष्ठ पर्यवेक्षक को कैटलॉग एक से पहले निष्पादित किया जाता है तो मुखपृष्ठ लिंक पहले जोड़ा जाना चाहिए। यदि नहीं, तो आप लिंक के क्रम को बदलने के लिए इस दृष्टिकोण पर एक नज़र डाल सकते हैं: magento.stackexchange.com/q/7329/146 । दृष्टिकोण Magento1 के लिए है, लेकिन आप इसे M2 कोड में अनुवाद कर सकते हैं।
Marius

1
@ मेरी: क्या होना चाहिए 'is_active'। कृपया कुछ उदाहरण जोड़ें। मुझे इस पेज पर सक्रिय लिंक चाहिए।
ब्लैकबीयर्ड जेड

1
एक घटना पर एक पर्यवेक्षक का उपयोग किया जाता है। एक प्लगइन किसी भी सार्वजनिक विधि पर काम कर सकता है। मैं प्लगइन दृष्टिकोण का उपयोग करने की सलाह दूंगा क्योंकि शीर्ष मेनू में श्रेणियों को जोड़ने के लिए कोर में एक का उपयोग किया जाता है।
मेरियस

1
क्षमा करें, मैं एक बेवकूफ की तरह महसूस करता हूं, लेकिन आप एक से अधिक मेनू कैसे जोड़ सकते हैं? यदि मैं $menu->addChild($node)एक से अधिक बार उपयोग करता हूं , तो अंतिम एक दूसरे को ओवरराइड करता है। यह केवल एक मेनू (अंतिम एक) दिखाता है।
पिनिकियो

17

हर कोई हमेशा एक मॉड्यूल क्यों लिखना चाहता है। मैंने अपने में layout.xmlऐसा किया और यह एक आकर्षण की तरह काम करता है:

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

उस लिंक को नए टैब में कैसे खोलें?
जाफर पिंजर

अच्छा प्रश्न। कोड में कुछ मिला। शायद यह कोशिश करें: <तर्क नाम = "गुण" xsi: प्रकार = "सरणी"> <आइटम नाम = "लक्ष्य" xsi: प्रकार = "स्ट्रिंग"> _ रिक्त </ आइटम> </ तर्क> परीक्षण नहीं किया गया है, लेकिन वहाँ है उपलब्ध विकल्प विकल्प।
जॉनी लॉन्गनेक

एक मॉड्यूल बनाना इसे और अधिक गतिशील बनाता है। मेरे साथ काम करने वाले बहुत से ग्राहक इस मामले में खुद ही काम करना चाहते हैं जैसे पेज बनाना और उन्हें एक विशिष्ट क्रम में शीर्षमेनू में जोड़ना।
रॉय ज्यूरीसेन

6

मॉड्यूल बनाने के बाहर एक और समाधान topmenu.phtml ओवरराइटिंग है। मैं नोट करूंगा कि @Marius द्वारा प्रदान किया गया समाधान ऐसा करने का सबसे अच्छा तरीका है यदि आप अपने लिंक को नेविगेशन कक्षाओं के वारिस करने का इरादा रखते हैं। यह केवल उचित सीएसएस के बिना, Magento के मोबाइल मेनू में दिखाता है। आप शैली के अनुसार css_class तर्क का उपयोग कर सकते हैं।

YourTheme / Magento_Theme / टेम्पलेट्स / 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 / लेआउट / 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>

मुझे सीएसएस वर्ग तर्क का एक उदाहरण कहां मिल सकता है?
कैमडिक्सन


आप टेम्पलेट फ़ाइल को xml फ़ाइल से कैसे लिंक करते हैं ..
सर्वेश तिवारी

6

यह उत्तर मारियस द्वारा प्रदान किया गया है have मैंने इसे श्रेणी टैब मेनू में बाल श्रेणी जोड़ने के लिए संशोधित किया है, आप मारियस के उत्तर का उल्लेख कर सकते हैं। मैंने मुख्य श्रेणी में बाल श्रेणी जोड़ने के लिए सिर्फ बच्चे Topmenu.php फ़ाइल को संशोधित किया है

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

आपको मूल श्रेणी और बाल श्रेणी के लिए नोड बनाने की आवश्यकता है और उसके बाद आप यहां एड-चिल्ड पद्धति का उपयोग करके बाल श्रेणी को माता-पिता की श्रेणी में निर्दिष्ट कर सकते हैं।

$contactsNode->addChild($warrantyRegistrationNode);

धन्यवाद! एहसास नहीं था कि यह सबमेनू को जोड़ना आसान था!
जूलियानो वर्गास

और सर अगर मैं अपने कस्टम डिव को मेरे द्वारा जोड़े गए कस्टम लिंक पर दिखाना चाहता हूं Topmenu। जैसे जब मैं लिंक पर माउस घुमाता हूँ तो यह मेरे कस्टम डिव को दिखाता है
असद खान

1

Marius द्वारा उपर्युक्त उत्तर का उपयोग करके मैंने सबमेनू आइटम जोड़े। मैं एक तरीका भी बताता हूं कि आप html बनाने से पहले पेड़ को संपादित कर सकते हैं और फिर एक बार इसे बनाने के बाद html को सीधे कैसे संपादित कर सकते हैं। यह Magento 2.1 में काम करता है। इसके साथ Topmenu.php अपडेट करें:

<?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>
सीएमएस पृष्ठ, गैलरी के लिए एक लिंक जोड़ने के हैं

यहां डिफ़ॉल्ट / xml संपादित करें / रखें:

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

निम्नलिखित कोड जोड़ें:

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

यह निम्नलिखित सेटिंग्स के साथ सीएमएस पृष्ठ, गैलरी के लिए एक लिंक जोड़ता है:

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

नई लिंक को सही ढंग से संरेखित करने के लिए निम्नलिखित स्टाइल जोड़ें:

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

कोड के परिणाम (उत्पाद एक उदाहरण के लिए एक श्रेणी के रूप में सेटअप है)


0

यदि आप CMS Pages या अन्य जोड़ना चाहते हैं तो यह सबसे अच्छा होगा

https://github.com/Mestrona/Mestrona_CategoryRedirect

मेरे लिए काम किया :)


मैंने इस मॉड्यूल की कोशिश की लेकिन यह Magento 2.1.3 में काम नहीं करता है
निकुंज वदरिया

0

is_activeअभिव्यक्ति जोड़ने के इच्छुक लोगों के लिए , विशेष रूप से @ ब्लैकबर्ड ने जो ऊपर पूछा।

मैंने संपर्क लिंक करने के लिए उपयोग किया है और यह कस्टम मॉड्यूल के साथ भी काम करेगा क्योंकि मैं किसी एक को लिंक कर रहा हूं।

'is_active' => ($ यह-> अनुरोध-> getFrontName () == 'संपर्क'? सत्य: वास्तविक)

// (मेनू आइटम चयनित है या नहीं यह निर्धारित करने के लिए अभिव्यक्ति)

आशा है कि यह किसी की मदद करता है।


0

यह भी एक अच्छा विकल्प है:

एप्लिकेशन / डिजाइन / दृश्यपटल / विक्रेता / yourtheme / Magento_Theme / लेआउट / 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

बस एक नेविगेशन मेनू लिंक के लिए, प्राप्त करने के लिए कोई बहुत अधिक कदम नहीं है, मैंने ऐसा करने पर एक छोटा ट्यूटोरियल पाया है, इसका मतलब है कि यह एक विषय है जो मॉड्यूल topmenu.phtmlसे फ़ाइल को ओवरराइड करता है Magento_Theme: https://linkstraffic.net/adding-custom- मेनू-मद-इनसाइड-मैगेंटो 2 / मैंने इसे सफलतापूर्वक परीक्षण किया है, इसलिए मैं इसे आप लोगों के साथ साझा करता हूं।


Magento SE में आपका स्वागत है। यदि आप किसी उत्तर में लिंक पोस्ट करते हैं, तो कृपया सुनिश्चित करें कि उत्तर अभी भी मूल्यवान है, यदि लिंक कुछ समय में मृत हो जाता है: उदाहरण के लिए, लिंक किए गए लेख को संक्षिप्त करें या संबंधित भागों को उद्धृत करें। यह महत्वपूर्ण है क्योंकि StackExchange का लक्ष्य एक ज्ञान डेटाबेस होना है, न कि एक समर्थन मंच जो अभी एक व्यक्ति की मदद करता है। भविष्य के आगंतुकों को अभी भी सवाल और जवाब से लाभ उठाना चाहिए।
सियारि उचुकलेबौ
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.