Magento – How to Get Top Menu in Header as dropdown in Magento 2

default.xmlheadermagento2toplinks

Want to show top links as "DROPDOWN" in custom theme. Trying from many days but still no success.

Have to show "Sign In/Up" Link in toplinks when customer is not logged in.

After Customer Logged In "Sign In/Up" replaced with Customer Name or Email Id with a "on hover" "DROPDOWN" having the following links in that

"My Account"
"My Orders"
"Custom Link"
"Sign Out"

Please help me out.

Reference for the above question

Reference Image for the above links

Best Answer

You have to create a block class to achieve that.

First of all in your module's frontend default.xml layout file you have to add the following code

<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <body>
        <referenceBlock name="top.links">
            <block class="Your_Namespace\Your_Modulename\Block\Link" name="custom-link" after="my-account-link"/>
        </referenceBlock>
    </body>
</page>

Your block class

namespace Your_Namespace\Your_Modulename\Block;
/**
 * Class Link
 *
 * @SuppressWarnings(PHPMD.DepthOfInheritance)
 */
class Link extends \Magento\Framework\View\Element\Html\Link
{
    /**
     * Template name
     *
     * @var string
     */
    protected $_template = 'Your_Namespace_Your_Modulename::link.phtml';  

    /**
     * @param \Magento\Framework\View\Element\Template\Context $context
     * @param array $data
     */
    public function __construct(
        \Magento\Framework\View\Element\Template\Context $context,
        array $data = []
    ) {
        parent::__construct($context, $data);
    }

    /**
     * @return string
     */
    public function getHref()
    {
        return $this->getUrl('custom/controller/action');
    }

    /**
     * @return \Magento\Framework\Phrase
     */
    public function getLabel()
    {
        return __('Your custom link');
    }
}

Then you need also to create the template file we defined in the block class and add the following code

<li class="link custom">
    <a <?php /* @escapeNotVerified */ echo $block->getLinkAttributes() ?>><?php echo $block->escapeHtml($block->getLabel()) ?></a>
</li>